mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-15 07:26:05 +09:00
fix: wrong timecode calculation on NTSC framerates
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -std=c99 -Wall -Wextra -O2 -D_GNU_SOURCE
|
||||
CXXFLAGS = -std=c++11 -Wall -Wextra -O2 -D_GNU_SOURCE
|
||||
CFLAGS = -std=c99 -Wall -Wextra -Ofast -D_GNU_SOURCE
|
||||
CXXFLAGS = -std=c++11 -Wall -Wextra -Ofast -D_GNU_SOURCE
|
||||
|
||||
# Zstd flags (use pkg-config if available, fallback for cross-platform compatibility)
|
||||
ZSTD_CFLAGS = $(shell pkg-config --cflags libzstd 2>/dev/null || echo "")
|
||||
|
||||
@@ -8108,13 +8108,14 @@ static void write_timecode_packet(FILE *output, int frame_num, int fps, int is_n
|
||||
fwrite(&packet_type, 1, 1, output);
|
||||
|
||||
// Calculate timecode in nanoseconds
|
||||
// For NTSC (29.97 fps): time = frame_num * 1001000000 / 30000
|
||||
// For NTSC framerates (X000/1001): time = frame_num * 1001 * 1000000000 / (fps * 1000)
|
||||
// For other framerates: time = frame_num * 1000000000 / fps
|
||||
uint64_t timecode_ns;
|
||||
if (is_ntsc_framerate) {
|
||||
// NTSC uses 30000/1001 fps (29.97...)
|
||||
// To avoid floating point: time_ns = frame_num * 1001000000 / 30000
|
||||
timecode_ns = ((uint64_t)frame_num * 1001000000ULL) / 30000ULL;
|
||||
// NTSC framerates use denominator 1001 (e.g., 24000/1001, 30000/1001, 60000/1001)
|
||||
// To avoid floating point: time_ns = frame_num * 1001 * 1e9 / (fps * 1000)
|
||||
// This works for 24fps NTSC (23.976), 30fps NTSC (29.97), 60fps NTSC (59.94), etc.
|
||||
timecode_ns = ((uint64_t)frame_num * 1001ULL * 1000000000ULL) / ((uint64_t)fps * 1000ULL);
|
||||
} else {
|
||||
// Standard framerate
|
||||
timecode_ns = ((uint64_t)frame_num * 1000000000ULL) / (uint64_t)fps;
|
||||
@@ -10779,7 +10780,8 @@ int main(int argc, char *argv[]) {
|
||||
// Update ENDT in extended header (calculate end time for last frame)
|
||||
uint64_t endt_ns;
|
||||
if (enc->is_ntsc_framerate) {
|
||||
endt_ns = ((uint64_t)(frame_count - 1) * 1001000000ULL) / 30000ULL;
|
||||
// NTSC framerates use denominator 1001 (e.g., 24000/1001, 30000/1001, 60000/1001)
|
||||
endt_ns = ((uint64_t)(frame_count - 1) * 1001ULL * 1000000000ULL) / ((uint64_t)enc->output_fps * 1000ULL);
|
||||
} else {
|
||||
endt_ns = ((uint64_t)(frame_count - 1) * 1000000000ULL) / (uint64_t)enc->output_fps;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#define TAV_PACKET_EXTENDED_HDR 0xEF
|
||||
#define TAV_PACKET_LOOP_START 0xF0
|
||||
#define TAV_PACKET_LOOP_END 0xF1
|
||||
#define TAV_PACKET_SCREEN_MASK 0xF2
|
||||
#define TAV_PACKET_GOP_SYNC 0xFC // GOP sync packet (N frames decoded)
|
||||
#define TAV_PACKET_TIMECODE 0xFD
|
||||
#define TAV_PACKET_SYNC_NTSC 0xFE
|
||||
@@ -130,6 +131,7 @@ const char* get_packet_type_name(uint8_t type) {
|
||||
case TAV_PACKET_EXTENDED_HDR: return "EXTENDED HEADER";
|
||||
case TAV_PACKET_LOOP_START: return "LOOP START";
|
||||
case TAV_PACKET_LOOP_END: return "LOOP END";
|
||||
case TAV_PACKET_SCREEN_MASK: return "SCREEN MASK";
|
||||
case TAV_PACKET_GOP_SYNC: return "GOP SYNC";
|
||||
case TAV_PACKET_TIMECODE: return "TIMECODE";
|
||||
case TAV_PACKET_SYNC_NTSC: return "SYNC (NTSC)";
|
||||
@@ -842,6 +844,23 @@ static const char* VERDESC[] = {"null", "YCoCg tiled, uniform", "ICtCp tiled, un
|
||||
}
|
||||
break;
|
||||
|
||||
case TAV_PACKET_SCREEN_MASK:
|
||||
uint32_t frame_number;
|
||||
if (fread(&frame_number, sizeof(uint32_t), 1, fp) != 1) break;
|
||||
uint16_t top;
|
||||
if (fread(&top, sizeof(uint16_t), 1, fp) != 1) break;
|
||||
uint16_t right;
|
||||
if (fread(&right, sizeof(uint16_t), 1, fp) != 1) break;
|
||||
uint16_t bottom;
|
||||
if (fread(&bottom, sizeof(uint16_t), 1, fp) != 1) break;
|
||||
uint16_t left;
|
||||
if (fread(&left, sizeof(uint16_t), 1, fp) != 1) break;
|
||||
|
||||
if (!opts.summary_only && display) {
|
||||
printf(" - Frame=%u [top=%u, right=%u, bottom=%u, left=%u]", frame_number, top, right, bottom, left);
|
||||
}
|
||||
break;
|
||||
|
||||
case TAV_PACKET_SYNC:
|
||||
stats.sync_count++;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user