blob: 25aba8ce6b4054157b18dff01a8268ee221ef3ba [file] [log] [blame]
sakalc522e752017-04-05 12:17:48 -07001/*
2 * Copyright 2017 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import "ARDCaptureController.h"
12
13#import "ARDSettingsModel.h"
Peter Hanspersd92e0b52017-10-23 14:30:25 +020014#import "WebRTC/RTCLogging.h"
sakalc522e752017-04-05 12:17:48 -070015
16@implementation ARDCaptureController {
17 RTCCameraVideoCapturer *_capturer;
18 ARDSettingsModel *_settings;
19 BOOL _usingFrontCamera;
20}
21
22- (instancetype)initWithCapturer:(RTCCameraVideoCapturer *)capturer
23 settings:(ARDSettingsModel *)settings {
24 if ([super init]) {
25 _capturer = capturer;
26 _settings = settings;
27 _usingFrontCamera = YES;
28 }
29
30 return self;
31}
32
33- (void)startCapture {
34 AVCaptureDevicePosition position =
35 _usingFrontCamera ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;
36 AVCaptureDevice *device = [self findDeviceForPosition:position];
37 AVCaptureDeviceFormat *format = [self selectFormatForDevice:device];
Peter Hanspersd92e0b52017-10-23 14:30:25 +020038
39 if (format == nil) {
40 RTCLogError(@"No valid formats for device %@", device);
41 NSAssert(NO, @"");
42
43 return;
44 }
45
sakalea12f4c2017-05-05 00:45:30 -070046 NSInteger fps = [self selectFpsForFormat:format];
sakalc522e752017-04-05 12:17:48 -070047
48 [_capturer startCaptureWithDevice:device format:format fps:fps];
49}
50
51- (void)stopCapture {
52 [_capturer stopCapture];
53}
54
55- (void)switchCamera {
56 _usingFrontCamera = !_usingFrontCamera;
57 [self startCapture];
58}
59
60#pragma mark - Private
61
62- (AVCaptureDevice *)findDeviceForPosition:(AVCaptureDevicePosition)position {
63 NSArray<AVCaptureDevice *> *captureDevices = [RTCCameraVideoCapturer captureDevices];
64 for (AVCaptureDevice *device in captureDevices) {
65 if (device.position == position) {
66 return device;
67 }
68 }
69 return captureDevices[0];
70}
71
72- (AVCaptureDeviceFormat *)selectFormatForDevice:(AVCaptureDevice *)device {
73 NSArray<AVCaptureDeviceFormat *> *formats =
74 [RTCCameraVideoCapturer supportedFormatsForDevice:device];
75 int targetWidth = [_settings currentVideoResolutionWidthFromStore];
76 int targetHeight = [_settings currentVideoResolutionHeightFromStore];
77 AVCaptureDeviceFormat *selectedFormat = nil;
78 int currentDiff = INT_MAX;
79
80 for (AVCaptureDeviceFormat *format in formats) {
81 CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
82 int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height);
83 if (diff < currentDiff) {
84 selectedFormat = format;
85 currentDiff = diff;
86 }
87 }
88
sakalc522e752017-04-05 12:17:48 -070089 return selectedFormat;
90}
91
sakalea12f4c2017-05-05 00:45:30 -070092- (NSInteger)selectFpsForFormat:(AVCaptureDeviceFormat *)format {
sakalc522e752017-04-05 12:17:48 -070093 Float64 maxFramerate = 0;
94 for (AVFrameRateRange *fpsRange in format.videoSupportedFrameRateRanges) {
95 maxFramerate = fmax(maxFramerate, fpsRange.maxFrameRate);
96 }
97 return maxFramerate;
98}
99
100@end