Skip to content

Commit 29f2604

Browse files
committed
Refactor writer thread error handling and stats
Consolidate the writer-thread loop and tighten up exception handling. Removed the conditional _save_timestamps path during teardown. In the writer loop sentinel handling and frame processing are unified; on write errors the exception is stored under _stats_lock, logged, and stop_event/stop_now are set. The stats updates (frames_written, total_latency, last_latency, written_times, frame_timestamps and periodic FPS computation) were moved into the same control flow to ensure consistent accounting and termination behavior.
1 parent ae1754c commit 29f2604

1 file changed

Lines changed: 26 additions & 32 deletions

File tree

dlclivegui/services/video_recorder.py

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,6 @@ def stop(self) -> None:
206206
except Exception:
207207
logger.exception("Failed to close WriteGear cleanly")
208208

209-
if self._writer_thread is None:
210-
# Save timestamps to JSON file
211-
self._save_timestamps()
212-
213209
self._writer = None
214210
self._writer_thread = None
215211
self._queue = None
@@ -271,35 +267,33 @@ def _writer_loop(self) -> None:
271267
try:
272268
if item is _SENTINEL:
273269
stop_now = True
274-
continue
275-
276-
frame, timestamp = item
277-
start = time.perf_counter()
278-
279-
try:
280-
writer = self._writer
281-
if writer is None:
282-
raise RuntimeError("WriteGear writer is not initialized")
283-
writer.write(frame)
284-
except Exception as exc: # <- broader than OSError
270+
else:
271+
frame, timestamp = item
272+
start = time.perf_counter()
273+
274+
try:
275+
writer = self._writer
276+
if writer is None:
277+
raise RuntimeError("WriteGear writer is not initialized")
278+
writer.write(frame)
279+
except Exception as exc:
280+
with self._stats_lock:
281+
self._encode_error = exc
282+
logger.exception("Video encoding failed while writing frame", exc_info=exc)
283+
self._stop_event.set()
284+
stop_now = True
285+
286+
elapsed = time.perf_counter() - start
287+
now = time.perf_counter()
285288
with self._stats_lock:
286-
self._encode_error = exc
287-
logger.exception("Video encoding failed while writing frame", exc_info=exc)
288-
self._stop_event.set()
289-
stop_now = True
290-
continue
291-
292-
elapsed = time.perf_counter() - start
293-
now = time.perf_counter()
294-
with self._stats_lock:
295-
self._frames_written += 1
296-
self._total_latency += elapsed
297-
self._last_latency = elapsed
298-
self._written_times.append(now)
299-
self._frame_timestamps.append(timestamp)
300-
if now - self._last_log_time >= 1.0:
301-
self._compute_write_fps_locked()
302-
self._last_log_time = now
289+
self._frames_written += 1
290+
self._total_latency += elapsed
291+
self._last_latency = elapsed
292+
self._written_times.append(now)
293+
self._frame_timestamps.append(timestamp)
294+
if now - self._last_log_time >= 1.0:
295+
self._compute_write_fps_locked()
296+
self._last_log_time = now
303297

304298
finally:
305299
# Ensure queue accounting is correct for every item pulled from q

0 commit comments

Comments
 (0)