remove birdseye from camera metrics

This commit is contained in:
Nicolas Mowen 2024-02-16 06:58:29 -07:00
parent ccacdc6a1b
commit e95004c211
4 changed files with 31 additions and 46 deletions

View File

@ -175,20 +175,6 @@ class FrigateApp:
"process": None, "process": None,
"audio_rms": mp.Value("d", 0.0), # type: ignore[typeddict-item] "audio_rms": mp.Value("d", 0.0), # type: ignore[typeddict-item]
"audio_dBFS": mp.Value("d", 0.0), # type: ignore[typeddict-item] "audio_dBFS": mp.Value("d", 0.0), # type: ignore[typeddict-item]
"birdseye_enabled": mp.Value( # type: ignore[typeddict-item]
# issue https://github.com/python/typeshed/issues/8799
# from mypy 0.981 onwards
"i",
self.config.cameras[camera_name].birdseye.enabled,
),
"birdseye_mode": mp.Value( # type: ignore[typeddict-item]
# issue https://github.com/python/typeshed/issues/8799
# from mypy 0.981 onwards
"i",
BirdseyeModeEnum.get_index(
self.config.cameras[camera_name].birdseye.mode.value
),
),
} }
self.ptz_metrics[camera_name] = { self.ptz_metrics[camera_name] = {
"ptz_autotracker_enabled": mp.Value( # type: ignore[typeddict-item] "ptz_autotracker_enabled": mp.Value( # type: ignore[typeddict-item]
@ -474,7 +460,6 @@ class FrigateApp:
args=( args=(
self.config, self.config,
self.video_output_queue, self.video_output_queue,
self.camera_metrics,
), ),
) )
output_processor.daemon = True output_processor.daemon = True

View File

@ -319,17 +319,18 @@ class Dispatcher:
birdseye_settings = self.config.cameras[camera_name].birdseye birdseye_settings = self.config.cameras[camera_name].birdseye
if payload == "ON": if payload == "ON":
if not self.camera_metrics[camera_name]["birdseye_enabled"].value: if not birdseye_settings.enabled:
logger.info(f"Turning on birdseye for {camera_name}") logger.info(f"Turning on birdseye for {camera_name}")
self.camera_metrics[camera_name]["birdseye_enabled"].value = True
birdseye_settings.enabled = True birdseye_settings.enabled = True
elif payload == "OFF": elif payload == "OFF":
if self.camera_metrics[camera_name]["birdseye_enabled"].value: if birdseye_settings.enabled:
logger.info(f"Turning off birdseye for {camera_name}") logger.info(f"Turning off birdseye for {camera_name}")
self.camera_metrics[camera_name]["birdseye_enabled"].value = False
birdseye_settings.enabled = False birdseye_settings.enabled = False
self.config_updater.publish(
f"config/birdseye/{camera_name}", self.config.cameras[camera_name].birdseye
)
self.publish(f"{camera_name}/birdseye/state", payload, retain=True) self.publish(f"{camera_name}/birdseye/state", payload, retain=True)
def _on_birdseye_mode_command(self, camera_name: str, payload: str) -> None: def _on_birdseye_mode_command(self, camera_name: str, payload: str) -> None:
@ -340,16 +341,17 @@ class Dispatcher:
return return
birdseye_config = self.config.cameras[camera_name].birdseye birdseye_config = self.config.cameras[camera_name].birdseye
if not birdseye_config.enabled: if not birdseye_config.enabled:
logger.info(f"Birdseye mode not enabled for {camera_name}") logger.info(f"Birdseye mode not enabled for {camera_name}")
return return
new_birdseye_mode = BirdseyeModeEnum(payload.lower()) birdseye_config.mode = BirdseyeModeEnum(payload.lower())
logger.info(f"Setting birdseye mode for {camera_name} to {new_birdseye_mode}") logger.info(
f"Setting birdseye mode for {camera_name} to {birdseye_config.mode}"
# update the metric (need the mode converted to an int)
self.camera_metrics[camera_name]["birdseye_mode"].value = (
BirdseyeModeEnum.get_index(new_birdseye_mode)
) )
self.config_updater.publish(
f"config/birdseye/{camera_name}", self.config.cameras[camera_name].birdseye
)
self.publish(f"{camera_name}/birdseye_mode/state", payload, retain=True) self.publish(f"{camera_name}/birdseye_mode/state", payload, retain=True)

View File

@ -14,9 +14,9 @@ import traceback
import cv2 import cv2
import numpy as np import numpy as np
from frigate.comms.config_updater import ConfigSubscriber
from frigate.config import BirdseyeModeEnum, FrigateConfig from frigate.config import BirdseyeModeEnum, FrigateConfig
from frigate.const import BASE_DIR, BIRDSEYE_PIPE from frigate.const import BASE_DIR, BIRDSEYE_PIPE
from frigate.types import CameraMetricsTypes
from frigate.util.image import ( from frigate.util.image import (
SharedMemoryFrameManager, SharedMemoryFrameManager,
copy_yuv_to_position, copy_yuv_to_position,
@ -267,7 +267,6 @@ class BirdsEyeFrameManager:
config: FrigateConfig, config: FrigateConfig,
frame_manager: SharedMemoryFrameManager, frame_manager: SharedMemoryFrameManager,
stop_event: mp.Event, stop_event: mp.Event,
camera_metrics: dict[str, CameraMetricsTypes],
): ):
self.config = config self.config = config
self.mode = config.birdseye.mode self.mode = config.birdseye.mode
@ -278,7 +277,6 @@ class BirdsEyeFrameManager:
self.frame = np.ndarray(self.yuv_shape, dtype=np.uint8) self.frame = np.ndarray(self.yuv_shape, dtype=np.uint8)
self.canvas = Canvas(width, height, config.birdseye.layout.scaling_factor) self.canvas = Canvas(width, height, config.birdseye.layout.scaling_factor)
self.stop_event = stop_event self.stop_event = stop_event
self.camera_metrics = camera_metrics
self.inactivity_threshold = config.birdseye.inactivity_threshold self.inactivity_threshold = config.birdseye.inactivity_threshold
if config.birdseye.layout.max_cameras: if config.birdseye.layout.max_cameras:
@ -675,15 +673,12 @@ class BirdsEyeFrameManager:
def update(self, camera, object_count, motion_count, frame_time, frame) -> bool: def update(self, camera, object_count, motion_count, frame_time, frame) -> bool:
# don't process if birdseye is disabled for this camera # don't process if birdseye is disabled for this camera
camera_config = self.config.cameras[camera].birdseye camera_config = self.config.cameras[camera].birdseye
if not camera_config.enabled: if not camera_config.enabled:
return False return False
# get our metrics (sync'd across processes)
# which allows us to control it via mqtt (or any other dispatcher)
camera_metrics = self.camera_metrics[camera]
# disabling birdseye is a little tricky # disabling birdseye is a little tricky
if not camera_metrics["birdseye_enabled"].value: if not camera_config.enabled:
# if we've rendered a frame (we have a value for last_active_frame) # if we've rendered a frame (we have a value for last_active_frame)
# then we need to set it to zero # then we need to set it to zero
if self.cameras[camera]["last_active_frame"] > 0: if self.cameras[camera]["last_active_frame"] > 0:
@ -691,12 +686,9 @@ class BirdsEyeFrameManager:
return False return False
# get the birdseye mode state from camera metrics
birdseye_mode = BirdseyeModeEnum.get(camera_metrics["birdseye_mode"].value)
# update the last active frame for the camera # update the last active frame for the camera
self.cameras[camera]["current_frame"] = frame_time self.cameras[camera]["current_frame"] = frame_time
if self.camera_active(birdseye_mode, object_count, motion_count): if self.camera_active(camera_config.mode, object_count, motion_count):
self.cameras[camera]["last_active_frame"] = frame_time self.cameras[camera]["last_active_frame"] = frame_time
now = datetime.datetime.now().timestamp() now = datetime.datetime.now().timestamp()
@ -725,7 +717,6 @@ class Birdseye:
self, self,
config: FrigateConfig, config: FrigateConfig,
frame_manager: SharedMemoryFrameManager, frame_manager: SharedMemoryFrameManager,
camera_metrics: dict[str, CameraMetricsTypes],
stop_event: mp.Event, stop_event: mp.Event,
websocket_server, websocket_server,
) -> None: ) -> None:
@ -745,9 +736,8 @@ class Birdseye:
self.broadcaster = BroadcastThread( self.broadcaster = BroadcastThread(
"birdseye", self.converter, websocket_server, stop_event "birdseye", self.converter, websocket_server, stop_event
) )
self.birdseye_manager = BirdsEyeFrameManager( self.birdseye_manager = BirdsEyeFrameManager(config, frame_manager, stop_event)
config, frame_manager, stop_event, camera_metrics self.config_subscriber = ConfigSubscriber("config/birdseye/")
)
if config.birdseye.restream: if config.birdseye.restream:
self.birdseye_buffer = frame_manager.create( self.birdseye_buffer = frame_manager.create(
@ -766,6 +756,18 @@ class Birdseye:
frame_time: float, frame_time: float,
frame, frame,
) -> None: ) -> None:
# check if there is an updated config
while True:
updated_topic, updated_birdseye_config = (
self.config_subscriber.check_for_update()
)
if not updated_topic:
break
camera_name = updated_topic.rpartition("/")[-1]
self.config.cameras[camera_name].birdseye = updated_birdseye_config
if self.birdseye_manager.update( if self.birdseye_manager.update(
camera, camera,
len([o for o in current_tracked_objects if not o["stationary"]]), len([o for o in current_tracked_objects if not o["stationary"]]),

View File

@ -21,7 +21,6 @@ from frigate.config import FrigateConfig
from frigate.output.birdseye import Birdseye from frigate.output.birdseye import Birdseye
from frigate.output.camera import JsmpegCamera from frigate.output.camera import JsmpegCamera
from frigate.output.preview import PreviewRecorder from frigate.output.preview import PreviewRecorder
from frigate.types import CameraMetricsTypes
from frigate.util.image import SharedMemoryFrameManager from frigate.util.image import SharedMemoryFrameManager
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -30,7 +29,6 @@ logger = logging.getLogger(__name__)
def output_frames( def output_frames(
config: FrigateConfig, config: FrigateConfig,
video_output_queue: mp.Queue, video_output_queue: mp.Queue,
camera_metrics: dict[str, CameraMetricsTypes],
): ):
threading.current_thread().name = "output" threading.current_thread().name = "output"
setproctitle("frigate.output") setproctitle("frigate.output")
@ -70,9 +68,7 @@ def output_frames(
preview_recorders[camera] = PreviewRecorder(cam_config) preview_recorders[camera] = PreviewRecorder(cam_config)
if config.birdseye.enabled: if config.birdseye.enabled:
birdseye = Birdseye( birdseye = Birdseye(config, frame_manager, stop_event, websocket_server)
config, frame_manager, camera_metrics, stop_event, websocket_server
)
websocket_thread.start() websocket_thread.start()