• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sdk/objc/api/peerconnection/RTCMediaConstraints.h"
15#import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h"
16#import "sdk/objc/components/video_codec/RTCDefaultVideoEncoderFactory.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#if defined(WEBRTC_IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13
81  Class expectedClass = [RTC_OBJC_TYPE(RTCVideoCodecInfo) class];
82  NSError *error;
83  RTC_OBJC_TYPE(RTCVideoCodecInfo) *videoCodecSetting =
84      [NSKeyedUnarchiver unarchivedObjectOfClass:expectedClass fromData:codecData error:&error];
85  if (!error) {
86    return videoCodecSetting;
87  }
88  return nil;
89#else
90  return [NSKeyedUnarchiver unarchiveObjectWithData:codecData];
91#endif
92}
93
94- (BOOL)storeVideoCodecSetting:(RTC_OBJC_TYPE(RTCVideoCodecInfo) *)videoCodec {
95  if (![[self availableVideoCodecs] containsObject:videoCodec]) {
96    return NO;
97  }
98
99#if defined(WEBRTC_IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13
100  NSError *error;
101  NSData *codecData = [NSKeyedArchiver archivedDataWithRootObject:videoCodec
102                                            requiringSecureCoding:NO
103                                                            error:&error];
104  if (error) {
105    return NO;
106  }
107#else
108  NSData *codecData = [NSKeyedArchiver archivedDataWithRootObject:videoCodec];
109#endif
110
111  [[self settingsStore] setVideoCodec:codecData];
112  return YES;
113}
114
115- (nullable NSNumber *)currentMaxBitrateSettingFromStore {
116  [self registerStoreDefaults];
117  return [[self settingsStore] maxBitrate];
118}
119
120- (void)storeMaxBitrateSetting:(nullable NSNumber *)bitrate {
121  [[self settingsStore] setMaxBitrate:bitrate];
122}
123
124- (BOOL)currentAudioOnlySettingFromStore {
125  return [[self settingsStore] audioOnly];
126}
127
128- (void)storeAudioOnlySetting:(BOOL)audioOnly {
129  [[self settingsStore] setAudioOnly:audioOnly];
130}
131
132- (BOOL)currentCreateAecDumpSettingFromStore {
133  return [[self settingsStore] createAecDump];
134}
135
136- (void)storeCreateAecDumpSetting:(BOOL)createAecDump {
137  [[self settingsStore] setCreateAecDump:createAecDump];
138}
139
140- (BOOL)currentUseManualAudioConfigSettingFromStore {
141  return [[self settingsStore] useManualAudioConfig];
142}
143
144- (void)storeUseManualAudioConfigSetting:(BOOL)useManualAudioConfig {
145  [[self settingsStore] setUseManualAudioConfig:useManualAudioConfig];
146}
147
148#pragma mark - Testable
149
150- (ARDSettingsStore *)settingsStore {
151  if (!_settingsStore) {
152    _settingsStore = [[ARDSettingsStore alloc] init];
153    [self registerStoreDefaults];
154  }
155  return _settingsStore;
156}
157
158- (int)currentVideoResolutionWidthFromStore {
159  NSString *resolution = [self currentVideoResolutionSettingFromStore];
160
161  return [self videoResolutionComponentAtIndex:0 inString:resolution];
162}
163
164- (int)currentVideoResolutionHeightFromStore {
165  NSString *resolution = [self currentVideoResolutionSettingFromStore];
166  return [self videoResolutionComponentAtIndex:1 inString:resolution];
167}
168
169#pragma mark -
170
171- (NSString *)defaultVideoResolutionSetting {
172  return [self availableVideoResolutions].firstObject;
173}
174
175- (RTC_OBJC_TYPE(RTCVideoCodecInfo) *)defaultVideoCodecSetting {
176  return [self availableVideoCodecs].firstObject;
177}
178
179- (int)videoResolutionComponentAtIndex:(int)index inString:(NSString *)resolution {
180  if (index != 0 && index != 1) {
181    return 0;
182  }
183  NSArray<NSString *> *components = [resolution componentsSeparatedByString:@"x"];
184  if (components.count != 2) {
185    return 0;
186  }
187  return components[index].intValue;
188}
189
190- (void)registerStoreDefaults {
191#if defined(WEBRTC_IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13
192  NSError *error;
193  NSData *codecData = [NSKeyedArchiver archivedDataWithRootObject:[self defaultVideoCodecSetting]
194                                            requiringSecureCoding:NO
195                                                            error:&error];
196  if (error) {
197    return;
198  }
199#else
200  NSData *codecData = [NSKeyedArchiver archivedDataWithRootObject:[self defaultVideoCodecSetting]];
201#endif
202
203  [ARDSettingsStore setDefaultsForVideoResolution:[self defaultVideoResolutionSetting]
204                                       videoCodec:codecData
205                                          bitrate:nil
206                                        audioOnly:NO
207                                    createAecDump:NO
208                             useManualAudioConfig:YES];
209}
210@end
211NS_ASSUME_NONNULL_END
212