tavlib: quant fix 2

This commit is contained in:
minjaesong
2025-12-06 23:49:16 +09:00
parent a2233aedaf
commit 7f951366da
3 changed files with 39 additions and 33 deletions

View File

@@ -1336,6 +1336,7 @@ try {
graphics.tavDecodeGopToVideoBufferAsync( graphics.tavDecodeGopToVideoBufferAsync(
compressedPtr, compressedSize, gopSize, compressedPtr, compressedSize, gopSize,
header.width, decodeHeight, // Use decodeHeight for interlaced field support header.width, decodeHeight, // Use decodeHeight for interlaced field support
baseVersion >= 5,
header.qualityLevel, header.qualityLevel,
QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg], QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg],
header.channelLayout, header.channelLayout,
@@ -1411,6 +1412,7 @@ try {
graphics.tavDecodeGopToVideoBufferAsync( graphics.tavDecodeGopToVideoBufferAsync(
compressedPtr, compressedSize, gopSize, compressedPtr, compressedSize, gopSize,
header.width, decodeHeight, // Use decodeHeight for interlaced field support header.width, decodeHeight, // Use decodeHeight for interlaced field support
baseVersion >= 5,
header.qualityLevel, header.qualityLevel,
QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg], QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg],
header.channelLayout, header.channelLayout,
@@ -1455,6 +1457,7 @@ try {
graphics.tavDecodeGopToVideoBufferAsync( graphics.tavDecodeGopToVideoBufferAsync(
compressedPtr, compressedSize, gopSize, compressedPtr, compressedSize, gopSize,
header.width, decodeHeight, // Use decodeHeight for interlaced field support header.width, decodeHeight, // Use decodeHeight for interlaced field support
baseVersion >= 5,
header.qualityLevel, header.qualityLevel,
QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg], QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg],
header.channelLayout, header.channelLayout,
@@ -1824,6 +1827,7 @@ try {
graphics.tavDecodeGopToVideoBufferAsync( graphics.tavDecodeGopToVideoBufferAsync(
readyGopData.compressedPtr, readyGopData.compressedSize, readyGopData.gopSize, readyGopData.compressedPtr, readyGopData.compressedSize, readyGopData.gopSize,
header.width, decodeHeight, // Use decodeHeight for interlaced field support header.width, decodeHeight, // Use decodeHeight for interlaced field support
baseVersion >= 5,
header.qualityLevel, header.qualityLevel,
QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg], QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg],
header.channelLayout, header.channelLayout,
@@ -2017,6 +2021,7 @@ try {
graphics.tavDecodeGopToVideoBufferAsync( graphics.tavDecodeGopToVideoBufferAsync(
decodingGopData.compressedPtr, decodingGopData.compressedSize, decodingGopData.gopSize, decodingGopData.compressedPtr, decodingGopData.compressedSize, decodingGopData.gopSize,
header.width, header.height, header.width, header.height,
baseVersion >= 5,
header.qualityLevel, header.qualityLevel,
QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg], QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg],
header.channelLayout, header.channelLayout,
@@ -2059,6 +2064,7 @@ try {
graphics.tavDecodeGopToVideoBufferAsync( graphics.tavDecodeGopToVideoBufferAsync(
readyGopData.compressedPtr, readyGopData.compressedSize, readyGopData.gopSize, readyGopData.compressedPtr, readyGopData.compressedSize, readyGopData.gopSize,
header.width, decodeHeight, // Use decodeHeight for interlaced field support header.width, decodeHeight, // Use decodeHeight for interlaced field support
baseVersion >= 5,
header.qualityLevel, header.qualityLevel,
QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg], QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg],
header.channelLayout, header.channelLayout,
@@ -2138,6 +2144,7 @@ try {
graphics.tavDecodeGopToVideoBufferAsync( graphics.tavDecodeGopToVideoBufferAsync(
overflow.compressedPtr, overflow.compressedSize, overflow.gopSize, overflow.compressedPtr, overflow.compressedSize, overflow.gopSize,
header.width, decodeHeight, // Use decodeHeight for interlaced field support header.width, decodeHeight, // Use decodeHeight for interlaced field support
baseVersion >= 5,
header.qualityLevel, header.qualityLevel,
QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg], QLUT[header.qualityY], QLUT[header.qualityCo], QLUT[header.qualityCg],
header.channelLayout, header.channelLayout,

View File

@@ -6483,6 +6483,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
gopSize: Int, gopSize: Int,
width: Int, width: Int,
height: Int, height: Int,
isPerceptual: Boolean,
qIndex: Int, qIndex: Int,
qYGlobal: Int, qYGlobal: Int,
qCoGlobal: Int, qCoGlobal: Int,
@@ -6577,28 +6578,33 @@ class GraphicsJSR223Delegate(private val vm: VM) {
val baseQCo = kotlin.math.round(qCoGlobal * temporalScale).coerceIn(1.0f, 4096.0f) val baseQCo = kotlin.math.round(qCoGlobal * temporalScale).coerceIn(1.0f, 4096.0f)
val baseQCg = kotlin.math.round(qCgGlobal * temporalScale).coerceIn(1.0f, 4096.0f) val baseQCg = kotlin.math.round(qCgGlobal * temporalScale).coerceIn(1.0f, 4096.0f)
if (isPerceptual) {
dequantiseDWTSubbandsPerceptual( dequantiseDWTSubbandsPerceptual(
qIndex, qYGlobal, qIndex, qYGlobal,
quantizedCoeffs[t][0], gopY[t], quantizedCoeffs[t][0], gopY[t],
subbands, baseQY, false, spatialLevels, subbands, baseQY, false, spatialLevels,
isEZBCMode isEZBCMode
) )
dequantiseDWTSubbandsPerceptual(
qIndex, qYGlobal,
dequantiseDWTSubbandsPerceptual( quantizedCoeffs[t][1], gopCo[t],
qIndex, qYGlobal, subbands, baseQCo, true, spatialLevels,
quantizedCoeffs[t][1], gopCo[t], isEZBCMode
subbands, baseQCo, true, spatialLevels, )
isEZBCMode dequantiseDWTSubbandsPerceptual(
) qIndex, qYGlobal,
quantizedCoeffs[t][2], gopCg[t],
dequantiseDWTSubbandsPerceptual( subbands, baseQCg, true, spatialLevels,
qIndex, qYGlobal, isEZBCMode
quantizedCoeffs[t][2], gopCg[t], )
subbands, baseQCg, true, spatialLevels, }
isEZBCMode else {
) for (i in 0 until width * height) {
gopY[t][i] = quantizedCoeffs[t][0][i] * baseQY
gopCo[t][i] = quantizedCoeffs[t][1][i] * baseQCo
gopCg[t][i] = quantizedCoeffs[t][2][i] * baseQCg
}
}
} }
@@ -6841,6 +6847,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
gopSize: Int, gopSize: Int,
width: Int, width: Int,
height: Int, height: Int,
isPerceptual: Boolean,
qIndex: Int, qIndex: Int,
qYGlobal: Int, qYGlobal: Int,
qCoGlobal: Int, qCoGlobal: Int,
@@ -6867,7 +6874,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
try { try {
val result = tavDecodeGopToVideoBuffer( val result = tavDecodeGopToVideoBuffer(
compressedDataPtr, compressedSize, gopSize, compressedDataPtr, compressedSize, gopSize,
width, height, width, height, isPerceptual,
qIndex, qYGlobal, qCoGlobal, qCgGlobal, qIndex, qYGlobal, qCoGlobal, qCgGlobal,
channelLayout, spatialFilter, spatialLevels, temporalLevels, channelLayout, spatialFilter, spatialLevels, temporalLevels,
entropyCoder, bufferOffset, temporalMotionCoder, encoderPreset entropyCoder, bufferOffset, temporalMotionCoder, encoderPreset

View File

@@ -1464,15 +1464,9 @@ static int encode_gop_unified(tav_encoder_context_t *ctx, gop_slot_t *slot) {
int base_quantiser_co = QLUT[ctx->quantiser_co]; int base_quantiser_co = QLUT[ctx->quantiser_co];
int base_quantiser_cg = QLUT[ctx->quantiser_cg]; int base_quantiser_cg = QLUT[ctx->quantiser_cg];
// CRITICAL: Force perceptual quantization for GOPs to match old encoder behavior // Use perceptual or uniform quantization based on user setting
// The old encoder's quantise_dwt_coefficients_perceptual_per_coeff() does NOT check
// perceptual_tuning flag - it always applies perceptual weights for GOP encoding.
// The --no-perceptual-tuning flag only affects I-frame encoding in the old encoder.
int saved_perceptual = ctx->compat_enc->perceptual_tuning;
ctx->compat_enc->perceptual_tuning = 1; // Force perceptual for GOP encoding
if (ctx->verbose) { if (ctx->verbose) {
fprintf(stderr, "[DEBUG] GOP quantization: decomp_levels=%d, base_q_y=%d, perceptual=%d (forced on for GOP), preset=0x%02x\n", fprintf(stderr, "[DEBUG] GOP quantization: decomp_levels=%d, base_q_y=%d, perceptual=%d, preset=0x%02x\n",
ctx->compat_enc->decomp_levels, base_quantiser_y, ctx->compat_enc->perceptual_tuning, ctx->compat_enc->encoder_preset); ctx->compat_enc->decomp_levels, base_quantiser_y, ctx->compat_enc->perceptual_tuning, ctx->compat_enc->encoder_preset);
} }
@@ -1483,8 +1477,6 @@ static int encode_gop_unified(tav_encoder_context_t *ctx, gop_slot_t *slot) {
tav_quantise_3d_dwt(ctx->compat_enc, work_cg, quant_cg, num_frames, num_pixels, tav_quantise_3d_dwt(ctx->compat_enc, work_cg, quant_cg, num_frames, num_pixels,
base_quantiser_cg, 1); base_quantiser_cg, 1);
ctx->compat_enc->perceptual_tuning = saved_perceptual; // Restore for I-frames
// Step 4: Unified GOP preprocessing (EZBC only) // Step 4: Unified GOP preprocessing (EZBC only)
size_t preprocess_capacity = num_pixels * num_frames * 3 * sizeof(int16_t) + 65536; size_t preprocess_capacity = num_pixels * num_frames * 3 * sizeof(int16_t) + 65536;
uint8_t *preprocess_buffer = tav_malloc(preprocess_capacity); uint8_t *preprocess_buffer = tav_malloc(preprocess_capacity);