1/*
2 *  Copyright 2018 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 "UIDevice+H264Profile.h"
12#import "helpers/UIDevice+RTCDevice.h"
13
14#include <algorithm>
15
16namespace {
17
18using namespace webrtc::H264;
19
20struct SupportedH264Profile {
21  const RTCDeviceType deviceType;
22  const ProfileLevelId profile;
23};
24
25constexpr SupportedH264Profile kH264MaxSupportedProfiles[] = {
26    // iPhones with at least iOS 9
27    {RTCDeviceTypeIPhone11ProMax, {kProfileHigh, kLevel5_2}},  // https://support.apple.com/kb/SP806
28    {RTCDeviceTypeIPhone11Pro, {kProfileHigh, kLevel5_2}},     // https://support.apple.com/kb/SP805
29    {RTCDeviceTypeIPhone11, {kProfileHigh, kLevel5_2}},        // https://support.apple.com/kb/SP804
30    {RTCDeviceTypeIPhoneXS, {kProfileHigh, kLevel5_2}},        // https://support.apple.com/kb/SP779
31    {RTCDeviceTypeIPhoneXSMax, {kProfileHigh, kLevel5_2}},     // https://support.apple.com/kb/SP780
32    {RTCDeviceTypeIPhoneXR, {kProfileHigh, kLevel5_2}},        // https://support.apple.com/kb/SP781
33    {RTCDeviceTypeIPhoneX, {kProfileHigh, kLevel5_2}},         // https://support.apple.com/kb/SP770
34    {RTCDeviceTypeIPhone8, {kProfileHigh, kLevel5_2}},         // https://support.apple.com/kb/SP767
35    {RTCDeviceTypeIPhone8Plus, {kProfileHigh, kLevel5_2}},     // https://support.apple.com/kb/SP768
36    {RTCDeviceTypeIPhone7, {kProfileHigh, kLevel5_1}},         // https://support.apple.com/kb/SP743
37    {RTCDeviceTypeIPhone7Plus, {kProfileHigh, kLevel5_1}},     // https://support.apple.com/kb/SP744
38    {RTCDeviceTypeIPhoneSE, {kProfileHigh, kLevel4_2}},        // https://support.apple.com/kb/SP738
39    {RTCDeviceTypeIPhone6S, {kProfileHigh, kLevel4_2}},        // https://support.apple.com/kb/SP726
40    {RTCDeviceTypeIPhone6SPlus, {kProfileHigh, kLevel4_2}},    // https://support.apple.com/kb/SP727
41    {RTCDeviceTypeIPhone6, {kProfileHigh, kLevel4_2}},         // https://support.apple.com/kb/SP705
42    {RTCDeviceTypeIPhone6Plus, {kProfileHigh, kLevel4_2}},     // https://support.apple.com/kb/SP706
43    {RTCDeviceTypeIPhone5SGSM, {kProfileHigh, kLevel4_2}},     // https://support.apple.com/kb/SP685
44    {RTCDeviceTypeIPhone5SGSM_CDMA,
45     {kProfileHigh, kLevel4_2}},                           // https://support.apple.com/kb/SP685
46    {RTCDeviceTypeIPhone5GSM, {kProfileHigh, kLevel4_1}},  // https://support.apple.com/kb/SP655
47    {RTCDeviceTypeIPhone5GSM_CDMA,
48     {kProfileHigh, kLevel4_1}},                            // https://support.apple.com/kb/SP655
49    {RTCDeviceTypeIPhone5CGSM, {kProfileHigh, kLevel4_1}},  // https://support.apple.com/kb/SP684
50    {RTCDeviceTypeIPhone5CGSM_CDMA,
51     {kProfileHigh, kLevel4_1}},                         // https://support.apple.com/kb/SP684
52    {RTCDeviceTypeIPhone4S, {kProfileHigh, kLevel4_1}},  // https://support.apple.com/kb/SP643
53
54    // iPods with at least iOS 9
55    {RTCDeviceTypeIPodTouch7G, {kProfileMain, kLevel4_1}},  // https://support.apple.com/kb/SP796
56    {RTCDeviceTypeIPodTouch6G, {kProfileMain, kLevel4_1}},  // https://support.apple.com/kb/SP720
57    {RTCDeviceTypeIPodTouch5G, {kProfileMain, kLevel3_1}},  // https://support.apple.com/kb/SP657
58
59    // iPads with at least iOS 9
60    {RTCDeviceTypeIPadAir3Gen, {kProfileHigh, kLevel4_1}},   // https://support.apple.com/kb/SP787
61    {RTCDeviceTypeIPadMini5Gen, {kProfileHigh, kLevel4_1}},  // https://support.apple.com/kb/SP788
62    {RTCDeviceTypeIPadPro3Gen12Inch,
63     {kProfileHigh, kLevel5_2}},  // https://support.apple.com/kb/SP785
64    {RTCDeviceTypeIPadPro3Gen11Inch,
65     {kProfileHigh, kLevel5_2}},                               // https://support.apple.com/kb/SP784
66    {RTCDeviceTypeIPad7Gen10Inch, {kProfileHigh, kLevel4_1}},  // https://support.apple.com/kb/SP807
67    {RTCDeviceTypeIPad2Wifi, {kProfileHigh, kLevel4_1}},       // https://support.apple.com/kb/SP622
68    {RTCDeviceTypeIPad2GSM, {kProfileHigh, kLevel4_1}},        // https://support.apple.com/kb/SP622
69    {RTCDeviceTypeIPad2CDMA, {kProfileHigh, kLevel4_1}},       // https://support.apple.com/kb/SP622
70    {RTCDeviceTypeIPad2Wifi2, {kProfileHigh, kLevel4_1}},      // https://support.apple.com/kb/SP622
71    {RTCDeviceTypeIPadMiniWifi, {kProfileHigh, kLevel4_1}},    // https://support.apple.com/kb/SP661
72    {RTCDeviceTypeIPadMiniGSM, {kProfileHigh, kLevel4_1}},     // https://support.apple.com/kb/SP661
73    {RTCDeviceTypeIPadMiniGSM_CDMA,
74     {kProfileHigh, kLevel4_1}},                              // https://support.apple.com/kb/SP661
75    {RTCDeviceTypeIPad3Wifi, {kProfileHigh, kLevel4_1}},      // https://support.apple.com/kb/SP647
76    {RTCDeviceTypeIPad3GSM_CDMA, {kProfileHigh, kLevel4_1}},  // https://support.apple.com/kb/SP647
77    {RTCDeviceTypeIPad3GSM, {kProfileHigh, kLevel4_1}},       // https://support.apple.com/kb/SP647
78    {RTCDeviceTypeIPad4Wifi, {kProfileHigh, kLevel4_1}},      // https://support.apple.com/kb/SP662
79    {RTCDeviceTypeIPad4GSM, {kProfileHigh, kLevel4_1}},       // https://support.apple.com/kb/SP662
80    {RTCDeviceTypeIPad4GSM_CDMA, {kProfileHigh, kLevel4_1}},  // https://support.apple.com/kb/SP662
81    {RTCDeviceTypeIPad5, {kProfileHigh, kLevel4_2}},          // https://support.apple.com/kb/SP751
82    {RTCDeviceTypeIPad6, {kProfileHigh, kLevel4_2}},          // https://support.apple.com/kb/SP774
83    {RTCDeviceTypeIPadAirWifi, {kProfileHigh, kLevel4_2}},    // https://support.apple.com/kb/SP692
84    {RTCDeviceTypeIPadAirCellular,
85     {kProfileHigh, kLevel4_2}},  // https://support.apple.com/kb/SP692
86    {RTCDeviceTypeIPadAirWifiCellular,
87     {kProfileHigh, kLevel4_2}},                               // https://support.apple.com/kb/SP692
88    {RTCDeviceTypeIPadAir2, {kProfileHigh, kLevel4_2}},        // https://support.apple.com/kb/SP708
89    {RTCDeviceTypeIPadMini2GWifi, {kProfileHigh, kLevel4_2}},  // https://support.apple.com/kb/SP693
90    {RTCDeviceTypeIPadMini2GCellular,
91     {kProfileHigh, kLevel4_2}},  // https://support.apple.com/kb/SP693
92    {RTCDeviceTypeIPadMini2GWifiCellular,
93     {kProfileHigh, kLevel4_2}},                               // https://support.apple.com/kb/SP693
94    {RTCDeviceTypeIPadMini3, {kProfileHigh, kLevel4_2}},       // https://support.apple.com/kb/SP709
95    {RTCDeviceTypeIPadMini4, {kProfileHigh, kLevel4_2}},       // https://support.apple.com/kb/SP725
96    {RTCDeviceTypeIPadPro9Inch, {kProfileHigh, kLevel4_2}},    // https://support.apple.com/kb/SP739
97    {RTCDeviceTypeIPadPro12Inch, {kProfileHigh, kLevel4_2}},   // https://support.apple.com/kb/sp723
98    {RTCDeviceTypeIPadPro12Inch2, {kProfileHigh, kLevel4_2}},  // https://support.apple.com/kb/SP761
99    {RTCDeviceTypeIPadPro10Inch, {kProfileHigh, kLevel4_2}},   // https://support.apple.com/kb/SP762
100};
101
102absl::optional<ProfileLevelId> FindMaxSupportedProfileForDevice(RTCDeviceType deviceType) {
103  const auto* result = std::find_if(std::begin(kH264MaxSupportedProfiles),
104                                    std::end(kH264MaxSupportedProfiles),
105                                    [deviceType](const SupportedH264Profile& supportedProfile) {
106                                      return supportedProfile.deviceType == deviceType;
107                                    });
108  if (result != std::end(kH264MaxSupportedProfiles)) {
109    return result->profile;
110  }
111  return absl::nullopt;
112}
113
114}  // namespace
115
116@implementation UIDevice (H264Profile)
117
118+ (absl::optional<webrtc::H264::ProfileLevelId>)maxSupportedH264Profile {
119  return FindMaxSupportedProfileForDevice([self deviceType]);
120}
121
122@end
123