Cattura: rimuovi videorate e limita la coda all'ultimo frame

La pipeline GStreamer non forza più la frequenza con videorate e usa un
appsink con max-buffers=1, drop e enable-last-sample=false: si elabora solo
il frame più recente invece di duplicare frame o accumulare ritardo.

Il demone rinnova inoltre l'ultimo frame inviato ogni 10 s quando la sorgente
a frequenza variabile non produce nuovi campioni (schermata statica),
evitando il timeout del firmware Adalight, e usa time.monotonic per il
pacing di invio al posto di time.time.
This commit is contained in:
enne2
2026-11-02 17:54:15 +01:00
parent 344e3c8764
commit a17021e610
2 changed files with 15 additions and 8 deletions
+12 -4
View File
@@ -208,6 +208,7 @@ def capture_loop(state, strip):
last_write = 0.0
t_log = time.time()
n_none = 0
last_frame = None
while True:
cfg = state.snapshot()
if not cfg["running"]:
@@ -215,6 +216,7 @@ def capture_loop(state, strip):
cap.stop()
cap = None
prev = None
last_frame = None
time.sleep(0.15)
continue
@@ -239,10 +241,15 @@ def capture_loop(state, strip):
frame = cap.frame(200)
if frame is None:
# Una sorgente a frequenza variabile può fermarsi su una schermata
# statica; rinnova il frame per il timeout del firmware Adalight.
if last_frame is not None and time.monotonic() - last_write >= 10:
if strip.write(last_frame):
last_write = time.monotonic()
n_none += 1
time.sleep(0.005)
if time.time() - t_log >= 10:
log(f"diagnostica: 10 s senza frame (timeout={n_none}), "
log(f"diagnostica: attese cattura negli ultimi 10 s (timeout={n_none}), "
f"fps={state.fps} sent={sent}")
t_log, n_none = time.time(), 0
continue
@@ -270,12 +277,13 @@ def capture_loop(state, strip):
frame_bits = (6 + 3 * cfg["leds"]) * 10
min_interval = max(1.0 / max(1, cfg["target_fps"]),
1.7 * frame_bits / max(9600, cfg["baud"]))
wait = min_interval - (time.time() - last_write)
wait = min_interval - (time.monotonic() - last_write)
if wait > 0:
time.sleep(wait)
ok = strip.write(adalight_frame(px))
last_frame = adalight_frame(px)
ok = strip.write(last_frame)
if ok:
last_write = time.time()
last_write = time.monotonic()
sent += 1
now = time.time()
if now - t_win >= 1.0: