From 5b1b6b5be082fb18ae8ac3b66f81c00ebc8a9493 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Sun, 17 Nov 2024 10:25:49 -0700 Subject: [PATCH] Fix round robin (#15035) * Move camera SHM frame creation to main process * Don't reset frame index * Don't fail if shm exists * Set more types --- frigate/app.py | 8 +++++++- frigate/util/image.py | 14 +++++++++----- frigate/video.py | 20 ++++++++++---------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/frigate/app.py b/frigate/app.py index 96edfbd15..f56ed1a8b 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -68,7 +68,7 @@ from frigate.stats.util import stats_init from frigate.storage import StorageMaintainer from frigate.timeline import TimelineProcessor from frigate.util.builtin import empty_and_close_queue -from frigate.util.image import UntrackedSharedMemory +from frigate.util.image import SharedMemoryFrameManager, UntrackedSharedMemory from frigate.util.object import get_camera_regions_grid from frigate.version import VERSION from frigate.video import capture_camera, track_camera @@ -426,12 +426,18 @@ class FrigateApp: def start_camera_capture_processes(self) -> None: shm_frame_count = self.shm_frame_count() + frame_manager = SharedMemoryFrameManager() for name, config in self.config.cameras.items(): if not self.config.cameras[name].enabled: logger.info(f"Capture process not started for disabled camera {name}") continue + # pre-create shms + for i in range(shm_frame_count): + frame_size = config.frame_shape_yuv[0] * config.frame_shape_yuv[1] + frame_manager.create(f"{config.name}{i}", frame_size) + capture_process = util.Process( target=capture_camera, name=f"camera_capture:{name}", diff --git a/frigate/util/image.py b/frigate/util/image.py index 4e3161192..7b22c138e 100644 --- a/frigate/util/image.py +++ b/frigate/util/image.py @@ -790,11 +790,15 @@ class SharedMemoryFrameManager(FrameManager): self.shm_store: dict[str, UntrackedSharedMemory] = {} def create(self, name: str, size) -> AnyStr: - shm = UntrackedSharedMemory( - name=name, - create=True, - size=size, - ) + try: + shm = UntrackedSharedMemory( + name=name, + create=True, + size=size, + ) + except FileExistsError: + shm = UntrackedSharedMemory(name=name) + self.shm_store[name] = shm return shm.buf diff --git a/frigate/video.py b/frigate/video.py index 4e7fe660d..5af3e13f4 100755 --- a/frigate/video.py +++ b/frigate/video.py @@ -94,7 +94,8 @@ def capture_frames( ffmpeg_process, config: CameraConfig, shm_frame_count: int, - frame_shape, + frame_index: int, + frame_shape: tuple[int, int], frame_manager: FrameManager, frame_queue, fps: mp.Value, @@ -108,12 +109,6 @@ def capture_frames( skipped_eps = EventsPerSecond() skipped_eps.start() - # pre-create shms - for i in range(shm_frame_count): - frame_manager.create(f"{config.name}{i}", frame_size) - - frame_index = 0 - while True: fps.value = frame_rate.eps() skipped_fps.value = skipped_eps.eps() @@ -159,7 +154,7 @@ class CameraWatchdog(threading.Thread): camera_name, config: CameraConfig, shm_frame_count: int, - frame_queue, + frame_queue: mp.Queue, camera_fps, skipped_fps, ffmpeg_pid, @@ -181,6 +176,7 @@ class CameraWatchdog(threading.Thread): self.frame_shape = self.config.frame_shape_yuv self.frame_size = self.frame_shape[0] * self.frame_shape[1] self.fps_overflow_count = 0 + self.frame_index = 0 self.stop_event = stop_event self.sleeptime = self.config.ffmpeg.retry_interval @@ -302,6 +298,7 @@ class CameraWatchdog(threading.Thread): self.capture_thread = CameraCapture( self.config, self.shm_frame_count, + self.frame_index, self.ffmpeg_detect_process, self.frame_shape, self.frame_queue, @@ -342,9 +339,10 @@ class CameraCapture(threading.Thread): self, config: CameraConfig, shm_frame_count: int, + frame_index: int, ffmpeg_process, - frame_shape, - frame_queue, + frame_shape: tuple[int, int], + frame_queue: mp.Queue, fps, skipped_fps, stop_event, @@ -353,6 +351,7 @@ class CameraCapture(threading.Thread): self.name = f"capture:{config.name}" self.config = config self.shm_frame_count = shm_frame_count + self.frame_index = frame_index self.frame_shape = frame_shape self.frame_queue = frame_queue self.fps = fps @@ -368,6 +367,7 @@ class CameraCapture(threading.Thread): self.ffmpeg_process, self.config, self.shm_frame_count, + self.frame_index, self.frame_shape, self.frame_manager, self.frame_queue,