blob: d7521262d4d0a159b6de0a46989be49924debe17 [file] [log] [blame]
kthelgasonfb143122017-07-25 07:55:58 -07001/*
2 * Copyright 2017 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 "WebRTC/RTCVideoCodec.h"
12
13#import "NSString+StdString.h"
14#import "RTCVideoCodec+Private.h"
Yura Yaroshevich0f77fea2018-04-26 15:41:01 +030015#if defined(WEBRTC_IOS)
16#import "UIDevice+H264Profile.h"
17#endif
kthelgasonfb143122017-07-25 07:55:58 -070018#import "WebRTC/RTCVideoCodecFactory.h"
19
VladimirTechMan80adac02017-11-23 12:22:11 -050020#include "media/base/mediaconstants.h"
21
Yura Yaroshevich0f77fea2018-04-26 15:41:01 +030022namespace {
23
24NSString *MaxSupportedProfileLevelConstrainedHigh();
25NSString *MaxSupportedProfileLevelConstrainedBaseline();
26
27} // namespace
28
VladimirTechMan80adac02017-11-23 12:22:11 -050029NSString *const kRTCVideoCodecVp8Name = @(cricket::kVp8CodecName);
30NSString *const kRTCVideoCodecVp9Name = @(cricket::kVp9CodecName);
31NSString *const kRTCVideoCodecH264Name = @(cricket::kH264CodecName);
Kári Tristan Helgasonfc313dc2017-10-20 11:01:22 +020032NSString *const kRTCLevel31ConstrainedHigh = @"640c1f";
33NSString *const kRTCLevel31ConstrainedBaseline = @"42e01f";
Yura Yaroshevich0f77fea2018-04-26 15:41:01 +030034NSString *const kRTCMaxSupportedH264ProfileLevelConstrainedHigh =
35 MaxSupportedProfileLevelConstrainedHigh();
36NSString *const kRTCMaxSupportedH264ProfileLevelConstrainedBaseline =
37 MaxSupportedProfileLevelConstrainedBaseline();
38
39namespace {
40
41#if defined(WEBRTC_IOS)
42
43using namespace webrtc::H264;
44
45NSString *MaxSupportedLevelForProfile(Profile profile) {
Danil Chapovalov196100e2018-06-21 10:17:24 +020046 const absl::optional<ProfileLevelId> profileLevelId = [UIDevice maxSupportedH264Profile];
Yura Yaroshevich0f77fea2018-04-26 15:41:01 +030047 if (profileLevelId && profileLevelId->profile >= profile) {
Danil Chapovalov196100e2018-06-21 10:17:24 +020048 const absl::optional<std::string> profileString =
Yura Yaroshevich0f77fea2018-04-26 15:41:01 +030049 ProfileLevelIdToString(ProfileLevelId(profile, profileLevelId->level));
50 if (profileString) {
51 return [NSString stringForStdString:*profileString];
52 }
53 }
54 return nil;
55}
56#endif
57
58NSString *MaxSupportedProfileLevelConstrainedBaseline() {
59#if defined(WEBRTC_IOS)
60 NSString *profile = MaxSupportedLevelForProfile(webrtc::H264::kProfileConstrainedBaseline);
61 if (profile != nil) {
62 return profile;
63 }
64#endif
65 return kRTCLevel31ConstrainedBaseline;
66}
67
68NSString *MaxSupportedProfileLevelConstrainedHigh() {
69#if defined(WEBRTC_IOS)
70 NSString *profile = MaxSupportedLevelForProfile(webrtc::H264::kProfileConstrainedHigh);
71 if (profile != nil) {
72 return profile;
73 }
74#endif
75 return kRTCLevel31ConstrainedHigh;
76}
77
78} // namespace
Kári Tristan Helgason117c4822017-10-18 14:22:22 +020079
kthelgasonfb143122017-07-25 07:55:58 -070080@implementation RTCVideoCodecInfo
81
kthelgasonfb143122017-07-25 07:55:58 -070082@synthesize name = _name;
83@synthesize parameters = _parameters;
84
Kári Tristan Helgasone71f3672017-10-02 14:59:59 +020085- (instancetype)initWithName:(NSString *)name {
86 return [self initWithName:name parameters:nil];
87}
88
andersc81bc5232017-08-18 06:34:09 -070089- (instancetype)initWithName:(NSString *)name
90 parameters:(nullable NSDictionary<NSString *, NSString *> *)parameters {
kthelgasonfb143122017-07-25 07:55:58 -070091 if (self = [super init]) {
kthelgasonfb143122017-07-25 07:55:58 -070092 _name = name;
andersc81bc5232017-08-18 06:34:09 -070093 _parameters = (parameters ? parameters : @{});
kthelgasonfb143122017-07-25 07:55:58 -070094 }
95
96 return self;
97}
98
Anders Carlsson7e042812017-10-05 16:55:38 +020099- (instancetype)initWithNativeSdpVideoFormat:(webrtc::SdpVideoFormat)format {
kthelgasonfb143122017-07-25 07:55:58 -0700100 NSMutableDictionary *params = [NSMutableDictionary dictionary];
Anders Carlsson7e042812017-10-05 16:55:38 +0200101 for (auto it = format.parameters.begin(); it != format.parameters.end(); ++it) {
kthelgasonfb143122017-07-25 07:55:58 -0700102 [params setObject:[NSString stringForStdString:it->second]
103 forKey:[NSString stringForStdString:it->first]];
104 }
Anders Carlsson7e042812017-10-05 16:55:38 +0200105 return [self initWithName:[NSString stringForStdString:format.name] parameters:params];
kthelgasonfb143122017-07-25 07:55:58 -0700106}
107
Kári Tristan Helgason3935c342017-09-28 15:08:47 +0200108- (BOOL)isEqualToCodecInfo:(RTCVideoCodecInfo *)info {
109 if (!info ||
Kári Tristan Helgason3935c342017-09-28 15:08:47 +0200110 ![self.name isEqualToString:info.name] ||
111 ![self.parameters isEqualToDictionary:info.parameters]) {
112 return NO;
113 }
114 return YES;
115}
116
117- (BOOL)isEqual:(id)object {
118 if (self == object)
119 return YES;
120 if (![object isKindOfClass:[self class]])
121 return NO;
122 return [self isEqualToCodecInfo:object];
123}
124
125- (NSUInteger)hash {
Anders Carlsson7e042812017-10-05 16:55:38 +0200126 return [self.name hash] ^ [self.parameters hash];
127}
128
129- (webrtc::SdpVideoFormat)nativeSdpVideoFormat {
130 std::map<std::string, std::string> parameters;
131 for (NSString *paramKey in _parameters.allKeys) {
132 std::string key = [NSString stdStringForString:paramKey];
133 std::string value = [NSString stdStringForString:_parameters[paramKey]];
134 parameters[key] = value;
135 }
136
137 return webrtc::SdpVideoFormat([NSString stdStringForString:_name], parameters);
138}
139
Anders Carlsson6bf43d22017-10-16 13:51:43 +0200140#pragma mark - NSCoding
141
142- (instancetype)initWithCoder:(NSCoder *)decoder {
143 return [self initWithName:[decoder decodeObjectForKey:@"name"]
144 parameters:[decoder decodeObjectForKey:@"parameters"]];
145}
146
147- (void)encodeWithCoder:(NSCoder *)encoder {
148 [encoder encodeObject:_name forKey:@"name"];
149 [encoder encodeObject:_parameters forKey:@"parameters"];
150}
151
kthelgasonfb143122017-07-25 07:55:58 -0700152@end
magjed5dfac332017-08-01 08:07:59 -0700153
154@implementation RTCVideoEncoderQpThresholds
155
156@synthesize low = _low;
157@synthesize high = _high;
158
159- (instancetype)initWithThresholdsLow:(NSInteger)low high:(NSInteger)high {
160 if (self = [super init]) {
161 _low = low;
162 _high = high;
163 }
164 return self;
165}
166
167@end