mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
ntsc framerate handling
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user