From 8dd16259287f58f9273002717ec4d27e97127719 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:43:14 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- .../api/peerconnection/RTCPeerConnectionFactory.h | 13 ++ .../api/peerconnection/RTCPeerConnectionFactory.mm | 29 ++++ .../peerconnection/RTCRtpCapabilities+Private.h | 32 ++++ .../objc/api/peerconnection/RTCRtpCapabilities.h | 31 ++++ .../objc/api/peerconnection/RTCRtpCapabilities.mm | 60 +++++++ .../peerconnection/RTCRtpCodecCapability+Private.h | 33 ++++ .../api/peerconnection/RTCRtpCodecCapability.h | 58 +++++++ .../api/peerconnection/RTCRtpCodecCapability.mm | 116 +++++++++++++ .../RTCRtpHeaderExtensionCapability+Private.h | 34 ++++ .../RTCRtpHeaderExtensionCapability.h | 33 ++++ .../RTCRtpHeaderExtensionCapability.mm | 56 ++++++ .../objc/api/peerconnection/RTCRtpTransceiver.h | 7 + .../objc/api/peerconnection/RTCRtpTransceiver.mm | 11 ++ .../unittests/RTCPeerConnectionFactory_xctest.m | 193 +++++++++++++++++++++ 14 files changed, 706 insertions(+) create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.h create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h create mode 100644 third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm (limited to 'third_party/libwebrtc/sdk/objc') diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h index 5575af98c9..17777f6d5d 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h @@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN +@class RTC_OBJC_TYPE(RTCRtpCapabilities); @class RTC_OBJC_TYPE(RTCAudioSource); @class RTC_OBJC_TYPE(RTCAudioTrack); @class RTC_OBJC_TYPE(RTCConfiguration); @@ -51,6 +52,18 @@ RTC_OBJC_EXPORT decoderFactory:(nullable id)decoderFactory audioDevice:(nullable id)audioDevice; +/** + * Valid kind values are kRTCMediaStreamTrackKindAudio and + * kRTCMediaStreamTrackKindVideo. + */ +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesForKind:(NSString *)kind; + +/** + * Valid kind values are kRTCMediaStreamTrackKindAudio and + * kRTCMediaStreamTrackKindVideo. + */ +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpReceiverCapabilitiesForKind:(NSString *)kind; + /** Initialize an RTCAudioSource with constraints. */ - (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints: (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints; diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm index 445006f0d0..64be41ae15 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm @@ -13,6 +13,7 @@ #import "RTCPeerConnectionFactory+Native.h" #import "RTCPeerConnectionFactory+Private.h" #import "RTCPeerConnectionFactoryOptions+Private.h" +#import "RTCRtpCapabilities+Private.h" #import "RTCAudioSource+Private.h" #import "RTCAudioTrack+Private.h" @@ -38,6 +39,7 @@ #include "api/transport/field_trial_based_config.h" #import "components/video_codec/RTCVideoDecoderFactoryH264.h" #import "components/video_codec/RTCVideoEncoderFactoryH264.h" +#include "media/base/media_constants.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -214,6 +216,20 @@ return self; } +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesForKind:(NSString *)kind { + cricket::MediaType mediaType = [[self class] mediaTypeForKind:kind]; + + webrtc::RtpCapabilities rtpCapabilities = _nativeFactory->GetRtpSenderCapabilities(mediaType); + return [[RTC_OBJC_TYPE(RTCRtpCapabilities) alloc] initWithNativeRtpCapabilities:rtpCapabilities]; +} + +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpReceiverCapabilitiesForKind:(NSString *)kind { + cricket::MediaType mediaType = [[self class] mediaTypeForKind:kind]; + + webrtc::RtpCapabilities rtpCapabilities = _nativeFactory->GetRtpReceiverCapabilities(mediaType); + return [[RTC_OBJC_TYPE(RTCRtpCapabilities) alloc] initWithNativeRtpCapabilities:rtpCapabilities]; +} + - (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints: (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints { std::unique_ptr nativeConstraints; @@ -338,4 +354,17 @@ return _networkThread.get(); } +#pragma mark - Private + ++ (cricket::MediaType)mediaTypeForKind:(NSString *)kind { + if (kind == kRTCMediaStreamTrackKindAudio) { + return cricket::MEDIA_TYPE_AUDIO; + } else if (kind == kRTCMediaStreamTrackKindVideo) { + return cricket::MEDIA_TYPE_VIDEO; + } else { + RTC_DCHECK_NOTREACHED(); + return cricket::MEDIA_TYPE_UNSUPPORTED; + } +} + @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h new file mode 100644 index 0000000000..be51993f2f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h @@ -0,0 +1,32 @@ +/* + * Copyright 2024 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 "RTCRtpCapabilities.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpCapabilities)() + +/** + * The native RtpCapabilities representation of this RTCRtpCapabilities + * object. This is needed to pass to the underlying C++ APIs. + */ +@property(nonatomic, readonly) webrtc::RtpCapabilities nativeRtpCapabilities; + +/** + * Initialize an RTCRtpCapabilities from a native RtpCapabilities. + */ +- (instancetype)initWithNativeRtpCapabilities:(const webrtc::RtpCapabilities &)rtpCapabilities; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.h new file mode 100644 index 0000000000..7e898b5a80 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.h @@ -0,0 +1,31 @@ +/* + * Copyright 2024 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 + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCRtpCodecCapability); +@class RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability); + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpCapabilities) : NSObject + +@property(nonatomic, copy) NSArray *codecs; +@property(nonatomic, copy) + NSArray *headerExtensions; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm new file mode 100644 index 0000000000..85537a91ad --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm @@ -0,0 +1,60 @@ +/* + * Copyright 2024 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 "RTCRtpCapabilities+Private.h" + +#import "RTCRtpCodecCapability+Private.h" +#import "RTCRtpHeaderExtensionCapability+Private.h" + +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtpCapabilities) + +@synthesize codecs = _codecs; +@synthesize headerExtensions = _headerExtensions; + +- (instancetype)init { + webrtc::RtpCapabilities nativeRtpCapabilities; + return [self initWithNativeRtpCapabilities:nativeRtpCapabilities]; +} + +- (instancetype)initWithNativeRtpCapabilities: + (const webrtc::RtpCapabilities &)nativeRtpCapabilities { + if (self = [super init]) { + NSMutableArray *codecs = [[NSMutableArray alloc] init]; + for (const auto &codec : nativeRtpCapabilities.codecs) { + [codecs addObject:[[RTC_OBJC_TYPE(RTCRtpCodecCapability) alloc] + initWithNativeRtpCodecCapability:codec]]; + } + _codecs = codecs; + + NSMutableArray *headerExtensions = [[NSMutableArray alloc] init]; + for (const auto &headerExtension : nativeRtpCapabilities.header_extensions) { + [headerExtensions addObject:[[RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) alloc] + initWithNativeRtpHeaderExtensionCapability:headerExtension]]; + } + _headerExtensions = headerExtensions; + } + return self; +} + +- (webrtc::RtpCapabilities)nativeRtpCapabilities { + webrtc::RtpCapabilities rtpCapabilities; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in _codecs) { + rtpCapabilities.codecs.push_back(codec.nativeRtpCodecCapability); + } + for (RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) * headerExtension in _headerExtensions) { + rtpCapabilities.header_extensions.push_back(headerExtension.nativeRtpHeaderExtensionCapability); + } + return rtpCapabilities; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h new file mode 100644 index 0000000000..6af13b3b23 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h @@ -0,0 +1,33 @@ +/* + * Copyright 2024 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 "RTCRtpCodecCapability.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpCodecCapability)() + +/** + * The native RtpCodecCapability representation of this RTCRtpCodecCapability + * object. This is needed to pass to the underlying C++ APIs. + */ +@property(nonatomic, readonly) webrtc::RtpCodecCapability nativeRtpCodecCapability; + +/** + * Initialize an RTCRtpCodecCapability from a native RtpCodecCapability. + */ +- (instancetype)initWithNativeRtpCodecCapability: + (const webrtc::RtpCodecCapability &)nativeRtpCodecCapability; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h new file mode 100644 index 0000000000..5604148e5d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h @@ -0,0 +1,58 @@ +/* + * Copyright 2024 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 + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpCodecCapability) : NSObject + +/** The preferred RTP payload type. */ +@property(nonatomic, readonly, nullable) NSNumber *preferredPayloadType; + +/** + * The codec MIME subtype. Valid types are listed in: + * http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-2 + * + * Several supported types are represented by the constants above. + */ +@property(nonatomic, readonly) NSString *name; + +/** + * The media type of this codec. Equivalent to MIME top-level type. + * + * Valid values are kRTCMediaStreamTrackKindAudio and + * kRTCMediaStreamTrackKindVideo. + */ +@property(nonatomic, readonly) NSString *kind; + +/** The codec clock rate expressed in Hertz. */ +@property(nonatomic, readonly, nullable) NSNumber *clockRate; + +/** + * The number of audio channels (mono=1, stereo=2). + * Set to null for video codecs. + **/ +@property(nonatomic, readonly, nullable) NSNumber *numChannels; + +/** The "format specific parameters" field from the "a=fmtp" line in the SDP */ +@property(nonatomic, readonly) NSDictionary *parameters; + +/** The MIME type of the codec. */ +@property(nonatomic, readonly) NSString *mimeType; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm new file mode 100644 index 0000000000..2dc1e5dc4b --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm @@ -0,0 +1,116 @@ +/* + * Copyright 2024 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 "RTCRtpCodecCapability+Private.h" + +#import "RTCMediaStreamTrack.h" +#import "helpers/NSString+StdString.h" + +#include "media/base/media_constants.h" +#include "rtc_base/checks.h" + +@implementation RTC_OBJC_TYPE (RTCRtpCodecCapability) + +@synthesize preferredPayloadType = _preferredPayloadType; +@synthesize name = _name; +@synthesize kind = _kind; +@synthesize clockRate = _clockRate; +@synthesize numChannels = _numChannels; +@synthesize parameters = _parameters; +@synthesize mimeType = _mimeType; + +- (instancetype)init { + webrtc::RtpCodecCapability rtpCodecCapability; + return [self initWithNativeRtpCodecCapability:rtpCodecCapability]; +} + +- (instancetype)initWithNativeRtpCodecCapability: + (const webrtc::RtpCodecCapability &)nativeRtpCodecCapability { + if (self = [super init]) { + if (nativeRtpCodecCapability.preferred_payload_type) { + _preferredPayloadType = + [NSNumber numberWithInt:*nativeRtpCodecCapability.preferred_payload_type]; + } + _name = [NSString stringForStdString:nativeRtpCodecCapability.name]; + switch (nativeRtpCodecCapability.kind) { + case cricket::MEDIA_TYPE_AUDIO: + _kind = kRTCMediaStreamTrackKindAudio; + break; + case cricket::MEDIA_TYPE_VIDEO: + _kind = kRTCMediaStreamTrackKindVideo; + break; + case cricket::MEDIA_TYPE_DATA: + RTC_DCHECK_NOTREACHED(); + break; + case cricket::MEDIA_TYPE_UNSUPPORTED: + RTC_DCHECK_NOTREACHED(); + break; + } + if (nativeRtpCodecCapability.clock_rate) { + _clockRate = [NSNumber numberWithInt:*nativeRtpCodecCapability.clock_rate]; + } + if (nativeRtpCodecCapability.num_channels) { + _numChannels = [NSNumber numberWithInt:*nativeRtpCodecCapability.num_channels]; + } + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + for (const auto ¶meter : nativeRtpCodecCapability.parameters) { + [parameters setObject:[NSString stringForStdString:parameter.second] + forKey:[NSString stringForStdString:parameter.first]]; + } + _parameters = parameters; + _mimeType = [NSString stringForStdString:nativeRtpCodecCapability.mime_type()]; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpCodecCapability) {\n " + @"preferredPayloadType: %@\n name: %@\n kind: %@\n " + @"clockRate: %@\n numChannels: %@\n parameters: %@\n " + @"mimeType: %@\n}", + _preferredPayloadType, + _name, + _kind, + _clockRate, + _numChannels, + _parameters, + _mimeType]; +} + +- (webrtc::RtpCodecCapability)nativeRtpCodecCapability { + webrtc::RtpCodecCapability rtpCodecCapability; + if (_preferredPayloadType != nil) { + rtpCodecCapability.preferred_payload_type = absl::optional(_preferredPayloadType.intValue); + } + rtpCodecCapability.name = [NSString stdStringForString:_name]; + // NSString pointer comparison is safe here since "kind" is readonly and only + // populated above. + if (_kind == kRTCMediaStreamTrackKindAudio) { + rtpCodecCapability.kind = cricket::MEDIA_TYPE_AUDIO; + } else if (_kind == kRTCMediaStreamTrackKindVideo) { + rtpCodecCapability.kind = cricket::MEDIA_TYPE_VIDEO; + } else { + RTC_DCHECK_NOTREACHED(); + } + if (_clockRate != nil) { + rtpCodecCapability.clock_rate = absl::optional(_clockRate.intValue); + } + if (_numChannels != nil) { + rtpCodecCapability.num_channels = absl::optional(_numChannels.intValue); + } + for (NSString *paramKey in _parameters.allKeys) { + std::string key = [NSString stdStringForString:paramKey]; + std::string value = [NSString stdStringForString:_parameters[paramKey]]; + rtpCodecCapability.parameters[key] = value; + } + return rtpCodecCapability; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h new file mode 100644 index 0000000000..4e800bc996 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h @@ -0,0 +1,34 @@ +/* + * Copyright 2024 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 "RTCRtpHeaderExtensionCapability.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability)() + +/** +* The native RtpHeaderExtensionCapability representation of this +* RTCRtpHeaderExtensionCapability object. This is needed to pass to the underlying C++ APIs. +*/ +@property(nonatomic, + readonly) webrtc::RtpHeaderExtensionCapability nativeRtpHeaderExtensionCapability; + +/** + * Initialize an RTCRtpHeaderExtensionCapability from a native RtpHeaderExtensionCapability. + */ +- (instancetype)initWithNativeRtpHeaderExtensionCapability: + (const webrtc::RtpHeaderExtensionCapability &)rtpHeaderExtensionCapability; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h new file mode 100644 index 0000000000..7a5d442e6a --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h @@ -0,0 +1,33 @@ +/* + * Copyright 2024 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 + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability) : NSObject + +/** The URI of the RTP header extension, as defined in RFC5285. */ +@property(nonatomic, readonly, copy) NSString *uri; + +/** The value put in the RTP packet to identify the header extension. */ +@property(nonatomic, readonly, nullable) NSNumber* preferredId; + +/** Whether the header extension is encrypted or not. */ +@property(nonatomic, readonly, getter=isPreferredEncrypted) BOOL preferredEncrypted; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm new file mode 100644 index 0000000000..c9af744a92 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm @@ -0,0 +1,56 @@ +/* + * Copyright 2024 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 "RTCRtpHeaderExtensionCapability+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability) + +@synthesize uri = _uri; +@synthesize preferredId = _preferredId; +@synthesize preferredEncrypted = _preferredEncrypted; + +- (instancetype)init { + webrtc::RtpHeaderExtensionCapability nativeRtpHeaderExtensionCapability; + return [self initWithNativeRtpHeaderExtensionCapability:nativeRtpHeaderExtensionCapability]; +} + +- (instancetype)initWithNativeRtpHeaderExtensionCapability: + (const webrtc::RtpHeaderExtensionCapability &)nativeRtpHeaderExtensionCapability { + if (self = [super init]) { + _uri = [NSString stringForStdString:nativeRtpHeaderExtensionCapability.uri]; + if (nativeRtpHeaderExtensionCapability.preferred_id) { + _preferredId = [NSNumber numberWithInt:*nativeRtpHeaderExtensionCapability.preferred_id]; + } + _preferredEncrypted = nativeRtpHeaderExtensionCapability.preferred_encrypt; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) {\n uri: " + @"%@\n preferredId: %@\n preferredEncrypted: %d\n}", + _uri, + _preferredId, + _preferredEncrypted]; +} + +- (webrtc::RtpHeaderExtensionCapability)nativeRtpHeaderExtensionCapability { + webrtc::RtpHeaderExtensionCapability rtpHeaderExtensionCapability; + rtpHeaderExtensionCapability.uri = [NSString stdStringForString:_uri]; + if (_preferredId != nil) { + rtpHeaderExtensionCapability.preferred_id = absl::optional(_preferredId.intValue); + } + rtpHeaderExtensionCapability.preferred_encrypt = _preferredEncrypted; + return rtpHeaderExtensionCapability; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h index fd59013639..1701f680a4 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h @@ -46,6 +46,7 @@ RTC_OBJC_EXPORT @end @class RTC_OBJC_TYPE(RTCRtpTransceiver); +@class RTC_OBJC_TYPE(RTCRtpCodecCapability); /** The RTCRtpTransceiver maps to the RTCRtpTransceiver defined by the * WebRTC specification. A transceiver represents a combination of an RTCRtpSender @@ -118,6 +119,12 @@ RTC_OBJC_EXPORT */ - (void)stopInternal; +/** The setCodecPreferences method overrides the default codec preferences used + * by WebRTC for this transceiver. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-setcodecpreferences + */ +- (void)setCodecPreferences:(NSArray *)codecs; + /** An update of directionality does not take effect immediately. Instead, * future calls to createOffer and createAnswer mark the corresponding media * descriptions as sendrecv, sendonly, recvonly, or inactive. diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm index ae1cf79864..eb0ad96738 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm @@ -10,6 +10,7 @@ #import "RTCRtpTransceiver+Private.h" +#import "RTCRtpCodecCapability+Private.h" #import "RTCRtpEncodingParameters+Private.h" #import "RTCRtpParameters+Private.h" #import "RTCRtpReceiver+Private.h" @@ -17,6 +18,8 @@ #import "base/RTCLogging.h" #import "helpers/NSString+StdString.h" +#include "api/rtp_parameters.h" + NSString *const kRTCRtpTransceiverErrorDomain = @"org.webrtc.RTCRtpTranceiver"; @implementation RTC_OBJC_TYPE (RTCRtpTransceiverInit) @@ -105,6 +108,14 @@ NSString *const kRTCRtpTransceiverErrorDomain = @"org.webrtc.RTCRtpTranceiver"; _nativeRtpTransceiver->StopInternal(); } +- (void)setCodecPreferences:(NSArray *)codecs { + std::vector codecCapabilities; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * rtpCodecCapability in codecs) { + codecCapabilities.push_back(rtpCodecCapability.nativeRtpCodecCapability); + } + _nativeRtpTransceiver->SetCodecPreferences(codecCapabilities); +} + - (NSString *)description { return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpTransceiver) {\n sender: %@\n receiver: %@\n}", diff --git a/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m b/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m index 56c74971b6..7d42b6bdbb 100644 --- a/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m +++ b/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m @@ -8,6 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ +#import "base/RTCVideoDecoderFactory.h" +#import "base/RTCVideoEncoderFactory.h" + #import "api/peerconnection/RTCAudioSource.h" #import "api/peerconnection/RTCConfiguration.h" #import "api/peerconnection/RTCDataChannel.h" @@ -16,6 +19,8 @@ #import "api/peerconnection/RTCMediaStreamTrack.h" #import "api/peerconnection/RTCPeerConnection.h" #import "api/peerconnection/RTCPeerConnectionFactory.h" +#import "api/peerconnection/RTCRtpCapabilities.h" +#import "api/peerconnection/RTCRtpCodecCapability.h" #import "api/peerconnection/RTCRtpReceiver.h" #import "api/peerconnection/RTCRtpSender.h" #import "api/peerconnection/RTCRtpTransceiver.h" @@ -25,6 +30,40 @@ #import +@interface MockVideoEncoderDecoderFactory + : NSObject +- (instancetype)initWithSupportedCodecs: + (nonnull NSArray *)supportedCodecs; +@end + +@implementation MockVideoEncoderDecoderFactory { + NSArray *_supportedCodecs; +} + +- (instancetype)initWithSupportedCodecs: + (nonnull NSArray *)supportedCodecs { + if (self = [super init]) { + _supportedCodecs = supportedCodecs; + } + return self; +} + +- (nullable id)createEncoder: + (nonnull RTC_OBJC_TYPE(RTCVideoCodecInfo) *)info { + return nil; +} + +- (nullable id)createDecoder: + (nonnull RTC_OBJC_TYPE(RTCVideoCodecInfo) *)info { + return nil; +} + +- (nonnull NSArray *)supportedCodecs { + return _supportedCodecs; +} + +@end + @interface RTCPeerConnectionFactoryTests : XCTestCase @end @@ -325,6 +364,148 @@ } } +- (void)testSenderCapabilities { + @autoreleasepool { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory; + MockVideoEncoderDecoderFactory *encoder; + MockVideoEncoderDecoderFactory *decoder; + + NSArray *supportedCodecs = @[ + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"], + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"] + ]; + + encoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + decoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder + decoderFactory:decoder]; + + RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities = + [factory rtpSenderCapabilitiesForKind:kRTCMediaStreamTrackKindVideo]; + NSMutableArray *codecNames = [NSMutableArray new]; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) { + [codecNames addObject:codec.name]; + } + + XCTAssertTrue([codecNames containsObject:@"VP8"]); + XCTAssertTrue([codecNames containsObject:@"H264"]); + factory = nil; + } +} + +- (void)testReceiverCapabilities { + @autoreleasepool { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory; + MockVideoEncoderDecoderFactory *encoder; + MockVideoEncoderDecoderFactory *decoder; + + NSArray *supportedCodecs = @[ + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"], + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"] + ]; + + encoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + decoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder + decoderFactory:decoder]; + + RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities = + [factory rtpReceiverCapabilitiesForKind:kRTCMediaStreamTrackKindVideo]; + NSMutableArray *codecNames = [NSMutableArray new]; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) { + [codecNames addObject:codec.name]; + } + + XCTAssertTrue([codecNames containsObject:@"VP8"]); + XCTAssertTrue([codecNames containsObject:@"H264"]); + factory = nil; + } +} + +- (void)testSetCodecPreferences { + @autoreleasepool { + RTC_OBJC_TYPE(RTCConfiguration) *config = [[RTC_OBJC_TYPE(RTCConfiguration) alloc] init]; + RTC_OBJC_TYPE(RTCMediaConstraints) *constraints = + [[RTC_OBJC_TYPE(RTCMediaConstraints) alloc] initWithMandatoryConstraints:nil + optionalConstraints:nil]; + RTC_OBJC_TYPE(RTCRtpTransceiverInit) *init = + [[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]; + + NSArray *supportedCodecs = @[ + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"], + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"] + ]; + + MockVideoEncoderDecoderFactory *encoder = + [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + MockVideoEncoderDecoderFactory *decoder = + [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory; + RTC_OBJC_TYPE(RTCPeerConnection) * peerConnection; + RTC_OBJC_TYPE(RTCRtpTransceiver) * tranceiver; + factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder + decoderFactory:decoder]; + + peerConnection = [factory peerConnectionWithConfiguration:config + constraints:constraints + delegate:nil]; + tranceiver = [peerConnection addTransceiverOfType:RTCRtpMediaTypeVideo init:init]; + XCTAssertNotNil(tranceiver); + + RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities = + [factory rtpReceiverCapabilitiesForKind:kRTCMediaStreamTrackKindVideo]; + + RTC_OBJC_TYPE(RTCRtpCodecCapability) * targetCodec; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) { + if ([codec.name isEqual:@"VP8"]) { + targetCodec = codec; + break; + } + } + XCTAssertNotNil(targetCodec); + + [tranceiver setCodecPreferences:@[ targetCodec ]]; + + @autoreleasepool { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + + __block BOOL completed = NO; + [peerConnection + offerForConstraints:constraints + completionHandler:^(RTC_OBJC_TYPE(RTCSessionDescription) *_Nullable sdp, + NSError *_Nullable error) { + XCTAssertNil(error); + XCTAssertNotNil(sdp); + + NSArray *rtpMaps = [self rtpMapsFromSDP:sdp.sdp]; + XCTAssertEqual(1, rtpMaps.count); + + XCTAssertNotNil(targetCodec.preferredPayloadType); + XCTAssertNotNil(targetCodec.clockRate); + + NSString *expected = + [NSString stringWithFormat:@"a=rtpmap:%i VP8/%i", + targetCodec.preferredPayloadType.intValue, + targetCodec.clockRate.intValue]; + + XCTAssertTrue([expected isEqualToString:rtpMaps[0]]); + + completed = YES; + dispatch_semaphore_signal(semaphore); + }]; + + [peerConnection close]; + peerConnection = nil; + factory = nil; + tranceiver = nil; + + dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 15.0 * NSEC_PER_SEC)); + XCTAssertTrue(completed); + } + } +} + - (bool)negotiatePeerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)pc1 withPeerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)pc2 negotiationTimeout:(NSTimeInterval)timeout { @@ -377,4 +558,16 @@ dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC))); } +- (NSArray *)rtpMapsFromSDP:(NSString *)sdp { + NSMutableArray *rtpMaps = [NSMutableArray new]; + NSArray *sdpLines = + [sdp componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + for (NSString *line in sdpLines) { + if ([line hasPrefix:@"a=rtpmap"]) { + [rtpMaps addObject:line]; + } + } + return rtpMaps; +} + @end -- cgit v1.2.3