1/* 2 * Copyright 2016 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 "ARDSettingsModel+Private.h" 12#import "ARDSettingsStore.h" 13 14#import <WebRTC/RTCCameraVideoCapturer.h> 15#import <WebRTC/RTCDefaultVideoEncoderFactory.h> 16#import <WebRTC/RTCMediaConstraints.h> 17 18NS_ASSUME_NONNULL_BEGIN 19 20@interface ARDSettingsModel () { 21 ARDSettingsStore *_settingsStore; 22} 23@end 24 25@implementation ARDSettingsModel 26 27- (NSArray<NSString *> *)availableVideoResolutions { 28 NSMutableSet<NSArray<NSNumber *> *> *resolutions = 29 [[NSMutableSet<NSArray<NSNumber *> *> alloc] init]; 30 for (AVCaptureDevice *device in [RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices]) { 31 for (AVCaptureDeviceFormat *format in 32 [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:device]) { 33 CMVideoDimensions resolution = 34 CMVideoFormatDescriptionGetDimensions(format.formatDescription); 35 NSArray<NSNumber *> *resolutionObject = @[ @(resolution.width), @(resolution.height) ]; 36 [resolutions addObject:resolutionObject]; 37 } 38 } 39 40 NSArray<NSArray<NSNumber *> *> *sortedResolutions = 41 [[resolutions allObjects] sortedArrayUsingComparator:^NSComparisonResult( 42 NSArray<NSNumber *> *obj1, NSArray<NSNumber *> *obj2) { 43 NSComparisonResult cmp = [obj1.firstObject compare:obj2.firstObject]; 44 if (cmp != NSOrderedSame) { 45 return cmp; 46 } 47 return [obj1.lastObject compare:obj2.lastObject]; 48 }]; 49 50 NSMutableArray<NSString *> *resolutionStrings = [[NSMutableArray<NSString *> alloc] init]; 51 for (NSArray<NSNumber *> *resolution in sortedResolutions) { 52 NSString *resolutionString = 53 [NSString stringWithFormat:@"%@x%@", resolution.firstObject, resolution.lastObject]; 54 [resolutionStrings addObject:resolutionString]; 55 } 56 57 return [resolutionStrings copy]; 58} 59 60- (NSString *)currentVideoResolutionSettingFromStore { 61 [self registerStoreDefaults]; 62 return [[self settingsStore] videoResolution]; 63} 64 65- (BOOL)storeVideoResolutionSetting:(NSString *)resolution { 66 if (![[self availableVideoResolutions] containsObject:resolution]) { 67 return NO; 68 } 69 [[self settingsStore] setVideoResolution:resolution]; 70 return YES; 71} 72 73- (NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *)availableVideoCodecs { 74 return [RTC_OBJC_TYPE(RTCDefaultVideoEncoderFactory) supportedCodecs]; 75} 76 77- (RTC_OBJC_TYPE(RTCVideoCodecInfo) *)currentVideoCodecSettingFromStore { 78 [self registerStoreDefaults]; 79 NSData *codecData = [[self settingsStore] videoCodec]; 80 return [NSKeyedUnarchiver unarchiveObjectWithData:codecData]; 81} 82 83- (BOOL)storeVideoCodecSetting:(RTC_OBJC_TYPE(RTCVideoCodecInfo) *)videoCodec { 84 if (![[self availableVideoCodecs] containsObject:videoCodec]) { 85 return NO; 86 } 87 NSData *codecData = [NSKeyedArchiver archivedDataWithRootObject:videoCodec]; 88 [[self settingsStore] setVideoCodec:codecData]; 89 return YES; 90} 91 92- (nullable NSNumber *)currentMaxBitrateSettingFromStore { 93 [self registerStoreDefaults]; 94 return [[self settingsStore] maxBitrate]; 95} 96 97- (void)storeMaxBitrateSetting:(nullable NSNumber *)bitrate { 98 [[self settingsStore] setMaxBitrate:bitrate]; 99} 100 101- (BOOL)currentAudioOnlySettingFromStore { 102 return [[self settingsStore] audioOnly]; 103} 104 105- (void)storeAudioOnlySetting:(BOOL)audioOnly { 106 [[self settingsStore] setAudioOnly:audioOnly]; 107} 108 109- (BOOL)currentCreateAecDumpSettingFromStore { 110 return [[self settingsStore] createAecDump]; 111} 112 113- (void)storeCreateAecDumpSetting:(BOOL)createAecDump { 114 [[self settingsStore] setCreateAecDump:createAecDump]; 115} 116 117- (BOOL)currentUseManualAudioConfigSettingFromStore { 118 return [[self settingsStore] useManualAudioConfig]; 119} 120 121- (void)storeUseManualAudioConfigSetting:(BOOL)useManualAudioConfig { 122 [[self settingsStore] setUseManualAudioConfig:useManualAudioConfig]; 123} 124 125#pragma mark - Testable 126 127- (ARDSettingsStore *)settingsStore { 128 if (!_settingsStore) { 129 _settingsStore = [[ARDSettingsStore alloc] init]; 130 [self registerStoreDefaults]; 131 } 132 return _settingsStore; 133} 134 135- (int)currentVideoResolutionWidthFromStore { 136 NSString *resolution = [self currentVideoResolutionSettingFromStore]; 137 138 return [self videoResolutionComponentAtIndex:0 inString:resolution]; 139} 140 141- (int)currentVideoResolutionHeightFromStore { 142 NSString *resolution = [self currentVideoResolutionSettingFromStore]; 143 return [self videoResolutionComponentAtIndex:1 inString:resolution]; 144} 145 146#pragma mark - 147 148- (NSString *)defaultVideoResolutionSetting { 149 return [self availableVideoResolutions].firstObject; 150} 151 152- (RTC_OBJC_TYPE(RTCVideoCodecInfo) *)defaultVideoCodecSetting { 153 return [self availableVideoCodecs].firstObject; 154} 155 156- (int)videoResolutionComponentAtIndex:(int)index inString:(NSString *)resolution { 157 if (index != 0 && index != 1) { 158 return 0; 159 } 160 NSArray<NSString *> *components = [resolution componentsSeparatedByString:@"x"]; 161 if (components.count != 2) { 162 return 0; 163 } 164 return components[index].intValue; 165} 166 167- (void)registerStoreDefaults { 168 NSData *codecData = [NSKeyedArchiver archivedDataWithRootObject:[self defaultVideoCodecSetting]]; 169 [ARDSettingsStore setDefaultsForVideoResolution:[self defaultVideoResolutionSetting] 170 videoCodec:codecData 171 bitrate:nil 172 audioOnly:NO 173 createAecDump:NO 174 useManualAudioConfig:YES]; 175} 176 177@end 178NS_ASSUME_NONNULL_END 179