TAV: fixed video luminance errors on -q 4 and 5

This commit is contained in:
minjaesong
2025-10-31 04:41:48 +09:00
parent 755d4deb95
commit f3b68e1164
2 changed files with 25 additions and 25 deletions

View File

@@ -1086,7 +1086,7 @@ try {
// Check GOP size fits in slot // Check GOP size fits in slot
if (gopSize > MAX_GOP_SIZE) { if (gopSize > MAX_GOP_SIZE) {
console.log(`[GOP] Error: GOP size ${gopSize} exceeds max ${MAX_GOP_SIZE} frames`) // console.log(`[GOP] Error: GOP size ${gopSize} exceeds max ${MAX_GOP_SIZE} frames`)
sys.free(compressedPtr) sys.free(compressedPtr)
break break
} }
@@ -1136,7 +1136,7 @@ try {
timeRemaining: 0 timeRemaining: 0
} }
if (interactive) { if (interactive) {
console.log(`[GOP] Buffered GOP ${gopSize} frames to ready slot during first GOP decode`) // console.log(`[GOP] Buffered GOP ${gopSize} frames to ready slot during first GOP decode`)
} }
} else if (decodingGopData === null) { } else if (decodingGopData === null) {
// Buffer as decoding GOP (will decode after ready GOP) // Buffer as decoding GOP (will decode after ready GOP)
@@ -1151,18 +1151,18 @@ try {
timeRemaining: 0 timeRemaining: 0
} }
if (interactive) { if (interactive) {
console.log(`[GOP] Buffered GOP ${gopSize} frames to decoding slot during first GOP decode`) // console.log(`[GOP] Buffered GOP ${gopSize} frames to decoding slot during first GOP decode`)
} }
// CRITICAL: Stop reading packets now that all 3 buffers are full // CRITICAL: Stop reading packets now that all 3 buffers are full
shouldReadPackets = false shouldReadPackets = false
if (interactive) { if (interactive) {
console.log(`[GOP] All 3 buffers full during first GOP decode - stopping packet reading`) // console.log(`[GOP] All 3 buffers full during first GOP decode - stopping packet reading`)
} }
} else { } else {
// All 3 buffers full - discard this GOP (shouldn't happen now with gate) // All 3 buffers full - discard this GOP (shouldn't happen now with gate)
if (interactive) { if (interactive) {
console.log(`[GOP] WARNING: All 3 buffers full during first GOP decode - discarding GOP ${gopSize} frames`) // console.log(`[GOP] WARNING: All 3 buffers full during first GOP decode - discarding GOP ${gopSize} frames`)
} }
sys.free(compressedPtr) sys.free(compressedPtr)
} }
@@ -1206,7 +1206,7 @@ try {
// to prevent next GOP from being discarded in Case 5 // to prevent next GOP from being discarded in Case 5
shouldReadPackets = false shouldReadPackets = false
if (interactive) { if (interactive) {
console.log(`[GOP] Case 3: Started decode to ready slot - stopping packet reading`) // console.log(`[GOP] Case 3: Started decode to ready slot - stopping packet reading`)
} }
} else if (currentGopSize > 0 && readyGopData !== null && decodingGopData === null && !asyncDecodeInProgress && graphics.tavDecodeGopIsComplete()) { } else if (currentGopSize > 0 && readyGopData !== null && decodingGopData === null && !asyncDecodeInProgress && graphics.tavDecodeGopIsComplete()) {
@@ -1248,7 +1248,7 @@ try {
// All 3 buffers are now full (playing + ready + decoding) // All 3 buffers are now full (playing + ready + decoding)
shouldReadPackets = false shouldReadPackets = false
if (interactive) { if (interactive) {
console.log(`[GOP] Case 4: Started decode to decoding slot - all buffers full, stopping packet reading`) // console.log(`[GOP] Case 4: Started decode to decoding slot - all buffers full, stopping packet reading`)
} }
} else { } else {
@@ -1259,7 +1259,7 @@ try {
compressedSize: compressedSize compressedSize: compressedSize
}) })
if (interactive) { if (interactive) {
console.log(`[GOP] Case 5: Buffered GOP ${gopSize} frames to overflow queue (queue size: ${overflowQueue.length})`) // console.log(`[GOP] Case 5: Buffered GOP ${gopSize} frames to overflow queue (queue size: ${overflowQueue.length})`)
} }
} }
} }
@@ -1273,7 +1273,7 @@ try {
if (currentGopSize > 0 && readyGopData !== null && decodingGopData !== null) { if (currentGopSize > 0 && readyGopData !== null && decodingGopData !== null) {
shouldReadPackets = false shouldReadPackets = false
if (interactive) { if (interactive) {
console.log(`[GOP] All 3 buffers full - stopping packet reading`) // console.log(`[GOP] All 3 buffers full - stopping packet reading`)
} }
} }
} }
@@ -1499,11 +1499,11 @@ try {
if (!(currentGopSize > 0 && readyGopData !== null && decodingGopData !== null)) { if (!(currentGopSize > 0 && readyGopData !== null && decodingGopData !== null)) {
shouldReadPackets = true shouldReadPackets = true
if (interactive) { if (interactive) {
console.log(`[GOP] First GOP ready - resuming packet reading (ready=${readyGopData !== null}, decoding=${decodingGopData !== null})`) // console.log(`[GOP] First GOP ready - resuming packet reading (ready=${readyGopData !== null}, decoding=${decodingGopData !== null})`)
} }
} else { } else {
if (interactive) { if (interactive) {
console.log(`[GOP] First GOP ready - all 3 buffers full, keeping packet reading paused`) // console.log(`[GOP] First GOP ready - all 3 buffers full, keeping packet reading paused`)
} }
} }
@@ -1544,7 +1544,7 @@ try {
readyGopData.timeRemaining = timeRemaining readyGopData.timeRemaining = timeRemaining
if (interactive) { if (interactive) {
console.log(`[GOP] Started decode of buffered GOP ${readyGopData.gopSize} frames (slot ${readyGopData.slot})`) // console.log(`[GOP] Started decode of buffered GOP ${readyGopData.gopSize} frames (slot ${readyGopData.slot})`)
} }
} }
} }
@@ -1624,7 +1624,7 @@ try {
uploadTime = (sys.nanoTime() - uploadStart) / 1000000.0 uploadTime = (sys.nanoTime() - uploadStart) / 1000000.0
if (interactive && currentGopFrameIndex === 0) { if (interactive && currentGopFrameIndex === 0) {
console.log(`[GOP] Playing GOP: ${currentGopSize} frames from slot ${currentGopBufferSlot}`) // console.log(`[GOP] Playing GOP: ${currentGopSize} frames from slot ${currentGopBufferSlot}`)
} }
// Apply bias lighting // Apply bias lighting
@@ -1692,7 +1692,7 @@ try {
decodingGopData.timeRemaining = timeRemaining decodingGopData.timeRemaining = timeRemaining
if (interactive) { if (interactive) {
console.log(`[GOP] Started decode of buffered GOP ${decodingGopData.gopSize} frames from decoding slot (slot ${decodingGopData.slot})`) // console.log(`[GOP] Started decode of buffered GOP ${decodingGopData.gopSize} frames from decoding slot (slot ${decodingGopData.slot})`)
} }
} }
@@ -1704,7 +1704,7 @@ try {
// Step 4-7: GOP finished? Transition to ready GOP (triple-buffering) // Step 4-7: GOP finished? Transition to ready GOP (triple-buffering)
if (!paused && currentGopSize > 0 && currentGopFrameIndex >= currentGopSize) { if (!paused && currentGopSize > 0 && currentGopFrameIndex >= currentGopSize) {
if (interactive) { if (interactive) {
console.log(`[GOP] GOP finished: played ${currentGopFrameIndex}/${currentGopSize} frames from slot ${currentGopBufferSlot}`) // console.log(`[GOP] GOP finished: played ${currentGopFrameIndex}/${currentGopSize} frames from slot ${currentGopBufferSlot}`)
} }
if (readyGopData !== null) { if (readyGopData !== null) {
// If ready GOP still needs decode, start it now (defensive - should already be started) // If ready GOP still needs decode, start it now (defensive - should already be started)
@@ -1755,7 +1755,7 @@ try {
// Resume packet reading now that one buffer is free (decoding slot available) // Resume packet reading now that one buffer is free (decoding slot available)
shouldReadPackets = true shouldReadPackets = true
if (interactive) { if (interactive) {
console.log(`[GOP] Transition complete - resuming packet reading (asyncInProgress=${asyncDecodeInProgress})`) // console.log(`[GOP] Transition complete - resuming packet reading (asyncInProgress=${asyncDecodeInProgress})`)
} }
// Process overflow queue if it has GOPs waiting // Process overflow queue if it has GOPs waiting
@@ -1774,7 +1774,7 @@ try {
// This shouldn't happen - put it back in queue // This shouldn't happen - put it back in queue
overflowQueue.unshift(overflow) overflowQueue.unshift(overflow)
if (interactive) { if (interactive) {
console.log(`[GOP] Overflow queue: no slots available, keeping in queue`) // console.log(`[GOP] Overflow queue: no slots available, keeping in queue`)
} }
targetSlot = -1 // Skip decode targetSlot = -1 // Skip decode
} }
@@ -1812,7 +1812,7 @@ try {
timeRemaining: timeRemaining timeRemaining: timeRemaining
} }
if (interactive) { if (interactive) {
console.log(`[GOP] Overflow: Started decode of queued GOP ${overflow.gopSize} frames to ready slot ${targetSlot} (${overflowQueue.length} left in queue)`) // console.log(`[GOP] Overflow: Started decode of queued GOP ${overflow.gopSize} frames to ready slot ${targetSlot} (${overflowQueue.length} left in queue)`)
} }
} else { } else {
decodingGopData = { decodingGopData = {
@@ -1823,7 +1823,7 @@ try {
timeRemaining: timeRemaining timeRemaining: timeRemaining
} }
if (interactive) { if (interactive) {
console.log(`[GOP] Overflow: Started decode of queued GOP ${overflow.gopSize} frames to decoding slot ${targetSlot} (${overflowQueue.length} left in queue)`) // console.log(`[GOP] Overflow: Started decode of queued GOP ${overflow.gopSize} frames to decoding slot ${targetSlot} (${overflowQueue.length} left in queue)`)
} }
} }
} // End if (targetSlot >= 0) } // End if (targetSlot >= 0)
@@ -1875,7 +1875,7 @@ try {
debugPrintAkku += (t2 - t1) debugPrintAkku += (t2 - t1)
if (debugPrintAkku > 5000000000) { if (debugPrintAkku > 5000000000) {
debugPrintAkku -= 5000000000 debugPrintAkku -= 5000000000
serial.println(`[PLAYTAV] decoding time = ${(decodeTime).toFixed(2)} ms`) // serial.println(`[PLAYTAV] decoding time = ${(decodeTime).toFixed(2)} ms`)
} }
// Small sleep to prevent 100% CPU and control loop rate // Small sleep to prevent 100% CPU and control loop rate

View File

@@ -18,7 +18,7 @@
#include <limits.h> #include <limits.h>
#include <float.h> #include <float.h>
#define ENCODER_VENDOR_STRING "Encoder-TAV 20251030 (3d-dwt,tad)" #define ENCODER_VENDOR_STRING "Encoder-TAV 20251031 (3d-dwt,tad)"
// TSVM Advanced Video (TAV) format constants // TSVM Advanced Video (TAV) format constants
#define TAV_MAGIC "\x1F\x54\x53\x56\x4D\x54\x41\x56" // "\x1FTSVM TAV" #define TAV_MAGIC "\x1F\x54\x53\x56\x4D\x54\x41\x56" // "\x1FTSVM TAV"
@@ -11206,7 +11206,7 @@ int main(int argc, char *argv[]) {
// Encode single frame as I-frame (GOP size 1) // Encode single frame as I-frame (GOP size 1)
int frame_num = frame_count - original_gop_frame_count + i; int frame_num = frame_count - original_gop_frame_count + i;
size_t bytes = gop_flush(enc, enc->output_fp, qY, &frame_num, 1); size_t bytes = gop_flush(enc, enc->output_fp, QLUT[qY], &frame_num, 1);
if (bytes == 0) { if (bytes == 0) {
fprintf(stderr, "Error: Failed to encode I-frame %d during hard scene change\n", frame_num); fprintf(stderr, "Error: Failed to encode I-frame %d during hard scene change\n", frame_num);
@@ -11233,7 +11233,7 @@ int main(int argc, char *argv[]) {
gop_frame_numbers[i] = frame_count - enc->temporal_gop_frame_count + i; gop_frame_numbers[i] = frame_count - enc->temporal_gop_frame_count + i;
} }
packet_size = gop_process_and_flush(enc, enc->output_fp, qY, packet_size = gop_process_and_flush(enc, enc->output_fp, QLUT[qY],
gop_frame_numbers, 1); gop_frame_numbers, 1);
free(gop_frame_numbers); free(gop_frame_numbers);
} }
@@ -11319,7 +11319,7 @@ int main(int argc, char *argv[]) {
int qY = enc->bitrate_mode ? quantiser_float_to_int_dithered(enc) : enc->quantiser_y; int qY = enc->bitrate_mode ? quantiser_float_to_int_dithered(enc) : enc->quantiser_y;
// Process and flush GOP with scene change detection // Process and flush GOP with scene change detection
packet_size = gop_process_and_flush(enc, enc->output_fp, qY, packet_size = gop_process_and_flush(enc, enc->output_fp, QLUT[qY],
gop_frame_numbers, force_flush); gop_frame_numbers, force_flush);
free(gop_frame_numbers); free(gop_frame_numbers);
@@ -11599,7 +11599,7 @@ int main(int argc, char *argv[]) {
int qY = enc->bitrate_mode ? quantiser_float_to_int_dithered(enc) : enc->quantiser_y; int qY = enc->bitrate_mode ? quantiser_float_to_int_dithered(enc) : enc->quantiser_y;
// Flush remaining GOP with force_flush=1 to process all frames // Flush remaining GOP with force_flush=1 to process all frames
size_t final_packet_size = gop_process_and_flush(enc, enc->output_fp, qY, size_t final_packet_size = gop_process_and_flush(enc, enc->output_fp, QLUT[qY],
gop_frame_numbers, 1); gop_frame_numbers, 1);
free(gop_frame_numbers); free(gop_frame_numbers);