Skip to content

feat(sensor-oak): runtime on/off for the H.264 stream (device-side Gate) - #14

Closed
edgarriba wants to merge 5 commits into
feat/sensor-oak-on-depthai-rsfrom
feat/sensor-oak-video-gate
Closed

edgarriba wants to merge 5 commits into
feat/sensor-oak-on-depthai-rsfrom
feat/sensor-oak-video-gate

Conversation

@edgarriba

Copy link
Copy Markdown
Member

Summary

Stacked on #13. The on-device H.264 path is now NV12 → Gate → VideoEncoder, and OakSource can drive the gate at runtime:

  • set_video_streaming(on): off = the encoder idles and no video bytes cross the link; the colour camera keeps serving RGB/depth. For a saturated PoE/USB2 link, or streaming only while something is worth watching.
  • video_burst(frames, fps): pass a clip, then close again ("record on detection").
  • Default open, so every existing caller behaves as before. OAK_VIDEO_GATED=1 starts closed via Gate::initialConfig (no frames leak before the first control).
  • oak_rgbd_probe --gate runs off / on / off / burst(10) windows and prints the frame count per window.

Pins depthai-rs at 51c6d02 (kornia/depthai-rs#1: Gate, InputQueue, GateControl, set_initial_config). Policy (knob, defaults) stays in sensor-oak; the wrapper only mirrors depthai.

Test plan

  • clippy + 15 unit tests natively on the Orin (knob parsing incl. OAK_VIDEO_GATED)
  • OAK-D attached: cargo run --release --example oak_rgbd_probe -- --gate → off window ≈ 0 frames, on window ≈ 2·fps, burst ≈ 10. Also confirms the Gate node runs on RVC2 firmware.
  • oak_stereo_probe unchanged (stereo path gains the gate too via the shared builder)

🤖 Generated with Claude Code

https://claude.ai/code/session_01XpkL1ayku6dKhdSTstGJJX

edgarriba and others added 5 commits September 2, 2026 09:01
…de Gate

add_h264_encoder now builds NV12 -> Gate -> VideoEncoder and keeps the gate's
control queue. OakSource::set_video_streaming(on) switches the stream at
runtime (off = the encoder idles and no video bytes cross the link, the camera
keeps serving RGB/depth); OakSource::video_burst(frames, fps) passes a clip
then closes again. The gate starts open, so existing callers see no change;
OAK_VIDEO_GATED=1 starts it closed (Gate::initialConfig) for consumers that
want nothing on the link until they ask.

oak_rgbd_probe --gate exercises off / on / off / burst(10) windows. Pins
depthai-rs at 51c6d02 (Gate, InputQueue, GateControl, set_initial_config).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpkL1ayku6dKhdSTstGJJX
…ure, trims

Review pass on the gate change:

- OakSource keeps the H264 { queue, control } the builder returns instead of
  splitting it into two Options with a hand-documented invariant.
- add_h264_encoder removes the gate and encoder nodes when any later step fails,
  so the degrade path (no video, everything else runs) cannot leave a half-wired
  node that fails Pipeline::start for the whole open. Same pattern as the stereo
  attacher.
- The gate's input takes the encoder's queue shape (3 deep, blocking) so the
  camera is back-pressured as before rather than dropping frames at the gate's
  default 1-deep overwrite queue.
- Docs say each thing once; CLAUDE.md folds the gate into the modalities bullet;
  the probe's window loop is a function with one duration constant.
- Pins depthai-rs b50c3ae (DAI_GATE macro, no ABI change).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmCRdrYoyj2zokHSv5EvvM
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmCRdrYoyj2zokHSv5EvvM
…eaders in calib.rs

Simplify + review pass over the whole rewrite (#13 + #14) before merging:

- Q<M>: one output queue with its own "first poll failure logged" latch,
  replacing the Which bitmask enum, the Cell<u8> on OakSource and the
  queue clones that dodged the borrow checker. OakSource holds the Queues
  the builder returned instead of re-flattening them.
- Session::finish is the one shared tail of both open paths (attach IMU last,
  start, read the reference camera's intrinsics); Built/from_parts are gone.
  Knobs are passed into Session::connect, so the session is a function of its
  arguments.
- Calibration readers (intrinsics, stereo calibration, IMU rotation) move from
  graph.rs to calib.rs next to the types they fill; one pinhole extractor.
- One row-pitch normaliser feeds the stereo tightness check and the RGB/depth
  repacks; depth repacks straight into u16 (one allocation instead of two).
- eye_image uses kornia's Image::from_borrowed_host_readonly directly; the
  kornia-tensor dependency goes.
- add_stereo_depth tracks the nodes it made and removes them all on failure
  (one shape with add_h264_encoder); the no-CAM_A degrade lives in
  try_add_h264_encoder for both modalities; clamp_imu_hz and the device-id
  normalisation live in policy.rs with the other rules.
- Docs say each thing once; README's open_stereo example has the right arity;
  CLAUDE.md points at the right files.

No public API change; behaviour unchanged (the IMU keeps its per-drain clock
offset as the shim always had).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmCRdrYoyj2zokHSv5EvvM
@edgarriba
edgarriba deleted the branch feat/sensor-oak-on-depthai-rs September 2, 2026 07:57
@edgarriba edgarriba closed this Sep 2, 2026
@edgarriba
edgarriba deleted the feat/sensor-oak-video-gate branch September 2, 2026 07:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant