fix(macos): select format and frame-rate range from the same AVCaptureDeviceFormat - #248
Open
kasper-cancilico wants to merge 1 commit into
Open
Conversation
…eDeviceFormat AVCaptureDevice::set_all kept overwriting selected_format for every format matching the requested resolution while selected_range could come from an earlier format. Applying a frame-rate range that does not belong to the active format makes AVFoundation throw NSInvalidArgumentException, which cannot unwind through the objc catch and aborts the process. Cameras exposing several formats at the same resolution (e.g. Logitech UVC devices with 420v and MJPEG variants) hit this deterministically on open. Select the format and range from the same AVCaptureDeviceFormat, stop at the first satisfying pair, and fall back consistently to the first resolution-matching format with its first range. Also record the acquired configuration lock in lock() so unlock() actually releases it (self.locked was never set, so unlockForConfiguration was never called).
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #247.
Problem
AVCaptureDevice::set_alloverwritesselected_formatfor every format matching the requested resolution, whileselected_rangemay come from an earlier format. Applying a frame-rate range that does not belong to the newactiveFormatmakes AVFoundation throwNSInvalidArgumentException, which cannot unwind through theobjccatch and aborts the process instead of returningErr. Cameras exposing several formats at one resolution (e.g. Logitech UVC devices: 420v + MJPEG variants) hit this deterministically inCamera::new().Change
selected_formatandselected_rangetogether from the sameAVCaptureDeviceFormat, breaking at the first pair that satisfies the requested fps (keeping the existing 0.999 tolerance for 29.97-style rates).lock(): setself.locked = trueafter a successfullockForConfigurationsounlock()(guarded byself.locked) actually callsunlockForConfiguration. Previously the flag was never set and the device stayed configuration-locked. This changeslock(&self)tolock(&mut self); the only in-tree caller (set_all) already takes&mut self.Testing
cargo checkonnokhwa-bindings-macos(macOS 26, Apple Silicon): compiles; no new warnings.Camera::new()withRequestedFormatType::AbsoluteHighestResolutionnow opens at 1280x960, streams frames continuously, and delivers full-resolution stills. A MacBook Air built-in camera and an iPhone Continuity camera still enumerate as before (open not re-tested on those).🤖 Generated with Claude Code