diff --git a/webrtc/sdk/BUILD.gn b/webrtc/sdk/BUILD.gn index 7264d35129..ce7dfc3f47 100644 --- a/webrtc/sdk/BUILD.gn +++ b/webrtc/sdk/BUILD.gn @@ -55,7 +55,9 @@ if (is_ios || (is_mac && mac_deployment_target == "10.7")) { "objc/Framework/Classes/RTCCameraPreviewView.m", "objc/Framework/Classes/RTCUIApplication.h", "objc/Framework/Classes/RTCUIApplication.mm", + "objc/Framework/Classes/UIDevice+RTCDevice.mm", "objc/Framework/Headers/WebRTC/RTCCameraPreviewView.h", + "objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h", ] libs = [ "AVFoundation.framework" ] } diff --git a/webrtc/sdk/objc/Framework/Classes/UIDevice+RTCDevice.mm b/webrtc/sdk/objc/Framework/Classes/UIDevice+RTCDevice.mm new file mode 100644 index 0000000000..523c950645 --- /dev/null +++ b/webrtc/sdk/objc/Framework/Classes/UIDevice+RTCDevice.mm @@ -0,0 +1,168 @@ +/* + * Copyright 2016 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 "WebRTC/UIDevice+RTCDevice.h" + +#include +#include + +@implementation UIDevice (RTCDevice) + ++ (RTCDeviceType)deviceType { + NSDictionary *machineNameToType = @{ + @"iPhone1,1": @(RTCDeviceTypeIPhone1G), + @"iPhone1,2": @(RTCDeviceTypeIPhone3G), + @"iPhone2,1": @(RTCDeviceTypeIPhone3GS), + @"iPhone3,1": @(RTCDeviceTypeIPhone4), + @"iPhone3,3": @(RTCDeviceTypeIPhone4Verizon), + @"iPhone4,1": @(RTCDeviceTypeIPhone4S), + @"iPhone5,1": @(RTCDeviceTypeIPhone5GSM), + @"iPhone5,2": @(RTCDeviceTypeIPhone5GSM_CDMA), + @"iPhone5,3": @(RTCDeviceTypeIPhone5CGSM), + @"iPhone5,4": @(RTCDeviceTypeIPhone5CGSM_CDMA), + @"iPhone6,1": @(RTCDeviceTypeIPhone5SGSM), + @"iPhone6,2": @(RTCDeviceTypeIPhone5SGSM_CDMA), + @"iPhone7,1": @(RTCDeviceTypeIPhone6Plus), + @"iPhone7,2": @(RTCDeviceTypeIPhone6), + @"iPhone8,1": @(RTCDeviceTypeIPhone6S), + @"iPhone8,2": @(RTCDeviceTypeIPhone6SPlus), + @"iPod1,1": @(RTCDeviceTypeIPodTouch1G), + @"iPod2,1": @(RTCDeviceTypeIPodTouch2G), + @"iPod3,1": @(RTCDeviceTypeIPodTouch3G), + @"iPod4,1": @(RTCDeviceTypeIPodTouch4G), + @"iPod5,1": @(RTCDeviceTypeIPodTouch5G), + @"iPad1,1": @(RTCDeviceTypeIPad), + @"iPad2,1": @(RTCDeviceTypeIPad2Wifi), + @"iPad2,2": @(RTCDeviceTypeIPad2GSM), + @"iPad2,3": @(RTCDeviceTypeIPad2CDMA), + @"iPad2,4": @(RTCDeviceTypeIPad2Wifi2), + @"iPad2,5": @(RTCDeviceTypeIPadMiniWifi), + @"iPad2,6": @(RTCDeviceTypeIPadMiniGSM), + @"iPad2,7": @(RTCDeviceTypeIPadMiniGSM_CDMA), + @"iPad3,1": @(RTCDeviceTypeIPad3Wifi), + @"iPad3,2": @(RTCDeviceTypeIPad3GSM_CDMA), + @"iPad3,3": @(RTCDeviceTypeIPad3GSM), + @"iPad3,4": @(RTCDeviceTypeIPad4Wifi), + @"iPad3,5": @(RTCDeviceTypeIPad4GSM), + @"iPad3,6": @(RTCDeviceTypeIPad4GSM_CDMA), + @"iPad4,1": @(RTCDeviceTypeIPadAirWifi), + @"iPad4,2": @(RTCDeviceTypeIPadAirCellular), + @"iPad4,4": @(RTCDeviceTypeIPadMini2GWifi), + @"iPad4,5": @(RTCDeviceTypeIPadMini2GCellular), + @"i386": @(RTCDeviceTypeSimulatori386), + @"x86_64": @(RTCDeviceTypeSimulatorx86_64), + }; + + size_t size = 0; + sysctlbyname("hw.machine", NULL, &size, NULL, 0); + std::unique_ptr machine; + machine.reset(new char[size]); + sysctlbyname("hw.machine", machine.get(), &size, NULL, 0); + NSString *machineName = [[NSString alloc] initWithCString:machine.get() + encoding:NSUTF8StringEncoding]; + RTCDeviceType deviceType = RTCDeviceTypeUnknown; + NSNumber *typeNumber = machineNameToType[machineName]; + if (typeNumber) { + deviceType = static_cast(typeNumber.integerValue); + } + return deviceType; +} + ++ (NSString *)stringForDeviceType:(RTCDeviceType)deviceType { + switch (deviceType) { + case RTCDeviceTypeUnknown: + return @"Unknown"; + case RTCDeviceTypeIPhone1G: + return @"iPhone 1G"; + case RTCDeviceTypeIPhone3G: + return @"iPhone 3G"; + case RTCDeviceTypeIPhone3GS: + return @"iPhone 3GS"; + case RTCDeviceTypeIPhone4: + return @"iPhone 4"; + case RTCDeviceTypeIPhone4Verizon: + return @"iPhone 4 Verizon"; + case RTCDeviceTypeIPhone4S: + return @"iPhone 4S"; + case RTCDeviceTypeIPhone5GSM: + return @"iPhone 5 (GSM)"; + case RTCDeviceTypeIPhone5GSM_CDMA: + return @"iPhone 5 (GSM+CDMA)"; + case RTCDeviceTypeIPhone5CGSM: + return @"iPhone 5C (GSM)"; + case RTCDeviceTypeIPhone5CGSM_CDMA: + return @"iPhone 5C (GSM+CDMA)"; + case RTCDeviceTypeIPhone5SGSM: + return @"iPhone 5S (GSM)"; + case RTCDeviceTypeIPhone5SGSM_CDMA: + return @"iPhone 5S (GSM+CDMA)"; + case RTCDeviceTypeIPhone6Plus: + return @"iPhone 6 Plus"; + case RTCDeviceTypeIPhone6: + return @"iPhone 6"; + case RTCDeviceTypeIPhone6S: + return @"iPhone 6S"; + case RTCDeviceTypeIPhone6SPlus: + return @"iPhone 6S Plus"; + case RTCDeviceTypeIPodTouch1G: + return @"iPod Touch 1G"; + case RTCDeviceTypeIPodTouch2G: + return @"iPod Touch 2G"; + case RTCDeviceTypeIPodTouch3G: + return @"iPod Touch 3G"; + case RTCDeviceTypeIPodTouch4G: + return @"iPod Touch 4G"; + case RTCDeviceTypeIPodTouch5G: + return @"iPod Touch 5G"; + case RTCDeviceTypeIPad: + return @"iPad"; + case RTCDeviceTypeIPad2Wifi: + return @"iPad 2 (WiFi)"; + case RTCDeviceTypeIPad2GSM: + return @"iPad 2 (GSM)"; + case RTCDeviceTypeIPad2CDMA: + return @"iPad 2 (CDMA)"; + case RTCDeviceTypeIPad2Wifi2: + return @"iPad 2 (WiFi) 2"; + case RTCDeviceTypeIPadMiniWifi: + return @"iPad Mini (WiFi)"; + case RTCDeviceTypeIPadMiniGSM: + return @"iPad Mini (GSM)"; + case RTCDeviceTypeIPadMiniGSM_CDMA: + return @"iPad Mini (GSM+CDMA)"; + case RTCDeviceTypeIPad3Wifi: + return @"iPad 3 (WiFi)"; + case RTCDeviceTypeIPad3GSM_CDMA: + return @"iPad 3 (GSM+CDMA)"; + case RTCDeviceTypeIPad3GSM: + return @"iPad 3 (GSM)"; + case RTCDeviceTypeIPad4Wifi: + return @"iPad 4 (WiFi)"; + case RTCDeviceTypeIPad4GSM: + return @"iPad 4 (GSM)"; + case RTCDeviceTypeIPad4GSM_CDMA: + return @"iPad 4 (GSM+CDMA)"; + case RTCDeviceTypeIPadAirWifi: + return @"iPad Air (WiFi)"; + case RTCDeviceTypeIPadAirCellular: + return @"iPad Air (Cellular)"; + case RTCDeviceTypeIPadMini2GWifi: + return @"iPad Mini 2G (Wifi)"; + case RTCDeviceTypeIPadMini2GCellular: + return @"iPad Mini 2G (Cellular)"; + case RTCDeviceTypeSimulatori386: + return @"i386 Simulator"; + case RTCDeviceTypeSimulatorx86_64: + return @"x86_64 Simulator"; + } + return @"Unknown"; +} + +@end diff --git a/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm b/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm index 9b1a7832d2..810bc622ac 100644 --- a/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm +++ b/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm @@ -18,6 +18,9 @@ #import "RTCDispatcher+Private.h" #import "WebRTC/RTCLogging.h" +#if TARGET_OS_IPHONE +#import "WebRTC/UIDevice+RTCDevice.h" +#endif #include "webrtc/base/bind.h" #include "webrtc/base/checks.h" @@ -31,6 +34,12 @@ static cricket::VideoFormat const kDefaultFormat = 480, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_NV12); +// iPhone4S is too slow to handle 30fps. +static cricket::VideoFormat const kIPhone4SFormat = + cricket::VideoFormat(640, + 480, + cricket::VideoFormat::FpsToInterval(15), + cricket::FOURCC_NV12); // This class used to capture frames using AVFoundation APIs on iOS. It is meant // to be owned by an instance of AVFoundationVideoCapturer. The reason for this @@ -383,6 +392,11 @@ static cricket::VideoFormat const kDefaultFormat = AVCaptureDeviceInput *input = self.useBackCamera ? backCameraInput : frontCameraInput; [captureSession addInput:input]; +#if TARGET_OS_IPHONE + if ([UIDevice deviceType] == RTCDeviceTypeIPhone4S) { + [self setMinFrameDuration:CMTimeMake(1, 15) forDevice:input.device]; + } +#endif _captureSession = captureSession; return YES; } @@ -465,6 +479,17 @@ static cricket::VideoFormat const kDefaultFormat = return _backCameraInput; } +- (void)setMinFrameDuration:(CMTime)minFrameDuration + forDevice:(AVCaptureDevice *)device { + NSError *error = nil; + if (![device lockForConfiguration:&error]) { + RTCLogError(@"Failed to lock device for configuration. Error: %@", error.localizedDescription); + return; + } + device.activeVideoMinFrameDuration = minFrameDuration; + [device unlockForConfiguration]; +} + // Called from capture session queue. - (void)updateOrientation { AVCaptureConnection *connection = @@ -520,6 +545,11 @@ static cricket::VideoFormat const kDefaultFormat = } [self updateOrientation]; [_captureSession commitConfiguration]; +#if TARGET_OS_IPHONE + if ([UIDevice deviceType] == RTCDeviceTypeIPhone4S) { + [self setMinFrameDuration:CMTimeMake(1, 15) forDevice:newInput.device]; + } +#endif }]; } @@ -541,9 +571,17 @@ struct AVFoundationFrame { AVFoundationVideoCapturer::AVFoundationVideoCapturer() : _capturer(nil), _startThread(nullptr) { // Set our supported formats. This matches kDefaultPreset. - std::vector supportedFormats; - supportedFormats.push_back(cricket::VideoFormat(kDefaultFormat)); - SetSupportedFormats(supportedFormats); + std::vector supported_formats; +#if TARGET_OS_IPHONE + if ([UIDevice deviceType] == RTCDeviceTypeIPhone4S) { + supported_formats.push_back(cricket::VideoFormat(kIPhone4SFormat)); + } else { + supported_formats.push_back(cricket::VideoFormat(kDefaultFormat)); + } +#else + supported_formats.push_back(cricket::VideoFormat(kDefaultFormat)); +#endif + SetSupportedFormats(supported_formats); _capturer = [[RTCAVFoundationVideoCapturerInternal alloc] initWithCapturer:this]; } @@ -562,7 +600,7 @@ cricket::CaptureState AVFoundationVideoCapturer::Start( LOG(LS_ERROR) << "The capturer is already running."; return cricket::CaptureState::CS_FAILED; } - if (format != kDefaultFormat) { + if (format != kDefaultFormat && format != kIPhone4SFormat) { LOG(LS_ERROR) << "Unsupported format provided."; return cricket::CaptureState::CS_FAILED; } diff --git a/webrtc/sdk/objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h b/webrtc/sdk/objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h new file mode 100644 index 0000000000..d38a3cb2db --- /dev/null +++ b/webrtc/sdk/objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h @@ -0,0 +1,63 @@ +/* + * Copyright 2016 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 + +typedef NS_ENUM(NSInteger, RTCDeviceType) { + RTCDeviceTypeUnknown, + RTCDeviceTypeIPhone1G, + RTCDeviceTypeIPhone3G, + RTCDeviceTypeIPhone3GS, + RTCDeviceTypeIPhone4, + RTCDeviceTypeIPhone4Verizon, + RTCDeviceTypeIPhone4S, + RTCDeviceTypeIPhone5GSM, + RTCDeviceTypeIPhone5GSM_CDMA, + RTCDeviceTypeIPhone5CGSM, + RTCDeviceTypeIPhone5CGSM_CDMA, + RTCDeviceTypeIPhone5SGSM, + RTCDeviceTypeIPhone5SGSM_CDMA, + RTCDeviceTypeIPhone6Plus, + RTCDeviceTypeIPhone6, + RTCDeviceTypeIPhone6S, + RTCDeviceTypeIPhone6SPlus, + RTCDeviceTypeIPodTouch1G, + RTCDeviceTypeIPodTouch2G, + RTCDeviceTypeIPodTouch3G, + RTCDeviceTypeIPodTouch4G, + RTCDeviceTypeIPodTouch5G, + RTCDeviceTypeIPad, + RTCDeviceTypeIPad2Wifi, + RTCDeviceTypeIPad2GSM, + RTCDeviceTypeIPad2CDMA, + RTCDeviceTypeIPad2Wifi2, + RTCDeviceTypeIPadMiniWifi, + RTCDeviceTypeIPadMiniGSM, + RTCDeviceTypeIPadMiniGSM_CDMA, + RTCDeviceTypeIPad3Wifi, + RTCDeviceTypeIPad3GSM_CDMA, + RTCDeviceTypeIPad3GSM, + RTCDeviceTypeIPad4Wifi, + RTCDeviceTypeIPad4GSM, + RTCDeviceTypeIPad4GSM_CDMA, + RTCDeviceTypeIPadAirWifi, + RTCDeviceTypeIPadAirCellular, + RTCDeviceTypeIPadMini2GWifi, + RTCDeviceTypeIPadMini2GCellular, + RTCDeviceTypeSimulatori386, + RTCDeviceTypeSimulatorx86_64, +}; + +@interface UIDevice (RTCDevice) + ++ (RTCDeviceType)deviceType; ++ (NSString *)stringForDeviceType:(RTCDeviceType)deviceType; + +@end diff --git a/webrtc/sdk/objc/Framework/Headers/WebRTC/WebRTC.h b/webrtc/sdk/objc/Framework/Headers/WebRTC/WebRTC.h index ad23236cfc..27f6152931 100644 --- a/webrtc/sdk/objc/Framework/Headers/WebRTC/WebRTC.h +++ b/webrtc/sdk/objc/Framework/Headers/WebRTC/WebRTC.h @@ -42,3 +42,4 @@ #import #import #import +#import diff --git a/webrtc/sdk/sdk.gyp b/webrtc/sdk/sdk.gyp index 26142e5312..6f46674bee 100644 --- a/webrtc/sdk/sdk.gyp +++ b/webrtc/sdk/sdk.gyp @@ -57,7 +57,9 @@ 'objc/Framework/Classes/RTCCameraPreviewView.m', 'objc/Framework/Classes/RTCUIApplication.h', 'objc/Framework/Classes/RTCUIApplication.mm', + 'objc/Framework/Classes/UIDevice+RTCDevice.mm', 'objc/Framework/Headers/WebRTC/RTCCameraPreviewView.h', + 'objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h', ], 'link_settings': { 'xcode_settings': { @@ -273,6 +275,7 @@ 'objc/Framework/Headers/WebRTC/RTCVideoRenderer.h', 'objc/Framework/Headers/WebRTC/RTCVideoSource.h', 'objc/Framework/Headers/WebRTC/RTCVideoTrack.h', + 'objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h', 'objc/Framework/Headers/WebRTC/WebRTC.h', ], 'dependencies': [