additional shutdown optimizations (#5380)

This commit is contained in:
Blake Blackshear 2023-02-04 08:58:45 -06:00 committed by GitHub
parent e8cd25ddf2
commit e10ddb343c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 17 deletions

View File

@ -416,10 +416,15 @@ class FrigateApp:
logger.info(f"Stopping...")
self.stop_event.set()
# Set the events for the camera processor processes because
# they may be waiting on the event coming out of the detection process
for name in self.config.cameras.keys():
self.detection_out_events[name].set()
for detector in self.detectors.values():
detector.stop()
# Empty the detection queue and set the events for all requests
while not self.detection_queue.empty():
connection_id = self.detection_queue.get(timeout=1)
self.detection_out_events[connection_id].set()
self.detection_queue.close()
self.detection_queue.join_thread()
self.dispatcher.stop()
self.detected_frames_processor.join()
@ -431,9 +436,6 @@ class FrigateApp:
self.frigate_watchdog.join()
self.db.stop()
for detector in self.detectors.values():
detector.stop()
while len(self.detection_shms) > 0:
shm = self.detection_shms.pop()
shm.close()
@ -445,6 +447,7 @@ class FrigateApp:
self.video_output_queue,
self.detected_frames_queue,
self.recordings_info_queue,
self.log_queue,
]:
while not queue.empty():
queue.get_nowait()

View File

@ -180,12 +180,13 @@ class ObjectDetectProcess:
class RemoteObjectDetector:
def __init__(self, name, labels, detection_queue, event, model_config):
def __init__(self, name, labels, detection_queue, event, model_config, stop_event):
self.labels = labels
self.name = name
self.fps = EventsPerSecond()
self.detection_queue = detection_queue
self.event = event
self.stop_event = stop_event
self.shm = mp.shared_memory.SharedMemory(name=self.name, create=False)
self.np_shm = np.ndarray(
(1, model_config.height, model_config.width, 3),
@ -200,11 +201,14 @@ class RemoteObjectDetector:
def detect(self, tensor_input, threshold=0.4):
detections = []
if self.stop_event.is_set():
return detections
# copy input to shared memory
self.np_shm[:] = tensor_input[:]
self.event.clear()
self.detection_queue.put(self.name)
result = self.event.wait(timeout=10.0)
result = self.event.wait(timeout=5.0)
# if it timed out
if result is None:

View File

@ -160,6 +160,7 @@ def capture_frames(
fps: mp.Value,
skipped_fps: mp.Value,
current_frame: mp.Value,
stop_event: mp.Event,
):
frame_size = frame_shape[0] * frame_shape[1]
@ -177,6 +178,9 @@ def capture_frames(
try:
frame_buffer[:] = ffmpeg_process.stdout.read(frame_size)
except Exception as e:
# shutdown has been initiated
if stop_event.is_set():
break
logger.error(f"{camera_name}: Unable to read frames from ffmpeg process.")
if ffmpeg_process.poll() != None:
@ -340,6 +344,7 @@ class CameraWatchdog(threading.Thread):
self.frame_shape,
self.frame_queue,
self.camera_fps,
self.stop_event,
)
self.capture_thread.start()
@ -368,13 +373,16 @@ class CameraWatchdog(threading.Thread):
class CameraCapture(threading.Thread):
def __init__(self, camera_name, ffmpeg_process, frame_shape, frame_queue, fps):
def __init__(
self, camera_name, ffmpeg_process, frame_shape, frame_queue, fps, stop_event
):
threading.Thread.__init__(self)
self.name = f"capture:{camera_name}"
self.camera_name = camera_name
self.frame_shape = frame_shape
self.frame_queue = frame_queue
self.fps = fps
self.stop_event = stop_event
self.skipped_fps = EventsPerSecond()
self.frame_manager = SharedMemoryFrameManager()
self.ffmpeg_process = ffmpeg_process
@ -392,6 +400,7 @@ class CameraCapture(threading.Thread):
self.fps,
self.skipped_fps,
self.current_frame,
self.stop_event,
)
@ -461,7 +470,7 @@ def track_camera(
motion_contour_area,
)
object_detector = RemoteObjectDetector(
name, labelmap, detection_queue, result_connection, model_config
name, labelmap, detection_queue, result_connection, model_config, stop_event
)
object_tracker = ObjectTracker(config.detect)
@ -723,9 +732,6 @@ def process_frames(
object_filters,
)
)
# if frigate is exiting
if stop_event.is_set():
return
#########
# merge objects, check for clipped objects and look again up to 4 times
@ -790,9 +796,7 @@ def process_frames(
refining = True
else:
selected_objects.append(obj)
# if frigate is exiting
if stop_event.is_set():
return
# set the detections list to only include top, complete objects
# and new detections
detections = selected_objects