ntsc framerate handling

This commit is contained in:
minjaesong
2025-09-16 22:59:45 +09:00
parent a639e116c5
commit ae59946883
3 changed files with 34 additions and 30 deletions

View File

@@ -553,7 +553,6 @@ let FRAME_TIME = 1.0 / header.fps
let frameCount = 0
let trueFrameCount = 0
let frameDuped = false
let stopPlay = false
let akku = FRAME_TIME
let akku2 = 0.0
@@ -613,38 +612,29 @@ try {
try {
// serial.println(actualSize)
// Duplicate every 1000th frame if NTSC (same as TEV)
if (!isNTSC || frameCount % 1000 != 501 || frameDuped) {
frameDuped = false
let decodeStart = sys.nanoTime()
let decodeStart = sys.nanoTime()
// Call TAV hardware decoder (like TEV's tevDecode but with RGB buffer outputs)
graphics.tavDecode(
blockDataPtr,
CURRENT_RGB_ADDR, PREV_RGB_ADDR, // RGB buffer pointers (not float arrays!)
header.width, header.height,
header.qualityY, header.qualityCo, header.qualityCg,
frameCount,
debugMotionVectors,
header.waveletFilter, // TAV-specific parameter
header.decompLevels, // TAV-specific parameter
enableDeblocking,
isLossless,
header.version // TAV version for colour space detection
)
// Call TAV hardware decoder (like TEV's tevDecode but with RGB buffer outputs)
graphics.tavDecode(
blockDataPtr,
CURRENT_RGB_ADDR, PREV_RGB_ADDR, // RGB buffer pointers (not float arrays!)
header.width, header.height,
header.qualityY, header.qualityCo, header.qualityCg,
frameCount,
debugMotionVectors,
header.waveletFilter, // TAV-specific parameter
header.decompLevels, // TAV-specific parameter
enableDeblocking,
isLossless,
header.version // TAV version for colour space detection
)
decodeTime = (sys.nanoTime() - decodeStart) / 1000000.0
decodeTime = (sys.nanoTime() - decodeStart) / 1000000.0
// Upload RGB buffer to display framebuffer (like TEV)
let uploadStart = sys.nanoTime()
graphics.uploadRGBToFramebuffer(CURRENT_RGB_ADDR, header.width, header.height, frameCount, true)
uploadTime = (sys.nanoTime() - uploadStart) / 1000000.0
} else {
frameCount -= 1
frameDuped = true
console.log(`Frame ${frameCount}: Duplicating previous frame`)
}
// Upload RGB buffer to display framebuffer (like TEV)
let uploadStart = sys.nanoTime()
graphics.uploadRGBToFramebuffer(CURRENT_RGB_ADDR, header.width, header.height, frameCount, true)
uploadTime = (sys.nanoTime() - uploadStart) / 1000000.0
// Defer audio playback until a first frame is sent
if (isInterlaced) {

View File

@@ -793,6 +793,10 @@ The format is designed to be compatible with SubRip and SAMI (without markups).
text argument may be terminated by 0x00 BEFORE the entire arguments being terminated by 0x00,
leaving extra 0x00 on the byte stream. A decoder must be able to handle the extra zeros.
## NTSC Framerate handling
The encoder encodes the frames as-is. The decoder must duplicate every 1000th frame to keep the decoding
in-sync.
--------------------------------------------------------------------------------
TSVM Advanced Video (TAV) Format
@@ -947,6 +951,10 @@ Reuses existing MP2 audio infrastructure from TEV/MOV formats for compatibility.
## Subtitle Support
Uses same Simple Subtitle Format (SSF) as TEV for text overlay functionality.
## NTSC Framerate handling
Unlike the TEV format, TAV emits extra sync packet for every 1000th frames. Decoder can just play the video
without any special treatment.
--------------------------------------------------------------------------------
Sound Adapter

View File

@@ -2089,6 +2089,12 @@ int main(int argc, char *argv[]) {
uint8_t sync_packet = TAV_PACKET_SYNC;
fwrite(&sync_packet, 1, 1, enc->output_fp);
// NTSC frame duplication: emit extra sync packet for every 1000n+500 frames
if (enc->is_ntsc_framerate && (frame_count % 1000 == 500)) {
fwrite(&sync_packet, 1, 1, enc->output_fp);
printf("Frame %d: NTSC duplication - extra sync packet emitted\n", frame_count);
}
if (is_keyframe)
count_iframe++;
else