Add handler logs when frame is None

This commit is contained in:
Nicolas Mowen 2024-07-09 09:15:04 -06:00
parent d1fbd82952
commit f5d889f364
7 changed files with 49 additions and 9 deletions

View File

@ -118,6 +118,7 @@ def run_detector(
) )
if input_frame is None: if input_frame is None:
logger.warning(f"Failed to get frame {connection_id} from SHM")
continue continue
# detect and send the output # detect and send the output

View File

@ -673,6 +673,9 @@ class CameraState:
frame_id, self.camera_config.frame_shape_yuv frame_id, self.camera_config.frame_shape_yuv
) )
if current_frame is None:
logger.warning(f"Failed to get frame {frame_id} from SHM")
tracked_objects = self.tracked_objects.copy() tracked_objects = self.tracked_objects.copy()
current_ids = set(current_detections.keys()) current_ids = set(current_detections.keys())
previous_ids = set(tracked_objects.keys()) previous_ids = set(tracked_objects.keys())

View File

@ -357,16 +357,17 @@ class BirdsEyeFrameManager:
frame = None frame = None
channel_dims = None channel_dims = None
else: else:
try:
frame = self.frame_manager.get( frame = self.frame_manager.get(
f"{camera}{frame_time}", self.config.cameras[camera].frame_shape_yuv f"{camera}{frame_time}", self.config.cameras[camera].frame_shape_yuv
) )
except FileNotFoundError:
if frame is None:
# TODO: better frame management would prevent this edge case # TODO: better frame management would prevent this edge case
logger.warning( logger.warning(
f"Unable to copy frame {camera}{frame_time} to birdseye." f"Unable to copy frame {camera}{frame_time} to birdseye."
) )
return return
channel_dims = self.cameras[camera]["channel_dims"] channel_dims = self.cameras[camera]["channel_dims"]
copy_yuv_to_position( copy_yuv_to_position(

View File

@ -99,6 +99,7 @@ def output_frames(
frame = frame_manager.get(frame_id, config.cameras[camera].frame_shape_yuv) frame = frame_manager.get(frame_id, config.cameras[camera].frame_shape_yuv)
if frame is None: if frame is None:
logger.warning(f"Failed to get frame {frame_id} from SHM")
continue continue
# send camera frame to ffmpeg process if websockets are connected # send camera frame to ffmpeg process if websockets are connected

View File

@ -292,6 +292,11 @@ class ReviewSegmentMaintainer(threading.Thread):
yuv_frame = self.frame_manager.get( yuv_frame = self.frame_manager.get(
frame_id, camera_config.frame_shape_yuv frame_id, camera_config.frame_shape_yuv
) )
if yuv_frame is None:
logger.warning(f"Failed to get frame {frame_id} from SHM")
return
self.update_segment( self.update_segment(
segment, camera_config, yuv_frame, active_objects, prev_data segment, camera_config, yuv_frame, active_objects, prev_data
) )
@ -305,6 +310,11 @@ class ReviewSegmentMaintainer(threading.Thread):
yuv_frame = self.frame_manager.get( yuv_frame = self.frame_manager.get(
frame_id, camera_config.frame_shape_yuv frame_id, camera_config.frame_shape_yuv
) )
if yuv_frame is None:
logger.warning(f"Failed to get frame {frame_id} from SHM")
return
segment.save_full_frame(camera_config, yuv_frame) segment.save_full_frame(camera_config, yuv_frame)
self.frame_manager.close(frame_id) self.frame_manager.close(frame_id)
self.update_segment(segment, camera_config, None, [], prev_data) self.update_segment(segment, camera_config, None, [], prev_data)
@ -401,6 +411,11 @@ class ReviewSegmentMaintainer(threading.Thread):
yuv_frame = self.frame_manager.get( yuv_frame = self.frame_manager.get(
frame_id, camera_config.frame_shape_yuv frame_id, camera_config.frame_shape_yuv
) )
if yuv_frame is None:
logger.warning(f"Failed to get frame {frame_id} from SHM")
return
self.active_review_segments[camera].update_frame( self.active_review_segments[camera].update_frame(
camera_config, yuv_frame, active_objects camera_config, yuv_frame, active_objects
) )

View File

@ -1,6 +1,7 @@
"""Utilities for creating and manipulating image frames.""" """Utilities for creating and manipulating image frames."""
import datetime import datetime
import inspect
import logging import logging
import subprocess as sp import subprocess as sp
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
@ -695,6 +696,7 @@ class SharedMemoryFrameManager(FrameManager):
return shm.buf return shm.buf
def get(self, name: str, shape) -> Optional[np.ndarray]: def get(self, name: str, shape) -> Optional[np.ndarray]:
logger.info(f"retrieving {name} from {inspect.stack()[1].filename} {inspect.stack()[1].function}")
try: try:
if name in self.shm_store: if name in self.shm_store:
shm = self.shm_store[name] shm = self.shm_store[name]
@ -703,19 +705,33 @@ class SharedMemoryFrameManager(FrameManager):
self.shm_store[name] = shm self.shm_store[name] = shm
return np.ndarray(shape, dtype=np.uint8, buffer=shm.buf) return np.ndarray(shape, dtype=np.uint8, buffer=shm.buf)
except FileNotFoundError: except FileNotFoundError:
logger.error(f"Failed to get {name} from SHM")
return None return None
def close(self, name: str): def close(self, name: str):
logger.info(f"closing {name}")
if name in self.shm_store: if name in self.shm_store:
self.shm_store[name].close() self.shm_store[name].close()
del self.shm_store[name] del self.shm_store[name]
def delete(self, name: str): def delete(self, name: str):
logger.info(f"deleting expired {name}")
if name in self.shm_store: if name in self.shm_store:
self.shm_store[name].close() self.shm_store[name].close()
try:
self.shm_store[name].unlink() self.shm_store[name].unlink()
except FileNotFoundError:
pass
del self.shm_store[name] del self.shm_store[name]
else:
shm = shared_memory.SharedMemory(name=name)
shm.close()
try:
shm.unlink()
except FileNotFoundError:
pass
def create_mask(frame_shape, mask): def create_mask(frame_shape, mask):

View File

@ -109,7 +109,7 @@ def capture_frames(
skipped_eps = EventsPerSecond() skipped_eps = EventsPerSecond()
skipped_eps.start() skipped_eps.start()
shm_count = max(10, config.detect.fps * 2) shm_count = max(10, config.detect.fps)
shm_frames: list[str] = [] shm_frames: list[str] = []
while True: while True:
@ -127,9 +127,11 @@ def capture_frames(
if len(shm_frames) > shm_count: if len(shm_frames) > shm_count:
expired_frame_name = shm_frames.pop(0) expired_frame_name = shm_frames.pop(0)
frame_manager.delete(expired_frame_name) frame_manager.delete(expired_frame_name)
except Exception: except Exception as e:
logger.error(f"something video bad happened :: {e}")
frame_manager.delete(frame_name) frame_manager.delete(frame_name)
# shutdown has been initiated # shutdown has been initiated
if stop_event.is_set(): if stop_event.is_set():
break break
@ -149,6 +151,7 @@ def capture_frames(
try: try:
# add to the queue # add to the queue
frame_queue.put(current_frame.value, False) frame_queue.put(current_frame.value, False)
frame_manager.close(frame_name)
except queue.Full: except queue.Full:
# if the queue is full, skip this frame # if the queue is full, skip this frame
skipped_eps.update() skipped_eps.update()