OBSAVCapture.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. //
  2. // OBSAVCapture.h
  3. // mac-avcapture
  4. //
  5. // Created by Patrick Heyer on 2023-03-07.
  6. //
  7. @import Foundation;
  8. @import AVFoundation;
  9. @import CoreMediaIO;
  10. #import "OBSAVCapturePresetInfo.h"
  11. // Import everything as libobs source data types are not available in a specific header.
  12. #import <obs.h>
  13. #import <pthread.h>
  14. #import <media-io/video-io.h>
  15. #pragma mark - Type aliases and type definitions
  16. typedef enum video_colorspace OBSAVCaptureColorSpace;
  17. typedef enum video_range_type OBSAVCaptureVideoRange;
  18. typedef enum video_format OBSAVCaptureVideoFormat;
  19. typedef struct obs_source_frame OBSAVCaptureVideoFrame;
  20. typedef struct obs_source_audio OBSAVCaptureAudioFrame;
  21. typedef struct gs_texture OBSAVCaptureTexture;
  22. typedef struct gs_effect OBSAVCaptureEffect;
  23. typedef struct media_frames_per_second OBSAVCaptureMediaFPS;
  24. /// C struct for errors encountered in capture callback
  25. typedef enum : NSUInteger {
  26. OBSAVCaptureError_NoError,
  27. OBSAVCaptureError_SampleBufferFormat,
  28. OBSAVCaptureError_ColorSpace,
  29. OBSAVCaptureError_AudioBuffer,
  30. } OBSAVCaptureError;
  31. /// C struct for interaction with obs-module functions
  32. typedef struct av_capture {
  33. IOSurfaceRef previousSurface;
  34. IOSurfaceRef currentSurface;
  35. OBSAVCaptureTexture *texture;
  36. OBSAVCaptureEffect *effect;
  37. OBSAVCaptureVideoFrame *videoFrame;
  38. OBSAVCaptureAudioFrame *audioFrame;
  39. NSRect frameSize;
  40. pthread_mutex_t mutex;
  41. OBSAVCaptureColorSpace configuredColorSpace;
  42. OBSAVCaptureVideoRange configuredFourCC;
  43. void *settings;
  44. void *source;
  45. bool isFastPath;
  46. OBSAVCaptureError lastError;
  47. CMFormatDescriptionRef sampleBufferDescription;
  48. OBSAVCaptureError lastAudioError;
  49. } OBSAVCaptureInfo;
  50. /// C struct for sample buffer validity checks in capture callback
  51. typedef struct av_capture_info {
  52. OBSAVCaptureColorSpace colorSpace;
  53. FourCharCode fourCC;
  54. bool isValid;
  55. } OBSAVCaptureVideoInfo;
  56. #pragma mark - OBSAVCapture Class
  57. /// Video Capture implementation for [CoreMediaIO](https://developer.apple.com/documentation/coremediaio?language=objc)-based devices
  58. ///
  59. /// Provides access to camera devices recognized by macOS via its [CoreMediaIO](https://developer.apple.com/documentation/coremediaio?language=objc) framework. Devices can be either entirely video-based or a "muxed" device that provides audio and video at the same time.
  60. ///
  61. /// Devices can be configured either via [presets](https://developer.apple.com/documentation/avfoundation/avcapturesessionpreset?language=objc) (usually 3 quality-based presets in addition to resolution based presets). The resolution defined by the preset does not necessarily switch the actual device to the same resolution, instead the device is automatically switched to the best possible resolution and the [CMSampleBuffer](https://developer.apple.com/documentation/coremedia/cmsamplebuffer?language=objc) provided via [AVCaptureVideoDataOutput](https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutput?language=objc) will be resized accordingly. If necessary the actual frame will be pillar-boxed to fit into a widescreen sample buffer in an attempt to fit the content into it.
  62. ///
  63. /// Alternatively, devices can be configured manually by specifying a particular [AVCaptureDeviceFormat](https://developer.apple.com/documentation/avfoundation/avcapturedeviceformat?language=objc) representing a specific combination of resolution, frame-rate, color format and color space supported by the device. If a device was **not** configured via a preset originally, the size of the [CMSampleBuffer](https://developer.apple.com/documentation/coremedia/cmsamplebuffer?language=objc) will be adjusted to the selected resolution.
  64. ///
  65. /// > Important: If a preset was configured before, the resolution of the last valid preset-based buffer will be retained and the frame will be fit into it with the selected resolution.
  66. ///
  67. /// If a device is switched back from manual configuration to a preset-based output, the preset's original settings will be restored, as device configuration is not mutually exclusive with the settings of a preset on macOS.
  68. @interface OBSAVCapture
  69. : NSObject <AVCaptureAudioDataOutputSampleBufferDelegate, AVCaptureVideoDataOutputSampleBufferDelegate>
  70. /// Bare initialiser for ``OBSAVCapture`` class.
  71. ///
  72. /// > Tip: Use ``OBSAVCapture/initWithCaptureInfo:capture_info:`` instead.
  73. ///
  74. /// - Returns: A new instance of ``OBSAVCapture`` without settings or a source attached and without an active [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc).
  75. - (instancetype)init;
  76. /// Creates new ``OBSAVCapture`` instance with provided ``mac_avcapture/OBSAVCaptureInfo`` struct. If settings and source pointers in the provided struct are valid, a new capture session will be created immediately and capture of a valid device will begin.
  77. ///
  78. /// If the device specified in the settings is not valid (e.g., because the device has been disconnected in the meantime) the source will retain the settings and can be reconfigured. If no valid device is specified, the source will stay empty.
  79. /// - Parameters:
  80. /// - capture_info: ``OBSAVCaptureInfo`` struct containing source and settings pointers provided by ``libobs``
  81. /// - Returns: A new instance of an ``OBSAVCapture``
  82. - (instancetype)initWithCaptureInfo:(OBSAVCaptureInfo *)capture_info NS_DESIGNATED_INITIALIZER;
  83. #pragma mark - Capture Session Handling
  84. /// Creates a new [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) for the device configured in the ``OBSAVCapture`` instance.
  85. /// - Parameters:
  86. /// - error: Optional pointer to a valid [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc) instance to retain possible errors that occurred
  87. /// - Returns: `YES` if session was created successfully, `NO` otherwise
  88. - (BOOL)createSession:(NSError **)error;
  89. /// Switches the active capture device used by ``OBSAVCapture`` instance.
  90. /// - Parameters:
  91. /// - uuid: UUID of new device to switch to (as provided by [CoreMediaIO](https://developer.apple.com/documentation/coremediaio?language=objc)
  92. /// - error: Optional pointer to a valid [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc) instance to retain possible errors that occurred
  93. /// - Returns: `YES` if the device was successfully switched, `NO` otherwise
  94. - (BOOL)switchCaptureDevice:(NSString *)uuid withError:(NSError **)error;
  95. /// Starts a capture session with the active capture device used by ``OBSAVCapture`` instance.
  96. - (void)startCaptureSession;
  97. /// Stops a capture session with the active capture device used by ``OBSAVCapture`` instance. Also sends an empty frame to clear any frames provided by the source.
  98. - (void)stopCaptureSession;
  99. /// Configures the current [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) to use the [AVCaptureSessionPreset](https://developer.apple.com/documentation/avfoundation/avcapturesessionpreset?language=objc) value selected in the source's property window.
  100. /// - Parameter error: Optional pointer to a valid [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc) instance to retain possible errors that occurred
  101. /// - Returns: `YES` if configuration finished successfully, `NO` otherwise
  102. - (BOOL)configureSessionWithPreset:(AVCaptureSessionPreset)preset withError:(NSError **)error;
  103. /// Configures the device used in the current [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) directly by attempting to apply the values selected in the source's property window.
  104. ///
  105. /// The available values are commonly filled by all settings available for the current [AVCaptureDevice](https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc). This includes:
  106. /// * Resolution
  107. /// * Frame rate
  108. /// * Color Format
  109. /// * Color Space
  110. ///
  111. /// If the combination of property values read from the settings does not match any format supported by the [AVCaptureDevice](https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc), the session will not be configured and if a valid [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) exist, it will be kept active.
  112. /// - Parameter error: Optional pointer to a valid [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc) instance to retain possible errors that occurred
  113. /// - Returns: `YES` if configuration finished successfully, `NO` otherwise
  114. - (BOOL)configureSession:(NSError **)error;
  115. /// Triggers an update of the current ``OBSAVCapture`` source using the property values currently set up on the source.
  116. ///
  117. /// The function will automatically call ``switchCaptureDevice:uuid:error`` if the device property was changed, and also call ``configureSession:error`` or ``configureSessionWithPreset:preset:error`` based on the value of the associated source property.
  118. ///
  119. /// A new [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) will be created and started to reflect any changes.
  120. ///
  121. /// - Parameter error: Optional pointer to a valid [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc) instance to retain possible errors that occurred
  122. /// - Returns: `YES` if session was updated successfully, `NO` otherwise
  123. - (BOOL)updateSessionwithError:(NSError **)error;
  124. #pragma mark - OBS Settings Helpers
  125. /// Reads source dimensions from the legacy user settings and converts them into a [CMVideoDimensions](https://developer.apple.com/documentation/coremedia/cmvideodimensions?language=objc) struct for convenience when interacting with the [CoreMediaIO](https://developer.apple.com/documentation/coremediaio?language=objc) framework.
  126. /// - Parameter settings: Pointer to settings struct used by ``libobs``
  127. /// - Returns: [CMVideoDimensions](https://developer.apple.com/documentation/coremedia/cmvideodimensions?language=objc) struct with resolution from user settings
  128. + (CMVideoDimensions)legacyDimensionsFromSettings:(void *)settings;
  129. /// Generates an appropriate frame rate value to fall back to (based on OBS's configured output framerate) when the user selects a format that does not support their previously configured frame rate.
  130. ///
  131. /// This function fetches OBS's configured output frame rate and uses it to determine the appropriate default frame rate supported by the format. It will return:
  132. ///
  133. /// * The frame rate nearest up to and including OBS's configured output frame rate.
  134. /// * If that does not exist on the format, the frame rate nearest above OBS's configured output frame rate.
  135. /// * If that does not exist, a struct representing an invalid frame rate.
  136. /// - Parameter format: [AVCaptureDeviceFormat](https://developer.apple.com/documentation/avfoundation/avcapturedevice/format?language=objc) instance that we are determining a fallback FPS for.
  137. /// - Returns: Struct representing a frames per second value as defined in ``libobs``.
  138. + (OBSAVCaptureMediaFPS)fallbackFrameRateForFormat:(AVCaptureDeviceFormat *)format;
  139. /// Generates a new [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance containing a human-readable aspect ratio for a given pixel width and height.
  140. /// - Parameter dimensions: [CMVideoDimensions](https://developer.apple.com/documentation/coremedia/cmvideodimensions?language=objc) struct containing the width and height in pixels.
  141. /// - Returns: New [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance containing the aspect ratio description.
  142. /// For resolutions with too low of a common divisor (i.e. 2.35:1, resolutions slightly off of a common aspect ratio), this function provides the ratio between 1 and the larger float value.
  143. + (NSString *)aspectRatioStringFromDimensions:(CMVideoDimensions)dimensions;
  144. /// Reads a C-character pointer from user settings and converts it into an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance.
  145. /// - Parameters:
  146. /// - settings: Pointer to user settings struct used by ``libobs``
  147. /// - setting: String identifier for setting
  148. /// - Returns: New [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance created from user setting if setting represented a valid C character pointer.
  149. + (NSString *)stringFromSettings:(void *)settings withSetting:(NSString *)setting;
  150. /// Reads a C-character pointer from user settings and converts it into an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance.
  151. /// - Parameters:
  152. /// - settings: Pointer to user settings struct used by ``libobs``
  153. /// - setting: String identifer for setting
  154. /// - widthDefault: Optional fallback value to use if C-character pointer read from settings is invalid
  155. /// - Returns: New [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance created from user setting if setting represented a valid C character pointer.
  156. + (NSString *)stringFromSettings:(void *)settings withSetting:(NSString *)setting withDefault:(NSString *)defaultValue;
  157. /// Generates an NSString representing the name of the warning to display in the properties window for macOS system effects that are active on a particular `AVCaptureDevice`.
  158. /// - Parameter device: The [AVCaptureDevice](https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc) to generate an effects warning string for.
  159. /// - Returns: `nil` if there are no effects active on the device. If effects are found, returns a new [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance containing the `libobs` key used to retrieve the appropriate localized warning string.
  160. + (NSString *)effectsWarningForDevice:(AVCaptureDevice *)device;
  161. #pragma mark - Format Conversion Helpers
  162. /// Converts a FourCC-based color format identifier into a human-readable string represented as an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance.
  163. /// - Parameter subtype: FourCC-based color format identifier
  164. /// - Returns: Human-readable representation of the color format
  165. + (NSString *)stringFromSubType:(FourCharCode)subtype;
  166. /// Converts a ``libobs``-based color space value into a human-readable string represented as an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance.
  167. /// - Parameter subtype: ``libobs``-based colorspace value
  168. /// - Returns: Human-readable representation of the color space
  169. + (NSString *)stringFromColorspace:(enum video_colorspace)colorspace;
  170. /// Converts a ``libobs``-based video range value into a human-readable string represented as an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance.
  171. /// - Parameter subtype: ``libobs``-based video range value
  172. /// - Returns: Human-readable representation of the video range
  173. + (NSString *)stringFromVideoRange:(enum video_range_type)videoRange;
  174. /// Converts a FourCC value into a human-readable string represented as an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance.
  175. /// - Parameter fourCharCode: Arbitrary FourCC code in big-endian format
  176. /// - Returns: Human-readable representation of the FourCC code
  177. + (NSString *)stringFromFourCharCode:(OSType)fourCharCode;
  178. /// Converts a [AVCaptureSessionPreset](https://developer.apple.com/documentation/avfoundation/avcapturesessionpreset?language=objc) into a human-readable string represented as an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance.
  179. ///
  180. /// Supported presets include:
  181. /// * High preset
  182. /// * Medium preset
  183. /// * Low preset
  184. /// * Common resolutions ranging from 320x240 up to and including 3840x2160 (4k)
  185. /// - Parameter preset: Supported [AVCaptureSessionPreset](https://developer.apple.com/documentation/avfoundation/avcapturesessionpreset?language=objc)
  186. /// - Returns: Human-readable representation of the [AVCaptureSessionPreset](https://developer.apple.com/documentation/avfoundation/avcapturesessionpreset?language=objc)
  187. + (NSString *)stringFromCapturePreset:(AVCaptureSessionPreset)preset;
  188. /// Converts an [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) into a big-endian FourCC value.
  189. /// - Parameter codeString: [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) representation of a big-endian FourCC value
  190. /// - Returns: Big-endian FourCC value of the provided [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc)
  191. + (FourCharCode)fourCharCodeFromString:(NSString *)codeString;
  192. /// Checks whether the provided colorspace value is actually supported by ``libobs``.
  193. /// - Parameter colorSpace: ``libobs``-based color-space value
  194. /// - Returns: `YES` if provided color space value is supported, `NO` otherwise
  195. + (BOOL)isValidColorspace:(enum video_colorspace)colorSpace;
  196. /// Checks whether the provided video range value is actually supported by ``libobs``.
  197. /// - Parameter videoRange: ``libobs``-based video range value
  198. /// - Returns: `YES` if provided video range value is supported, `NO` otherwise
  199. + (BOOL)isValidVideoRange:(enum video_range_type)videoRange;
  200. /// Checks whether the provided FourCC-based pixel format is a full video range variant.
  201. /// - Parameter pixelFormat: FourCC code of the pixel format in big-endian format
  202. /// - Returns: `YES` if provided pixel format has full video range, `NO` otherwise
  203. + (BOOL)isFullRangeFormat:(FourCharCode)pixelFormat;
  204. /// Converts a FourCC-based media subtype in big-endian format to a video format understood by ``libobs``.
  205. /// - Parameter subtype: FourCC code of the media subtype in big-endian format
  206. /// - Returns: Video format identifier understood by ``libobs``
  207. + (OBSAVCaptureVideoFormat)formatFromSubtype:(FourCharCode)subtype;
  208. /// Converts a ``libobs``based video format its FourCC-based media subtype in big-endian format
  209. /// - Parameter format: ``libobs``-based video format
  210. /// - Returns: FourCC-based media subtype in big-endian format
  211. + (FourCharCode)fourCharCodeFromFormat:(OBSAVCaptureVideoFormat)format;
  212. /// Converts a ``libobs``based video format with a provided video range into its FourCC-based media subtype in big-endian format
  213. /// - Parameters:
  214. /// - format: ``libobs``-based video format
  215. /// - videoRange: ``libobs``-based video range
  216. /// - Returns: FourCC-based media subtype in big-endian format
  217. + (FourCharCode)fourCharCodeFromFormat:(OBSAVCaptureVideoFormat)format withRange:(enum video_range_type)videoRange;
  218. /// Generates a string describing an array of frame rate ranges. The frame rate ranges are described in ascending order.
  219. /// - Parameter ranges: [NSArray](https://developer.apple.com/documentation/foundation/nsarray?language=objc) of [AVFrameRateRange](https://developer.apple.com/documentation/avfoundation/avframeraterange?language=objc), such as might be provided by an `AVCaptureDeviceFormat` instance's [videoSupportedFrameRateRanges](https://developer.apple.com/documentation/avfoundation/avcapturedeviceformat/1387592-videosupportedframerateranges) property.
  220. /// - Returns: A new [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance that describes the frame rate ranges.
  221. + (NSString *)frameRateDescription:(NSArray<AVFrameRateRange *> *)ranges;
  222. /// Converts a [CMFormatDescription](https://developer.apple.com/documentation/coremedia/cmformatdescription?language=objc) into a ``libobs``-based color space value
  223. /// - Parameter description: A [CMFormatDescription](https://developer.apple.com/documentation/coremedia/cmformatdescription?language=objc) media format descriptor
  224. /// - Returns: A ``libobs``-based color space value
  225. + (OBSAVCaptureColorSpace)colorspaceFromDescription:(CMFormatDescriptionRef)description;
  226. #pragma mark - Notification Handlers
  227. /// Notification center callback function for [AVCaptureDeviceWasDisconnected](https://developer.apple.com/documentation/avfoundation/avcapturedevicewasdisconnectednotification?language=objc) notification.
  228. /// - Parameter notification: [NSNotification](https://developer.apple.com/documentation/foundation/nsnotification?language=objc) container for notification
  229. - (void)deviceDisconnected:(NSNotification *)notification;
  230. /// Notification center callback function for [AVCaptureDeviceWasConnected](https://developer.apple.com/documentation/avfoundation/avcapturedevicewasconnectednotification?language=objc) notification.
  231. /// - Parameter notification: [NSNotification](https://developer.apple.com/documentation/foundation/nsnotification?language=objc) container for notification
  232. - (void)deviceConnected:(NSNotification *)notification;
  233. #pragma mark - Log Helpers
  234. /// ObjC-based wrapper for ``libobs`` logging. This instance function automatically adds the localized ``OBSAVCapture`` source name to all provided log strings.
  235. ///
  236. /// The signature for string composition is similar to [NSString:stringWithFormat](https://developer.apple.com/documentation/foundation/nsstring/1497275-stringwithformat?language=objc), accepting a `printf`-like format string with added support for ObjC types:
  237. ///
  238. /// ```objc
  239. /// [self AVCaptureLog:LOG_WARNING withFormat:@"%@ - %i", @"Some String", 12];
  240. /// ```
  241. ///
  242. /// - Parameters:
  243. /// - logLevel: ``libobs``-based log severity level
  244. /// - format: [NSString:stringWithFormat:](https://developer.apple.com/documentation/foundation/nsstring/1497275-stringwithformat?language=objc)-compatible format string]
  245. - (void)AVCaptureLog:(int)logLevel withFormat:(NSString *)format, ...;
  246. /// ObjC-based wrapper for ``libobs`` logging. This class function is available for ObjC code without access to an existing ``OBSAVCapture`` instance.
  247. ///
  248. /// The signature for string composition is similar to [NSString:stringWithFormat](https://developer.apple.com/documentation/foundation/nsstring/1497275-stringwithformat?language=objc), accepting a `printf`-like format string with added support for ObjC types:
  249. ///
  250. /// ```objc
  251. /// [self AVCaptureLog:LOG_WARNING withFormat:@"%@ - %i", @"Some String", 12];
  252. /// ```
  253. ///
  254. /// - Parameters:
  255. /// - logLevel: ``libobs``-based log severity level
  256. /// - format: [NSString:stringWithFormat:](https://developer.apple.com/documentation/foundation/nsstring/1497275-stringwithformat?language=objc)-compatible format string]
  257. + (void)AVCaptureLog:(int)logLevel withFormat:(NSString *)format, ...;
  258. #pragma mark - Instance Properties
  259. /// Internal reference to ``OBSAVCaptureInfo`` struct created by ``libobs`` module code.
  260. @property (nonatomic) OBSAVCaptureInfo *captureInfo;
  261. /// ``OBSVideoCaptureVideoInfo`` struct used to hold state information of the video configuration
  262. @property OBSAVCaptureVideoInfo videoInfo;
  263. /// ``libobs``-based frame struct represented by a [NSMutableData](https://developer.apple.com/documentation/foundation/nsmutabledata?language=objc) instance
  264. @property NSMutableData *obsFrame;
  265. /// ``libobs``-based audio frame struct represented by a [NSMutableData](https://developer.apple.com/documentation/foundation/nsmutabledata?language=objc) instance
  266. @property NSMutableData *obsAudioFrame;
  267. /// Dictionary of human-readable descriptions of [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) values
  268. @property NSDictionary<NSString *, NSString *> *presetList;
  269. /// UUID of [AVCaptureDevice](https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc) currently used by the ``OBSAVCapture`` instance
  270. @property NSString *deviceUUID;
  271. /// Instance of ``OBSAVCapturePresetInfo`` to store format and frame rate of a [AVCaptureSessionPreset](https://developer.apple.com/documentation/avfoundation/avcapturesessionpreset?language=objc).
  272. @property OBSAVCapturePresetInfo *presetFormat;
  273. /// Instance of [AVCaptureSession](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) used by ``OBSAVCapture``
  274. @property AVCaptureSession *session;
  275. /// Instance of [AVCaptureDeviceInput](https://developer.apple.com/documentation/avfoundation/avcapturesession?language=objc) used by ``OBSAVCapture``
  276. @property AVCaptureDeviceInput *deviceInput;
  277. /// Instance of [AVCaptureVideoDataOutput](https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutput?language=objc) used by ``OBSAVCapture``
  278. @property AVCaptureVideoDataOutput *videoOutput;
  279. /// Instance of [AVCaptureAudioDataOutput](https://developer.apple.com/documentation/avfoundation/avcaptureaudiodataoutput?language=objc) used by ``OBSAVCapture``
  280. @property AVCaptureAudioDataOutput *audioOutput;
  281. /// [Dispatch Queue](https://developer.apple.com/documentation/dispatch/dispatch_queue?language=objc) used by the [AVCaptureVideoDataOutput](https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutput?language=objc) instance
  282. @property dispatch_queue_t videoQueue;
  283. /// [Dispatch Queue](https://developer.apple.com/documentation/dispatch/dispatch_queue?language=objc) used by the [AVCaptureAudioDataOutput](https://developer.apple.com/documentation/avfoundation/avcaptureaudiodataoutput?language=objc) instance
  284. @property dispatch_queue_t audioQueue;
  285. /// [Dispatch Queue](https://developer.apple.com/documentation/dispatch/dispatch_queue?language=objc) used by asynchronous blocks for functions that are required to not block the main thread.
  286. @property (nonatomic) dispatch_queue_t sessionQueue;
  287. /// `YES` if the device's active format is set and is locked against configuration changes, `NO` otherwise
  288. @property BOOL isDeviceLocked;
  289. /// `YES` if the device's configuration is based on a preset, `NO` otherwise
  290. @property BOOL isPresetBased;
  291. /// `YES` if the ``OBSAVCapture`` instance handles frame rendering by itself (used by the Capture Card variant), `NO` otherwise
  292. @property (readonly) BOOL isFastPath;
  293. /// Error domain identifier used for [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc) instances
  294. @property (readonly) NSString *errorDomain;
  295. @end
  296. #pragma mark - Static helper functions
  297. /// Clamp an unsigned 64-bit integer value to the specified minimum and maximum values
  298. static inline UInt64 clamp_Uint(UInt64 value, UInt64 min, UInt64 max)
  299. {
  300. const UInt64 clamped = value < min ? min : value;
  301. return clamped > max ? max : value;
  302. }
  303. /// Clamp a signed 64-bit integer value to the specified minimum and maximum values
  304. static inline SInt64 clamp_Sint(SInt64 value, SInt64 min, SInt64 max)
  305. {
  306. const SInt64 clamped = value < min ? min : value;
  307. return clamped > max ? max : value;
  308. }
  309. /// Compute the greatest common divisor of two signed 32-bit integers.
  310. static inline SInt32 gcd(SInt32 a, SInt32 b)
  311. {
  312. return (b == 0) ? a : gcd(b, a % b);
  313. }