Skip to content

feat(#16): optional exposure/framerate lock#19

Merged
opariffazman merged 1 commit into
mainfrom
worktree-exposure-lock-16
Jun 25, 2026
Merged

feat(#16): optional exposure/framerate lock#19
opariffazman merged 1 commit into
mainfrom
worktree-exposure-lock-16

Conversation

@opariffazman

Copy link
Copy Markdown
Contributor

Closes #16.

Problem

Webcam auto-exposure raises frame time past the 33 ms/frame budget in low light, so the camera physically drops to ~15 fps. Confirmed live (overlay reads ~15 dim, 30 bright). Camera firmware behavior, not the capture pipeline.

Change

Optional control to pin the camera to Manual exposure so framerate holds at 30 regardless of lighting, at the cost of a darker image in dim rooms. Off by default (keeps auto-exposure).

  • Native: worker queries IAMCameraControl off the reader''s media source; if the camera supports Manual exposure it maps a normalized 0..1 value onto the camera range (snapped to stepping) and pushes on change; OFF restores Auto. No-ops when unsupported; restores Auto on shutdown.
  • ABI: CosParams += exposure_lock_enabled + exposure_value; CosStatus += exposure_supported (per-camera support is known only while running, so surfaced via the polled status, not the pre-start capability probe).
  • C#: ShimParams/ShimStatus + PInvoke mirrors; EffectSettings persistence; VM observable ExposureLock/ExposureValue/ExposureSupported with live push + config round-trip; XAML toggle + brightness slider, greyed until running and the camera reports support.

The native camControl==null check is the authoritative gate (a managed ApplyParams gate would force exposure off at Start before the first status poll lands and break persisted-on exposure).

Verification

  • Native SDK shim build clean; export-verify passes (GreenScreen + GazeRedirection present, no stub).
  • Core tests: 59 passed (incl. new exposure round-trip test).
  • App build: 0 warnings.
  • Human gate (real RTX + camera): dim room ~15 fps → toggle ON → ~30 + darker; slider trades brightness; greyed on cameras without manual exposure.

🤖 Generated with Claude Code

Auto-exposure raises frame time past the 33ms budget in low light, halving
fps to ~15. Add an optional control to pin the camera to Manual exposure so
framerate holds steady, at the cost of a darker image. Off by default.

Native: worker queries IAMCameraControl off the reader's media source; when the
camera supports Manual exposure it maps a normalized 0..1 value onto the camera
range (snapped to stepping) and pushes on change; OFF restores Auto. No-ops when
unsupported; restores Auto on shutdown. ABI: CosParams += exposure_lock_enabled
+ exposure_value; CosStatus += exposure_supported (support is per open camera,
known only while running, so surfaced via the polled status not the pre-start
capability probe).

C#: ShimParams/ShimStatus + PInvoke mirrors; EffectSettings persistence; VM
observable ExposureLock/ExposureValue/ExposureSupported with live push + config
round-trip; XAML toggle + brightness slider, greyed until running and supported.

The native camControl==null check is the authoritative gate (not a managed
ApplyParams gate, which would force exposure off at Start before the first
status poll and break persisted-on exposure).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@opariffazman
opariffazman merged commit be65612 into main Jun 25, 2026
1 check passed
@opariffazman
opariffazman deleted the worktree-exposure-lock-16 branch June 25, 2026 12:35
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.

Optional exposure/framerate lock (prevent auto-exposure halving FPS in low light)

1 participant