Skip to content

targetResolution is ignored when requesting high FPS — records 4K@60 even though a native 1080p@60 format exists (iOS) #3963

@richkuo

Description

@richkuo

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.currentResolution3840×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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions