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

View File

@@ -6483,6 +6483,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
gopSize: Int,
width: Int,
height: Int,
isPerceptual: Boolean,
qIndex: Int,
qYGlobal: Int,
qCoGlobal: Int,
@@ -6577,22 +6578,19 @@ class GraphicsJSR223Delegate(private val vm: VM) {
val baseQCo = kotlin.math.round(qCoGlobal * temporalScale).coerceIn(1.0f, 4096.0f)
val baseQCg = kotlin.math.round(qCgGlobal * temporalScale).coerceIn(1.0f, 4096.0f)
if (isPerceptual) {
dequantiseDWTSubbandsPerceptual(
qIndex, qYGlobal,
quantizedCoeffs[t][0], gopY[t],
subbands, baseQY, false, spatialLevels,
isEZBCMode
)
dequantiseDWTSubbandsPerceptual(
qIndex, qYGlobal,
quantizedCoeffs[t][1], gopCo[t],
subbands, baseQCo, true, spatialLevels,
isEZBCMode
)
dequantiseDWTSubbandsPerceptual(
qIndex, qYGlobal,
quantizedCoeffs[t][2], gopCg[t],
@@ -6600,6 +6598,14 @@ class GraphicsJSR223Delegate(private val vm: VM) {
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
}
}
}
// Step 5.5: Remove grain synthesis from Y channel for each GOP frame
@@ -6841,6 +6847,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
gopSize: Int,
width: Int,
height: Int,
isPerceptual: Boolean,
qIndex: Int,
qYGlobal: Int,
qCoGlobal: Int,
@@ -6867,7 +6874,7 @@ class GraphicsJSR223Delegate(private val vm: VM) {
try {
val result = tavDecodeGopToVideoBuffer(
compressedDataPtr, compressedSize, gopSize,
width, height,
width, height, isPerceptual,
qIndex, qYGlobal, qCoGlobal, qCgGlobal,
channelLayout, spatialFilter, spatialLevels, temporalLevels,
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_cg = QLUT[ctx->quantiser_cg];
// CRITICAL: Force perceptual quantization for GOPs to match old encoder behavior
// 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
// Use perceptual or uniform quantization based on user setting
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);
}
@@ -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,
base_quantiser_cg, 1);
ctx->compat_enc->perceptual_tuning = saved_perceptual; // Restore for I-frames
// Step 4: Unified GOP preprocessing (EZBC only)
size_t preprocess_capacity = num_pixels * num_frames * 3 * sizeof(int16_t) + 65536;
uint8_t *preprocess_buffer = tav_malloc(preprocess_capacity);