diff --git a/frigate/http.py b/frigate/http.py index a469709b8..0fc230c47 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -825,6 +825,24 @@ def latest_frame(camera_name): frame = cv2.resize(frame, dsize=(width, height), interpolation=cv2.INTER_AREA) + ret, jpg = cv2.imencode( + ".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), resize_quality] + ) + response = make_response(jpg.tobytes()) + response.headers["Content-Type"] = "image/jpeg" + response.headers["Cache-Control"] = "no-store" + return response + elif camera_name == "birdseye" and current_app.frigate_config.restream.birdseye: + frame = cv2.cvtColor( + current_app.detected_frames_processor.get_current_frame(camera_name), + cv2.COLOR_YUV2BGR_I420, + ) + + height = int(request.args.get("h", str(frame.shape[0]))) + width = int(height * frame.shape[1] / frame.shape[0]) + + frame = cv2.resize(frame, dsize=(width, height), interpolation=cv2.INTER_AREA) + ret, jpg = cv2.imencode( ".jpg", frame, [int(cv2.IMWRITE_JPEG_QUALITY), resize_quality] ) diff --git a/frigate/object_processing.py b/frigate/object_processing.py index 49679f9b0..5477f57b9 100644 --- a/frigate/object_processing.py +++ b/frigate/object_processing.py @@ -880,6 +880,12 @@ class TrackedObjectProcessor(threading.Thread): return {} def get_current_frame(self, camera, draw_options={}): + if camera == "birdseye": + return self.frame_manager.get( + "birdseye", + (self.config.birdseye.height * 3 // 2, self.config.birdseye.width), + ) + return self.camera_states[camera].get_current_frame(draw_options) def get_current_frame_time(self, camera) -> int: diff --git a/frigate/output.py b/frigate/output.py index 59490c7f8..e987c7080 100644 --- a/frigate/output.py +++ b/frigate/output.py @@ -152,7 +152,7 @@ class BroadcastThread(threading.Thread): class BirdsEyeFrameManager: - def __init__(self, config, frame_manager: SharedMemoryFrameManager): + def __init__(self, config: FrigateConfig, frame_manager: SharedMemoryFrameManager): self.config = config self.mode = config.birdseye.mode self.frame_manager = frame_manager @@ -463,6 +463,12 @@ def output_frames(config: FrigateConfig, video_output_queue): birdseye_manager = BirdsEyeFrameManager(config, frame_manager) + if config.restream.birdseye: + birdseye_buffer = frame_manager.create( + "birdseye", + birdseye_manager.yuv_shape[0] * birdseye_manager.yuv_shape[1], + ) + while not stop_event.is_set(): try: ( @@ -500,7 +506,12 @@ def output_frames(config: FrigateConfig, video_output_queue): frame_time, frame, ): - converters["birdseye"].write(birdseye_manager.frame.tobytes()) + frame_bytes = birdseye_manager.frame.tobytes() + + if config.restream.birdseye: + birdseye_buffer[:] = frame_bytes + + converters["birdseye"].write(frame_bytes) if camera in previous_frames: frame_manager.delete(f"{camera}{previous_frames[camera]}")