ARDCaptureController.m 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  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. #import "ARDCaptureController.h"
  11. #import "ARDSettingsModel.h"
  12. const Float64 kFramerateLimit = 30.0;
  13. @implementation ARDCaptureController {
  14. RTCCameraVideoCapturer *_capturer;
  15. ARDSettingsModel *_settings;
  16. BOOL _usingFrontCamera;
  17. }
  18. - (instancetype)initWithCapturer:(RTCCameraVideoCapturer *)capturer
  19. settings:(ARDSettingsModel *)settings {
  20. if ([super init]) {
  21. _capturer = capturer;
  22. _settings = settings;
  23. _usingFrontCamera = YES;
  24. }
  25. return self;
  26. }
  27. - (void)startCapture {
  28. AVCaptureDevicePosition position =
  29. _usingFrontCamera ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;
  30. AVCaptureDevice *device = [self findDeviceForPosition:position];
  31. AVCaptureDeviceFormat *format = [self selectFormatForDevice:device];
  32. NSInteger fps = [self selectFpsForFormat:format];
  33. [_capturer startCaptureWithDevice:device format:format fps:fps];
  34. }
  35. - (void)stopCapture {
  36. [_capturer stopCapture];
  37. }
  38. - (void)switchCamera {
  39. _usingFrontCamera = !_usingFrontCamera;
  40. [self startCapture];
  41. }
  42. #pragma mark - Private
  43. - (AVCaptureDevice *)findDeviceForPosition:(AVCaptureDevicePosition)position {
  44. NSArray<AVCaptureDevice *> *captureDevices = [RTCCameraVideoCapturer captureDevices];
  45. for (AVCaptureDevice *device in captureDevices) {
  46. if (device.position == position) {
  47. return device;
  48. }
  49. }
  50. return captureDevices[0];
  51. }
  52. - (AVCaptureDeviceFormat *)selectFormatForDevice:(AVCaptureDevice *)device {
  53. NSArray<AVCaptureDeviceFormat *> *formats =
  54. [RTCCameraVideoCapturer supportedFormatsForDevice:device];
  55. int targetWidth = [_settings currentVideoResolutionWidthFromStore];
  56. int targetHeight = [_settings currentVideoResolutionHeightFromStore];
  57. AVCaptureDeviceFormat *selectedFormat = nil;
  58. int currentDiff = INT_MAX;
  59. for (AVCaptureDeviceFormat *format in formats) {
  60. CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
  61. int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height);
  62. if (diff < currentDiff) {
  63. selectedFormat = format;
  64. currentDiff = diff;
  65. }
  66. }
  67. NSAssert(selectedFormat != nil, @"No suitable capture format found.");
  68. return selectedFormat;
  69. }
  70. - (NSInteger)selectFpsForFormat:(AVCaptureDeviceFormat *)format {
  71. Float64 maxFramerate = 0;
  72. for (AVFrameRateRange *fpsRange in format.videoSupportedFrameRateRanges) {
  73. maxFramerate = fmax(maxFramerate, fpsRange.maxFrameRate);
  74. }
  75. return fmin(maxFramerate, kFramerateLimit);
  76. }
  77. @end