use std::ops::{Deref, DerefMut};
use crate::{api, arc, av, ca, cg, define_cls, define_obj_type, ns, objc};
#[cfg(feature = "cm")]
use crate::cm;
#[cfg(feature = "blocks")]
use crate::blocks;
#[link(name = "AVFoundation", kind = "framework")]
#[api::weak]
unsafe extern "C-unwind" {
#[api::available(
macos = 14.0,
ios = 17.0,
maccatalyst = 17.0,
tvos = 17.0,
visionos = 2.1
)]
static AVCaptureDeviceTypeExternal: &'static Type;
#[api::available(macos = 10.15, ios = 10.0)]
static AVCaptureDeviceTypeBuiltInMicrophone: &'static Type;
#[api::available(macos = 14.0, ios = 17.0)]
static AVCaptureDeviceTypeMicrophone: &'static Type;
#[api::available(
macos = 10.15,
ios = 10.0,
maccatalyst = 14.0,
tvos = 17.0,
visionos = 2.1
)]
static AVCaptureDeviceTypeBuiltInWideAngleCamera: &'static Type;
#[api::available(ios = 10.0, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceTypeBuiltInTelephotoCamera: &'static Type;
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceTypeBuiltInUltraWideCamera: &'static Type;
#[api::available(ios = 10.2, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceTypeBuiltInDualCamera: &'static Type;
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceTypeBuiltInDualWideCamera: &'static Type;
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceTypeBuiltInTripleCamera: &'static Type;
#[api::available(ios = 11.1, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceTypeBuiltInTrueDepthCamera: &'static Type;
#[api::available(ios = 15.4, maccatalyst = 15.4, tvos = 17.0)]
static AVCaptureDeviceTypeBuiltInLiDARDepthCamera: &'static Type;
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
static AVCaptureDeviceTypeContinuityCamera: &'static Type;
#[api::available(macos = 13.0)]
static AVCaptureDeviceTypeDeskViewCamera: &'static Type;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
static AVCaptureLensPositionCurrent: f32;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
static AVCaptureISOCurrent: f32;
#[cfg(all(feature = "cm", any(target_os = "tvos", target_os = "ios")))]
static AVCaptureExposureDurationCurrent: cm::Time;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
static AVCaptureExposureTargetBiasCurrent: f32;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
static AVCaptureWhiteBalanceGainsCurrent: WbGains;
static AVCaptureMaxAvailableTorchLevel: f32;
}
define_obj_type!(
#[doc(alias = "AVCaptureDevice")]
pub Device(ns::Id)
);
impl Device {
define_cls!(AV_CAPTURE_DEVICE);
#[objc::msg_send(defaultDeviceWithDeviceType:mediaType:position:)]
pub fn with_type_media_and_pos(
device_type: &Type,
media_type: Option<&av::MediaType>,
position: Pos,
) -> Option<arc::R<Self>>;
#[objc::msg_send(devices)]
pub fn devices() -> arc::R<ns::Array<Self>>;
#[objc::msg_send(defaultDeviceWithMediaType:)]
pub fn default_with_media(media_type: &av::MediaType) -> Option<arc::R<Self>>;
#[objc::msg_send(deviceWithUniqueID:)]
pub fn with_unique_id(unique_id: &ns::String) -> Option<arc::R<Self>>;
#[objc::msg_send(uniqueID)]
pub fn unique_id(&self) -> arc::R<ns::String>;
#[objc::msg_send(modelID)]
pub fn model_id(&self) -> arc::R<ns::String>;
#[objc::msg_send(localizedName)]
pub fn localized_name(&self) -> arc::R<ns::String>;
#[objc::msg_send(manufacturer)]
pub fn manufacturer(&self) -> Option<arc::R<ns::String>>;
#[objc::msg_send(hasMediaType:)]
pub fn has_media_type(&self, media_type: &av::MediaType) -> bool;
#[objc::msg_send(formats)]
pub fn formats(&self) -> arc::R<ns::Array<Format>>;
#[objc::msg_send(supportsAVCaptureSessionPreset:)]
pub fn supports_preset(&self, preset: &av::CaptureSessionPreset) -> bool;
#[objc::msg_send(activeFormat)]
pub fn active_format(&self) -> Option<arc::R<Format>>;
#[objc::msg_send(isConnected)]
pub fn is_connected(&self) -> bool;
#[cfg(feature = "cm")]
#[objc::msg_send(activeVideoMinFrameDuration)]
pub fn active_video_min_frame_duration(&self) -> cm::Time;
#[cfg(feature = "cm")]
#[objc::msg_send(activeVideoMaxFrameDuration)]
pub fn active_video_max_frame_duration(&self) -> cm::Time;
#[objc::msg_send(isAutoVideoFrameRateEnabled)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn is_auto_video_frame_rate_enabled(&self) -> bool;
pub fn config_lock(&mut self) -> Result<ConfigLockGuard<'_>, arc::R<ns::Error>> {
let mut error = None;
unsafe {
let result = self.lock_for_config(&mut error);
if let Some(error) = error.take() {
return Err(error);
}
debug_assert!(result);
Ok(ConfigLockGuard { device: self })
}
}
#[objc::msg_send(lockForConfiguration:)]
pub unsafe fn lock_for_config(&mut self, error: *mut Option<arc::R<ns::Error>>) -> bool;
#[objc::msg_send(unlockForConfiguration)]
pub unsafe fn unlock_for_config(&mut self);
#[objc::msg_send(setActiveFormat:)]
pub unsafe fn set_active_format(&mut self, val: &Format);
#[objc::msg_send(setAutoVideoFrameRateEnabled:)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub unsafe fn set_auto_video_frame_rate_enabled_throws(&mut self, val: bool);
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub unsafe fn set_auto_video_frame_rate_enabled<'ear>(
&mut self,
val: bool,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_auto_video_frame_rate_enabled_throws(val) })
}
#[cfg(feature = "cm")]
#[objc::msg_send(setActiveVideoMinFrameDuration:)]
pub unsafe fn set_active_video_min_frame_duration_throws(&mut self, val: cm::Time);
#[cfg(feature = "cm")]
pub unsafe fn set_active_video_min_frame_duration<'ear>(
&mut self,
val: cm::Time,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_active_video_min_frame_duration_throws(val) })
}
#[cfg(feature = "cm")]
#[objc::msg_send(setActiveVideoMaxFrameDuration:)]
pub unsafe fn set_active_video_max_frame_duration_throws(&mut self, val: cm::Time);
#[cfg(feature = "cm")]
pub unsafe fn set_active_video_max_frame_duration<'ear>(
&mut self,
val: cm::Time,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_active_video_max_frame_duration_throws(val) })
}
}
#[doc(alias = "AVCaptureFlashMode")]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(isize)]
pub enum FlashMode {
Off = 0,
On = 1,
Auto = 2,
}
impl Device {
#[objc::msg_send(hasFlash)]
pub fn has_flash(&self) -> bool;
#[objc::msg_send(isFlashAvailable)]
pub fn is_flash_available(&self) -> bool;
}
#[doc(alias = "AVCaptureTorchMode")]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(isize)]
pub enum TorchMode {
Off = 0,
On = 1,
Auto = 2,
}
impl Device {
#[objc::msg_send(hasTorch)]
pub fn has_torch(&self) -> bool;
#[objc::msg_send(isTorchAvailable)]
pub fn is_torch_available(&self) -> bool;
#[objc::msg_send(isTorchActive)]
pub fn is_torch_active(&self) -> bool;
#[objc::msg_send(torchLevel)]
pub fn torch_level(&self) -> f32;
#[objc::msg_send(isTorchModeSupported:)]
pub fn is_torch_mode_supported(&self, val: TorchMode) -> bool;
#[objc::msg_send(torchMode)]
pub fn torch_mode(&self) -> TorchMode;
#[objc::msg_send(setTorchMode:)]
unsafe fn set_torch_mode_throws(&self, val: TorchMode);
#[objc::msg_send(setTorchModeOnWithLevel:error:)]
unsafe fn set_torch_mode_on_with_level_err<'ear>(
&mut self,
torch_level: f32,
error: *mut Option<&'ear ns::Error>,
) -> bool;
}
impl<'a> ConfigLockGuard<'a> {
pub unsafe fn set_torch_mode_throws(&mut self, val: TorchMode) {
unsafe { self.device.set_torch_mode_throws(val) }
}
pub fn set_torch_mode<'ear>(&mut self, val: TorchMode) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_torch_mode_throws(val) })
}
pub unsafe fn set_torch_mode_on_with_level_err<'ear>(
&mut self,
torch_level: f32,
error: *mut Option<&'ear ns::Error>,
) -> bool {
unsafe {
self.device
.set_torch_mode_on_with_level_err(torch_level, error)
}
}
pub fn set_torch_mode_on_with_level<'ear>(&mut self, torch_level: f32) -> ns::Result<'ear> {
ns::if_false(|err| unsafe { self.set_torch_mode_on_with_level_err(torch_level, err) })
}
}
impl Device {
#[objc::msg_send(reactionEffectsEnabled)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn reaction_effects_enabled() -> bool;
#[objc::msg_send(reactionEffectGesturesEnabled)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn reaction_effect_gestures_enabled() -> bool;
#[objc::msg_send(canPerformReactionEffects)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn can_perform_reaction_effects(&self) -> bool;
#[objc::msg_send(availableReactionTypes)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn available_reaction_types(&self) -> arc::R<ns::Set<av::CaptureReactionType>>;
#[objc::msg_send(performEffectForReaction:)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn perform_effect_for_reaction(&mut self, reaction_type: &av::CaptureReactionType);
#[objc::msg_send(reactionEffectsInProgress)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn reaction_effects_in_progress(&self)
-> arc::R<ns::Array<av::CaptureReactionEffectState>>;
}
impl Device {
#[objc::msg_send(isBackgroundReplacementEnabled)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn is_background_replacement_enabled() -> bool;
#[objc::msg_send(isBackgroundReplacementActive)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn is_background_replacement_active(&self) -> bool;
}
impl Device {
#[objc::msg_send(isContinuityCamera)]
pub fn is_continuity_camera(&self) -> bool;
}
impl Device {
#[objc::msg_send(companionDeskViewCamera)]
pub fn companion_desk_view_camera(&self) -> Option<arc::R<Device>>;
}
impl Device {
#[objc::msg_send(automaticallyAdjustsVideoHDREnabled)]
pub fn automatically_adjusts_video_hdr_enabled(&self) -> bool;
#[objc::msg_send(setAutomaticallyAdjustsVideoHDREnabled:)]
pub unsafe fn set_automatically_adjusts_video_hdr_enabled_throws(&mut self, val: bool);
#[objc::msg_send(isVideoHDREnabled)]
pub fn is_video_hdr_enabled(&self) -> bool;
#[objc::msg_send(setVideoHDREnabled:)]
pub unsafe fn set_video_hdr_enabled_throws(&mut self, val: bool);
}
impl<'a> ConfigLockGuard<'a> {
pub fn set_video_hdr_enabled<'ear>(&mut self, val: bool) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.device.set_video_hdr_enabled_throws(val) })
}
pub fn set_automatically_adjusts_video_hdr_enabled<'ear>(
&mut self,
val: bool,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.device
.set_automatically_adjusts_video_hdr_enabled_throws(val)
})
}
}
#[doc(alias = "AVCaptureMicrophoneMode")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(isize)]
pub enum MicMode {
Standard = 0,
WideSpectrum = 1,
VoiceIsolation = 2,
}
impl Device {
#[objc::msg_send(preferredMicrophoneMode)]
#[api::available(macos = 12.0, ios = 15.0, maccatalyst = 15.0, tvos = 17.0)]
pub fn preferred_mic_mode() -> MicMode;
#[objc::msg_send(activeMicrophoneMode)]
#[api::available(macos = 12.0, ios = 15.0, maccatalyst = 15.0, tvos = 17.0)]
pub fn active_mic_mode() -> MicMode;
}
#[doc(alias = "AVCaptureCenterStageControlMode")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(isize)]
pub enum CenterStageControlMode {
User = 0,
App = 1,
Cooperative = 2,
}
impl Device {
#[objc::msg_send(centerStageControlMode)]
pub fn center_stage_control_mode() -> CenterStageControlMode;
#[objc::msg_send(setCenterStageControlMode:)]
pub fn set_center_stage_control_mode(val: CenterStageControlMode);
#[objc::msg_send(isCenterStageActive)]
pub fn is_center_stage_active(&self) -> bool;
#[objc::msg_send(centerStageRectOfInterest)]
pub fn center_stage_rect_of_interest(&self) -> cg::Rect;
#[objc::msg_send(setCenterStageRectOfInterest:)]
pub unsafe fn set_center_stage_rect_of_interest_throws(&mut self, val: cg::Rect);
}
#[doc(alias = "AVCaptureSystemUserInterface")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(isize)]
pub enum SysUi {
VideoEffects = 1,
MicModes = 2,
}
impl Device {
#[objc::msg_send(showSystemUserInterface:)]
#[api::available(macos = 12.0, ios = 15.0, maccatalyst = 15.0, tvos = 17.0)]
pub fn show_sys_ui(system_ui: SysUi);
}
#[doc(alias = "AVCaptureColorSpace")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
#[repr(isize)]
pub enum ColorSpace {
#[doc(alias = "AVCaptureColorSpace_sRGB")]
Srgb = 0,
#[doc(alias = "AVCaptureColorSpace_P3_D65")]
P3D65 = 1,
#[doc(alias = "AVCaptureColorSpace_HLG_BT2020")]
HlgBt2020 = 2,
#[doc(alias = "AVCaptureColorSpace_AppleLog")]
AppleLog = 3,
#[doc(alias = "AVCaptureColorSpace_AppleLog2")]
AppleLog2 = 4,
}
impl ColorSpace {
#[inline]
pub fn as_ns_number(&self) -> &'static ns::Number {
ns::Number::tagged_i32(*self as isize as i32)
}
}
impl Device {
#[objc::msg_send(activeColorSpace)]
pub fn active_color_space(&self) -> ColorSpace;
#[objc::msg_send(setActiveColorSpace:)]
pub unsafe fn set_active_color_space_throws(&mut self, val: ColorSpace);
}
pub struct ConfigLockGuard<'a> {
device: &'a mut Device,
}
impl<'a> ConfigLockGuard<'a> {
pub fn set_active_format(&mut self, val: &Format) {
unsafe { self.device.set_active_format(val) }
}
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn set_auto_video_frame_rate_enabled<'ear>(&mut self, val: bool) -> ns::ExResult<'ear> {
unsafe { self.device.set_auto_video_frame_rate_enabled(val) }
}
#[cfg(feature = "cm")]
pub fn set_active_video_min_frame_duration<'ear>(
&mut self,
val: cm::Time,
) -> ns::ExResult<'ear> {
unsafe { self.device.set_active_video_min_frame_duration(val) }
}
#[cfg(feature = "cm")]
pub fn set_active_video_max_frame_duration<'ear>(
&mut self,
val: cm::Time,
) -> ns::ExResult<'ear> {
unsafe { self.device.set_active_video_max_frame_duration(val) }
}
pub fn set_center_stage_rect_of_interest<'ear>(&mut self, val: cg::Rect) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.device.set_center_stage_rect_of_interest_throws(val) })
}
#[inline]
pub unsafe fn set_active_color_space_throws(&mut self, val: ColorSpace) {
unsafe { self.device.set_active_color_space_throws(val) }
}
#[inline]
pub unsafe fn set_focus_mode_throws(&mut self, mode: FocusMode) {
unsafe { self.device.set_focus_mode_throws(mode) }
}
pub fn set_focus_mode<'ear>(&mut self, mode: FocusMode) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_focus_mode_throws(mode) })
}
#[inline]
pub unsafe fn set_focus_point_of_interest_throws(&mut self, val: cg::Point) {
unsafe { self.device.set_focus_point_of_interest_throws(val) }
}
pub fn set_focus_point_of_interest<'ear>(&mut self, val: cg::Point) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_focus_point_of_interest_throws(val) })
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[inline]
pub unsafe fn set_auto_focus_range_restriction_throws(
&mut self,
val: AutoFocusRangeRestriction,
) {
unsafe { self.device.set_auto_focus_range_restriction_throws(val) }
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub fn set_auto_focus_range_restriction<'ear>(
&mut self,
val: AutoFocusRangeRestriction,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_auto_focus_range_restriction_throws(val) })
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[inline]
pub unsafe fn set_smooth_auto_focus_enabled_throws(&mut self, val: bool) {
unsafe { self.device.set_smooth_auto_focus_enabled_throws(val) }
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub fn set_smooth_auto_focus_enabled<'ear>(&mut self, val: bool) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_smooth_auto_focus_enabled_throws(val) })
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[inline]
pub unsafe fn set_automatically_adjusts_face_driven_auto_focus_enabled_throws(
&mut self,
val: bool,
) {
unsafe {
self.device
.set_automatically_adjusts_face_driven_auto_focus_enabled_throws(val)
}
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub fn set_automatically_adjusts_face_driven_auto_focus_enabled<'ear>(
&mut self,
val: bool,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.set_automatically_adjusts_face_driven_auto_focus_enabled_throws(val)
})
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[inline]
pub unsafe fn set_face_driven_auto_focus_enabled_throws(&mut self, val: bool) {
unsafe { self.device.set_face_driven_auto_focus_enabled_throws(val) }
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub fn set_face_driven_auto_focus_enabled<'ear>(&mut self, val: bool) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_face_driven_auto_focus_enabled_throws(val) })
}
#[cfg(all(feature = "blocks", any(target_os = "tvos", target_os = "ios")))]
pub unsafe fn set_focus_mode_locked_with_lens_pos_no_ch_throws(&mut self, val: f32) {
unsafe {
self.device
.set_focus_mode_locked_with_lens_pos_ch_throws(val, None)
}
}
#[cfg(all(feature = "blocks", any(target_os = "tvos", target_os = "ios")))]
pub fn set_focus_mode_locked_with_lens_pos_no_ch<'ear>(
&mut self,
val: f32,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_focus_mode_locked_with_lens_pos_no_ch_throws(val) })
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub unsafe fn set_focus_mode_locked_with_lens_pos_with_ch_throws(
&mut self,
val: f32,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) {
unsafe {
self.device
.set_focus_mode_locked_with_lens_pos_ch_throws(val, Some(block))
}
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub fn set_focus_mode_locked_with_lens_pos_with_ch<'ear>(
&mut self,
val: f32,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.device
.set_focus_mode_locked_with_lens_pos_ch_throws(val, Some(block))
})
}
#[cfg(all(
feature = "async",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async unsafe fn set_focus_mode_locked_with_lens_pos_throws(
&mut self,
val: f32,
) -> cm::Time {
let (future, mut block) = blocks::comp1();
unsafe { self.set_focus_mode_locked_with_lens_pos_with_ch_throws(val, block.as_esc_mut()) };
future.await
}
#[cfg(all(
feature = "async",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async fn set_focus_mode_locked_with_lens_pos(
&mut self,
val: f32,
) -> Result<cm::Time, arc::R<ns::Exception>> {
let (future, mut block) = blocks::comp1();
let res = ns::try_catch(move || unsafe {
self.set_focus_mode_locked_with_lens_pos_with_ch_throws(val, block.as_esc_mut())
});
if let Err(err) = res {
return Err(err.retained());
}
Ok(future.await)
}
}
#[doc(alias = "AVCaptureDevicePosition")]
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
#[repr(isize)]
pub enum Pos {
#[default]
Unspecified = 0,
Back = 1,
Front = 2,
}
impl Device {
#[objc::msg_send(position)]
pub fn pos(&self) -> Pos;
}
impl<'a> Drop for ConfigLockGuard<'a> {
fn drop(&mut self) {
unsafe { self.device.unlock_for_config() }
}
}
impl<'a> Deref for ConfigLockGuard<'a> {
type Target = Device;
fn deref(&self) -> &Self::Target {
self.device
}
}
impl<'a> DerefMut for ConfigLockGuard<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.device
}
}
#[link(name = "av", kind = "static")]
unsafe extern "C" {
static AV_CAPTURE_DEVICE: &'static objc::Class<Device>;
}
#[doc(alias = "AVCaptureFocusMode")]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(isize)]
pub enum FocusMode {
Locked = 0,
AutoFocus = 1,
ContinuousAutoFocus = 2,
}
#[doc(alias = "AVCaptureAutoFocusSystem")]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(isize)]
pub enum AutoFocusSys {
None = 0,
ContrastDetection = 1,
PhaseDetection = 2,
}
#[doc(alias = "AVCaptureAutoFocusRangeRestriction")]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(isize)]
pub enum AutoFocusRangeRestriction {
#[doc(alias = "AVCaptureAutoFocusRangeRestrictionNone")]
None = 0,
#[doc(alias = "AVCaptureAutoFocusRangeRestrictionNear")]
Near = 1,
#[doc(alias = "AVCaptureAutoFocusRangeRestrictionFar")]
Far = 2,
}
impl Device {
#[objc::msg_send(isFocusModeSupported:)]
pub fn is_focus_mode_supported(&self, mode: FocusMode) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isLockingFocusWithCustomLensPositionSupported)]
pub fn is_locking_focus_with_custom_lens_pos_supported(&self) -> bool;
#[objc::msg_send(focusMode)]
pub fn focus_mode(&self) -> FocusMode;
#[objc::msg_send(setFocusMode:)]
unsafe fn set_focus_mode_throws(&mut self, mode: FocusMode);
#[objc::msg_send(isFocusPointOfInterestSupported)]
pub fn is_focus_point_of_interest_supported(&self) -> bool;
#[objc::msg_send(focusPointOfInterest)]
pub fn focus_point_of_intereset(&self) -> cg::Point;
#[objc::msg_send(setFocusPointOfInterest:)]
unsafe fn set_focus_point_of_interest_throws(&mut self, val: cg::Point);
#[objc::msg_send(isAdjustingFocus)]
pub fn is_adjusting_focus(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isAutoFocusRangeRestrictionSupported)]
pub fn is_auto_focus_range_restriction_supported(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(autoFocusRangeRestriction)]
pub fn auto_focus_range_restriction(&self) -> AutoFocusRangeRestriction;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(setAutoFocusRangeRestriction:)]
unsafe fn set_auto_focus_range_restriction_throws(&mut self, val: AutoFocusRangeRestriction);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isSmoothAutoFocusSupported)]
pub fn is_smooth_auto_focus_supported(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isSmoothAutoFocusEnabled)]
pub fn is_smooth_auto_focus_enabled(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(setSmoothAutoFocusEnabled:)]
unsafe fn set_smooth_auto_focus_enabled_throws(&mut self, val: bool);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(automaticallyAdjustsFaceDrivenAutoFocusEnabled)]
pub fn automatically_adjusts_face_driven_auto_focus_enabled(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(setAutomaticallyAdjustsFaceDrivenAutoFocusEnabled:)]
unsafe fn set_automatically_adjusts_face_driven_auto_focus_enabled_throws(&mut self, val: bool);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isFaceDrivenAutoFocusEnabled)]
pub fn is_face_driven_auto_focus_enabled(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(setFaceDrivenAutoFocusEnabled:)]
unsafe fn set_face_driven_auto_focus_enabled_throws(&mut self, val: bool);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(lensPosition)]
pub fn lens_pos(&self) -> f32;
#[cfg(all(feature = "blocks", feature = "cm"))]
#[objc::msg_send(setFocusModeLockedWithLensPosition:completionHandler:)]
unsafe fn set_focus_mode_locked_with_lens_pos_ch_throws(
&mut self,
val: f32,
ch: Option<&mut blocks::EscBlock<fn(sync_time: cm::Time)>>,
);
#[objc::msg_send(minimumFocusDistance)]
pub fn minimum_focus_distance(&self) -> ns::Integer;
}
#[doc(alias = "AVCaptureCinematicVideoFocusMode")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(isize)]
pub enum CinematicVideoFocusMode {
None = 0,
Strong = 1,
Weak = 2,
}
#[doc(alias = "AVCaptureExposureMode")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(isize)]
pub enum ExposureMode {
Locked = 0,
AutoExpose = 1,
ContinuousAutoExposure = 2,
Custom = 3,
}
impl Device {
#[objc::msg_send(isExposureModeSupported:)]
pub fn is_exposure_mode_supported(&self, val: ExposureMode) -> bool;
#[objc::msg_send(exposureMode)]
pub fn exposure_mode(&self) -> ExposureMode;
#[objc::msg_send(setExposureMode:)]
unsafe fn set_exposure_mode_throws(&mut self, val: ExposureMode);
#[objc::msg_send(isExposurePointOfInterestSupported)]
pub fn is_exposure_point_of_interest_supported(&self) -> bool;
#[objc::msg_send(exposurePointOfInterest)]
pub fn exposure_point_of_interest(&self) -> cg::Point;
#[objc::msg_send(setExposurePointOfInterest:)]
unsafe fn set_exposure_point_of_interest_throws(&mut self, val: cg::Point);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(automaticallyAdjustsFaceDrivenAutoExposureEnabled)]
pub fn automatically_adjusts_face_driven_auto_exposure_enabled(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(setAutomaticallyAdjustsFaceDrivenAutoExposureEnabled:)]
unsafe fn set_automatically_adjusts_face_driven_auto_exposure_enabled_throws(
&mut self,
val: bool,
);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isFaceDrivenAutoExposureEnabled)]
pub fn is_face_driven_auto_exposure_enabled(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(setFaceDrivenAutoExposureEnabled:)]
unsafe fn set_face_driven_auto_exposure_enabled_throws(&mut self, val: bool);
#[cfg(all(feature = "cm", any(target_os = "tvos", target_os = "ios")))]
#[objc::msg_send(activeMaxExposureDuration)]
pub fn active_max_exposure_duration(&self) -> cm::Time;
#[cfg(all(feature = "cm", any(target_os = "tvos", target_os = "ios")))]
#[objc::msg_send(setActiveMaxExposureDuration:)]
unsafe fn set_active_max_exposure_duration_throws(&mut self, val: cm::Time);
#[objc::msg_send(isAdjustingExposure)]
pub fn is_adjusting_exposure(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(lensAperture)]
pub fn lens_aperture(&self) -> f32;
#[cfg(all(feature = "cm", any(target_os = "tvos", target_os = "ios")))]
#[objc::msg_send(exposureDuration)]
pub fn exposure_duration(&self) -> cm::Time;
#[cfg(all(feature = "cm", any(target_os = "tvos", target_os = "ios")))]
#[objc::msg_send(ISO)]
pub fn iso(&self) -> cm::Time;
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
#[objc::msg_send(setExposureModeCustomWithDuration:ISO:completionHandler:)]
pub fn set_exposure_mode_custom_with_duration_and_iso_throws(
&mut self,
duration: cm::Time,
iso: f32,
handler: Option<&mut blocks::EscBlock<fn(sync_time: cm::Time)>>,
);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(exposureTargetOffset)]
pub fn exposure_target_offset(&self) -> f32;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(exposureTargetBias)]
pub fn exposure_target_bias(&self) -> f32;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(minExposureTargetBias)]
pub fn min_exposure_target_bias(&self) -> f32;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(maxExposureTargetBias)]
pub fn max_exposure_target_bias(&self) -> f32;
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
#[objc::msg_send(setExposureTargetBias:completionHandler:)]
unsafe fn set_exposure_target_bias_throws(
&mut self,
bias: f32,
handler: Option<&mut blocks::EscBlock<fn(sync_time: cm::Time)>>,
);
}
impl<'a> ConfigLockGuard<'a> {
pub unsafe fn set_exposure_mode_throws(&mut self, val: ExposureMode) {
unsafe { self.device.set_exposure_mode_throws(val) }
}
pub fn set_exposure_mode<'ear>(&mut self, val: ExposureMode) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_exposure_mode_throws(val) })
}
pub unsafe fn set_exposure_point_of_interest_throws(&mut self, val: cg::Point) {
unsafe { self.device.set_exposure_point_of_interest_throws(val) }
}
pub fn set_exposure_point_of_interest<'ear>(&mut self, val: cg::Point) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_exposure_point_of_interest_throws(val) })
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub unsafe fn set_automatically_adjusts_face_driven_auto_exposure_enabled_throws(
&mut self,
val: bool,
) {
unsafe {
self.device
.set_automatically_adjusts_face_driven_auto_exposure_enabled_throws(val)
}
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub fn set_automatically_adjusts_face_driven_auto_exposure_enabled<'ear>(
&mut self,
val: bool,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.set_automatically_adjusts_face_driven_auto_exposure_enabled_throws(val)
})
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub unsafe fn set_face_driven_auto_exposure_enabled_throws(&mut self, val: bool) {
unsafe {
self.device
.set_face_driven_auto_exposure_enabled_throws(val)
}
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub fn set_face_driven_auto_exposure_enabled<'ear>(&mut self, val: bool) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_face_driven_auto_exposure_enabled_throws(val) })
}
#[cfg(all(feature = "cm", any(target_os = "tvos", target_os = "ios")))]
pub unsafe fn set_active_max_exposure_duration_throws(&mut self, val: cm::Time) {
unsafe { self.device.set_active_max_exposure_duration_throws(val) }
}
#[cfg(all(feature = "cm", any(target_os = "tvos", target_os = "ios")))]
pub fn set_active_max_exposure_duration<'ear>(&mut self, val: cm::Time) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_active_max_exposure_duration_throws(val) })
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub unsafe fn set_exposure_mode_custom_with_duration_and_iso_no_ch_throws(
&mut self,
duration: cm::Time,
iso: f32,
) {
self.device
.set_exposure_mode_custom_with_duration_and_iso_throws(duration, iso, None)
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub fn set_exposure_mode_custom_with_duration_and_iso_no_ch<'ear>(
&mut self,
duration: cm::Time,
iso: f32,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.set_exposure_mode_custom_with_duration_and_iso_no_ch_throws(duration, iso)
})
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub unsafe fn set_exposure_mode_custom_with_duration_and_iso_with_ch_throws(
&mut self,
duration: cm::Time,
iso: f32,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) {
self.device
.set_exposure_mode_custom_with_duration_and_iso_throws(duration, iso, Some(block))
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub fn set_exposure_mode_custom_with_duration_and_iso_with_ch<'ear>(
&mut self,
duration: cm::Time,
iso: f32,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) -> ns::ExResult<'ear> {
ns::try_catch(|| {
self.device
.set_exposure_mode_custom_with_duration_and_iso_throws(duration, iso, Some(block))
})
}
#[cfg(all(
feature = "async",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async unsafe fn set_exposure_mode_custom_with_duration_and_iso_throws(
&mut self,
duration: cm::Time,
iso: f32,
) -> cm::Time {
let (future, mut block) = blocks::comp1();
unsafe {
self.set_exposure_mode_custom_with_duration_and_iso_with_ch_throws(
duration,
iso,
block.as_esc_mut(),
)
};
future.await
}
#[cfg(all(
feature = "async",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async fn set_exposure_mode_custom_with_duration_and_iso(
&mut self,
duration: cm::Time,
iso: f32,
) -> Result<cm::Time, arc::R<ns::Exception>> {
let (future, mut block) = blocks::comp1();
let res = ns::try_catch(move || unsafe {
self.set_exposure_mode_custom_with_duration_and_iso_with_ch_throws(
duration,
iso,
block.as_esc_mut(),
)
});
if let Err(err) = res {
return Err(err.retained());
}
Ok(future.await)
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub unsafe fn set_exposure_target_bias_with_ch_throws(
&mut self,
bias: f32,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) {
unsafe {
self.device
.set_exposure_target_bias_throws(bias, Some(block))
}
}
#[cfg(all(feature = "blocks", any(target_os = "tvos", target_os = "ios")))]
pub unsafe fn set_exposure_target_bias_no_ch_throws(&mut self, bias: f32) {
unsafe { self.device.set_exposure_target_bias_throws(bias, None) }
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub fn set_exposure_target_bias_with_ch<'ear>(
&mut self,
bias: f32,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.device
.set_exposure_target_bias_throws(bias, Some(block))
})
}
#[cfg(all(feature = "blocks", any(target_os = "tvos", target_os = "ios")))]
pub fn set_exposure_target_bias_no_ch<'ear>(&mut self, bias: f32) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.device.set_exposure_target_bias_throws(bias, None) })
}
#[cfg(all(
feature = "async",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async unsafe fn set_exposure_target_bias_throws(&mut self, bias: f32) -> cm::Time {
let (future, mut block) = blocks::comp1();
unsafe { self.set_exposure_target_bias_with_ch_throws(bias, block.as_esc_mut()) };
future.await
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async fn set_exposure_target_bias(
&mut self,
bias: f32,
) -> Result<cm::Time, arc::R<ns::Exception>> {
let (future, mut block) = blocks::comp1();
let res = ns::try_catch(move || unsafe {
self.set_exposure_target_bias_with_ch_throws(bias, block.as_esc_mut())
});
if let Err(err) = res {
return Err(err.retained());
}
Ok(future.await)
}
}
impl Device {
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isGlobalToneMappingEnabled)]
pub fn is_global_tone_mapping_enabled(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(setGlobalToneMappingEnabled:)]
pub fn set_global_tone_mapping_enabled_throws(&mut self, val: bool);
}
impl<'a> ConfigLockGuard<'a> {
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[inline]
pub unsafe fn set_global_tone_mapping_enabled_throws(&mut self, val: bool) {
self.device.set_global_tone_mapping_enabled_throws(val)
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
pub fn set_global_tone_mapping_enabled<'ear>(&mut self, val: bool) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_global_tone_mapping_enabled_throws(val) })
}
}
#[doc(alias = "AVCaptureWhiteBalanceMode")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(isize)]
pub enum WbMode {
Locked = 0,
Auto = 1,
ContinuousAuto = 2,
}
#[doc(alias = "AVCaptureWhiteBalanceGains")]
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(C)]
pub struct WbGains {
pub r: f32,
pub g: f32,
pub b: f32,
}
#[doc(alias = "AVCaptureWhiteBalanceChromaticityValues")]
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(C)]
pub struct WbChromaticityValues {
pub x: f32,
pub y: f32,
}
#[doc(alias = "AVCaptureWhiteBalanceTemperatureAndTintValues")]
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(C)]
pub struct WbTempTintValues {
pub temp: f32,
pub tint: f32,
}
impl Device {
#[objc::msg_send(isWhiteBalanceModeSupported:)]
pub fn is_wb_mode_supported(&self, mode: WbMode) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(isLockingWhiteBalanceWithCustomDeviceGainsSupported)]
pub fn is_locking_wb_with_custom_device_gains_supported(&self) -> bool;
#[objc::msg_send(whiteBalanceMode)]
pub fn wb_mode(&self) -> WbMode;
#[objc::msg_send(setWhiteBalanceMode:)]
unsafe fn set_wb_mode_throws(&mut self, val: WbMode);
#[objc::msg_send(isAdjustingWhiteBalance)]
pub fn is_adjusting_wb(&self) -> bool;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(deviceWhiteBalanceGains)]
pub fn device_wb_gains(&self) -> WbGains;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(grayWorldDeviceWhiteBalanceGains)]
pub fn gray_world_device_wb_gains(&self) -> WbGains;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(maxWhiteBalanceGain)]
pub fn max_wb_gain(&self) -> f32;
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
#[objc::msg_send(setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains:completionHandler:)]
unsafe fn set_wb_mode_locked_with_device_wb_gains_throws(
&mut self,
gains: WbGains,
block: Option<&mut blocks::EscBlock<fn(sync_time: cm::Time)>>,
);
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(deviceWhiteBalanceGainsForChromaticityValues:)]
pub fn device_wb_gains_for_chromaticity_values(&self, values: WbChromaticityValues) -> WbGains;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(temperatureAndTintValuesForDeviceWhiteBalanceGains:)]
pub fn temp_tint_values_for_device_wb_gains(&self, gains: WbGains) -> WbTempTintValues;
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[objc::msg_send(deviceWhiteBalanceGainsForTemperatureAndTintValues:)]
pub fn device_wb_gains_for_temp_tint_values(&self, values: WbTempTintValues) -> WbGains;
}
impl<'a> ConfigLockGuard<'a> {
#[inline]
pub unsafe fn set_wb_mode_throws(&mut self, val: WbMode) {
unsafe { self.device.set_wb_mode_throws(val) }
}
pub fn set_wb_mode<'ear>(&mut self, val: WbMode) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_wb_mode_throws(val) })
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub unsafe fn set_wb_mode_locked_with_device_wb_gains_with_ch_throws(
&mut self,
gains: WbGains,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) {
unsafe {
self.device
.set_wb_mode_locked_with_device_wb_gains_throws(gains, Some(block))
}
}
#[cfg(all(feature = "blocks", any(target_os = "tvos", target_os = "ios")))]
pub unsafe fn set_wb_mode_locked_with_device_wb_gains_no_ch_throws(&mut self, gains: WbGains) {
unsafe {
self.device
.set_wb_mode_locked_with_device_wb_gains_throws(gains, None)
}
}
#[cfg(all(
feature = "blocks",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub fn set_wb_mode_locked_with_device_wb_gains_with_ch<'ear>(
&mut self,
gains: WbGains,
block: &mut blocks::EscBlock<fn(sync_time: cm::Time)>,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.set_wb_mode_locked_with_device_wb_gains_with_ch_throws(gains, block)
})
}
#[cfg(all(feature = "blocks", any(target_os = "tvos", target_os = "ios")))]
pub fn set_wb_mode_locked_with_device_wb_gains_no_ch<'ear>(
&mut self,
gains: WbGains,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.set_wb_mode_locked_with_device_wb_gains_no_ch_throws(gains)
})
}
#[cfg(all(
feature = "async",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async unsafe fn set_wb_mode_locked_with_device_wb_gains_throws(
&mut self,
gains: WbGains,
) -> cm::Time {
let (future, mut block) = blocks::comp1();
unsafe {
self.set_wb_mode_locked_with_device_wb_gains_with_ch_throws(gains, block.as_esc_mut())
};
future.await
}
#[cfg(all(
feature = "async",
feature = "cm",
any(target_os = "tvos", target_os = "ios")
))]
pub async fn set_wb_mode_locked_with_device_wb_gains(
&mut self,
gains: WbGains,
) -> Result<cm::Time, arc::R<ns::Exception>> {
let (future, mut block) = blocks::comp1();
let res = ns::try_catch(move || unsafe {
self.set_wb_mode_locked_with_device_wb_gains_with_ch_throws(gains, block.as_esc_mut())
});
if let Err(err) = res {
return Err(err.retained());
}
Ok(future.await)
}
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
impl Device {
#[objc::msg_send(isSubjectAreaChangeMonitoringEnabled)]
pub fn is_subject_area_change_monitoring_enabled(&self) -> bool;
#[objc::msg_send(setSubjectAreaChangeMonitoringEnabled:)]
unsafe fn set_subject_area_change_monitoring_enabled_throws(&mut self, val: bool);
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
impl<'a> ConfigLockGuard<'a> {
pub fn set_subject_area_change_monitoring_enabled(&mut self, val: bool) {
unsafe {
self.device
.set_subject_area_change_monitoring_enabled_throws(val)
}
}
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
impl Device {
#[objc::msg_send(isLowLightBoostSupported)]
pub fn is_low_light_boost_supported(&self) -> bool;
#[objc::msg_send(isLowLightBoostEnabled)]
pub fn is_low_light_boost_enabled(&self) -> bool;
#[objc::msg_send(setLowLightBoostEnabled:)]
unsafe fn set_low_light_boost_enabled_throws(&mut self, val: bool);
#[objc::msg_send(automaticallyEnablesLowLightBoostWhenAvailable)]
pub fn automatically_enables_low_light_boost_when_available(&self) -> bool;
#[objc::msg_send(setAutomaticallyEnablesLowLightBoostWhenAvailable:)]
unsafe fn set_automatically_enables_low_light_boost_when_available_throws(&mut self, val: bool);
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
impl<'a> ConfigLockGuard<'a> {
pub unsafe fn set_low_light_boost_enabled_throws(&mut self, val: bool) {
unsafe { self.device.set_low_light_boost_enabled_throws(val) }
}
pub fn set_low_light_boost_enabled<'ear>(&mut self, val: bool) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe { self.set_low_light_boost_enabled_throws(val) })
}
pub unsafe fn set_automatically_enables_low_light_boost_when_available_throws(
&mut self,
val: bool,
) {
unsafe {
self.device
.set_automatically_enables_low_light_boost_when_available_throws(val)
}
}
pub fn set_automatically_enables_low_light_boost_when_available<'ear>(
&mut self,
val: bool,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
self.set_automatically_enables_low_light_boost_when_available_throws(val)
})
}
}
impl Device {
#[objc::msg_send(videoZoomFactor)]
pub fn video_zoom_factor(&self) -> cg::Float;
#[objc::msg_send(setVideoZoomFactor:)]
unsafe fn set_video_zoom_factor_throws(&mut self, val: cg::Float);
#[objc::msg_send(isRampingVideoZoom)]
pub fn is_ramping_video_zoom(&self) -> bool;
#[objc::msg_send(rampToVideoZoomFactor:withRate:)]
pub unsafe fn ramp_to_video_zoom_factor_throws(&mut self, factor: cg::Float, rate: f32);
#[objc::msg_send(cancelVideoZoomRamp)]
pub unsafe fn cancel_video_zoom_ramp_throws(&mut self);
#[objc::msg_send(displayVideoZoomFactorMultiplier)]
pub fn display_video_zoom_factor_multiplier(&self) -> cg::Float;
}
impl<'a> ConfigLockGuard<'a> {
pub fn set_video_zoom_factor(&mut self, val: cg::Float) {
unsafe { self.device.set_video_zoom_factor_throws(val) }
}
pub fn ramp_to_video_zoom_factor(&mut self, factor: cg::Float, rate: f32) {
unsafe { self.device.ramp_to_video_zoom_factor_throws(factor, rate) }
}
pub fn cancel_video_zoom_ramp(&mut self) {
unsafe { self.device.cancel_video_zoom_ramp_throws() }
}
}
define_obj_type!(pub Type(ns::String));
impl Type {
#[doc(alias = "AVCaptureDeviceTypeExternal")]
#[api::available(
macos = 14.0,
ios = 17.0,
maccatalyst = 17.0,
tvos = 17.0,
visionos = 2.1
)]
pub fn external() -> &'static Self {
unsafe { AVCaptureDeviceTypeExternal }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInMicrophone")]
#[api::available(macos = 10.15, ios = 10.0)]
pub fn built_in_microphone() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInMicrophone }
}
#[doc(alias = "AVCaptureDeviceTypeMicrophone")]
#[api::available(macos = 14.0, ios = 17.0)]
pub fn microphone() -> &'static Self {
unsafe { AVCaptureDeviceTypeMicrophone }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInWideAngleCamera")]
#[api::available(
macos = 10.15,
ios = 10.0,
maccatalyst = 14.0,
tvos = 17.0,
visionos = 2.1
)]
pub fn built_in_wide_angle_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInWideAngleCamera }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInTelephotoCamera")]
#[api::available(ios = 10.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn built_in_telephoto_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInTelephotoCamera }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInUltraWideCamera")]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn built_in_ultra_wide_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInUltraWideCamera }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInDualCamera")]
#[api::available(ios = 10.2, maccatalyst = 14.0, tvos = 17.0)]
pub fn built_in_dual_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInDualCamera }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInDualWideCamera")]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn built_in_dual_wide_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInDualWideCamera }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInTripleCamera")]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn built_in_tripple_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInTripleCamera }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInTrueDepthCamera")]
#[api::available(ios = 11.1, maccatalyst = 14.0, tvos = 17.0)]
pub fn built_in_true_depth_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInTrueDepthCamera }
}
#[doc(alias = "AVCaptureDeviceTypeBuiltInLiDARDepthCamera")]
#[api::available(ios = 15.4, maccatalyst = 15.4, tvos = 17.0)]
pub fn built_in_lidar_depth_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeBuiltInLiDARDepthCamera }
}
#[doc(alias = "AVCaptureDeviceTypeContinuityCamera")]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn continuity_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeContinuityCamera }
}
#[doc(alias = "AVCaptureDeviceTypeDeskViewCamera")]
#[api::available(macos = 13.0)]
pub fn desk_view_camera() -> &'static Self {
unsafe { AVCaptureDeviceTypeDeskViewCamera }
}
}
impl Device {
#[objc::msg_send(deviceType)]
pub fn device_type(&self) -> &Type;
}
impl Device {
#[objc::msg_send(userPreferredCamera)]
fn user_preferred_camera<'a>() -> Option<&'a Self>;
#[objc::msg_send(setUserPreferredCamera:)]
fn set_user_preferred_camera(val: Option<&Self>);
#[objc::msg_send(systemPreferredCamera)]
fn sys_preferred_camera<'a>() -> Option<&'a Self>;
}
#[doc(alias = "AVAuthorizationStatus")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(isize)]
pub enum AuthorizationStatus {
NotDetermined = 0,
Restricted = 1,
Denied = 2,
Authorized = 3,
}
impl Device {
#[objc::msg_send(authorizationStatusForMediaType:)]
pub unsafe fn authorization_status_for_media_type_throws(
media_type: &av::MediaType,
) -> AuthorizationStatus;
pub fn authorization_status_for_media_type<'ear>(
media_type: &av::MediaType,
) -> ns::ExResult<'ear, AuthorizationStatus> {
ns::try_catch(|| unsafe { Self::authorization_status_for_media_type_throws(media_type) })
}
#[cfg(feature = "blocks")]
#[objc::msg_send(requestAccessForMediaType:completionHandler:)]
unsafe fn _request_access_for_media_type_ch_throws(
media_type: &av::MediaType,
block: &mut blocks::SendBlock<fn(bool)>,
);
#[cfg(feature = "blocks")]
pub unsafe fn request_access_for_media_type_ch_throws(
media_type: &av::MediaType,
block: &mut blocks::SendBlock<fn(bool)>,
) {
unsafe { Self::_request_access_for_media_type_ch_throws(media_type, block) }
}
#[cfg(feature = "blocks")]
pub fn request_access_for_media_type_ch<'ear>(
media_type: &av::MediaType,
block: &mut blocks::SendBlock<fn(bool)>,
) -> ns::ExResult<'ear> {
ns::try_catch(|| unsafe {
Self::request_access_for_media_type_ch_throws(media_type, block)
})
}
#[cfg(feature = "async")]
pub async fn request_access_for_media_type(
media_type: &av::MediaType,
) -> Result<bool, arc::R<ns::Exception>> {
let (future, mut block) = blocks::comp1();
match Self::request_access_for_media_type_ch(media_type, &mut block) {
Ok(_) => Ok(future.await),
Err(e) => Err(e.retained()),
}
}
}
define_obj_type!(
#[doc(alias = "AVFrameRateRange")]
pub FrameRateRange(ns::Id)
);
impl FrameRateRange {
#[objc::msg_send(minFrameRate)]
pub fn min_frame_rate(&self) -> f64;
#[objc::msg_send(maxFrameRate)]
pub fn max_frame_rate(&self) -> f64;
#[cfg(feature = "cm")]
#[objc::msg_send(maxFrameDuration)]
pub fn max_frame_duration(&self) -> cm::Time;
#[cfg(feature = "cm")]
#[objc::msg_send(minFrameDuration)]
pub fn min_frame_duration(&self) -> cm::Time;
}
define_obj_type!(
#[doc(alias = "AVCaptureDeviceFormat")]
pub Format(ns::Id)
);
impl Format {
#[objc::msg_send(isAutoVideoFrameRateSupported)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn is_auto_video_frame_rate_supported(&self) -> bool;
}
impl Format {
#[objc::msg_send(reactionEffectsSupported)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn reaction_effects_supported(&self) -> bool;
#[objc::msg_send(videoFrameRateRangeForReactionEffectsInProgress)]
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn video_frame_rate_range_for_reaction_effects_in_progress(
&self,
) -> Option<&av::FrameRateRange>;
}
impl Format {
#[objc::msg_send(mediaType)]
pub fn media_type(&self) -> arc::R<av::MediaType>;
#[cfg(feature = "cm")]
#[objc::msg_send(formatDescription)]
pub fn format_desc(&self) -> &cm::FormatDesc;
}
impl Format {
#[objc::msg_send(unsupportedCaptureOutputClasses)]
pub fn unsupported_capture_output_classes(&self) -> arc::R<ns::Array<objc::Class<ns::Id>>>;
}
impl Format {
#[cfg(all(not(target_os = "macos"), not(target_os = "visionos")))]
#[objc::msg_send(isVideoBinned)]
pub fn is_video_binned(&self) -> bool;
#[objc::msg_send(isVideoHDRSupported)]
#[api::available(ios = 8.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn is_video_hdr_supported(&self) -> bool;
#[objc::msg_send(videoSupportedFrameRateRanges)]
pub fn video_supported_frame_rate_ranges(&self) -> arc::R<ns::Array<FrameRateRange>>;
}
impl Format {
#[cfg(not(target_os = "macos"))]
#[objc::msg_send(videoFieldOfView)]
pub fn video_fov(&self) -> f32;
#[objc::msg_send(geometricDistortionCorrectedVideoFieldOfView)]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn geometric_distortion_corrected_video_fov(&self) -> f32;
}
impl Format {
#[objc::msg_send(minExposureDuration)]
#[api::available(ios = 8.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn min_exposure_duration(&self) -> cm::Time;
#[objc::msg_send(maxExposureDuration)]
#[api::available(ios = 8.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn max_exposure_duration(&self) -> cm::Time;
#[objc::msg_send(minISO)]
#[api::available(ios = 8.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn min_iso(&self) -> f32;
#[objc::msg_send(maxISO)]
#[api::available(ios = 8.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn max_iso(&self) -> f32;
#[objc::msg_send(isGlobalToneMappingSupported)]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn is_global_tone_mapping_supported(&self) -> bool;
#[objc::msg_send(isHighPhotoQualitySupported)]
#[api::available(macos = 12.0, ios = 15.0, maccatalyst = 15.0, tvos = 17.0)]
pub fn is_high_photo_quality_supported(&self) -> bool;
#[objc::msg_send(isHighestPhotoQualitySupported)]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn is_highest_photo_quality_supported(&self) -> bool;
#[objc::msg_send(autoFocusSystem)]
#[api::available(macos = 10.15, ios = 8.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn auto_focus_sys(&self) -> AutoFocusSys;
}
impl Format {
#[cfg(not(target_os = "macos"))]
#[objc::msg_send(isVideoStabilizationModeSupported:)]
pub fn is_video_stabilization_mode_supported(&self, mode: VideoStabilizationMode) -> bool;
#[cfg(not(target_os = "macos"))]
#[objc::msg_send(videoMaxZoomFactor)]
pub fn video_max_zoom_factor(&self) -> cg::Float;
#[cfg(not(target_os = "macos"))]
#[objc::msg_send(videoZoomFactorUpscaleThreshold)]
pub fn video_zoom_factor_upscale_threshold(&self) -> cg::Float;
}
impl Format {
#[objc::msg_send(isCenterStageSupported)]
pub fn is_center_stage_supported(&self) -> bool;
#[objc::msg_send(videoMinZoomFactorForCenterStage)]
pub fn video_min_zoom_factor_for_center_stage(&self) -> cg::Float;
#[objc::msg_send(videoFrameRateRangeForCenterStage)]
pub fn video_frame_rate_range_for_center_stage(&self) -> Option<arc::R<FrameRateRange>>;
}
impl Format {
#[objc::msg_send(isPortraitEffectSupported)]
#[api::available(macos = 12.0, ios = 15.0, maccatalyst = 15.0, tvos = 17.0)]
pub fn is_portrait_effect_supported(&self) -> bool;
#[objc::msg_send(videoFrameRateRangeForPortraitEffect)]
#[api::available(macos = 12.0, ios = 15.0, maccatalyst = 15.0, tvos = 17.0)]
pub fn video_frame_rate_range_for_portrait_effect(&self) -> Option<arc::R<av::FrameRateRange>>;
}
impl Format {
#[objc::msg_send(isStudioLightSupported)]
#[api::available(macos = 13.0, ios = 16.0, maccatalyst = 16.0, tvos = 17.0)]
pub fn is_studio_light_supported(&self) -> bool;
#[objc::msg_send(videoFrameRateRangeForStudioLight)]
#[api::available(macos = 13.0, ios = 16.0, maccatalyst = 16.0, tvos = 17.0)]
pub fn video_frame_rate_range_for_studio_light(&self) -> Option<arc::R<av::FrameRateRange>>;
}
impl Format {
#[objc::msg_send(supportedColorSpaces)]
pub fn supported_color_spaces(&self) -> arc::R<ns::Array<ns::Number>>;
pub fn color_space_supported(&self, val: av::CaptureColorSpace) -> bool {
self.supported_color_spaces().contains(val.as_ns_number())
}
#[objc::msg_send(globalToneMappingSupported)]
pub fn global_tone_mapping_supported(&self) -> bool;
}
impl Format {
#[objc::msg_send(isMultiCamSupported)]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn is_mutli_cam_supported(&self) -> bool;
}
impl Format {
#[objc::msg_send(isSpatialVideoCaptureSupported)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn is_spatial_video_capture_supported(&self) -> bool;
}
impl Format {
#[objc::msg_send(isBackgroundReplacementSupported)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn is_background_replacement_supported(&self) -> bool;
#[objc::msg_send(videoFrameRateRangeForBackgroundReplacement)]
#[api::available(macos = 15.0, ios = 18.0, maccatalyst = 18.0, tvos = 18.0)]
pub fn video_frame_rate_range_for_background_replacement(
&self,
) -> Option<arc::R<av::FrameRateRange>>;
}
impl Format {
#[objc::msg_send(isCinematicVideoCaptureSupported)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn is_cinematic_video_capture_supported(&self) -> bool;
#[objc::msg_send(defaultSimulatedAperture)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn default_simulated_aperture(&self) -> f32;
#[objc::msg_send(minSimulatedAperture)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn min_simulated_aperture(&self) -> f32;
#[objc::msg_send(maxSimulatedAperture)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn max_simulated_aperture(&self) -> f32;
#[objc::msg_send(videoMinZoomFactorForCinematicVideo)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn video_min_zoom_factor_for_cinematic_video(&self) -> f32;
#[objc::msg_send(videoMaxZoomFactorForCinematicVideo)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn video_max_zoom_factor_for_cinematic_video(&self) -> f32;
#[objc::msg_send(videoFrameRateRangeForCinematicVideo)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn video_frame_rate_range_for_cinematic_video(&self) -> Option<arc::R<av::FrameRateRange>>;
}
impl Format {
#[objc::msg_send(isCameraLensSmudgeDetectionSupported)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn is_cam_lens_smudge_detection_supported(&self) -> bool;
}
impl Device {
#[objc::msg_send(setCameraLensSmudgeDetectionEnabled:detectionInterval:)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub unsafe fn set_cam_lens_smudge_detection_enabled_throws(
&mut self,
val: bool,
detection_interval: cm::Time,
);
#[objc::msg_send(isCameraLensSmudgeDetectionEnabled)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn is_cam_lens_smudge_detection_enabled(&self) -> bool;
#[objc::msg_send(cameraLensSmudgeDetectionInterval)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn cam_lens_smudge_detection_interval(&self) -> cm::Time;
#[objc::msg_send(cameraLensSmudgeDetectionStatus)]
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn cam_lens_smudge_detection_status(&self) -> CamLensSmudgeDetectionStatus;
}
#[doc(alias = "AVCaptureCameraLensSmudgeDetectionStatus")]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(isize)]
pub enum CamLensSmudgeDetectionStatus {
Disabled = 0,
SmudgeNotDetected = 1,
Smudged = 2,
Unknown = 3,
}
impl<'a> ConfigLockGuard<'a> {
#[api::available(macos = 26.0, ios = 26.0, maccatalyst = 26.0, tvos = 26.0)]
pub fn set_cam_lens_smudge_detection_enabled<'ear>(
&mut self,
val: bool,
detection_interval: cm::Time,
) -> ns::ExResult<'ear> {
unsafe {
ns::try_catch(|| {
self.device
.set_cam_lens_smudge_detection_enabled_throws(val, detection_interval)
})
}
}
}
pub mod notifications {
use crate::{api, ns};
#[doc(alias = "AVCaptureDeviceWasConnectedNotification")]
#[api::available(macos = 10.7, ios = 4.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn was_connected() -> &'static ns::NotificationName {
unsafe { AVCaptureDeviceWasConnectedNotification }
}
#[doc(alias = "AVCaptureDeviceWasDisconnectedNotification")]
#[api::available(macos = 10.7, ios = 4.0, maccatalyst = 14.0, tvos = 17)]
pub fn was_disconnected() -> &'static ns::NotificationName {
unsafe { AVCaptureDeviceWasDisconnectedNotification }
}
#[doc(alias = "AVCaptureDeviceSubjectAreaDidChangeNotification")]
#[api::available(ios = 5.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn subject_area_did_change() -> &'static ns::NotificationName {
unsafe { AVCaptureDeviceSubjectAreaDidChangeNotification }
}
#[link(name = "AVFoundation", kind = "framework")]
#[api::weak]
unsafe extern "C" {
#[api::available(macos = 10.7, ios = 4.0, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceWasConnectedNotification: &'static ns::NotificationName;
#[api::available(macos = 10.7, ios = 4.0, maccatalyst = 14.0, tvos = 17)]
static AVCaptureDeviceWasDisconnectedNotification: &'static ns::NotificationName;
#[api::available(ios = 5.0, maccatalyst = 14.0, tvos = 17.0)]
static AVCaptureDeviceSubjectAreaDidChangeNotification: &'static ns::NotificationName;
}
}
define_obj_type!(
#[doc(alias = "AVCaptureDevice.DiscoverySession")]
#[doc(alias = "AVCaptureDeviceDiscoverySession")]
pub DiscoverySession(ns::Id)
);
impl DiscoverySession {
define_cls!(AV_CAPTURE_DEVICE_DISCOVERY_SESSION);
#[objc::msg_send(discoverySessionWithDeviceTypes:mediaType:position:)]
pub fn with_device_types_media_and_pos(
device_types: &ns::Array<Type>,
media_type: Option<&av::MediaType>,
position: Pos,
) -> arc::R<Self>;
#[objc::msg_send(devices)]
pub fn devices(&self) -> arc::R<ns::Array<Device>>;
#[objc::msg_send(supportedMultiCamDeviceSets)]
#[api::available(ios = 13.0, maccatalyst = 14.0, tvos = 17.0)]
pub fn supported_multi_cam_device_sets(&self) -> arc::R<ns::Array<ns::Set<Device>>>;
}
impl ns::KvObserverRegistration for DiscoverySession {}
define_obj_type!(
#[doc(alias = "AVCaptureDeviceRotationCoordinator")]
pub RotationCoordinator(ns::Id)
);
impl arc::A<RotationCoordinator> {
#[objc::msg_send(initWithDevice:previewLayer:)]
pub fn init_with_device_preview_layer(
&self,
device: &Device,
preview_layer: Option<&ca::Layer>,
) -> arc::R<RotationCoordinator>;
}
impl RotationCoordinator {
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
crate::define_cls!(AV_CAPTURE_DEVICE_ROTATION_COORDINATOR);
#[api::available(macos = 14.0, ios = 17.0, maccatalyst = 17.0, tvos = 17.0)]
pub fn with_device_preview_layer(
device: &Device,
preview_layer: Option<&ca::Layer>,
) -> arc::R<Self> {
Self::alloc().init_with_device_preview_layer(device, preview_layer)
}
#[objc::msg_send(device)]
pub fn device(&self) -> Option<&Device>;
#[objc::msg_send(previewLayer)]
pub fn preview_layer(&self) -> Option<&ca::Layer>;
#[objc::msg_send(videoRotationAngleForHorizonLevelPreview)]
pub fn video_rotation_angle_for_horizon_level_preview(&self) -> cg::Float;
#[objc::msg_send(videoRotationAngleForHorizonLevelCapture)]
pub fn video_rotation_angle_for_horizon_level_capture(&self) -> cg::Float;
}
define_obj_type!(
#[doc(alias = "AVZoomRange")]
pub ZoomRange(ns::Id)
);
impl ZoomRange {
#[objc::msg_send(minZoomFactor)]
pub fn min_zoom_factor(&self) -> cg::Float;
#[objc::msg_send(maxZoomFactor)]
pub fn max_zoom_factor(&self) -> cg::Float;
#[objc::msg_send(containsZoomFactor:)]
pub fn contains_zoom_factor(&self, zoom_factor: cg::Float) -> bool;
}
#[link(name = "av", kind = "static")]
unsafe extern "C" {
static AV_CAPTURE_DEVICE_DISCOVERY_SESSION: &'static objc::Class<DiscoverySession>;
static AV_CAPTURE_DEVICE_ROTATION_COORDINATOR: &'static objc::Class<RotationCoordinator>;
}
#[doc(alias = "AVCaptureVideoStabilizationMode")]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(isize)]
pub enum VideoStabilizationMode {
#[doc(alias = "AVCaptureVideoStabilizationModeOff")]
Off = 0,
#[doc(alias = "AVCaptureVideoStabilizationModeStandard")]
Standard = 1,
#[doc(alias = "AVCaptureVideoStabilizationModeCinematic")]
Cinematic = 2,
#[doc(alias = "AVCaptureVideoStabilizationModeCinematicExtended")]
CinematicExtended = 3,
#[doc(alias = "AVCaptureVideoStabilizationModePreviewOptimized")]
PreviewOptimized = 4,
#[doc(alias = "AVCaptureVideoStabilizationModeCinematicExtendedEnhanced")]
CinematicExtendedEnhanced = 5,
#[doc(alias = "AVCaptureVideoStabilizationModeAuto")]
Auto = -1,
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[doc(alias = "AVCaptureLensPositionCurrent")]
pub fn lens_pos_current() -> f32 {
unsafe { AVCaptureLensPositionCurrent }
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[doc(alias = "AVCaptureISOCurrent")]
pub fn iso_current() -> f32 {
unsafe { AVCaptureISOCurrent }
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[doc(alias = "AVCaptureExposureDurationCurrent")]
pub fn exposure_duration_current() -> cm::Time {
unsafe { AVCaptureExposureDurationCurrent }
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[doc(alias = "AVCaptureExposureTargetBiasCurrent")]
pub fn exposure_target_bias_current() -> f32 {
unsafe { AVCaptureExposureTargetBiasCurrent }
}
#[cfg(any(target_os = "tvos", target_os = "ios"))]
#[doc(alias = "AVCaptureWhiteBalanceGainsCurrent")]
pub fn wb_gains_current() -> WbGains {
unsafe { AVCaptureWhiteBalanceGainsCurrent }
}
#[doc(alias = "AVCaptureMaxAvailableTorchLevel")]
pub fn torch_max_level() -> f32 {
unsafe { AVCaptureMaxAvailableTorchLevel }
}
#[cfg(target_os = "macos")]
#[cfg(test)]
mod tests {
use crate::{
av::{
self,
capture::{
self,
device::{self, Device},
},
},
cm::io,
ns,
objc::Obj,
};
#[test]
fn basics() {
let device_type = device::Type::built_in_wide_angle_camera();
let media_type = av::MediaType::video();
let pos = device::Pos::Front;
let mut device =
Device::with_type_media_and_pos(device_type, Some(media_type), pos).expect("device");
assert!(!device.has_torch());
assert!(device.formats().len() > 0);
assert!(device.supports_preset(av::CaptureSessionPreset::photo()));
let mut _lock = device.config_lock().expect("locked");
}
#[test]
fn session() {
io::Obj::SYS.allow_screen_capture_devices(true).unwrap();
io::Obj::SYS
.allow_wireless_screen_capture_devices(true)
.unwrap();
io::Obj::SYS.show();
let list = ns::Array::from_slice(&[av::CaptureDeviceType::external()]);
let session = capture::DiscoverySession::with_device_types_media_and_pos(
list.as_ref(),
Some(av::MediaType::muxed()),
capture::DevicePos::Unspecified,
);
let devices = session.devices();
devices.as_type_ref().show();
}
#[tokio::test]
async fn access() {
let res = av::CaptureDevice::request_access_for_media_type(av::MediaType::video()).await;
assert!(matches!(res, Ok(true)));
let res = av::CaptureDevice::request_access_for_media_type(av::MediaType::audio()).await;
assert!(matches!(res, Ok(true)));
let res = av::CaptureDevice::request_access_for_media_type(av::MediaType::text()).await;
assert!(res.is_err());
let status = av::CaptureDevice::authorization_status_for_media_type(av::MediaType::video())
.expect("Failed on valid media type");
assert_eq!(status, av::AuthorizationStatus::Authorized);
let res = av::CaptureDevice::authorization_status_for_media_type(av::MediaType::text());
assert!(res.is_err());
}
#[test]
fn color_space() {
let num = av::CaptureColorSpace::AppleLog.as_ns_number();
assert_eq!(3, num.as_i32());
assert!(num.is_tagged_ptr());
}
}