av_foundation/
capture_device.rs

1use block2::RcBlock;
2use core_foundation::base::TCFType;
3use core_graphics::{base::CGFloat, geometry::CGPoint};
4use core_media::{
5    format_description::{CMFormatDescription, CMFormatDescriptionRef},
6    time::CMTime,
7};
8#[cfg(target_os = "ios")]
9use objc2::{
10    encode::{Encode, Encoding, RefEncode},
11    Encoding::Float,
12};
13use objc2::{extern_class, msg_send, msg_send_id, mutability::InteriorMutable, rc::Id, runtime::Bool, ClassType};
14use objc2_foundation::{NSArray, NSError, NSInteger, NSNumber, NSObject, NSObjectProtocol, NSString};
15
16use crate::{capture_session_preset::AVCaptureSessionPreset, media_format::AVMediaType};
17
18extern "C" {
19    pub static AVCaptureDeviceWasConnectedNotification: &'static NSString;
20    pub static AVCaptureDeviceWasDisconnectedNotification: &'static NSString;
21    pub static AVCaptureDeviceSubjectAreaDidChangeNotification: &'static NSString;
22}
23
24extern_class!(
25    #[derive(Debug, PartialEq, Eq, Hash)]
26    pub struct AVCaptureDevice;
27
28    unsafe impl ClassType for AVCaptureDevice {
29        type Super = NSObject;
30        type Mutability = InteriorMutable;
31    }
32);
33
34unsafe impl NSObjectProtocol for AVCaptureDevice {}
35
36impl AVCaptureDevice {
37    pub fn devices() -> Id<NSArray<AVCaptureDevice>> {
38        unsafe { msg_send_id![AVCaptureDevice::class(), devices] }
39    }
40
41    pub fn devices_with_media_type(media_type: &AVMediaType) -> Id<NSArray<AVCaptureDevice>> {
42        unsafe { msg_send_id![AVCaptureDevice::class(), devicesWithMediaType: media_type] }
43    }
44
45    pub fn default_device_with_media_type(media_type: &AVMediaType) -> Option<Id<AVCaptureDevice>> {
46        unsafe { msg_send_id![AVCaptureDevice::class(), defaultDeviceWithMediaType: media_type] }
47    }
48
49    pub fn device_with_unique_id(unique_id: &NSString) -> Option<Id<AVCaptureDevice>> {
50        unsafe { msg_send_id![AVCaptureDevice::class(), deviceWithUniqueID: unique_id] }
51    }
52
53    pub fn unique_id(&self) -> Id<NSString> {
54        unsafe { msg_send_id![self, uniqueID] }
55    }
56
57    pub fn model_id(&self) -> Id<NSString> {
58        unsafe { msg_send_id![self, modelID] }
59    }
60
61    pub fn localized_name(&self) -> Id<NSString> {
62        unsafe { msg_send_id![self, localizedName] }
63    }
64
65    pub fn manufacturer(&self) -> Id<NSString> {
66        unsafe { msg_send_id![self, manufacturer] }
67    }
68
69    #[cfg(target_os = "macos")]
70    pub fn transport_type(&self) -> i32 {
71        unsafe { msg_send![self, transportType] }
72    }
73
74    pub fn has_media_type(&self, media_type: &AVMediaType) -> Bool {
75        unsafe { msg_send![self, hasMediaType: media_type] }
76    }
77
78    pub fn lock_for_configuration(&self) -> Result<Bool, Id<NSError>> {
79        let mut error: *mut NSError = std::ptr::null_mut();
80        let result: Bool = unsafe { msg_send![self, lockForConfiguration: &mut error] };
81        if result.is_true() {
82            Ok(result)
83        } else {
84            Err(unsafe { Id::retain(error).unwrap() })
85        }
86    }
87
88    pub fn unlock_for_configuration(&self) {
89        unsafe { msg_send![self, unlockForConfiguration] }
90    }
91
92    pub fn supports_av_capture_session_preset(&self, preset: &AVCaptureSessionPreset) -> Bool {
93        unsafe { msg_send![self, supportsAVCaptureSessionPreset: preset] }
94    }
95
96    pub fn is_connected(&self) -> Bool {
97        unsafe { msg_send![self, isConnected] }
98    }
99
100    #[cfg(target_os = "macos")]
101    pub fn is_in_use_by_another_application(&self) -> Bool {
102        unsafe { msg_send![self, isInUseByAnotherApplication] }
103    }
104
105    pub fn is_suspended(&self) -> Bool {
106        unsafe { msg_send![self, isSuspended] }
107    }
108
109    #[cfg(target_os = "macos")]
110    pub fn linked_devices(&self) -> Id<NSArray<AVCaptureDevice>> {
111        unsafe { msg_send_id![self, linkedDevices] }
112    }
113
114    pub fn formats(&self) -> Id<NSArray<AVCaptureDeviceFormat>> {
115        unsafe { msg_send_id![self, formats] }
116    }
117
118    pub fn get_active_format(&self) -> Id<AVCaptureDeviceFormat> {
119        unsafe { msg_send_id![self, activeFormat] }
120    }
121
122    pub fn set_active_format(&self, format: &AVCaptureDeviceFormat) {
123        unsafe { msg_send![self, setActiveFormat: format] }
124    }
125
126    pub fn get_active_video_min_frame_duration(&self) -> CMTime {
127        unsafe { msg_send![self, activeVideoMinFrameDuration] }
128    }
129
130    pub fn set_active_video_min_frame_duration(&self, duration: CMTime) {
131        unsafe { msg_send![self, setActiveVideoMinFrameDuration: duration] }
132    }
133
134    pub fn get_active_video_max_frame_duration(&self) -> CMTime {
135        unsafe { msg_send![self, activeVideoMaxFrameDuration] }
136    }
137
138    pub fn set_active_video_max_frame_duration(&self, duration: CMTime) {
139        unsafe { msg_send![self, setActiveVideoMaxFrameDuration: duration] }
140    }
141
142    pub fn input_sources(&self) -> Id<NSArray<AVCaptureDeviceInputSource>> {
143        unsafe { msg_send_id![self, inputSources] }
144    }
145
146    pub fn get_active_input_source(&self) -> Id<AVCaptureDeviceInputSource> {
147        unsafe { msg_send_id![self, activeInputSource] }
148    }
149
150    pub fn set_active_input_source(&self, input_source: &AVCaptureDeviceInputSource) {
151        unsafe { msg_send![self, setActiveInputSource: input_source] }
152    }
153}
154
155pub type AVCaptureDevicePosition = NSInteger;
156
157pub const AVCaptureDevicePositionUnspecified: AVCaptureDevicePosition = 0;
158pub const AVCaptureDevicePositionBack: AVCaptureDevicePosition = 1;
159pub const AVCaptureDevicePositionFront: AVCaptureDevicePosition = 2;
160
161// AVCaptureDevicePosition
162impl AVCaptureDevice {
163    pub fn position(&self) -> AVCaptureDevicePosition {
164        unsafe { msg_send![self, position] }
165    }
166}
167
168pub type AVCaptureDeviceType = NSString;
169
170extern "C" {
171    pub static AVCaptureDeviceTypeExternal: &'static AVCaptureDeviceType;
172    pub static AVCaptureDeviceTypeMicrophone: &'static AVCaptureDeviceType;
173    pub static AVCaptureDeviceTypeBuiltInWideAngleCamera: &'static AVCaptureDeviceType;
174    #[cfg(target_os = "ios")]
175    pub static AVCaptureDeviceTypeBuiltInTelephotoCamera: &'static AVCaptureDeviceType;
176    #[cfg(target_os = "ios")]
177    pub static AVCaptureDeviceTypeBuiltInUltraWideCamera: &'static AVCaptureDeviceType;
178    #[cfg(target_os = "ios")]
179    pub static AVCaptureDeviceTypeBuiltInDualCamera: &'static AVCaptureDeviceType;
180    #[cfg(target_os = "ios")]
181    pub static AVCaptureDeviceTypeBuiltInDualWideCamera: &'static AVCaptureDeviceType;
182    #[cfg(target_os = "ios")]
183    pub static AVCaptureDeviceTypeBuiltInTripleCamera: &'static AVCaptureDeviceType;
184    #[cfg(target_os = "ios")]
185    pub static AVCaptureDeviceTypeBuiltInTrueDepthCamera: &'static AVCaptureDeviceType;
186    #[cfg(target_os = "ios")]
187    pub static AVCaptureDeviceTypeBuiltInLiDARDepthCamera: &'static AVCaptureDeviceType;
188    pub static AVCaptureDeviceTypeContinuityCamera: &'static AVCaptureDeviceType;
189    #[cfg(target_os = "macos")]
190    pub static AVCaptureDeviceTypeDeskViewCamera: &'static AVCaptureDeviceType;
191    #[cfg(target_os = "macos")]
192    pub static AVCaptureDeviceTypeExternalUnknown: &'static AVCaptureDeviceType;
193    #[cfg(target_os = "ios")]
194    pub static AVCaptureDeviceTypeBuiltInDuoCamera: &'static AVCaptureDeviceType;
195    pub static AVCaptureDeviceTypeBuiltInMicrophone: &'static AVCaptureDeviceType;
196}
197
198impl AVCaptureDevice {
199    pub fn device_type(&self) -> Id<AVCaptureDeviceType> {
200        unsafe { msg_send_id![self, deviceType] }
201    }
202
203    pub fn default_device_with_device_type(
204        device_type: &AVCaptureDeviceType,
205        media_type: &AVMediaType,
206        position: AVCaptureDevicePosition,
207    ) -> Option<Id<AVCaptureDevice>> {
208        unsafe { msg_send_id![AVCaptureDevice::class(), defaultDeviceWithDeviceType: device_type mediaType: media_type position: position] }
209    }
210}
211
212pub type AVCaptureFlashMode = NSInteger;
213
214pub const AVCaptureFlashModeOff: AVCaptureFlashMode = 0;
215pub const AVCaptureFlashModeOn: AVCaptureFlashMode = 1;
216pub const AVCaptureFlashModeAuto: AVCaptureFlashMode = 2;
217
218// AVCaptureDeviceFlash
219impl AVCaptureDevice {
220    pub fn has_flash(&self) -> Bool {
221        unsafe { msg_send![self, hasFlash] }
222    }
223
224    pub fn is_flash_available(&self) -> Bool {
225        unsafe { msg_send![self, isFlashAvailable] }
226    }
227
228    #[cfg(target_os = "ios")]
229    pub fn is_flash_active(&self) -> Bool {
230        unsafe { msg_send![self, isFlashActive] }
231    }
232
233    #[cfg(target_os = "ios")]
234    pub fn is_flash_mode_supported(&self, flash_mode: AVCaptureFlashMode) -> Bool {
235        unsafe { msg_send![self, isFlashModeSupported: flash_mode] }
236    }
237
238    #[cfg(target_os = "ios")]
239    pub fn flash_mode(&self) -> AVCaptureFlashMode {
240        unsafe { msg_send![self, flashMode] }
241    }
242
243    #[cfg(target_os = "ios")]
244    pub fn set_flash_mode(&self, flash_mode: AVCaptureFlashMode) {
245        unsafe { msg_send![self, setFlashMode: flash_mode] }
246    }
247}
248
249pub type AVCaptureTorchMode = NSInteger;
250
251pub const AVCaptureTorchModeOff: AVCaptureTorchMode = 0;
252pub const AVCaptureTorchModeOn: AVCaptureTorchMode = 1;
253pub const AVCaptureTorchModeAuto: AVCaptureTorchMode = 2;
254
255extern "C" {
256    pub static AVCaptureMaxAvailableTorchLevel: &'static f32;
257}
258
259// AVCaptureDeviceTorch
260impl AVCaptureDevice {
261    pub fn has_torch(&self) -> Bool {
262        unsafe { msg_send![self, hasTorch] }
263    }
264
265    pub fn is_torch_available(&self) -> Bool {
266        unsafe { msg_send![self, isTorchAvailable] }
267    }
268
269    pub fn is_torch_active(&self) -> Bool {
270        unsafe { msg_send![self, isTorchActive] }
271    }
272
273    pub fn torch_level(&self) -> f32 {
274        unsafe { msg_send![self, torchLevel] }
275    }
276
277    pub fn is_torch_mode_supported(&self, torch_mode: AVCaptureTorchMode) -> Bool {
278        unsafe { msg_send![self, isTorchModeSupported: torch_mode] }
279    }
280
281    pub fn torch_mode(&self) -> AVCaptureTorchMode {
282        unsafe { msg_send![self, torchMode] }
283    }
284
285    pub fn set_torch_mode(&self, torch_mode: AVCaptureTorchMode) {
286        unsafe { msg_send![self, setTorchMode: torch_mode] }
287    }
288
289    pub fn set_torch_mode_on_with_level(&self, torch_level: f32) -> Result<Bool, Id<NSError>> {
290        let mut error: *mut NSError = std::ptr::null_mut();
291        let result: Bool = unsafe { msg_send![self, setTorchModeOnWithLevel: torch_level error: &mut error] };
292        if result.is_true() {
293            Ok(result)
294        } else {
295            Err(unsafe { Id::retain(error).unwrap() })
296        }
297    }
298}
299
300pub type AVCaptureFocusMode = NSInteger;
301
302pub const AVCaptureFocusModeLocked: AVCaptureFocusMode = 0;
303pub const AVCaptureFocusModeAutoFocus: AVCaptureFocusMode = 1;
304pub const AVCaptureFocusModeContinuousAutoFocus: AVCaptureFocusMode = 2;
305
306#[cfg(target_os = "ios")]
307pub type AVCaptureAutoFocusRangeRestriction = NSInteger;
308
309#[cfg(target_os = "ios")]
310pub const AVCaptureAutoFocusRangeRestrictionNone: AVCaptureAutoFocusRangeRestriction = 0;
311#[cfg(target_os = "ios")]
312pub const AVCaptureAutoFocusRangeRestrictionNear: AVCaptureAutoFocusRangeRestriction = 1;
313#[cfg(target_os = "ios")]
314pub const AVCaptureAutoFocusRangeRestrictionFar: AVCaptureAutoFocusRangeRestriction = 2;
315
316#[cfg(target_os = "ios")]
317extern "C" {
318    pub static AVCaptureLensPositionCurrent: &'static f32;
319}
320
321// AVCaptureDeviceFocus
322impl AVCaptureDevice {
323    pub fn is_focus_mode_supported(&self, focus_mode: AVCaptureFocusMode) -> Bool {
324        unsafe { msg_send![self, isFocusModeSupported: focus_mode] }
325    }
326
327    #[cfg(target_os = "ios")]
328    pub fn is_locking_focus_with_custom_lens_position_supported(&self) -> Bool {
329        unsafe { msg_send![self, isLockingFocusWithCustomLensPositionSupported] }
330    }
331
332    pub fn focus_mode(&self) -> AVCaptureFocusMode {
333        unsafe { msg_send![self, focusMode] }
334    }
335
336    pub fn set_focus_mode(&self, focus_mode: AVCaptureFocusMode) {
337        unsafe { msg_send![self, setFocusMode: focus_mode] }
338    }
339
340    pub fn is_focus_point_of_interest_supported(&self) -> Bool {
341        unsafe { msg_send![self, isFocusPointOfInterestSupported] }
342    }
343
344    pub fn focus_point_of_interest(&self) -> CGPoint {
345        unsafe { msg_send![self, focusPointOfInterest] }
346    }
347
348    pub fn set_focus_point_of_interest(&self, point: CGPoint) {
349        unsafe { msg_send![self, setFocusPointOfInterest: point] }
350    }
351
352    pub fn is_adjusting_focus(&self) -> Bool {
353        unsafe { msg_send![self, isAdjustingFocus] }
354    }
355
356    #[cfg(target_os = "ios")]
357    pub fn is_auto_focus_range_restriction_supported(&self) -> Bool {
358        unsafe { msg_send![self, isAutoFocusRangeRestrictionSupported] }
359    }
360
361    #[cfg(target_os = "ios")]
362    pub fn auto_focus_range_restriction(&self) -> AVCaptureAutoFocusRangeRestriction {
363        unsafe { msg_send![self, autoFocusRangeRestriction] }
364    }
365
366    #[cfg(target_os = "ios")]
367    pub fn set_auto_focus_range_restriction(&self, auto_focus_range_restriction: AVCaptureAutoFocusRangeRestriction) {
368        unsafe { msg_send![self, setAutoFocusRangeRestriction: auto_focus_range_restriction] }
369    }
370
371    #[cfg(target_os = "ios")]
372    pub fn is_smooth_auto_focus_supported(&self) -> Bool {
373        unsafe { msg_send![self, isSmoothAutoFocusSupported] }
374    }
375
376    #[cfg(target_os = "ios")]
377    pub fn is_smooth_auto_focus_enabled(&self) -> Bool {
378        unsafe { msg_send![self, isSmoothAutoFocusEnabled] }
379    }
380
381    #[cfg(target_os = "ios")]
382    pub fn set_smooth_auto_focus_enabled(&self, enabled: Bool) {
383        unsafe { msg_send![self, setSmoothAutoFocusEnabled: enabled] }
384    }
385
386    #[cfg(target_os = "ios")]
387    pub fn automatically_adjusts_face_driven_auto_focus_enabled(&self) -> Bool {
388        unsafe { msg_send![self, automaticallyAdjustsFaceDrivenAutoFocusEnabled] }
389    }
390
391    #[cfg(target_os = "ios")]
392    pub fn set_automatically_adjusts_face_driven_auto_focus_enabled(&self, enabled: Bool) {
393        unsafe { msg_send![self, setAutomaticallyAdjustsFaceDrivenAutoFocusEnabled: enabled] }
394    }
395
396    #[cfg(target_os = "ios")]
397    pub fn is_face_driven_auto_focus_enabled(&self) -> Bool {
398        unsafe { msg_send![self, isFaceDrivenAutoFocusEnabled] }
399    }
400
401    #[cfg(target_os = "ios")]
402    pub fn lens_position(&self) -> f32 {
403        unsafe { msg_send![self, lensPosition] }
404    }
405
406    pub fn minimum_focus_distance(&self) -> NSInteger {
407        unsafe { msg_send![self, minimumFocusDistance] }
408    }
409}
410
411pub type AVCaptureExposureMode = NSInteger;
412
413pub const AVCaptureExposureModeLocked: AVCaptureExposureMode = 0;
414pub const AVCaptureExposureModeAutoExpose: AVCaptureExposureMode = 1;
415pub const AVCaptureExposureModeContinuousAutoExposure: AVCaptureExposureMode = 2;
416pub const AVCaptureExposureModeCustom: AVCaptureExposureMode = 3;
417
418#[cfg(target_os = "ios")]
419extern "C" {
420    pub static AVCaptureExposureDurationCurrent: &'static CMTime;
421    pub static AVCaptureExposureTargetBiasCurrent: &'static f32;
422    pub static AVCaptureISOCurrent: &'static f32;
423}
424
425// AVCaptureDeviceExposure
426impl AVCaptureDevice {
427    pub fn is_exposure_mode_supported(&self, exposure_mode: AVCaptureExposureMode) -> Bool {
428        unsafe { msg_send![self, isExposureModeSupported: exposure_mode] }
429    }
430
431    pub fn exposure_mode(&self) -> AVCaptureExposureMode {
432        unsafe { msg_send![self, exposureMode] }
433    }
434
435    pub fn set_exposure_mode(&self, exposure_mode: AVCaptureExposureMode) {
436        unsafe { msg_send![self, setExposureMode: exposure_mode] }
437    }
438
439    pub fn is_exposure_point_of_interest_supported(&self) -> Bool {
440        unsafe { msg_send![self, isExposurePointOfInterestSupported] }
441    }
442
443    pub fn exposure_point_of_interest(&self) -> CGPoint {
444        unsafe { msg_send![self, exposurePointOfInterest] }
445    }
446
447    pub fn set_exposure_point_of_interest(&self, point: CGPoint) {
448        unsafe { msg_send![self, setExposurePointOfInterest: point] }
449    }
450
451    #[cfg(target_os = "ios")]
452    pub fn automatically_adjusts_face_driven_auto_exposure_enabled(&self) -> Bool {
453        unsafe { msg_send![self, automaticallyAdjustsFaceDrivenAutoExposureEnabled] }
454    }
455
456    #[cfg(target_os = "ios")]
457    pub fn set_automatically_adjusts_face_driven_auto_exposure_enabled(&self, enabled: Bool) {
458        unsafe { msg_send![self, setAutomaticallyAdjustsFaceDrivenAutoExposureEnabled: enabled] }
459    }
460
461    #[cfg(target_os = "ios")]
462    pub fn is_face_driven_auto_exposure_enabled(&self) -> Bool {
463        unsafe { msg_send![self, isFaceDrivenAutoExposureEnabled] }
464    }
465
466    #[cfg(target_os = "ios")]
467    pub fn active_max_exposure_duration(&self) -> CMTime {
468        unsafe { msg_send![self, activeMaxExposureDuration] }
469    }
470
471    #[cfg(target_os = "ios")]
472    pub fn set_active_max_exposure_duration(&self, duration: CMTime) {
473        unsafe { msg_send![self, setActiveMaxExposureDuration: duration] }
474    }
475
476    pub fn is_adjusting_exposure(&self) -> Bool {
477        unsafe { msg_send![self, isAdjustingExposure] }
478    }
479
480    #[cfg(target_os = "ios")]
481    pub fn lens_aperture(&self) -> f32 {
482        unsafe { msg_send![self, lensAperture] }
483    }
484
485    #[cfg(target_os = "ios")]
486    pub fn exposure_duration(&self) -> CMTime {
487        unsafe { msg_send![self, exposureDuration] }
488    }
489
490    #[cfg(target_os = "ios")]
491    pub fn iso(&self) -> f32 {
492        unsafe { msg_send![self, ISO] }
493    }
494
495    #[cfg(target_os = "ios")]
496    pub fn exposure_target_offset(&self) -> f32 {
497        unsafe { msg_send![self, exposureTargetOffset] }
498    }
499
500    #[cfg(target_os = "ios")]
501    pub fn exposure_target_bias(&self) -> f32 {
502        unsafe { msg_send![self, exposureTargetBias] }
503    }
504
505    #[cfg(target_os = "ios")]
506    pub fn min_exposure_target_bias(&self) -> f32 {
507        unsafe { msg_send![self, minExposureTargetBias] }
508    }
509
510    #[cfg(target_os = "ios")]
511    pub fn max_exposure_target_bias(&self) -> f32 {
512        unsafe { msg_send![self, maxExposureTargetBias] }
513    }
514}
515
516// AVCaptureDeviceToneMapping
517#[cfg(target_os = "ios")]
518impl AVCaptureDevice {
519    pub fn is_global_tone_mapping_enabled(&self) -> Bool {
520        unsafe { msg_send![self, isGlobalToneMappingEnabled] }
521    }
522}
523
524pub type AVCaptureWhiteBalanceMode = NSInteger;
525
526pub const AVCaptureWhiteBalanceModeLocked: AVCaptureWhiteBalanceMode = 0;
527pub const AVCaptureWhiteBalanceModeAutoWhiteBalance: AVCaptureWhiteBalanceMode = 1;
528pub const AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance: AVCaptureWhiteBalanceMode = 2;
529
530#[cfg(target_os = "ios")]
531#[repr(C)]
532#[derive(Clone, Copy, Debug, Default, PartialEq)]
533pub struct AVCaptureWhiteBalanceGains {
534    pub redGain: f32,
535    pub greenGain: f32,
536    pub blueGain: f32,
537}
538
539#[cfg(target_os = "ios")]
540unsafe impl Encode for AVCaptureWhiteBalanceGains {
541    const ENCODING: Encoding = Encoding::Struct("AVCaptureWhiteBalanceGains", &[Float, Float, Float]);
542}
543
544#[cfg(target_os = "ios")]
545unsafe impl RefEncode for AVCaptureWhiteBalanceGains {
546    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
547}
548
549#[cfg(target_os = "ios")]
550#[repr(C)]
551#[derive(Clone, Copy, Debug, Default, PartialEq)]
552pub struct AVCaptureWhiteBalanceChromaticityValues {
553    pub x: f32,
554    pub y: f32,
555}
556
557#[cfg(target_os = "ios")]
558unsafe impl Encode for AVCaptureWhiteBalanceChromaticityValues {
559    const ENCODING: Encoding = Encoding::Struct("AVCaptureWhiteBalanceChromaticityValues", &[Float, Float]);
560}
561
562#[cfg(target_os = "ios")]
563unsafe impl RefEncode for AVCaptureWhiteBalanceChromaticityValues {
564    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
565}
566
567#[cfg(target_os = "ios")]
568#[repr(C)]
569#[derive(Clone, Copy, Debug, Default, PartialEq)]
570pub struct AVCaptureWhiteBalanceTemperatureAndTintValues {
571    pub temperature: f32,
572    pub tint: f32,
573}
574
575#[cfg(target_os = "ios")]
576extern "C" {
577    pub static AVCaptureWhiteBalanceGainsCurrent: &'static AVCaptureWhiteBalanceGains;
578}
579
580#[cfg(target_os = "ios")]
581unsafe impl Encode for AVCaptureWhiteBalanceTemperatureAndTintValues {
582    const ENCODING: Encoding = Encoding::Struct("AVCaptureWhiteBalanceTemperatureAndTintValues", &[Float, Float]);
583}
584
585#[cfg(target_os = "ios")]
586unsafe impl RefEncode for AVCaptureWhiteBalanceTemperatureAndTintValues {
587    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
588}
589
590// AVCaptureDeviceWhiteBalance
591impl AVCaptureDevice {
592    pub fn is_white_balance_mode_supported(&self, white_balance_mode: AVCaptureWhiteBalanceMode) -> Bool {
593        unsafe { msg_send![self, isWhiteBalanceModeSupported: white_balance_mode] }
594    }
595
596    #[cfg(target_os = "ios")]
597    pub fn is_locking_white_balance_with_custom_device_gains_supported(&self) -> Bool {
598        unsafe { msg_send![self, isLockingWhiteBalanceWithCustomDeviceGainsSupported] }
599    }
600
601    pub fn white_balance_mode(&self) -> AVCaptureWhiteBalanceMode {
602        unsafe { msg_send![self, whiteBalanceMode] }
603    }
604
605    pub fn set_white_balance_mode(&self, white_balance_mode: AVCaptureWhiteBalanceMode) {
606        unsafe { msg_send![self, setWhiteBalanceMode: white_balance_mode] }
607    }
608
609    pub fn is_adjusting_white_balance(&self) -> Bool {
610        unsafe { msg_send![self, isAdjustingWhiteBalance] }
611    }
612
613    #[cfg(target_os = "ios")]
614    pub fn device_white_balance_gains(&self) -> AVCaptureWhiteBalanceGains {
615        unsafe { msg_send![self, deviceWhiteBalanceGains] }
616    }
617
618    #[cfg(target_os = "ios")]
619    pub fn gray_world_device_white_balance_gains(&self) -> AVCaptureWhiteBalanceGains {
620        unsafe { msg_send![self, grayWorldDeviceWhiteBalanceGains] }
621    }
622
623    #[cfg(target_os = "ios")]
624    pub fn max_white_balance_gain(&self) -> f32 {
625        unsafe { msg_send![self, maxWhiteBalanceGain] }
626    }
627
628    #[cfg(target_os = "ios")]
629    pub fn chromaticity_values_for_device_white_balance_gains(
630        &self,
631        white_balance_gains: AVCaptureWhiteBalanceGains,
632    ) -> AVCaptureWhiteBalanceChromaticityValues {
633        unsafe { msg_send![self, chromaticityValuesForDeviceWhiteBalanceGains: white_balance_gains] }
634    }
635
636    #[cfg(target_os = "ios")]
637    pub fn device_white_balance_gains_for_chromaticity_values(
638        &self,
639        chromaticity_values: AVCaptureWhiteBalanceChromaticityValues,
640    ) -> AVCaptureWhiteBalanceGains {
641        unsafe { msg_send![self, deviceWhiteBalanceGainsForChromaticityValues: chromaticity_values] }
642    }
643
644    #[cfg(target_os = "ios")]
645    pub fn temperature_and_tint_values_for_device_white_balance_gains(
646        &self,
647        white_balance_gains: AVCaptureWhiteBalanceGains,
648    ) -> AVCaptureWhiteBalanceTemperatureAndTintValues {
649        unsafe { msg_send![self, temperatureAndTintValuesForDeviceWhiteBalanceGains: white_balance_gains] }
650    }
651
652    #[cfg(target_os = "ios")]
653    pub fn device_white_balance_gains_for_temperature_and_tint_values(
654        &self,
655        temp_and_tint_values: AVCaptureWhiteBalanceTemperatureAndTintValues,
656    ) -> AVCaptureWhiteBalanceGains {
657        unsafe { msg_send![self, deviceWhiteBalanceGainsForTemperatureAndTintValues: temp_and_tint_values] }
658    }
659}
660
661// AVCaptureDeviceLowLightBoost
662#[cfg(target_os = "ios")]
663impl AVCaptureDevice {
664    pub fn is_low_light_boost_supported(&self) -> Bool {
665        unsafe { msg_send![self, isLowLightBoostSupported] }
666    }
667
668    pub fn is_low_light_boost_enabled(&self) -> Bool {
669        unsafe { msg_send![self, isLowLightBoostEnabled] }
670    }
671
672    pub fn automatically_enables_low_light_boost_when_available(&self) -> Bool {
673        unsafe { msg_send![self, automaticallyEnablesLowLightBoostWhenAvailable] }
674    }
675
676    pub fn set_automatically_enables_low_light_boost_when_available(&self, value: Bool) {
677        unsafe { msg_send![self, setAutomaticallyEnablesLowLightBoostWhenAvailable: value] }
678    }
679}
680
681// AVCaptureDeviceVideoZoom
682impl AVCaptureDevice {
683    #[cfg(target_os = "ios")]
684    pub fn video_zoom_factor(&self) -> CGFloat {
685        unsafe { msg_send![self, videoZoomFactor] }
686    }
687
688    #[cfg(target_os = "ios")]
689    pub fn set_video_zoom_factor(&self, factor: CGFloat) {
690        unsafe { msg_send![self, setVideoZoomFactor: factor] }
691    }
692
693    #[cfg(target_os = "ios")]
694    pub fn ramp_to_video_zoom_factor(&self, factor: CGFloat, rate: f32) {
695        unsafe { msg_send![self, rampToVideoZoomFactor: factor withRate: rate] }
696    }
697
698    #[cfg(target_os = "ios")]
699    pub fn is_ramping_video_zoom(&self) -> Bool {
700        unsafe { msg_send![self, isRampingVideoZoom] }
701    }
702
703    #[cfg(target_os = "ios")]
704    pub fn cancel_video_zoom_ramp(&self) {
705        unsafe { msg_send![self, cancelVideoZoomRamp] }
706    }
707
708    #[cfg(target_os = "macos")]
709    pub fn display_video_zoom_factor_multiplier(&self) -> CGFloat {
710        unsafe { msg_send![self, displayVideoZoomFactorMultiplier] }
711    }
712
713    #[cfg(target_os = "ios")]
714    pub fn min_available_video_zoom_factor(&self) -> CGFloat {
715        unsafe { msg_send![self, minAvailableVideoZoomFactor] }
716    }
717
718    #[cfg(target_os = "ios")]
719    pub fn max_available_video_zoom_factor(&self) -> CGFloat {
720        unsafe { msg_send![self, maxAvailableVideoZoomFactor] }
721    }
722}
723
724pub type AVAuthorizationStatus = NSInteger;
725
726pub const AVAuthorizationStatusNotDetermined: AVAuthorizationStatus = 0;
727pub const AVAuthorizationStatusRestricted: AVAuthorizationStatus = 1;
728pub const AVAuthorizationStatusDenied: AVAuthorizationStatus = 2;
729pub const AVAuthorizationStatusAuthorized: AVAuthorizationStatus = 3;
730
731// AVCaptureDeviceAuthorization
732impl AVCaptureDevice {
733    pub fn authorization_status_for_media_type(media_type: &AVMediaType) -> AVAuthorizationStatus {
734        unsafe { msg_send![AVCaptureDevice::class(), authorizationStatusForMediaType: media_type] }
735    }
736
737    pub fn request_access_for_media_type<F>(media_type: &AVMediaType, handler: F)
738    where
739        F: Fn(Bool) + 'static,
740    {
741        unsafe { msg_send![AVCaptureDevice::class(), requestAccessForMediaType: media_type completionHandler: &*RcBlock::new(handler)] }
742    }
743}
744
745// AVCaptureDeviceHighDynamicRangeSupport
746#[cfg(target_os = "ios")]
747impl AVCaptureDevice {
748    pub fn automatically_adjusts_video_hdr_enabled(&self) -> Bool {
749        unsafe { msg_send![self, automaticallyAdjustsVideoHDREnabled] }
750    }
751
752    pub fn is_video_hdr_enabled(&self) -> Bool {
753        unsafe { msg_send![self, isVideoHDREnabled] }
754    }
755}
756
757pub type AVCaptureColorSpace = NSInteger;
758
759pub const AVCaptureColorSpace_sRGB: AVCaptureColorSpace = 0;
760pub const AVCaptureColorSpace_P3_D65: AVCaptureColorSpace = 1;
761pub const AVCaptureColorSpace_HLG_BT2020: AVCaptureColorSpace = 2;
762pub const AVCaptureColorSpace_AppleLog: AVCaptureColorSpace = 3;
763
764// AVCaptureDeviceColorSpaceSupport
765impl AVCaptureDevice {
766    pub fn active_color_space(&self) -> AVCaptureColorSpace {
767        unsafe { msg_send![self, activeColorSpace] }
768    }
769}
770
771extern_class!(
772    #[derive(Debug, PartialEq, Eq, Hash)]
773    pub struct AVCaptureDeviceDiscoverySession;
774
775    unsafe impl ClassType for AVCaptureDeviceDiscoverySession {
776        type Super = NSObject;
777        type Mutability = InteriorMutable;
778    }
779);
780
781unsafe impl NSObjectProtocol for AVCaptureDeviceDiscoverySession {}
782
783impl AVCaptureDeviceDiscoverySession {
784    pub fn discovery_session_with_device_types(
785        device_types: &NSArray<AVCaptureDeviceType>,
786        media_type: &AVMediaType,
787        position: AVCaptureDevicePosition,
788    ) -> Id<AVCaptureDeviceDiscoverySession> {
789        unsafe {
790            msg_send_id![AVCaptureDeviceDiscoverySession::class(), discoverySessionWithDeviceTypes: device_types mediaType: media_type position: position]
791        }
792    }
793
794    pub fn devices(&self) -> Id<NSArray<AVCaptureDevice>> {
795        unsafe { msg_send_id![self, devices] }
796    }
797}
798
799extern_class!(
800    #[derive(Debug, PartialEq, Eq, Hash)]
801    pub struct AVFrameRateRange;
802
803    unsafe impl ClassType for AVFrameRateRange {
804        type Super = NSObject;
805        type Mutability = InteriorMutable;
806    }
807);
808
809unsafe impl NSObjectProtocol for AVFrameRateRange {}
810
811impl AVFrameRateRange {
812    pub fn min_frame_rate(&self) -> f64 {
813        unsafe { msg_send![self, minFrameRate] }
814    }
815
816    pub fn max_frame_rate(&self) -> f64 {
817        unsafe { msg_send![self, maxFrameRate] }
818    }
819
820    pub fn min_frame_duration(&self) -> CMTime {
821        unsafe { msg_send![self, minFrameDuration] }
822    }
823
824    pub fn max_frame_duration(&self) -> CMTime {
825        unsafe { msg_send![self, maxFrameDuration] }
826    }
827}
828
829#[cfg(target_os = "ios")]
830pub type AVCaptureVideoStabilizationMode = NSInteger;
831
832#[cfg(target_os = "ios")]
833pub const AVCaptureVideoStabilizationModeOff: AVCaptureVideoStabilizationMode = 0;
834#[cfg(target_os = "ios")]
835pub const AVCaptureVideoStabilizationModeStandard: AVCaptureVideoStabilizationMode = 1;
836#[cfg(target_os = "ios")]
837pub const AVCaptureVideoStabilizationModeCinematic: AVCaptureVideoStabilizationMode = 2;
838#[cfg(target_os = "ios")]
839pub const AVCaptureVideoStabilizationModeCinematicExtended: AVCaptureVideoStabilizationMode = 3;
840#[cfg(target_os = "ios")]
841pub const AVCaptureVideoStabilizationModePreviewOptimized: AVCaptureVideoStabilizationMode = 4;
842#[cfg(target_os = "ios")]
843pub const AVCaptureVideoStabilizationModeAuto: AVCaptureVideoStabilizationMode = -1;
844
845pub type AVCaptureAutoFocusSystem = NSInteger;
846
847pub const AVCaptureAutoFocusSystemNone: AVCaptureAutoFocusSystem = 0;
848pub const AVCaptureAutoFocusSystemContrastDetection: AVCaptureAutoFocusSystem = 1;
849pub const AVCaptureAutoFocusSystemPhaseDetection: AVCaptureAutoFocusSystem = 2;
850
851extern_class!(
852    #[derive(Debug, PartialEq, Eq, Hash)]
853    pub struct AVCaptureDeviceFormat;
854
855    unsafe impl ClassType for AVCaptureDeviceFormat {
856        type Super = NSObject;
857        type Mutability = InteriorMutable;
858    }
859);
860
861unsafe impl NSObjectProtocol for AVCaptureDeviceFormat {}
862
863impl AVCaptureDeviceFormat {
864    pub fn media_type(&self) -> Id<AVMediaType> {
865        unsafe { msg_send_id![self, mediaType] }
866    }
867
868    pub fn format_description(&self) -> CMFormatDescription {
869        unsafe {
870            let format_description: CMFormatDescriptionRef = msg_send![self, formatDescription];
871            CMFormatDescription::wrap_under_get_rule(format_description)
872        }
873    }
874
875    pub fn video_supported_frame_rate_ranges(&self) -> Id<NSArray<AVFrameRateRange>> {
876        unsafe { msg_send_id![self, videoSupportedFrameRateRanges] }
877    }
878
879    pub fn video_field_of_view(&self) -> f32 {
880        unsafe { msg_send![self, videoFieldOfView] }
881    }
882
883    pub fn is_video_binned(&self) -> Bool {
884        unsafe { msg_send![self, isVideoBinned] }
885    }
886
887    #[cfg(target_os = "ios")]
888    pub fn is_video_stabilization_mode_supported(&self, video_stabilization_mode: AVCaptureVideoStabilizationMode) -> Bool {
889        unsafe { msg_send![self, isVideoStabilizationModeSupported: video_stabilization_mode] }
890    }
891
892    #[cfg(target_os = "ios")]
893    pub fn video_max_zoom_factor(&self) -> CGFloat {
894        unsafe { msg_send![self, videoMaxZoomFactor] }
895    }
896
897    #[cfg(target_os = "ios")]
898    pub fn video_zoom_factor_upscale_threshold(&self) -> CGFloat {
899        unsafe { msg_send![self, videoZoomFactorUpscaleThreshold] }
900    }
901
902    #[cfg(target_os = "ios")]
903    pub fn min_exposure_duration(&self) -> CMTime {
904        unsafe { msg_send![self, minExposureDuration] }
905    }
906
907    #[cfg(target_os = "ios")]
908    pub fn max_exposure_duration(&self) -> CMTime {
909        unsafe { msg_send![self, maxExposureDuration] }
910    }
911
912    #[cfg(target_os = "ios")]
913    pub fn min_iso(&self) -> f32 {
914        unsafe { msg_send![self, minISO] }
915    }
916
917    #[cfg(target_os = "ios")]
918    pub fn max_iso(&self) -> f32 {
919        unsafe { msg_send![self, maxISO] }
920    }
921
922    #[cfg(target_os = "ios")]
923    pub fn is_global_tone_mapping_supported(&self) -> Bool {
924        unsafe { msg_send![self, isGlobalToneMappingSupported] }
925    }
926
927    #[cfg(target_os = "ios")]
928    pub fn is_video_hdr_supported(&self) -> Bool {
929        unsafe { msg_send![self, isVideoHDRSupported] }
930    }
931
932    pub fn is_high_photo_quality_supported(&self) -> Bool {
933        unsafe { msg_send![self, isHighPhotoQualitySupported] }
934    }
935
936    pub fn auto_focus_system(&self) -> AVCaptureAutoFocusSystem {
937        unsafe { msg_send![self, autoFocusSystem] }
938    }
939
940    pub fn supported_color_spaces(&self) -> Id<NSArray<NSNumber>> {
941        unsafe { msg_send_id![self, supportedColorSpaces] }
942    }
943
944    pub fn supported_depth_data_formats(&self) -> Id<NSArray<AVCaptureDeviceFormat>> {
945        unsafe { msg_send_id![self, supportedDepthDataFormats] }
946    }
947}
948
949extern_class!(
950    #[derive(Debug, PartialEq, Eq, Hash)]
951    pub struct AVCaptureDeviceInputSource;
952
953    unsafe impl ClassType for AVCaptureDeviceInputSource {
954        type Super = NSObject;
955        type Mutability = InteriorMutable;
956    }
957);
958
959unsafe impl NSObjectProtocol for AVCaptureDeviceInputSource {}
960
961impl AVCaptureDeviceInputSource {
962    pub fn input_source_id(&self) -> Id<NSString> {
963        unsafe { msg_send_id![self, inputSourceID] }
964    }
965
966    pub fn localized_name(&self) -> Id<NSString> {
967        unsafe { msg_send_id![self, localizedName] }
968    }
969}