pull from memory if event in progress

This commit is contained in:
Blake Blackshear 2020-11-25 10:37:41 -06:00
parent e07c4e0d8c
commit b39da3ee01
4 changed files with 34 additions and 9 deletions

View File

@ -55,8 +55,9 @@ class FrigateApp():
} }
def init_queues(self): def init_queues(self):
# Queue for clip processing # Queues for clip processing
self.event_queue = mp.Queue() self.event_queue = mp.Queue()
self.event_processed_queue = mp.Queue()
# Queue for cameras to push tracked objects to # Queue for cameras to push tracked objects to
self.detected_frames_queue = mp.Queue(maxsize=len(self.config.cameras.keys())*2) self.detected_frames_queue = mp.Queue(maxsize=len(self.config.cameras.keys())*2)
@ -89,7 +90,7 @@ class FrigateApp():
def start_detected_frames_processor(self): def start_detected_frames_processor(self):
self.detected_frames_processor = TrackedObjectProcessor(self.config, self.mqtt_client, self.config.mqtt.topic_prefix, self.detected_frames_processor = TrackedObjectProcessor(self.config, self.mqtt_client, self.config.mqtt.topic_prefix,
self.detected_frames_queue, self.event_queue, self.stop_event) self.detected_frames_queue, self.event_queue, self.event_processed_queue, self.stop_event)
self.detected_frames_processor.start() self.detected_frames_processor.start()
def start_camera_processors(self): def start_camera_processors(self):
@ -112,7 +113,7 @@ class FrigateApp():
logger.info(f"Capture process started for {name}: {capture_process.pid}") logger.info(f"Capture process started for {name}: {capture_process.pid}")
def start_event_processor(self): def start_event_processor(self):
self.event_processor = EventProcessor(self.config, self.camera_metrics, self.event_queue, self.stop_event) self.event_processor = EventProcessor(self.config, self.camera_metrics, self.event_queue, self.event_processed_queue, self.stop_event)
self.event_processor.start() self.event_processor.start()
def start_event_cleanup(self): def start_event_cleanup(self):

View File

@ -19,7 +19,7 @@ from peewee import fn
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class EventProcessor(threading.Thread): class EventProcessor(threading.Thread):
def __init__(self, config, camera_processes, event_queue, stop_event): def __init__(self, config, camera_processes, event_queue, event_processed_queue, stop_event):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.name = 'event_processor' self.name = 'event_processor'
self.config = config self.config = config
@ -28,6 +28,7 @@ class EventProcessor(threading.Thread):
self.camera_processes = camera_processes self.camera_processes = camera_processes
self.cached_clips = {} self.cached_clips = {}
self.event_queue = event_queue self.event_queue = event_queue
self.event_processed_queue = event_processed_queue
self.events_in_process = {} self.events_in_process = {}
self.stop_event = stop_event self.stop_event = stop_event
@ -190,6 +191,7 @@ class EventProcessor(threading.Thread):
thumbnail=event_data['thumbnail'] thumbnail=event_data['thumbnail']
) )
del self.events_in_process[event_data['id']] del self.events_in_process[event_data['id']]
self.event_processed_queue.put((event_data['id'], camera))
class EventCleanup(threading.Thread): class EventCleanup(threading.Thread):
def __init__(self, config: FrigateConfig, stop_event): def __init__(self, config: FrigateConfig, stop_event):

View File

