From b9f38dfa0869738187b7765a03b21c9810cd34e2 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 1 Oct 2025 12:21:04 +0900 Subject: [PATCH] TAV: revised psychovisual model --- .../net/torvald/tsvm/GraphicsJSR223Delegate.kt | 13 ++++++++----- video_encoder/encoder_tav.c | 16 +++++++++------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt index ee31fdc..d197653 100644 --- a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt +++ b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt @@ -4148,12 +4148,15 @@ class GraphicsJSR223Delegate(private val vm: VM) { private fun perceptual_model3_LH(quality: Int, level: Float): Float { val H4 = 1.2f - val Lx = H4 - ((quality + 1f) / 15f) * (level - 4f) - val Ld = (quality + 1f) / -15f - val C = H4 - 4f * Ld - ((-16f * (quality - 5f)) / (15f)) - val Gx = (Ld * level) - (((quality - 5f) * (level - 8f) * level) / (15f)) + C + val Q = 2f // using fixed value for fixed curve; quantiser will scale it up anyway + val Q12 = Q * 12f + val x = level - return if (level >= 4) Lx else Gx + val Lx = H4 - ((Q + 1f) / 15f) * (x - 4f) + val C3 = -1f / 45f * (Q12 + 92) + val G3x = (-x / 180f) * (Q12 + 5 * x * x - 60 * x + 252) - C3 + H4 + + return if (level >= 4) Lx else G3x } private fun perceptual_model3_HL(quality: Int, LH: Float): Float { diff --git a/video_encoder/encoder_tav.c b/video_encoder/encoder_tav.c index a806e24..e75aa91 100644 --- a/video_encoder/encoder_tav.c +++ b/video_encoder/encoder_tav.c @@ -1386,15 +1386,17 @@ static void quantise_dwt_coefficients(float *coeffs, int16_t *quantised, int siz } // https://www.desmos.com/calculator/mjlpwqm8ge -// where Q=quality, x=level static float perceptual_model3_LH(int quality, float level) { float H4 = 1.2f; - float Lx = H4 - ((quality + 1.f) / 15.f) * (level - 4.f); - float Ld = (quality + 1.f) / -15.f; - float C = H4 - 4.f * Ld - ((-16.f*(quality - 5.f))/(15.f)); - float Gx = (Ld * level) - (((quality - 5.f)*(level - 8.f)*level)/(15.f)) + C; + float Q = 2.f; // using fixed value for fixed curve; quantiser will scale it up anyway + float Q12 = Q * 12.f; + float x = level; - return (level >= 4) ? Lx : Gx; + float Lx = H4 - ((Q + 1.f) / 15.f) * (x - 4.f); + float C3 = -1.f / 45.f * (Q12 + 92); + float G3x = (-x / 180.f) * (Q12 + 5*x*x - 60*x + 252) - C3 + H4; + + return (level >= 4) ? Lx : G3x; } static float perceptual_model3_HL(int quality, float LH) { @@ -1406,7 +1408,7 @@ static float lerp(float x, float y, float a) { } static float perceptual_model3_HH(float LH, float HL, float level) { - float Kx = (sqrtf(level) - 1.f) * 0.5f + 0.5f; + float Kx = fmaf((sqrtf(level) - 1.f), 0.5f, 0.5f); return lerp(LH, HL, Kx); }