feat: frame work off the event loop, each frame encoded once
- Endpoints that wait for the camera or encode/compute (capture, rgb, depth, depth/color, pointcloud, pointcloud/roi, measure, snapshot, and the SDK calls discover/open/close) are plain `def`: FastAPI runs them in its thread pool, so one slow request no longer holds the others. Plain `def` rather than asyncio.to_thread in each route: it is FastAPI's own mechanism and keeps the route bodies unchanged. - /ws and the NATS snapshot stay async and use asyncio.to_thread for the frame wait, the encoding and the recording write. - EncodedFrame: the JPEG q85, 16-bit PNG, colormap JPEG q90, their base64 and the depth stats of a frame are computed once, on first use, and shared: parallel requests, /ws and NATS on the same frame get the same bytes. The last 4 frames' encodings are kept. - camera.cached_frame(): the whole cached frame (get_rgb/get_depth unchanged). Contract unchanged: same endpoints, same JSON fields. frame_id still counts responses (now under a lock); two parallel /api/capture served by one frame have different frame_id and the same timestamp and images. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cc28127c9c
commit
1ad422062c
4 files changed
+125
-50
No files matched your search
@@ -466,6 +466,10 @@ class RealSenseD435:
|
||||
return last
|
||||
return self.capture()
|
||||
|
||||
def cached_frame(self) -> Optional[CameraFrame]:
|
||||
"""Like get_rgb()/get_depth(), but the whole frame (so its encodings can be shared)."""
|
||||
return self._cached_or_capture()
|
||||
|
||||
def get_rgb(self) -> Optional[np.ndarray]:
|
||||
f = self._cached_or_capture()
|
||||
return f.rgb if f else None
|
||||
|
||||
Reference in new issue
Block a user