summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatTheMav <PatTheMav@users.noreply.github.com>2024-02-24 03:33:04 +0100
committerLain <lain@obsproject.com>2024-02-24 17:38:18 -0600
commit745f87f21ff6a1fca2d2dbf909b93a752736eab7 (patch)
tree062747adcf9dd1c762a3f6b8c2b4c88ddf63b069
parent409bd12db38095f440bd59da68a7df46c6787a4e (diff)
mac-avcapture: Fix frame rate collection for camera device formats
Some devices will report different framerate ranges for formats that are identical apart from color primaries. Without taking these into account, only framerates for one color primary variant would be used to populate the framerate dropdown in the property view of the camera source. Checking for a difference in color primaries when iterating over all available formats for a device thus requires checking for this variation and adding the additional frame rate range as well.
-rw-r--r--plugins/mac-avcapture/OBSAVCapture.m1
-rw-r--r--plugins/mac-avcapture/plugin-properties.m53
2 files changed, 33 insertions, 21 deletions
diff --git a/plugins/mac-avcapture/OBSAVCapture.m b/plugins/mac-avcapture/OBSAVCapture.m
index df1a03e6c..ba8507ad3 100644
--- a/plugins/mac-avcapture/OBSAVCapture.m
+++ b/plugins/mac-avcapture/OBSAVCapture.m
@@ -197,6 +197,7 @@
[self.deviceInput.device unlockForConfiguration];
self.deviceInput = nil;
self.isDeviceLocked = NO;
+ self.presetFormat = nil;
}
if (!device) {
diff --git a/plugins/mac-avcapture/plugin-properties.m b/plugins/mac-avcapture/plugin-properties.m
index 4aed2eda9..8bd37bbea 100644
--- a/plugins/mac-avcapture/plugin-properties.m
+++ b/plugins/mac-avcapture/plugin-properties.m
@@ -338,6 +338,8 @@ bool properties_update_config(OBSAVCapture *capture, obs_properties_t *propertie
BOOL hasFoundColorSpace = capture.isFastPath;
BOOL hasFoundVideoRange = capture.isFastPath;
+ CFPropertyListRef priorColorPrimary = @"";
+
if (device) {
// Iterate over all formats reported by the device and gather them for property lists
for (AVCaptureDeviceFormat *format in device.formats) {
@@ -419,29 +421,38 @@ bool properties_update_config(OBSAVCapture *capture, obs_properties_t *propertie
}
// Only iterate over available framerates if input format, color space, and resolution are matching
- if (hasFoundInputFormat && hasFoundColorSpace && hasFoundResolution && !hasFoundFramerate) {
- for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges.reverseObjectEnumerator) {
- FourCharCode formatSubType = CMFormatDescriptionGetMediaSubType(format.formatDescription);
- int device_format = [OBSAVCapture formatFromSubtype:formatSubType];
-
- if (input_format == device_format) {
- struct media_frames_per_second min_fps = {
- .numerator = (uint32_t) clamp_Uint(range.maxFrameDuration.timescale, 0, UINT32_MAX),
- .denominator = (uint32_t) clamp_Uint(range.maxFrameDuration.value, 0, UINT32_MAX)};
- struct media_frames_per_second max_fps = {
- .numerator = (uint32_t) clamp_Uint(range.minFrameDuration.timescale, 0, UINT32_MAX),
- .denominator = (uint32_t) clamp_Uint(range.minFrameDuration.value, 0, UINT32_MAX)};
-
- if (![frameRates containsObject:range]) {
- obs_property_frame_rate_fps_range_add(prop_framerate, min_fps, max_fps);
- [frameRates addObject:range];
- }
-
- if (!hasFoundFramerate && CMTimeCompare(range.maxFrameDuration, time) >= 0 &&
- CMTimeCompare(range.minFrameDuration, time) <= 0) {
- hasFoundFramerate = YES;
+ if (hasFoundInputFormat && hasFoundColorSpace && hasFoundResolution) {
+ CFPropertyListRef colorPrimary = CMFormatDescriptionGetExtension(
+ format.formatDescription, kCMFormatDescriptionExtension_ColorPrimaries);
+
+ CFComparisonResult isColorPrimaryMatch = CFStringCompare(colorPrimary, priorColorPrimary, 0);
+
+ if (isColorPrimaryMatch != kCFCompareEqualTo || !hasFoundFramerate) {
+ for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges.reverseObjectEnumerator) {
+ FourCharCode formatSubType = CMFormatDescriptionGetMediaSubType(format.formatDescription);
+ int device_format = [OBSAVCapture formatFromSubtype:formatSubType];
+
+ if (input_format == device_format) {
+ struct media_frames_per_second min_fps = {
+ .numerator = (uint32_t) clamp_Uint(range.maxFrameDuration.timescale, 0, UINT32_MAX),
+ .denominator = (uint32_t) clamp_Uint(range.maxFrameDuration.value, 0, UINT32_MAX)};
+ struct media_frames_per_second max_fps = {
+ .numerator = (uint32_t) clamp_Uint(range.minFrameDuration.timescale, 0, UINT32_MAX),
+ .denominator = (uint32_t) clamp_Uint(range.minFrameDuration.value, 0, UINT32_MAX)};
+
+ if (![frameRates containsObject:range]) {
+ obs_property_frame_rate_fps_range_add(prop_framerate, min_fps, max_fps);
+ [frameRates addObject:range];
+ }
+
+ if (!hasFoundFramerate && CMTimeCompare(range.maxFrameDuration, time) >= 0 &&
+ CMTimeCompare(range.minFrameDuration, time) <= 0) {
+ hasFoundFramerate = YES;
+ }
}
}
+
+ priorColorPrimary = colorPrimary;
}
}
}