TAV: first working psychovisual tuning

This commit is contained in:
minjaesong
2025-09-20 11:15:04 +09:00
parent d3a18c081a
commit 206e43a308
2 changed files with 186 additions and 47 deletions

View File

@@ -3889,10 +3889,97 @@ class GraphicsJSR223Delegate(private val vm: VM) {
}
private fun getPerceptualWeight(level: Int, subbandType: Int, isChroma: Boolean, maxLevels: Int): Float {
return 1f
// Psychovisual model based on DWT coefficient statistics and Human Visual System sensitivity
// Data-driven model based on coefficient variance analysis - MUST match encoder exactly
if (!isChroma) {
// LUMA CHANNEL: Based on statistical analysis from real video content
when (subbandType) {
0 -> { // LL subband - contains most image energy, preserve carefully
return when {
level >= 6 -> 0.6f // LL6: High energy but can tolerate moderate quantization (range up to 22K)
level >= 5 -> 0.7f // LL5: Good preservation
else -> 0.8f // Lower LL levels: Fine preservation
}
}
1 -> { // LH subband - horizontal details (human eyes more sensitive)
return when {
level >= 6 -> 0.7f // LH6: Significant coefficients (max ~500), preserve well
level >= 5 -> 0.8f // LH5: Moderate coefficients (max ~600)
level >= 4 -> 1.0f // LH4: Small coefficients (max ~50)
level >= 3 -> 1.2f // LH3: Very small coefficients, can quantize more
level >= 2 -> 1.4f // LH2: Minimal impact
else -> 1.6f // LH1: Least important
}
}
2 -> { // HL subband - vertical details (less sensitive due to HVS characteristics)
return when {
level >= 6 -> 0.9f // HL6: Can quantize more aggressively than LH6
level >= 5 -> 1.0f // HL5: Standard quantization
level >= 4 -> 1.3f // HL4: Notable range but less critical
level >= 3 -> 1.5f // HL3: Can tolerate more quantization
level >= 2 -> 1.7f // HL2: Less important
else -> 2.0f // HL1: Most aggressive for vertical details
}
}
3 -> { // HH subband - diagonal details (least important for HVS)
return when {
level >= 6 -> 1.1f // HH6: Preserve some diagonal detail
level >= 5 -> 1.3f // HH5: Can quantize aggressively
level >= 4 -> 1.6f // HH4: Very aggressive
level >= 3 -> 2.0f // HH3: Minimal preservation
level >= 2 -> 2.2f // HH2: Maximum compression
else -> 2.5f // HH1: Most aggressive quantization
}
}
else -> 1.0f
}
} else {
// CHROMA CHANNELS: Less critical for human perception, more aggressive quantization
when (subbandType) {
0 -> { // LL chroma - still important but less than luma
return when {
level >= 6 -> 0.8f // Chroma LL6: Less critical than luma LL
level >= 5 -> 0.9f
else -> 1.0f
}
}
1 -> { // LH chroma - horizontal chroma details
return when {
level >= 6 -> 1.0f
level >= 5 -> 1.2f
level >= 4 -> 1.4f
level >= 3 -> 1.6f
level >= 2 -> 1.8f
else -> 2.0f
}
}
2 -> { // HL chroma - vertical chroma details (even less critical)
return when {
level >= 6 -> 1.2f
level >= 5 -> 1.4f
level >= 4 -> 1.6f
level >= 3 -> 1.8f
level >= 2 -> 2.0f
else -> 2.2f
}
}
3 -> { // HH chroma - diagonal chroma details (most aggressive)
return when {
level >= 6 -> 1.4f
level >= 5 -> 1.6f
level >= 4 -> 1.8f
level >= 3 -> 2.1f
level >= 2 -> 2.3f
else -> 2.5f
}
}
else -> 1.0f
}
}
return 1.0f
// Legacy data-driven model (kept for reference but not used)
/*if (!isChroma) {
// Luma strategy based on statistical variance analysis from real video data
return when (subbandType) {
0 -> { // LL
@@ -3939,7 +4026,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
// Chroma strategy - apply 0.85x reduction to luma weights for color preservation
val lumaWeight = getPerceptualWeight(level, subbandType, false, maxLevels)
return lumaWeight * 1.6f
}
}*/
}
// Helper function to calculate five-number summary for coefficient analysis
@@ -4027,7 +4114,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
}
}
private val tavDebugFrameTarget = 0 // use negative number to disable the debug print
private val tavDebugFrameTarget = -1 // use negative number to disable the debug print
private var tavDebugCurrentFrameNumber = 0
fun tavDecode(blockDataPtr: Long, currentRGBAddr: Long, prevRGBAddr: Long,