@ -14,6 +14,8 @@ from playhouse.shortcuts import model_to_dict
from frigate.models import Event from frigate.models import Event
logger = logging.getLogger(__name__)
bp = Blueprint('frigate', __name__) bp = Blueprint('frigate', __name__)
def create_app(frigate_config, database: SqliteDatabase, camera_metrics, detectors, detected_frames_processor): def create_app(frigate_config, database: SqliteDatabase, camera_metrics, detectors, detected_frames_processor):
@ -79,6 +81,17 @@ def event_snapshot(id):
response.headers['Content-Type'] = 'image/jpg' response.headers['Content-Type'] = 'image/jpg'
return response return response
except DoesNotExist: except DoesNotExist:
# see if the object is currently being tracked
try:
for camera_state in current_app.detected_frames_processor.camera_states.values():
if id in camera_state.tracked_objects:
tracked_obj = camera_state.tracked_objects.get(id)
if not tracked_obj is None:
response = make_response(tracked_obj.get_jpg_bytes())
response.headers['Content-Type'] = 'image/jpg'
return response
except:
return "Event not found", 404
return "Event not found", 404 return "Event not found", 404
@bp.route('/events') @bp.route('/events')

View File

@ -279,6 +279,9 @@ class CameraState():
return frame_copy return frame_copy
def finished(self, obj_id):
del self.tracked_objects[obj_id]
def on(self, event_type: str, callback: Callable[[Dict], None]): def on(self, event_type: str, callback: Callable[[Dict], None]):
self.callbacks[event_type].append(callback) self.callbacks[event_type].append(callback)
@ -317,10 +320,10 @@ class CameraState():
for id in removed_ids: for id in removed_ids:
# publish events to mqtt # publish events to mqtt
removed_obj = self.tracked_objects[id] removed_obj = self.tracked_objects[id]
if not 'end_time' in removed_obj.obj_data:
removed_obj.obj_data['end_time'] = frame_time removed_obj.obj_data['end_time'] = frame_time
for c in self.callbacks['end']: for c in self.callbacks['end']:
c(self.name, removed_obj) c(self.name, removed_obj)
del self.tracked_objects[id]
# TODO: can i switch to looking this up and only changing when an event ends? # TODO: can i switch to looking this up and only changing when an event ends?
# maybe make an api endpoint that pulls the thumbnail from the file system? # maybe make an api endpoint that pulls the thumbnail from the file system?
@ -382,7 +385,7 @@ class CameraState():
self.previous_frame_id = frame_id self.previous_frame_id = frame_id
class TrackedObjectProcessor(threading.Thread): class TrackedObjectProcessor(threading.Thread):
def __init__(self, config: FrigateConfig, client, topic_prefix, tracked_objects_queue, event_queue, stop_event): def __init__(self, config: FrigateConfig, client, topic_prefix, tracked_objects_queue, event_queue, event_processed_queue, stop_event):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.name = "detected_frames_processor" self.name = "detected_frames_processor"
self.config = config self.config = config
@ -390,6 +393,7 @@ class TrackedObjectProcessor(threading.Thread):
self.topic_prefix = topic_prefix self.topic_prefix = topic_prefix
self.tracked_objects_queue = tracked_objects_queue self.tracked_objects_queue = tracked_objects_queue
self.event_queue = event_queue self.event_queue = event_queue
self.event_processed_queue = event_processed_queue
self.stop_event = stop_event self.stop_event = stop_event
self.camera_states: Dict[str, CameraState] = {} self.camera_states: Dict[str, CameraState] = {}
self.frame_manager = SharedMemoryFrameManager() self.frame_manager = SharedMemoryFrameManager()
@ -480,3 +484,8 @@ class TrackedObjectProcessor(threading.Thread):
self.client.publish(f"{self.topic_prefix}/{zone}/{label}", 'ON', retain=False) self.client.publish(f"{self.topic_prefix}/{zone}/{label}", 'ON', retain=False)
elif previous_state == True and new_state == False: elif previous_state == True and new_state == False:
self.client.publish(f"{self.topic_prefix}/{zone}/{label}", 'OFF', retain=False) self.client.publish(f"{self.topic_prefix}/{zone}/{label}", 'OFF', retain=False)
# cleanup event finished queue
while not self.event_processed_queue.empty():
event_id, camera = self.event_processed_queue.get()
self.camera_states[camera].finished(event_id)