Refactor no-signal timing to integer milliseconds

Replace double wall-time with uint64_t monotonic milliseconds for
last_frame_ms and last_no_signal_ms. Integer ms is the right type
for a threshold comparison — no floating point needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-29 19:33:22 +00:00
parent 8460841e8e
commit 2481c3bae4

View File

@@ -7,6 +7,7 @@
#include <pthread.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <time.h>
#include <math.h>
#include <sys/sysmacros.h>
@@ -187,8 +188,8 @@ struct Display_Slot {
/* No-signal animation */
int no_signal_fps; /* 0 → default 15 */
double last_frame_t; /* wall time of last successfully displayed frame */
double last_no_signal_t;
uint64_t last_frame_ms; /* monotonic ms of last successfully displayed frame */
uint64_t last_no_signal_ms; /* monotonic ms of last no-signal render */
/* Viewer — created and used only on the main thread */
Xorg_Viewer *viewer;
@@ -524,24 +525,26 @@ static void display_loop_tick(struct Node *node)
struct timespec _ts;
clock_gettime(CLOCK_MONOTONIC, &_ts);
double now = (double)_ts.tv_sec + (double)_ts.tv_nsec * 1e-9;
uint64_t now_ms = (uint64_t)_ts.tv_sec * 1000u
+ (uint64_t)_ts.tv_nsec / 1000000u;
if (fdata) {
struct Proto_Video_Frame vf;
if (APP_IS_OK(proto_read_video_frame(fdata, flen, &vf))) {
xorg_viewer_push_mjpeg(d->viewer, vf.data, vf.data_len);
d->last_frame_t = now;
d->last_frame_ms = now_ms;
}
free(fdata);
}
/* Render no-signal only when stream has been silent for ≥1 s */
if (now - d->last_frame_t >= 1.0) {
double interval = 1.0 / (double)(d->no_signal_fps > 0 ? d->no_signal_fps : 15);
if (now - d->last_no_signal_t >= interval) {
/* Wrap to [0, 1000) to preserve float32 fractional precision */
xorg_viewer_render_no_signal(d->viewer, (float)fmod(now, 1000.0), 80.0f);
d->last_no_signal_t = now;
if (now_ms - d->last_frame_ms >= 1000u) {
uint64_t interval_ms = 1000u / (uint64_t)(d->no_signal_fps > 0 ? d->no_signal_fps : 15);
if (now_ms - d->last_no_signal_ms >= interval_ms) {
/* shader time: wrap ms to [0, 1000000) → [0, 1000) s, preserving float32 precision */
float shader_t = (float)(now_ms % 1000000u) / 1000.0f;
xorg_viewer_render_no_signal(d->viewer, shader_t, 80.0f);
d->last_no_signal_ms = now_ms;
}
}