What's happening
On an iPhone front TrueDepth camera, requesting 1080p at 60fps records 3840×2160@60 instead of the device's native 1920×1080@60 format.
Repro
const videoOutput = useVideoOutput({ targetResolution: CommonResolutions.FHD_16_9, enableAudio: true })
<Camera
device={frontDevice}
outputs={[videoOutput]}
constraints={[{ resolutionBias: videoOutput }, { fps: 60 }]}
/>
videoOutput.currentResolution → 3840×2160.
Why (traced in ConstraintResolver / CMVideoDimensions+penalty)
The device exposes native 1920×1080 @ [2–60] formats. But the per-format penalties at target 1080p / 60fps come out:
| format @60fps |
penalty |
| 1920×1080 @60 |
54.5 |
| 1280×720 @60 |
62.6 |
| 3840×2160 @60 |
9.7 ← selected |
The resolutionBias penalty actually favors 1080p (its logPixelDistance is 0; 4K's is 1.386), but resolution distance is on a log scale (~0–1.4) while the FPS penalty is in raw frame units (max(undershoot, overshoot), up to 30) and weighted higher in the sum. So FPS and the other constraints swamp the resolution target, and requesting a higher FPS silently escalates the recording resolution far beyond targetResolution.
Device format / fps dump (front TrueDepth)
Video resolutions:
…1280×720, 1440×1080, 1920×1080, 1920×1440, 3088×2316, 3840×2160, 4032×3024
Native 1920×1080 formats are present with frame-rate ranges [2–30], [2–60], and [1–120] — so a native 1080p@60 path exists; the negotiation just doesn't select it.
Question
Is this intended? targetResolution seems like it should be a stronger signal — a user asking for 1080p shouldn't get 4K just because they also asked for 60fps. Should pixel-distance be weighted comparably to the aspect term, or the FPS penalty normalized to a relative scale? Happy to PR (draft incoming) once the intended direction is confirmed.
Environment
react-native-vision-camera 5.0.10
- iOS, iPhone front TrueDepth camera
LLM: Claude Opus 4.8 (1M) | Effort: High | Harness: Claude Code
What's happening
On an iPhone front TrueDepth camera, requesting 1080p at 60fps records 3840×2160@60 instead of the device's native 1920×1080@60 format.
Repro
videoOutput.currentResolution→3840×2160.Why (traced in
ConstraintResolver/CMVideoDimensions+penalty)The device exposes native
1920×1080 @ [2–60]formats. But the per-format penalties at target1080p / 60fpscome out:The
resolutionBiaspenalty actually favors 1080p (itslogPixelDistanceis0; 4K's is1.386), but resolution distance is on a log scale (~0–1.4) while the FPS penalty is in raw frame units (max(undershoot, overshoot), up to 30) and weighted higher in the sum. So FPS and the other constraints swamp the resolution target, and requesting a higher FPS silently escalates the recording resolution far beyondtargetResolution.Device format / fps dump (front TrueDepth)
Video resolutions:
…1280×720, 1440×1080, 1920×1080, 1920×1440, 3088×2316, 3840×2160, 4032×3024Native
1920×1080formats are present with frame-rate ranges[2–30],[2–60], and[1–120]— so a native 1080p@60 path exists; the negotiation just doesn't select it.Question
Is this intended?
targetResolutionseems like it should be a stronger signal — a user asking for 1080p shouldn't get 4K just because they also asked for 60fps. Should pixel-distance be weighted comparably to the aspect term, or the FPS penalty normalized to a relative scale? Happy to PR (draft incoming) once the intended direction is confirmed.Environment
react-native-vision-camera5.0.10LLM: Claude Opus 4.8 (1M) | Effort: High | Harness: Claude Code