diff --git a/frigate/video/ffmpeg.py b/frigate/video/ffmpeg.py index 24b7805333..482e9da6bf 100644 --- a/frigate/video/ffmpeg.py +++ b/frigate/video/ffmpeg.py @@ -54,59 +54,48 @@ def capture_frames( skipped_eps = EventsPerSecond() skipped_eps.start() - config_subscriber = CameraConfigUpdateSubscriber( - None, {config.name: config}, [CameraConfigUpdateEnum.enabled] - ) + while not stop_event.is_set(): + # CameraWatchdog applies enabled updates onto this same CameraConfig + # before it stops ffmpeg. Do not subscribe here: it would be rebuilt per + # ffmpeg restart and strand a pipe in the idle main process config PUB. + if not config.enabled: + logger.debug(f"Stopping capture thread for disabled {config.name}") + break - def get_enabled_state(): - """Fetch the latest enabled state from ZMQ.""" - config_subscriber.check_for_updates() - return config.enabled - - try: - while not stop_event.is_set(): - if not get_enabled_state(): - logger.debug(f"Stopping capture thread for disabled {config.name}") + fps.value = frame_rate.eps() + skipped_fps.value = skipped_eps.eps() + current_frame.value = datetime.now().timestamp() + frame_name = f"{config.name}_frame{frame_index}" + frame_buffer = frame_manager.write(frame_name) + try: + frame_buffer[:] = ffmpeg_process.stdout.read(frame_size) + except Exception: + # shutdown has been initiated + if stop_event.is_set(): break - fps.value = frame_rate.eps() - skipped_fps.value = skipped_eps.eps() - current_frame.value = datetime.now().timestamp() - frame_name = f"{config.name}_frame{frame_index}" - frame_buffer = frame_manager.write(frame_name) - try: - frame_buffer[:] = ffmpeg_process.stdout.read(frame_size) - except Exception: - # shutdown has been initiated - if stop_event.is_set(): - break + logger.error(f"{config.name}: Unable to read frames from ffmpeg process.") + if ffmpeg_process.poll() is not None: logger.error( - f"{config.name}: Unable to read frames from ffmpeg process." + f"{config.name}: ffmpeg process is not running. exiting capture thread..." ) + break - if ffmpeg_process.poll() is not None: - logger.error( - f"{config.name}: ffmpeg process is not running. exiting capture thread..." - ) - break + continue - continue + frame_rate.update() - frame_rate.update() + # don't lock the queue to check, just try since it should rarely be full + try: + # add to the queue + frame_queue.put((frame_name, current_frame.value), False) + frame_manager.close(frame_name) + except queue.Full: + # if the queue is full, skip this frame + skipped_eps.update() - # don't lock the queue to check, just try since it should rarely be full - try: - # add to the queue - frame_queue.put((frame_name, current_frame.value), False) - frame_manager.close(frame_name) - except queue.Full: - # if the queue is full, skip this frame - skipped_eps.update() - - frame_index = 0 if frame_index == shm_frame_count - 1 else frame_index + 1 - finally: - config_subscriber.stop() + frame_index = 0 if frame_index == shm_frame_count - 1 else frame_index + 1 class CameraWatchdog(threading.Thread):