mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	additional shutdown optimizations (#5380)
This commit is contained in:
		
							parent
							
								
									e8cd25ddf2
								
							
						
					
					
						commit
						e10ddb343c
					
				@ -416,10 +416,15 @@ class FrigateApp:
 | 
				
			|||||||
        logger.info(f"Stopping...")
 | 
					        logger.info(f"Stopping...")
 | 
				
			||||||
        self.stop_event.set()
 | 
					        self.stop_event.set()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Set the events for the camera processor processes because
 | 
					        for detector in self.detectors.values():
 | 
				
			||||||
        # they may be waiting on the event coming out of the detection process
 | 
					            detector.stop()
 | 
				
			||||||
        for name in self.config.cameras.keys():
 | 
					
 | 
				
			||||||
            self.detection_out_events[name].set()
 | 
					        # 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.dispatcher.stop()
 | 
				
			||||||
        self.detected_frames_processor.join()
 | 
					        self.detected_frames_processor.join()
 | 
				
			||||||
@ -431,9 +436,6 @@ class FrigateApp:
 | 
				
			|||||||
        self.frigate_watchdog.join()
 | 
					        self.frigate_watchdog.join()
 | 
				
			||||||
        self.db.stop()
 | 
					        self.db.stop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for detector in self.detectors.values():
 | 
					 | 
				
			||||||
            detector.stop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        while len(self.detection_shms) > 0:
 | 
					        while len(self.detection_shms) > 0:
 | 
				
			||||||
            shm = self.detection_shms.pop()
 | 
					            shm = self.detection_shms.pop()
 | 
				
			||||||
            shm.close()
 | 
					            shm.close()
 | 
				
			||||||
@ -445,6 +447,7 @@ class FrigateApp:
 | 
				
			|||||||
            self.video_output_queue,
 | 
					            self.video_output_queue,
 | 
				
			||||||
            self.detected_frames_queue,
 | 
					            self.detected_frames_queue,
 | 
				
			||||||
            self.recordings_info_queue,
 | 
					            self.recordings_info_queue,
 | 
				
			||||||
 | 
					            self.log_queue,
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            while not queue.empty():
 | 
					            while not queue.empty():
 | 
				
			||||||
                queue.get_nowait()
 | 
					                queue.get_nowait()
 | 
				
			||||||
 | 
				
			|||||||
@ -180,12 +180,13 @@ class ObjectDetectProcess:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RemoteObjectDetector:
 | 
					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.labels = labels
 | 
				
			||||||
        self.name = name
 | 
					        self.name = name
 | 
				
			||||||
        self.fps = EventsPerSecond()
 | 
					        self.fps = EventsPerSecond()
 | 
				
			||||||
        self.detection_queue = detection_queue
 | 
					        self.detection_queue = detection_queue
 | 
				
			||||||
        self.event = event
 | 
					        self.event = event
 | 
				
			||||||
 | 
					        self.stop_event = stop_event
 | 
				
			||||||
        self.shm = mp.shared_memory.SharedMemory(name=self.name, create=False)
 | 
					        self.shm = mp.shared_memory.SharedMemory(name=self.name, create=False)
 | 
				
			||||||
        self.np_shm = np.ndarray(
 | 
					        self.np_shm = np.ndarray(
 | 
				
			||||||
            (1, model_config.height, model_config.width, 3),
 | 
					            (1, model_config.height, model_config.width, 3),
 | 
				
			||||||
@ -200,11 +201,14 @@ class RemoteObjectDetector:
 | 
				
			|||||||
    def detect(self, tensor_input, threshold=0.4):
 | 
					    def detect(self, tensor_input, threshold=0.4):
 | 
				
			||||||
        detections = []
 | 
					        detections = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.stop_event.is_set():
 | 
				
			||||||
 | 
					            return detections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # copy input to shared memory
 | 
					        # copy input to shared memory
 | 
				
			||||||
        self.np_shm[:] = tensor_input[:]
 | 
					        self.np_shm[:] = tensor_input[:]
 | 
				
			||||||
        self.event.clear()
 | 
					        self.event.clear()
 | 
				
			||||||
        self.detection_queue.put(self.name)
 | 
					        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 it timed out
 | 
				
			||||||
        if result is None:
 | 
					        if result is None:
 | 
				
			||||||
 | 
				
			|||||||
@ -160,6 +160,7 @@ def capture_frames(
 | 
				
			|||||||
    fps: mp.Value,
 | 
					    fps: mp.Value,
 | 
				
			||||||
    skipped_fps: mp.Value,
 | 
					    skipped_fps: mp.Value,
 | 
				
			||||||
    current_frame: mp.Value,
 | 
					    current_frame: mp.Value,
 | 
				
			||||||
 | 
					    stop_event: mp.Event,
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    frame_size = frame_shape[0] * frame_shape[1]
 | 
					    frame_size = frame_shape[0] * frame_shape[1]
 | 
				
			||||||
@ -177,6 +178,9 @@ def capture_frames(
 | 
				
			|||||||
        try:
 | 
					        try:
 | 
				
			||||||
            frame_buffer[:] = ffmpeg_process.stdout.read(frame_size)
 | 
					            frame_buffer[:] = ffmpeg_process.stdout.read(frame_size)
 | 
				
			||||||
        except Exception as e:
 | 
					        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.")
 | 
					            logger.error(f"{camera_name}: Unable to read frames from ffmpeg process.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ffmpeg_process.poll() != None:
 | 
					            if ffmpeg_process.poll() != None:
 | 
				
			||||||
@ -340,6 +344,7 @@ class CameraWatchdog(threading.Thread):
 | 
				
			|||||||
            self.frame_shape,
 | 
					            self.frame_shape,
 | 
				
			||||||
            self.frame_queue,
 | 
					            self.frame_queue,
 | 
				
			||||||
            self.camera_fps,
 | 
					            self.camera_fps,
 | 
				
			||||||
 | 
					            self.stop_event,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.capture_thread.start()
 | 
					        self.capture_thread.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -368,13 +373,16 @@ class CameraWatchdog(threading.Thread):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CameraCapture(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)
 | 
					        threading.Thread.__init__(self)
 | 
				
			||||||
        self.name = f"capture:{camera_name}"
 | 
					        self.name = f"capture:{camera_name}"
 | 
				
			||||||
        self.camera_name = camera_name
 | 
					        self.camera_name = camera_name
 | 
				
			||||||
        self.frame_shape = frame_shape
 | 
					        self.frame_shape = frame_shape
 | 
				
			||||||
        self.frame_queue = frame_queue
 | 
					        self.frame_queue = frame_queue
 | 
				
			||||||
        self.fps = fps
 | 
					        self.fps = fps
 | 
				
			||||||
 | 
					        self.stop_event = stop_event
 | 
				
			||||||
        self.skipped_fps = EventsPerSecond()
 | 
					        self.skipped_fps = EventsPerSecond()
 | 
				
			||||||
        self.frame_manager = SharedMemoryFrameManager()
 | 
					        self.frame_manager = SharedMemoryFrameManager()
 | 
				
			||||||
        self.ffmpeg_process = ffmpeg_process
 | 
					        self.ffmpeg_process = ffmpeg_process
 | 
				
			||||||
@ -392,6 +400,7 @@ class CameraCapture(threading.Thread):
 | 
				
			|||||||
            self.fps,
 | 
					            self.fps,
 | 
				
			||||||
            self.skipped_fps,
 | 
					            self.skipped_fps,
 | 
				
			||||||
            self.current_frame,
 | 
					            self.current_frame,
 | 
				
			||||||
 | 
					            self.stop_event,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -461,7 +470,7 @@ def track_camera(
 | 
				
			|||||||
        motion_contour_area,
 | 
					        motion_contour_area,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    object_detector = RemoteObjectDetector(
 | 
					    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)
 | 
					    object_tracker = ObjectTracker(config.detect)
 | 
				
			||||||
@ -723,9 +732,6 @@ def process_frames(
 | 
				
			|||||||
                        object_filters,
 | 
					                        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
 | 
					            # merge objects, check for clipped objects and look again up to 4 times
 | 
				
			||||||
@ -790,9 +796,7 @@ def process_frames(
 | 
				
			|||||||
                            refining = True
 | 
					                            refining = True
 | 
				
			||||||
                        else:
 | 
					                        else:
 | 
				
			||||||
                            selected_objects.append(obj)
 | 
					                            selected_objects.append(obj)
 | 
				
			||||||
                        # if frigate is exiting
 | 
					
 | 
				
			||||||
                        if stop_event.is_set():
 | 
					 | 
				
			||||||
                            return
 | 
					 | 
				
			||||||
                # set the detections list to only include top, complete objects
 | 
					                # set the detections list to only include top, complete objects
 | 
				
			||||||
                # and new detections
 | 
					                # and new detections
 | 
				
			||||||
                detections = selected_objects
 | 
					                detections = selected_objects
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user