mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-04 06:33:45 +00:00
Only store PID instead of entire process reference
This commit is contained in:
parent
4dd5e9c66e
commit
85dcfdd670
@ -85,8 +85,8 @@ class FrigateApp:
|
||||
self.detectors: dict[str, ObjectDetectProcess] = {}
|
||||
self.detection_shms: list[mp.shared_memory.SharedMemory] = []
|
||||
self.log_queue: Queue = mp.Queue()
|
||||
self.camera_metrics: dict[str, CameraMetrics] = {}
|
||||
self.metrics_manager = mp.Manager()
|
||||
self.camera_metrics: dict[str, CameraMetrics] = self.metrics_manager.dict()
|
||||
self.embeddings_metrics: DataProcessorMetrics | None = (
|
||||
DataProcessorMetrics(
|
||||
self.metrics_manager, list(config.classification.custom.keys())
|
||||
@ -128,7 +128,7 @@ class FrigateApp:
|
||||
def init_camera_metrics(self) -> None:
|
||||
# create camera_metrics
|
||||
for camera_name in self.config.cameras.keys():
|
||||
self.camera_metrics[camera_name] = CameraMetrics()
|
||||
self.camera_metrics[camera_name] = CameraMetrics(self.metrics_manager)
|
||||
self.ptz_metrics[camera_name] = PTZMetrics(
|
||||
autotracker_enabled=self.config.cameras[
|
||||
camera_name
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import multiprocessing as mp
|
||||
from multiprocessing.managers import SyncManager
|
||||
from multiprocessing.sharedctypes import Synchronized
|
||||
from multiprocessing.synchronize import Event
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class CameraMetrics:
|
||||
@ -16,25 +16,25 @@ class CameraMetrics:
|
||||
|
||||
frame_queue: mp.Queue
|
||||
|
||||
process: Optional[mp.Process]
|
||||
capture_process: Optional[mp.Process]
|
||||
process_pid: Synchronized
|
||||
capture_process_pid: Synchronized
|
||||
ffmpeg_pid: Synchronized
|
||||
|
||||
def __init__(self):
|
||||
self.camera_fps = mp.Value("d", 0)
|
||||
self.detection_fps = mp.Value("d", 0)
|
||||
self.detection_frame = mp.Value("d", 0)
|
||||
self.process_fps = mp.Value("d", 0)
|
||||
self.skipped_fps = mp.Value("d", 0)
|
||||
self.read_start = mp.Value("d", 0)
|
||||
self.audio_rms = mp.Value("d", 0)
|
||||
self.audio_dBFS = mp.Value("d", 0)
|
||||
def __init__(self, manager: SyncManager):
|
||||
self.camera_fps = manager.Value("d", 0)
|
||||
self.detection_fps = manager.Value("d", 0)
|
||||
self.detection_frame = manager.Value("d", 0)
|
||||
self.process_fps = manager.Value("d", 0)
|
||||
self.skipped_fps = manager.Value("d", 0)
|
||||
self.read_start = manager.Value("d", 0)
|
||||
self.audio_rms = manager.Value("d", 0)
|
||||
self.audio_dBFS = manager.Value("d", 0)
|
||||
|
||||
self.frame_queue = mp.Queue(maxsize=2)
|
||||
self.frame_queue = manager.Queue(maxsize=2)
|
||||
|
||||
self.process = None
|
||||
self.capture_process = None
|
||||
self.ffmpeg_pid = mp.Value("i", 0)
|
||||
self.process_pid = manager.Value("i", 0)
|
||||
self.capture_process_pid = manager.Value("i", 0)
|
||||
self.ffmpeg_pid = manager.Value("i", 0)
|
||||
|
||||
|
||||
class PTZMetrics:
|
||||
|
||||
@ -54,6 +54,8 @@ class CameraMaintainer(threading.Thread):
|
||||
],
|
||||
)
|
||||
self.shm_count = self.__calculate_shm_frame_count()
|
||||
self.camera_processes: dict[str, mp.Process] = {}
|
||||
self.capture_processes: dict[str, mp.Process] = {}
|
||||
|
||||
def __init_historical_regions(self) -> None:
|
||||
# delete region grids for removed or renamed cameras
|
||||
@ -120,7 +122,7 @@ class CameraMaintainer(threading.Thread):
|
||||
|
||||
def __start_camera_processor(
|
||||
self, name: str, config: CameraConfig, runtime: bool = False
|
||||
) -> mp.Process:
|
||||
) -> None:
|
||||
if not config.enabled_in_config:
|
||||
logger.info(f"Camera processor not started for disabled camera {name}")
|
||||
return
|
||||
@ -168,13 +170,14 @@ class CameraMaintainer(threading.Thread):
|
||||
),
|
||||
daemon=True,
|
||||
)
|
||||
self.camera_processes[config.name] = camera_process
|
||||
camera_process.start()
|
||||
self.camera_metrics[config.name].process_pid.value = camera_process.pid
|
||||
logger.info(f"Camera processor started for {config.name}: {camera_process.pid}")
|
||||
return camera_process
|
||||
|
||||
def __start_camera_capture(
|
||||
self, name: str, config: CameraConfig, runtime: bool = False
|
||||
) -> mp.Process:
|
||||
) -> None:
|
||||
if not config.enabled_in_config:
|
||||
logger.info(f"Capture process not started for disabled camera {name}")
|
||||
return
|
||||
@ -191,26 +194,26 @@ class CameraMaintainer(threading.Thread):
|
||||
args=(config, count, self.camera_metrics[name]),
|
||||
)
|
||||
capture_process.daemon = True
|
||||
self.capture_processes[name] = capture_process
|
||||
capture_process.start()
|
||||
self.camera_metrics[name].capture_process_pid.value = capture_process.pid
|
||||
logger.info(f"Capture process started for {name}: {capture_process.pid}")
|
||||
return capture_process
|
||||
|
||||
def __stop_camera_capture_process(self, camera: str) -> None:
|
||||
capture_process = self.camera_metrics[camera].capture_process
|
||||
capture_process = self.capture_processes[camera]
|
||||
if capture_process is not None:
|
||||
logger.info(f"Waiting for capture process for {camera} to stop")
|
||||
capture_process.terminate()
|
||||
capture_process.join()
|
||||
|
||||
def __stop_camera_process(self, camera: str) -> None:
|
||||
metrics = self.camera_metrics[camera]
|
||||
camera_process = metrics.process
|
||||
camera_process = self.camera_processes[camera]
|
||||
if camera_process is not None:
|
||||
logger.info(f"Waiting for process for {camera} to stop")
|
||||
camera_process.terminate()
|
||||
camera_process.join()
|
||||
logger.info(f"Closing frame queue for {camera}")
|
||||
empty_and_close_queue(metrics.frame_queue)
|
||||
empty_and_close_queue(self.camera_metrics[camera].frame_queue)
|
||||
|
||||
def run(self):
|
||||
self.__init_historical_regions()
|
||||
@ -226,30 +229,26 @@ class CameraMaintainer(threading.Thread):
|
||||
for update_type, updated_cameras in updates.items():
|
||||
if update_type == CameraConfigUpdateEnum.add.name:
|
||||
for camera in updated_cameras:
|
||||
camera_process = self.__start_camera_processor(
|
||||
self.__start_camera_processor(
|
||||
camera,
|
||||
self.update_subscriber.camera_configs[camera],
|
||||
runtime=True,
|
||||
)
|
||||
capture_process = self.__start_camera_capture(
|
||||
self.__start_camera_capture(
|
||||
camera,
|
||||
self.update_subscriber.camera_configs[camera],
|
||||
runtime=True,
|
||||
)
|
||||
self.camera_metrics[config.name].process = camera_process
|
||||
self.camera_metrics[
|
||||
config.name
|
||||
].capture_process = capture_process
|
||||
elif update_type == CameraConfigUpdateEnum.remove.name:
|
||||
self.__stop_camera_capture_process(camera)
|
||||
self.__stop_camera_process(camera)
|
||||
|
||||
# ensure the capture processes are done
|
||||
for camera in self.camera_metrics.keys():
|
||||
for camera in self.camera_processes.keys():
|
||||
self.__stop_camera_capture_process(camera)
|
||||
|
||||
# ensure the camera processors are done
|
||||
for camera in self.camera_metrics.keys():
|
||||
for camera in self.capture_processes.keys():
|
||||
self.__stop_camera_process(camera)
|
||||
|
||||
self.update_subscriber.stop()
|
||||
|
||||
@ -271,10 +271,12 @@ def stats_snapshot(
|
||||
stats["cameras"] = {}
|
||||
for name, camera_stats in camera_metrics.items():
|
||||
total_detection_fps += camera_stats.detection_fps.value
|
||||
pid = camera_stats.process.pid if camera_stats.process else None
|
||||
pid = camera_stats.process_pid.value if camera_stats.process_pid.value else None
|
||||
ffmpeg_pid = camera_stats.ffmpeg_pid.value if camera_stats.ffmpeg_pid else None
|
||||
capture_pid = (
|
||||
camera_stats.capture_process.pid if camera_stats.capture_process else None
|
||||
camera_stats.capture_process_pid.value
|
||||
if camera_stats.capture_process_pid.value
|
||||
else None
|
||||
)
|
||||
stats["cameras"][name] = {
|
||||
"camera_fps": round(camera_stats.camera_fps.value, 2),
|
||||
|
||||
@ -173,7 +173,7 @@ export default function CameraMetrics({
|
||||
});
|
||||
series[key]["detect"].data.push({
|
||||
x: statsIdx,
|
||||
y: stats.cpu_usages[camStats.pid.toString()].cpu,
|
||||
y: stats.cpu_usages[camStats.pid?.toString()]?.cpu,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user