Files
NX2navi/tests/flight_flash_check.py
chrg6 202fd47ceb Let the flight recorder dump on its own when one frame flashes.
With flight = 1 and its thumbnails kept, the recorder now also writes a dump when a frame's picture differs strongly from the frame before and the frame after while those two agree, which is what a one-frame flicker looks like. Each thumbnail is reduced to 16x9 cells of mean brightness where the present thread already sees it complete, and a frame is a flash when at least three cells are more than 24 of 255 brighter or darker than in both neighbours, the neighbours being alike in those cells, around them and over the picture as a whole. A camera cut, a fade, a pan and shapes crossing the picture are no flash, and a frame beside one without a thumbnail is not judged. The dump is the one F8 writes, named "flash" with the frame's number in its header line, at most one every 30 seconds. flight_flash = 0 turns it off; flight_flash_diff and flight_flash_cells set the two thresholds.

On the thumbnails of earlier dumps the defaults flag the frames whose scene was white once and nothing in the runs without that fault. tests/flight_flash_check.py checks the test itself on drawn pictures.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 15:16:30 -05:00

45 lines
1.7 KiB
Python

"""Build and run tests/flight_flash_check.c: runtime/flight_flash.h, which frames the flight recorder takes for a
one-frame flash (a flash, a camera cut, steady motion, frames whose neighbours have no thumbnail).
No GPU, no game files, any Python. Built as the runtime is (-O2, x86-64-v3 on x86-64), so the "time" run measures what
the present thread pays.
Usage: flight_flash_check.py [time]
"""
import os
import platform
import shutil
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
MSYS_BIN = Path(r'C:\msys64\ucrt64\bin')
def compiler():
"""$CC, else MSYS2 UCRT64's clang, else clang on PATH (as tests/diff/common.py picks it, without its Unicorn)."""
if os.environ.get('CC'):
return os.environ['CC']
if os.name == 'nt' and (MSYS_BIN / 'clang.exe').exists():
return str(MSYS_BIN / 'clang.exe')
return shutil.which('clang') or 'clang'
def main():
work = ROOT / 'build' / 'test' / 'flight_flash'
work.mkdir(parents=True, exist_ok=True)
exe = work / ('flight_flash_check.exe' if os.name == 'nt' else 'flight_flash_check')
env = dict(os.environ)
if os.name == 'nt' and MSYS_BIN.exists():
env['PATH'] = str(MSYS_BIN) + os.pathsep + env.get('PATH', '')
arch = ['-march=x86-64-v3'] if platform.machine().lower() in ('amd64', 'x86_64') else []
subprocess.check_call([compiler(), '-std=gnu11', '-O2', *arch, '-Wall', '-Wextra', '-Werror',
'-I', str(ROOT / 'runtime'), str(ROOT / 'tests' / 'flight_flash_check.c'), '-o', str(exe)],
env=env)
return subprocess.run([str(exe), *sys.argv[1:2]], env=env).returncode
if __name__ == '__main__':
sys.exit(main())