Using objc2 crate to set AVCaptureVideoDataOutput video settings causes fatal runtime error: "Rust cannot catch foreign exceptions"

I'm currently using the objc2 crates, specifically the following crates:

  • objc2_foundation
  • objc2_core_video
  • objc2_av_foundation

Im trying to set the video settings for an AVCaptureVideoDataOutput instance to use the kCVPixelFormatType_32BGRA pixel format.

Here is my code:

use objc2_foundation::{NSString, NSNumber, NSDictionary};
use objc2_core_video::kCVPixelFormatType_32BGRA;
use objc2_av_foundation::AVCaptureVideoDataOutput;

fn main() {
    unsafe {
        let output = AVCaptureVideoDataOutput::new();

        let pixel_format_key = NSString::from_str("kCVPixelBufferPixelFormatTypeKey");
        let pixel_format_value = NSNumber::new_u32(kCVPixelFormatType_32BGRA);

        let video_settings = NSDictionary::from_slices::<NSString>(
            &[pixel_format_key.as_ref()],
            &[pixel_format_value.as_ref()],
        );

        output.setVideoSettings(Some(&video_settings));
    }
}

Thanks!!

I am unfamiliar with objc2, but it has types and documentation for exception handling: objc2::exception - Rust.

1 Like

Thank you, @parasyte! I was able to track down the bug using exception handling, and it turns out I was setting invalid keys.

Originally, I was creating the key like this:

let pixel_format_key = NSString::from_str("kCVPixelBufferPixelFormatTypeKey");

That doesn't work because the system wants a specific constant not just a string with the same value. The fix was to use the actual CFStringRef constant provided by the objc2_core_video crate, and then safely cast it to an NSString reference:

rust

let pixel_format_key: &NSString = &*(kCVPixelBufferPixelFormatTypeKey as *const _ as *const NSString);

This change makes sure that AVCaptureVideoDataOutput receives a properly recognized key, which fixed the issue with setVideoSettings. Everything works now🥳!!