Skip to content
Prev Previous commit
Next Next commit
add comments and small changes
  • Loading branch information
misos1 committed Sep 19, 2024
commit 39832731fe14925808bdf9613baada04256abb4a
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,60 @@ - (instancetype)initWithCameraName:(NSString *)cameraName
error:error];
}

// Returns frame rate supported by format closest to targetFrameRate.
static double bestFrameRateForFormat(AVCaptureDeviceFormat *format, double targetFrameRate) {
double bestFrameRate = 0;
double minDistance = DBL_MAX;
for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) {
double frameRate = MIN(MAX(targetFrameRate, range.minFrameRate), range.maxFrameRate);
double distance = fabs(frameRate - targetFrameRate);
if (distance < minDistance) {
bestFrameRate = frameRate;
minDistance = distance;
}
}
return bestFrameRate;
}

// Finds format with same resolution as current activeFormat for which bestFrameRateForFormat
// returned frame rate closest to mediaSettings.framesPerSecond. Preferred are formats with the
// same subtype as current activeFormat. Sets this format as activeFormat and also updates
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "Sets this format as the activeFormat in captureDevice and [...]"; I wasn't sure what activeFormat was referring to without reading the implementation.

// mediaSettings.framesPerSecond to value which bestFrameRateForFormat returned for that format.
static void selectBestFormatForRequestedFrameRate(
AVCaptureDevice *captureDevice, FCPPlatformMediaSettings *mediaSettings,
VideoDimensionsForFormat videoDimensionsForFormat) {
CMVideoDimensions targetResolution = videoDimensionsForFormat(captureDevice.activeFormat);
double targetFrameRate = mediaSettings.framesPerSecond.doubleValue;
FourCharCode preferredSubType =
CMFormatDescriptionGetMediaSubType(captureDevice.activeFormat.formatDescription);
AVCaptureDeviceFormat *bestFormat = captureDevice.activeFormat;
double bestFrameRate = bestFrameRateForFormat(bestFormat, targetFrameRate);
double minDistance = fabs(bestFrameRate - targetFrameRate);
BOOL isBestSubTypePreferred = YES;
for (AVCaptureDeviceFormat *format in captureDevice.formats) {
CMVideoDimensions resolution = videoDimensionsForFormat(format);
if (resolution.width != targetResolution.width ||
resolution.height != targetResolution.height) {
continue;
}
double frameRate = bestFrameRateForFormat(format, targetFrameRate);
double distance = fabs(frameRate - targetFrameRate);
FourCharCode subType = CMFormatDescriptionGetMediaSubType(format.formatDescription);
BOOL isSubTypePreferred = subType == preferredSubType;
if (distance < minDistance || (distance == minDistance && isSubTypePreferred &&
!isBestSubTypePreferred)) {
bestFormat = format;
bestFrameRate = frameRate;
minDistance = distance;
isBestSubTypePreferred = isSubTypePreferred;
}
}
if (![bestFormat isEqual:captureDevice.activeFormat]) {
captureDevice.activeFormat = bestFormat;
}
mediaSettings.framesPerSecond = @(bestFrameRate);
}

- (instancetype)initWithMediaSettings:(FCPPlatformMediaSettings *)mediaSettings
mediaSettingsAVWrapper:(FLTCamMediaSettingsAVWrapper *)mediaSettingsAVWrapper
orientation:(UIDeviceOrientation)orientation
Expand Down Expand Up @@ -254,55 +308,6 @@ - (instancetype)initWithMediaSettings:(FCPPlatformMediaSettings *)mediaSettings
return self;
}

static void selectBestFormatForRequestedFrameRate(
AVCaptureDevice *captureDevice, FCPPlatformMediaSettings *mediaSettings,
VideoDimensionsForFormat videoDimensionsForFormat) {
// Find the format which frame rate ranges are closest to the wanted frame rate.
CMVideoDimensions targetResolution = videoDimensionsForFormat(captureDevice.activeFormat);
double targetFrameRate = mediaSettings.framesPerSecond.doubleValue;
FourCharCode preferredSubType =
CMFormatDescriptionGetMediaSubType(captureDevice.activeFormat.formatDescription);
AVCaptureDeviceFormat *bestFormat = captureDevice.activeFormat;
double bestFrameRate = bestFrameRateForFormat(bestFormat, targetFrameRate);
double minDistance = fabs(bestFrameRate - targetFrameRate);
FourCharCode bestSubType = preferredSubType;
for (AVCaptureDeviceFormat *format in captureDevice.formats) {
CMVideoDimensions resolution = videoDimensionsForFormat(format);
if (resolution.width != targetResolution.width ||
resolution.height != targetResolution.height) {
continue;
}
double frameRate = bestFrameRateForFormat(format, targetFrameRate);
double distance = fabs(frameRate - targetFrameRate);
FourCharCode subType = CMFormatDescriptionGetMediaSubType(format.formatDescription);
if (distance < minDistance || (distance == minDistance && subType == preferredSubType &&
bestSubType != preferredSubType)) {
bestFormat = format;
bestFrameRate = frameRate;
minDistance = distance;
bestSubType = subType;
}
}
if (![bestFormat isEqual:captureDevice.activeFormat]) {
captureDevice.activeFormat = bestFormat;
}
mediaSettings.framesPerSecond = @(bestFrameRate);
}

static double bestFrameRateForFormat(AVCaptureDeviceFormat *format, double targetFrameRate) {
double bestFrameRate = 0;
double minDistance = DBL_MAX;
for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) {
double frameRate = MIN(MAX(targetFrameRate, range.minFrameRate), range.maxFrameRate);
double distance = fabs(frameRate - targetFrameRate);
if (distance < minDistance) {
bestFrameRate = frameRate;
minDistance = distance;
}
}
return bestFrameRate;
}

- (AVCaptureConnection *)createConnection:(NSError **)error {
// Setup video capture input.
_captureVideoInput = [AVCaptureDeviceInput deviceInputWithDevice:_captureDevice error:error];
Expand Down Expand Up @@ -588,18 +593,19 @@ - (AVCaptureDeviceFormat *)highestResolutionFormatForCaptureDevice:
CMFormatDescriptionGetMediaSubType(_captureDevice.activeFormat.formatDescription);
AVCaptureDeviceFormat *bestFormat = nil;
NSUInteger maxPixelCount = 0;
FourCharCode bestSubType = 0;
BOOL isBestSubTypePreferred = NO;
for (AVCaptureDeviceFormat *format in _captureDevice.formats) {
CMVideoDimensions res = self.videoDimensionsForFormat(format);
NSUInteger height = res.height;
NSUInteger width = res.width;
NSUInteger pixelCount = height * width;
FourCharCode subType = CMFormatDescriptionGetMediaSubType(format.formatDescription);
if (pixelCount > maxPixelCount || (pixelCount == maxPixelCount && subType == preferredSubType &&
bestSubType != preferredSubType)) {
BOOL isSubTypePreferred = subType == preferredSubType;
if (pixelCount > maxPixelCount || (pixelCount == maxPixelCount && isSubTypePreferred &&
!isBestSubTypePreferred)) {
bestFormat = format;
maxPixelCount = pixelCount;
bestSubType = subType;
isBestSubTypePreferred = isSubTypePreferred;
}
}
return bestFormat;
Expand Down