Init max supported H.264 profile at runtime on iOS
Bug: webrtc:9134, webrtc:7992
Change-Id: Id24c570bf3296298901f61ee817a3d7c3f8c6347
Reviewed-on: https://webrtc-review.googlesource.com/71560
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23034}
diff --git a/sdk/objc/Framework/Classes/Common/UIDevice+RTCDevice.mm b/sdk/objc/Framework/Classes/Common/UIDevice+RTCDevice.mm
index b2cfb20..997666d 100644
--- a/sdk/objc/Framework/Classes/Common/UIDevice+RTCDevice.mm
+++ b/sdk/objc/Framework/Classes/Common/UIDevice+RTCDevice.mm
@@ -21,6 +21,7 @@
@"iPhone1,2": @(RTCDeviceTypeIPhone3G),
@"iPhone2,1": @(RTCDeviceTypeIPhone3GS),
@"iPhone3,1": @(RTCDeviceTypeIPhone4),
+ @"iPhone3,2": @(RTCDeviceTypeIPhone4),
@"iPhone3,3": @(RTCDeviceTypeIPhone4Verizon),
@"iPhone4,1": @(RTCDeviceTypeIPhone4S),
@"iPhone5,1": @(RTCDeviceTypeIPhone5GSM),
@@ -33,6 +34,7 @@
@"iPhone7,2": @(RTCDeviceTypeIPhone6),
@"iPhone8,1": @(RTCDeviceTypeIPhone6S),
@"iPhone8,2": @(RTCDeviceTypeIPhone6SPlus),
+ @"iPhone8,4": @(RTCDeviceTypeIPhoneSE),
@"iPhone9,1": @(RTCDeviceTypeIPhone7),
@"iPhone9,2": @(RTCDeviceTypeIPhone7Plus),
@"iPhone9,3": @(RTCDeviceTypeIPhone7),
@@ -48,6 +50,7 @@
@"iPod3,1": @(RTCDeviceTypeIPodTouch3G),
@"iPod4,1": @(RTCDeviceTypeIPodTouch4G),
@"iPod5,1": @(RTCDeviceTypeIPodTouch5G),
+ @"iPod7,1": @(RTCDeviceTypeIPodTouch6G),
@"iPad1,1": @(RTCDeviceTypeIPad),
@"iPad2,1": @(RTCDeviceTypeIPad2Wifi),
@"iPad2,2": @(RTCDeviceTypeIPad2GSM),
@@ -64,8 +67,29 @@
@"iPad3,6": @(RTCDeviceTypeIPad4GSM_CDMA),
@"iPad4,1": @(RTCDeviceTypeIPadAirWifi),
@"iPad4,2": @(RTCDeviceTypeIPadAirCellular),
+ @"iPad4,3": @(RTCDeviceTypeIPadAirWifiCellular),
@"iPad4,4": @(RTCDeviceTypeIPadMini2GWifi),
@"iPad4,5": @(RTCDeviceTypeIPadMini2GCellular),
+ @"iPad4,6": @(RTCDeviceTypeIPadMini2GWifiCellular),
+ @"iPad4,7": @(RTCDeviceTypeIPadMini3),
+ @"iPad4,8": @(RTCDeviceTypeIPadMini3),
+ @"iPad4,9": @(RTCDeviceTypeIPadMini3),
+ @"iPad5,1": @(RTCDeviceTypeIPadMini4),
+ @"iPad5,2": @(RTCDeviceTypeIPadMini4),
+ @"iPad5,3": @(RTCDeviceTypeIPadAir2),
+ @"iPad5,4": @(RTCDeviceTypeIPadAir2),
+ @"iPad6,3": @(RTCDeviceTypeIPadPro9Inch),
+ @"iPad6,4": @(RTCDeviceTypeIPadPro9Inch),
+ @"iPad6,7": @(RTCDeviceTypeIPadPro12Inch),
+ @"iPad6,8": @(RTCDeviceTypeIPadPro12Inch),
+ @"iPad6,11": @(RTCDeviceTypeIPad5),
+ @"iPad6,12": @(RTCDeviceTypeIPad5),
+ @"iPad7,1": @(RTCDeviceTypeIPadPro12Inch2),
+ @"iPad7,2": @(RTCDeviceTypeIPadPro12Inch2),
+ @"iPad7,3": @(RTCDeviceTypeIPadPro10Inch),
+ @"iPad7,4": @(RTCDeviceTypeIPadPro10Inch),
+ @"iPad7,5": @(RTCDeviceTypeIPad6),
+ @"iPad7,6": @(RTCDeviceTypeIPad6),
@"i386": @(RTCDeviceTypeSimulatori386),
@"x86_64": @(RTCDeviceTypeSimulatorx86_64),
};
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCDefaultVideoEncoderFactory.m b/sdk/objc/Framework/Classes/PeerConnection/RTCDefaultVideoEncoderFactory.m
index 8de3071..60a0b5f 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCDefaultVideoEncoderFactory.m
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCDefaultVideoEncoderFactory.m
@@ -25,7 +25,7 @@
+ (NSArray<RTCVideoCodecInfo *> *)supportedCodecs {
NSDictionary<NSString *, NSString *> *constrainedHighParams = @{
- @"profile-level-id" : kRTCLevel31ConstrainedHigh,
+ @"profile-level-id" : kRTCMaxSupportedH264ProfileLevelConstrainedHigh,
@"level-asymmetry-allowed" : @"1",
@"packetization-mode" : @"1",
};
@@ -34,7 +34,7 @@
parameters:constrainedHighParams];
NSDictionary<NSString *, NSString *> *constrainedBaselineParams = @{
- @"profile-level-id" : kRTCLevel31ConstrainedBaseline,
+ @"profile-level-id" : kRTCMaxSupportedH264ProfileLevelConstrainedBaseline,
@"level-asymmetry-allowed" : @"1",
@"packetization-mode" : @"1",
};
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm
index 4a5d450..fc2c1ce 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm
@@ -12,15 +12,70 @@
#import "NSString+StdString.h"
#import "RTCVideoCodec+Private.h"
+#if defined(WEBRTC_IOS)
+#import "UIDevice+H264Profile.h"
+#endif
#import "WebRTC/RTCVideoCodecFactory.h"
#include "media/base/mediaconstants.h"
+namespace {
+
+NSString *MaxSupportedProfileLevelConstrainedHigh();
+NSString *MaxSupportedProfileLevelConstrainedBaseline();
+
+} // namespace
+
NSString *const kRTCVideoCodecVp8Name = @(cricket::kVp8CodecName);
NSString *const kRTCVideoCodecVp9Name = @(cricket::kVp9CodecName);
NSString *const kRTCVideoCodecH264Name = @(cricket::kH264CodecName);
NSString *const kRTCLevel31ConstrainedHigh = @"640c1f";
NSString *const kRTCLevel31ConstrainedBaseline = @"42e01f";
+NSString *const kRTCMaxSupportedH264ProfileLevelConstrainedHigh =
+ MaxSupportedProfileLevelConstrainedHigh();
+NSString *const kRTCMaxSupportedH264ProfileLevelConstrainedBaseline =
+ MaxSupportedProfileLevelConstrainedBaseline();
+
+namespace {
+
+#if defined(WEBRTC_IOS)
+
+using namespace webrtc::H264;
+
+NSString *MaxSupportedLevelForProfile(Profile profile) {
+ const rtc::Optional<ProfileLevelId> profileLevelId = [UIDevice maxSupportedH264Profile];
+ if (profileLevelId && profileLevelId->profile >= profile) {
+ const rtc::Optional<std::string> profileString =
+ ProfileLevelIdToString(ProfileLevelId(profile, profileLevelId->level));
+ if (profileString) {
+ return [NSString stringForStdString:*profileString];
+ }
+ }
+ return nil;
+}
+#endif
+
+NSString *MaxSupportedProfileLevelConstrainedBaseline() {
+#if defined(WEBRTC_IOS)
+ NSString *profile = MaxSupportedLevelForProfile(webrtc::H264::kProfileConstrainedBaseline);
+ if (profile != nil) {
+ return profile;
+ }
+#endif
+ return kRTCLevel31ConstrainedBaseline;
+}
+
+NSString *MaxSupportedProfileLevelConstrainedHigh() {
+#if defined(WEBRTC_IOS)
+ NSString *profile = MaxSupportedLevelForProfile(webrtc::H264::kProfileConstrainedHigh);
+ if (profile != nil) {
+ return profile;
+ }
+#endif
+ return kRTCLevel31ConstrainedHigh;
+}
+
+} // namespace
@implementation RTCVideoCodecInfo
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm
index 402e09f..5477791 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm
@@ -50,7 +50,7 @@
if (IsHighProfileEnabled()) {
NSDictionary<NSString *, NSString *> *constrainedHighParams = @{
- @"profile-level-id" : kRTCLevel31ConstrainedHigh,
+ @"profile-level-id" : kRTCMaxSupportedH264ProfileLevelConstrainedHigh,
@"level-asymmetry-allowed" : @"1",
@"packetization-mode" : @"1",
};
@@ -60,7 +60,7 @@
}
NSDictionary<NSString *, NSString *> *constrainedBaselineParams = @{
- @"profile-level-id" : kRTCLevel31ConstrainedBaseline,
+ @"profile-level-id" : kRTCMaxSupportedH264ProfileLevelConstrainedBaseline,
@"level-asymmetry-allowed" : @"1",
@"packetization-mode" : @"1",
};
diff --git a/sdk/objc/Framework/Classes/Video/UIDevice+H264Profile.h b/sdk/objc/Framework/Classes/Video/UIDevice+H264Profile.h
new file mode 100644
index 0000000..03ea780
--- /dev/null
+++ b/sdk/objc/Framework/Classes/Video/UIDevice+H264Profile.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2018 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 <UIKit/UIKit.h>
+
+#include "media/base/h264_profile_level_id.h"
+
+@interface UIDevice (H264Profile)
+
++ (rtc::Optional<webrtc::H264::ProfileLevelId>)maxSupportedH264Profile;
+
+@end
diff --git a/sdk/objc/Framework/Classes/Video/UIDevice+H264Profile.mm b/sdk/objc/Framework/Classes/Video/UIDevice+H264Profile.mm
new file mode 100644
index 0000000..41123a5
--- /dev/null
+++ b/sdk/objc/Framework/Classes/Video/UIDevice+H264Profile.mm
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2018 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 "UIDevice+H264Profile.h"
+#import "WebRTC/UIDevice+RTCDevice.h"
+
+#include <algorithm>
+
+namespace {
+
+using namespace webrtc::H264;
+
+struct SupportedH264Profile {
+ const RTCDeviceType deviceType;
+ const ProfileLevelId profile;
+};
+
+const SupportedH264Profile kH264MaxSupportedProfiles[] = {
+ // iPhones with at least iOS 9
+ {RTCDeviceTypeIPhoneX, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP770
+ {RTCDeviceTypeIPhone8, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP767
+ {RTCDeviceTypeIPhone8Plus, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP768
+ {RTCDeviceTypeIPhone7, {kProfileHigh, kLevel5_1}}, // https://support.apple.com/kb/SP743
+ {RTCDeviceTypeIPhone7Plus, {kProfileHigh, kLevel5_1}}, // https://support.apple.com/kb/SP744
+ {RTCDeviceTypeIPhoneSE, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP738
+ {RTCDeviceTypeIPhone6S, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP726
+ {RTCDeviceTypeIPhone6SPlus, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP727
+ {RTCDeviceTypeIPhone6, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP705
+ {RTCDeviceTypeIPhone6Plus, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP706
+ {RTCDeviceTypeIPhone5SGSM, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP685
+ {RTCDeviceTypeIPhone5SGSM_CDMA,
+ {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP685
+ {RTCDeviceTypeIPhone5GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP655
+ {RTCDeviceTypeIPhone5GSM_CDMA,
+ {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP655
+ {RTCDeviceTypeIPhone5CGSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP684
+ {RTCDeviceTypeIPhone5CGSM_CDMA,
+ {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP684
+ {RTCDeviceTypeIPhone4S, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP643
+
+ // iPods with at least iOS 9
+ {RTCDeviceTypeIPodTouch6G, {kProfileMain, kLevel4_1}}, // https://support.apple.com/kb/SP720
+ {RTCDeviceTypeIPodTouch5G, {kProfileMain, kLevel3_1}}, // https://support.apple.com/kb/SP657
+
+ // iPads with at least iOS 9
+ {RTCDeviceTypeIPad2Wifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPad2GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPad2CDMA, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPad2Wifi2, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPadMiniWifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP661
+ {RTCDeviceTypeIPadMiniGSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP661
+ {RTCDeviceTypeIPadMiniGSM_CDMA,
+ {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP661
+ {RTCDeviceTypeIPad3Wifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP647
+ {RTCDeviceTypeIPad3GSM_CDMA, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP647
+ {RTCDeviceTypeIPad3GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP647
+ {RTCDeviceTypeIPad4Wifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP662
+ {RTCDeviceTypeIPad4GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP662
+ {RTCDeviceTypeIPad4GSM_CDMA, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP662
+ {RTCDeviceTypeIPad5, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP751
+ {RTCDeviceTypeIPad6, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP774
+ {RTCDeviceTypeIPadAirWifi, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP692
+ {RTCDeviceTypeIPadAirCellular,
+ {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP692
+ {RTCDeviceTypeIPadAirWifiCellular,
+ {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP692
+ {RTCDeviceTypeIPadAir2, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP708
+ {RTCDeviceTypeIPadMini2GWifi, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP693
+ {RTCDeviceTypeIPadMini2GCellular,
+ {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP693
+ {RTCDeviceTypeIPadMini2GWifiCellular,
+ {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP693
+ {RTCDeviceTypeIPadMini3, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP709
+ {RTCDeviceTypeIPadMini4, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP725
+ {RTCDeviceTypeIPadPro9Inch, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP739
+ {RTCDeviceTypeIPadPro12Inch, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/sp723
+ {RTCDeviceTypeIPadPro12Inch2, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP761
+ {RTCDeviceTypeIPadPro10Inch, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP762
+};
+
+rtc::Optional<ProfileLevelId> FindMaxSupportedProfileForDevice(RTCDeviceType deviceType) {
+ const auto* result = std::find_if(std::begin(kH264MaxSupportedProfiles),
+ std::end(kH264MaxSupportedProfiles),
+ [deviceType](const SupportedH264Profile& supportedProfile) {
+ return supportedProfile.deviceType == deviceType;
+ });
+ if (result != std::end(kH264MaxSupportedProfiles)) {
+ return result->profile;
+ }
+ return rtc::nullopt;
+}
+
+} // namespace
+
+@implementation UIDevice (H264Profile)
+
++ (rtc::Optional<webrtc::H264::ProfileLevelId>)maxSupportedH264Profile {
+ return FindMaxSupportedProfileForDevice([self deviceType]);
+}
+
+@end