mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
TAV: fixed video luminance errors on -q 4 and 5
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user