Two threads while the camera is open:
- realsense-raw (continuous, FrameAcquisition(on_demand=False)): the only
caller of wait_for_frames. For every frameset it publishes the color image
(own BGR copy) with the camera timestamp, its domain and the host arrival
time, and keeps the SDK frameset. No align and no depth conversion at the
camera rate: per frame it costs wait + one color copy (YUYV decode on USB 2).
- realsense-align (on demand, as in R01): when someone asks for color+depth
it aligns the newest frameset not aligned yet, converts the depth, copies.
Concurrent callers share one align. capture(), the 100 ms cache of
get_rgb/get_depth/cached_frame and every existing endpoint read this
aligned frame, so /api/rgb stays the color of the same frame as /api/depth.
The aligned color reuses the raw color pixels (align maps depth onto color).
At most 3 SDK framesets are referenced at a time (latest, receiving,
aligning); ColorFrame and CameraFrame hold no SDK memory.
New timing phase color_convert. One commit for items 1 and 2 of the request:
once the continuous thread owns the pipeline, the aligned path must take
its framesets, so they cannot be split without a broken intermediate state.
color_frame(after_seq, timeout_ms) gives the fast channel to the API.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>