From e10ddb343c859d951600767f3f07766653d38ac7 Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Sat, 4 Feb 2023 08:58:45 -0600 Subject: [PATCH] additional shutdown optimizations (#5380) --- frigate/app.py | 17 ++++++++++------- frigate/object_detection.py | 8 ++++++-- frigate/video.py | 20 ++++++++++++-------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/frigate/app.py b/frigate/app.py index 1e5140603..c5cc8411a 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -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() diff --git a/frigate/object_detection.py b/frigate/object_detection.py index 206c47839..129fd6b26 100644 --- a/frigate/object_detection.py +++ b/frigate/object_detection.py @@ -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: diff --git a/frigate/video.py b/frigate/video.py index 1b64b21a4..ca200fd53 100755 --- a/frigate/video.py +++ b/frigate/video.py @@ -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