diff options
Diffstat (limited to 'third_party/libwebrtc/examples/objc/AppRTCMobile/ARDCaptureController.m')
-rw-r--r-- | third_party/libwebrtc/examples/objc/AppRTCMobile/ARDCaptureController.m | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/third_party/libwebrtc/examples/objc/AppRTCMobile/ARDCaptureController.m b/third_party/libwebrtc/examples/objc/AppRTCMobile/ARDCaptureController.m new file mode 100644 index 0000000000..26cce9fdaa --- /dev/null +++ b/third_party/libwebrtc/examples/objc/AppRTCMobile/ARDCaptureController.m @@ -0,0 +1,116 @@ +/* + * Copyright 2017 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#import "ARDCaptureController.h" + +#import "sdk/objc/base/RTCLogging.h" + +#import "ARDSettingsModel.h" + +const Float64 kFramerateLimit = 30.0; + +@implementation ARDCaptureController { + RTC_OBJC_TYPE(RTCCameraVideoCapturer) * _capturer; + ARDSettingsModel *_settings; + BOOL _usingFrontCamera; +} + +- (instancetype)initWithCapturer:(RTC_OBJC_TYPE(RTCCameraVideoCapturer) *)capturer + settings:(ARDSettingsModel *)settings { + if (self = [super init]) { + _capturer = capturer; + _settings = settings; + _usingFrontCamera = YES; + } + + return self; +} + +- (void)startCapture { + [self startCapture:nil]; +} + +- (void)startCapture:(void (^)(NSError *))completion { + AVCaptureDevicePosition position = + _usingFrontCamera ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack; + AVCaptureDevice *device = [self findDeviceForPosition:position]; + AVCaptureDeviceFormat *format = [self selectFormatForDevice:device]; + + if (format == nil) { + RTCLogError(@"No valid formats for device %@", device); + NSAssert(NO, @""); + + return; + } + + NSInteger fps = [self selectFpsForFormat:format]; + + [_capturer startCaptureWithDevice:device format:format fps:fps completionHandler:completion]; +} + +- (void)stopCapture { + [_capturer stopCapture]; +} + +- (void)switchCamera { + _usingFrontCamera = !_usingFrontCamera; + [self startCapture:nil]; +} + +- (void)switchCamera:(void (^)(NSError *))completion { + _usingFrontCamera = !_usingFrontCamera; + [self startCapture:completion]; +} + +#pragma mark - Private + +- (AVCaptureDevice *)findDeviceForPosition:(AVCaptureDevicePosition)position { + NSArray<AVCaptureDevice *> *captureDevices = + [RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices]; + for (AVCaptureDevice *device in captureDevices) { + if (device.position == position) { + return device; + } + } + return captureDevices[0]; +} + +- (AVCaptureDeviceFormat *)selectFormatForDevice:(AVCaptureDevice *)device { + NSArray<AVCaptureDeviceFormat *> *formats = + [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:device]; + int targetWidth = [_settings currentVideoResolutionWidthFromStore]; + int targetHeight = [_settings currentVideoResolutionHeightFromStore]; + AVCaptureDeviceFormat *selectedFormat = nil; + int currentDiff = INT_MAX; + + for (AVCaptureDeviceFormat *format in formats) { + CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription); + FourCharCode pixelFormat = CMFormatDescriptionGetMediaSubType(format.formatDescription); + int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height); + if (diff < currentDiff) { + selectedFormat = format; + currentDiff = diff; + } else if (diff == currentDiff && pixelFormat == [_capturer preferredOutputPixelFormat]) { + selectedFormat = format; + } + } + + return selectedFormat; +} + +- (NSInteger)selectFpsForFormat:(AVCaptureDeviceFormat *)format { + Float64 maxSupportedFramerate = 0; + for (AVFrameRateRange *fpsRange in format.videoSupportedFrameRateRanges) { + maxSupportedFramerate = fmax(maxSupportedFramerate, fpsRange.maxFrameRate); + } + return fmin(maxSupportedFramerate, kFramerateLimit); +} + +@end |