mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-09 22:54:03 +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 frameCount = 0
|
||||||
let trueFrameCount = 0
|
let trueFrameCount = 0
|
||||||
let frameDuped = false
|
|
||||||
let stopPlay = false
|
let stopPlay = false
|
||||||
let akku = FRAME_TIME
|
let akku = FRAME_TIME
|
||||||
let akku2 = 0.0
|
let akku2 = 0.0
|
||||||
@@ -613,38 +612,29 @@ try {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// serial.println(actualSize)
|
// serial.println(actualSize)
|
||||||
// Duplicate every 1000th frame if NTSC (same as TEV)
|
let decodeStart = sys.nanoTime()
|
||||||
if (!isNTSC || frameCount % 1000 != 501 || frameDuped) {
|
|
||||||
frameDuped = false
|
|
||||||
|
|
||||||
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)
|
decodeTime = (sys.nanoTime() - decodeStart) / 1000000.0
|
||||||
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
|
// Upload RGB buffer to display framebuffer (like TEV)
|
||||||
|
let uploadStart = sys.nanoTime()
|
||||||
// Upload RGB buffer to display framebuffer (like TEV)
|
graphics.uploadRGBToFramebuffer(CURRENT_RGB_ADDR, header.width, header.height, frameCount, true)
|
||||||
let uploadStart = sys.nanoTime()
|
uploadTime = (sys.nanoTime() - uploadStart) / 1000000.0
|
||||||
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`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defer audio playback until a first frame is sent
|
// Defer audio playback until a first frame is sent
|
||||||
if (isInterlaced) {
|
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,
|
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.
|
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
|
TSVM Advanced Video (TAV) Format
|
||||||
@@ -947,6 +951,10 @@ Reuses existing MP2 audio infrastructure from TEV/MOV formats for compatibility.
|
|||||||
## Subtitle Support
|
## Subtitle Support
|
||||||
Uses same Simple Subtitle Format (SSF) as TEV for text overlay functionality.
|
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
|
Sound Adapter
|
||||||
|
|||||||
@@ -2089,6 +2089,12 @@ int main(int argc, char *argv[]) {
|
|||||||
uint8_t sync_packet = TAV_PACKET_SYNC;
|
uint8_t sync_packet = TAV_PACKET_SYNC;
|
||||||
fwrite(&sync_packet, 1, 1, enc->output_fp);
|
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)
|
if (is_keyframe)
|
||||||
count_iframe++;
|
count_iframe++;
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user