For the longest time I couldn't figure out why PBJVision was recording 640x480 even though my device (iPhone 5s) supports much higher quality. I was hoping to get 1920x1080. But the issue is that the formats loop below was never executed because videoDevice is nil. I solved this by recalling [self setVideoFrameRate:_videoFrameRate] in _setCurrentDevice:
- (void)setVideoFrameRate:(NSInteger)videoFrameRate
{
if (![self supportsVideoFrameRate:videoFrameRate]) {
DLog(@"frame rate range not supported for current device format");
return;
}
BOOL isRecording = _flags.recording;
if (isRecording) {
[self pauseVideoCapture];
}
CMTime fps = CMTimeMake(1, (int32_t)videoFrameRate);
AVCaptureDevice *videoDevice = _currentDevice;
AVCaptureDeviceFormat *supportingFormat = nil;
int32_t maxWidth = 0;
NSArray *formats = [videoDevice formats];
for (AVCaptureDeviceFormat *format in formats) {
NSArray *videoSupportedFrameRateRanges = format.videoSupportedFrameRateRanges;
for (AVFrameRateRange *range in videoSupportedFrameRateRanges) {
CMFormatDescriptionRef desc = format.formatDescription;
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(desc);
int32_t width = dimensions.width;
if (range.minFrameRate <= videoFrameRate && videoFrameRate <= range.maxFrameRate && width >= maxWidth) {
supportingFormat = format;
maxWidth = width;
}
}
}
if (supportingFormat) {
NSError *error = nil;
[_captureSession beginConfiguration]; // the session to which the receiver's AVCaptureDeviceInput is added.
if ([_currentDevice lockForConfiguration:&error]) {
[_currentDevice setActiveFormat:supportingFormat];
_currentDevice.activeVideoMinFrameDuration = fps;
_currentDevice.activeVideoMaxFrameDuration = fps;
_videoFrameRate = videoFrameRate;
[_currentDevice unlockForConfiguration];
} else if (error) {
DLog(@"error locking device for frame rate change (%@)", error);
}
}
[_captureSession commitConfiguration];
[self _enqueueBlockOnMainQueue:^{
if ([_delegate respondsToSelector:@selector(visionDidChangeVideoFormatAndFrameRate:)])
[_delegate visionDidChangeVideoFormatAndFrameRate:self];
}];
if (isRecording) {
[self resumeVideoCapture];
}
}
For the longest time I couldn't figure out why PBJVision was recording 640x480 even though my device (iPhone 5s) supports much higher quality. I was hoping to get 1920x1080. But the issue is that the formats loop below was never executed because videoDevice is nil. I solved this by recalling
[self setVideoFrameRate:_videoFrameRate]
in_setCurrentDevice: