diff options
Diffstat (limited to '')
120 files changed, 9732 insertions, 0 deletions
diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource+Private.h new file mode 100644 index 0000000000..2c333f9d73 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource+Private.h @@ -0,0 +1,34 @@ +/* + * 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 "RTCAudioSource.h" + +#import "RTCMediaSource+Private.h" + +@interface RTC_OBJC_TYPE (RTCAudioSource) +() + + /** + * The AudioSourceInterface object passed to this RTCAudioSource during + * construction. + */ + @property(nonatomic, + readonly) rtc::scoped_refptr<webrtc::AudioSourceInterface> nativeAudioSource; + +/** Initialize an RTCAudioSource from a native AudioSourceInterface. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeAudioSource:(rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource + type:(RTCMediaSourceType)type NS_UNAVAILABLE; + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource.h new file mode 100644 index 0000000000..9272fdf2d8 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource.h @@ -0,0 +1,32 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" +#import "RTCMediaSource.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCAudioSource) : RTC_OBJC_TYPE(RTCMediaSource) + +- (instancetype)init NS_UNAVAILABLE; + +// Sets the volume for the RTCMediaSource. `volume` is a gain value in the range +// [0, 10]. +// Temporary fix to be able to modify volume of remote audio tracks. +// TODO(kthelgason): Property stays here temporarily until a proper volume-api +// is available on the surface exposed by webrtc. +@property(nonatomic, assign) double volume; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource.mm new file mode 100644 index 0000000000..1541045099 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioSource.mm @@ -0,0 +1,52 @@ +/* + * 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 "RTCAudioSource+Private.h" + +#include "rtc_base/checks.h" + +@implementation RTC_OBJC_TYPE (RTCAudioSource) { +} + +@synthesize volume = _volume; +@synthesize nativeAudioSource = _nativeAudioSource; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeAudioSource: + (rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource { + RTC_DCHECK(factory); + RTC_DCHECK(nativeAudioSource); + + if (self = [super initWithFactory:factory + nativeMediaSource:nativeAudioSource + type:RTCMediaSourceTypeAudio]) { + _nativeAudioSource = nativeAudioSource; + } + return self; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource + type:(RTCMediaSourceType)type { + RTC_DCHECK_NOTREACHED(); + return nil; +} + +- (NSString *)description { + NSString *stateString = [[self class] stringForState:self.state]; + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCAudioSource)( %p ): %@", self, stateString]; +} + +- (void)setVolume:(double)volume { + _volume = volume; + _nativeAudioSource->SetVolume(volume); +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack+Private.h new file mode 100644 index 0000000000..6495500484 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack+Private.h @@ -0,0 +1,31 @@ +/* + * Copyright 2015 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 "RTCAudioTrack.h" + +#include "api/media_stream_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); +@interface RTC_OBJC_TYPE (RTCAudioTrack) +() + + /** AudioTrackInterface created or passed in at construction. */ + @property(nonatomic, readonly) rtc::scoped_refptr<webrtc::AudioTrackInterface> nativeAudioTrack; + +/** Initialize an RTCAudioTrack with an id. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + source:(RTC_OBJC_TYPE(RTCAudioSource) *)source + trackId:(NSString *)trackId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack.h new file mode 100644 index 0000000000..95eb5d3d48 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack.h @@ -0,0 +1,28 @@ +/* + * Copyright 2015 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 "RTCMacros.h" +#import "RTCMediaStreamTrack.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCAudioSource); + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCAudioTrack) : RTC_OBJC_TYPE(RTCMediaStreamTrack) + +- (instancetype)init NS_UNAVAILABLE; + +/** The audio source for this audio track. */ +@property(nonatomic, readonly) RTC_OBJC_TYPE(RTCAudioSource) * source; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack.mm new file mode 100644 index 0000000000..5c1736f436 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCAudioTrack.mm @@ -0,0 +1,67 @@ +/* + * Copyright 2015 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 "RTCAudioTrack+Private.h" + +#import "RTCAudioSource+Private.h" +#import "RTCMediaStreamTrack+Private.h" +#import "RTCPeerConnectionFactory+Private.h" +#import "helpers/NSString+StdString.h" + +#include "rtc_base/checks.h" + +@implementation RTC_OBJC_TYPE (RTCAudioTrack) + +@synthesize source = _source; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + source:(RTC_OBJC_TYPE(RTCAudioSource) *)source + trackId:(NSString *)trackId { + RTC_DCHECK(factory); + RTC_DCHECK(source); + RTC_DCHECK(trackId.length); + + std::string nativeId = [NSString stdStringForString:trackId]; + rtc::scoped_refptr<webrtc::AudioTrackInterface> track = + factory.nativeFactory->CreateAudioTrack(nativeId, source.nativeAudioSource.get()); + if (self = [self initWithFactory:factory nativeTrack:track type:RTCMediaStreamTrackTypeAudio]) { + _source = source; + } + return self; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack + type:(RTCMediaStreamTrackType)type { + NSParameterAssert(factory); + NSParameterAssert(nativeTrack); + NSParameterAssert(type == RTCMediaStreamTrackTypeAudio); + return [super initWithFactory:factory nativeTrack:nativeTrack type:type]; +} + +- (RTC_OBJC_TYPE(RTCAudioSource) *)source { + if (!_source) { + rtc::scoped_refptr<webrtc::AudioSourceInterface> source(self.nativeAudioTrack->GetSource()); + if (source) { + _source = [[RTC_OBJC_TYPE(RTCAudioSource) alloc] initWithFactory:self.factory + nativeAudioSource:source]; + } + } + return _source; +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::AudioTrackInterface>)nativeAudioTrack { + return rtc::scoped_refptr<webrtc::AudioTrackInterface>( + static_cast<webrtc::AudioTrackInterface *>(self.nativeTrack.get())); +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCertificate.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCertificate.h new file mode 100644 index 0000000000..5ac8984d4a --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCertificate.h @@ -0,0 +1,44 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCCertificate) : NSObject <NSCopying> + +/** Private key in PEM. */ +@property(nonatomic, readonly, copy) NSString *private_key; + +/** Public key in an x509 cert encoded in PEM. */ +@property(nonatomic, readonly, copy) NSString *certificate; + +/** + * Initialize an RTCCertificate with PEM strings for private_key and certificate. + */ +- (instancetype)initWithPrivateKey:(NSString *)private_key + certificate:(NSString *)certificate NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/** Generate a new certificate for 're' use. + * + * Optional dictionary of parameters. Defaults to KeyType ECDSA if none are + * provided. + * - name: "ECDSA" or "RSASSA-PKCS1-v1_5" + */ ++ (nullable RTC_OBJC_TYPE(RTCCertificate) *)generateCertificateWithParams:(NSDictionary *)params; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCertificate.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCertificate.mm new file mode 100644 index 0000000000..e5c33e407c --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCertificate.mm @@ -0,0 +1,72 @@ +/* + * 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 "RTCCertificate.h" + +#import "base/RTCLogging.h" + +#include "rtc_base/logging.h" +#include "rtc_base/rtc_certificate_generator.h" +#include "rtc_base/ssl_identity.h" + +@implementation RTC_OBJC_TYPE (RTCCertificate) + +@synthesize private_key = _private_key; +@synthesize certificate = _certificate; + +- (id)copyWithZone:(NSZone *)zone { + id copy = [[[self class] alloc] initWithPrivateKey:[self.private_key copyWithZone:zone] + certificate:[self.certificate copyWithZone:zone]]; + return copy; +} + +- (instancetype)initWithPrivateKey:(NSString *)private_key certificate:(NSString *)certificate { + if (self = [super init]) { + _private_key = [private_key copy]; + _certificate = [certificate copy]; + } + return self; +} + ++ (nullable RTC_OBJC_TYPE(RTCCertificate) *)generateCertificateWithParams:(NSDictionary *)params { + rtc::KeyType keyType = rtc::KT_ECDSA; + NSString *keyTypeString = [params valueForKey:@"name"]; + if (keyTypeString && [keyTypeString isEqualToString:@"RSASSA-PKCS1-v1_5"]) { + keyType = rtc::KT_RSA; + } + + NSNumber *expires = [params valueForKey:@"expires"]; + rtc::scoped_refptr<rtc::RTCCertificate> cc_certificate = nullptr; + if (expires != nil) { + uint64_t expirationTimestamp = [expires unsignedLongLongValue]; + cc_certificate = rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType), + expirationTimestamp); + } else { + cc_certificate = + rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType), absl::nullopt); + } + if (!cc_certificate) { + RTCLogError(@"Failed to generate certificate."); + return nullptr; + } + // grab PEMs and create an NS RTCCerticicate + rtc::RTCCertificatePEM pem = cc_certificate->ToPEM(); + std::string pem_private_key = pem.private_key(); + std::string pem_certificate = pem.certificate(); + RTC_LOG(LS_INFO) << "CERT PEM "; + RTC_LOG(LS_INFO) << pem_certificate; + + RTC_OBJC_TYPE(RTCCertificate) *cert = + [[RTC_OBJC_TYPE(RTCCertificate) alloc] initWithPrivateKey:@(pem_private_key.c_str()) + certificate:@(pem_certificate.c_str())]; + return cert; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Native.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Native.h new file mode 100644 index 0000000000..07c0da6041 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Native.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 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 "RTCConfiguration.h" + +#include "api/peer_connection_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCConfiguration) +() + + /** Optional TurnCustomizer. + * With this class one can modify outgoing TURN messages. + * The object passed in must remain valid until PeerConnection::Close() is + * called. + */ + @property(nonatomic, nullable) webrtc::TurnCustomizer* turnCustomizer; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Private.h new file mode 100644 index 0000000000..70a6532dbc --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Private.h @@ -0,0 +1,79 @@ +/* + * Copyright 2015 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 "RTCConfiguration.h" + +#include "api/peer_connection_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCConfiguration) +() + + + (webrtc::PeerConnectionInterface::IceTransportsType)nativeTransportsTypeForTransportPolicy + : (RTCIceTransportPolicy)policy; + ++ (RTCIceTransportPolicy)transportPolicyForTransportsType: + (webrtc::PeerConnectionInterface::IceTransportsType)nativeType; + ++ (NSString *)stringForTransportPolicy:(RTCIceTransportPolicy)policy; + ++ (webrtc::PeerConnectionInterface::BundlePolicy)nativeBundlePolicyForPolicy: + (RTCBundlePolicy)policy; + ++ (RTCBundlePolicy)bundlePolicyForNativePolicy: + (webrtc::PeerConnectionInterface::BundlePolicy)nativePolicy; + ++ (NSString *)stringForBundlePolicy:(RTCBundlePolicy)policy; + ++ (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativeRtcpMuxPolicyForPolicy: + (RTCRtcpMuxPolicy)policy; + ++ (RTCRtcpMuxPolicy)rtcpMuxPolicyForNativePolicy: + (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativePolicy; + ++ (NSString *)stringForRtcpMuxPolicy:(RTCRtcpMuxPolicy)policy; + ++ (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativeTcpCandidatePolicyForPolicy: + (RTCTcpCandidatePolicy)policy; + ++ (RTCTcpCandidatePolicy)tcpCandidatePolicyForNativePolicy: + (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativePolicy; + ++ (NSString *)stringForTcpCandidatePolicy:(RTCTcpCandidatePolicy)policy; + ++ (webrtc::PeerConnectionInterface::CandidateNetworkPolicy)nativeCandidateNetworkPolicyForPolicy: + (RTCCandidateNetworkPolicy)policy; + ++ (RTCCandidateNetworkPolicy)candidateNetworkPolicyForNativePolicy: + (webrtc::PeerConnectionInterface::CandidateNetworkPolicy)nativePolicy; + ++ (NSString *)stringForCandidateNetworkPolicy:(RTCCandidateNetworkPolicy)policy; + ++ (rtc::KeyType)nativeEncryptionKeyTypeForKeyType:(RTCEncryptionKeyType)keyType; + ++ (webrtc::SdpSemantics)nativeSdpSemanticsForSdpSemantics:(RTCSdpSemantics)sdpSemantics; + ++ (RTCSdpSemantics)sdpSemanticsForNativeSdpSemantics:(webrtc::SdpSemantics)sdpSemantics; + ++ (NSString *)stringForSdpSemantics:(RTCSdpSemantics)sdpSemantics; + +/** + * RTCConfiguration struct representation of this RTCConfiguration. + * This is needed to pass to the underlying C++ APIs. + */ +- (nullable webrtc::PeerConnectionInterface::RTCConfiguration *)createNativeConfiguration; + +- (instancetype)initWithNativeConfiguration: + (const webrtc::PeerConnectionInterface::RTCConfiguration &)config NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration.h new file mode 100644 index 0000000000..1b0d14baf1 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration.h @@ -0,0 +1,268 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCCertificate.h" +#import "RTCCryptoOptions.h" +#import "RTCMacros.h" + +@class RTC_OBJC_TYPE(RTCIceServer); + +/** + * Represents the ice transport policy. This exposes the same states in C++, + * which include one more state than what exists in the W3C spec. + */ +typedef NS_ENUM(NSInteger, RTCIceTransportPolicy) { + RTCIceTransportPolicyNone, + RTCIceTransportPolicyRelay, + RTCIceTransportPolicyNoHost, + RTCIceTransportPolicyAll +}; + +/** Represents the bundle policy. */ +typedef NS_ENUM(NSInteger, RTCBundlePolicy) { + RTCBundlePolicyBalanced, + RTCBundlePolicyMaxCompat, + RTCBundlePolicyMaxBundle +}; + +/** Represents the rtcp mux policy. */ +typedef NS_ENUM(NSInteger, RTCRtcpMuxPolicy) { RTCRtcpMuxPolicyNegotiate, RTCRtcpMuxPolicyRequire }; + +/** Represents the tcp candidate policy. */ +typedef NS_ENUM(NSInteger, RTCTcpCandidatePolicy) { + RTCTcpCandidatePolicyEnabled, + RTCTcpCandidatePolicyDisabled +}; + +/** Represents the candidate network policy. */ +typedef NS_ENUM(NSInteger, RTCCandidateNetworkPolicy) { + RTCCandidateNetworkPolicyAll, + RTCCandidateNetworkPolicyLowCost +}; + +/** Represents the continual gathering policy. */ +typedef NS_ENUM(NSInteger, RTCContinualGatheringPolicy) { + RTCContinualGatheringPolicyGatherOnce, + RTCContinualGatheringPolicyGatherContinually +}; + +/** Represents the encryption key type. */ +typedef NS_ENUM(NSInteger, RTCEncryptionKeyType) { + RTCEncryptionKeyTypeRSA, + RTCEncryptionKeyTypeECDSA, +}; + +/** Represents the chosen SDP semantics for the RTCPeerConnection. */ +typedef NS_ENUM(NSInteger, RTCSdpSemantics) { + // TODO(https://crbug.com/webrtc/13528): Remove support for Plan B. + RTCSdpSemanticsPlanB, + RTCSdpSemanticsUnifiedPlan, +}; + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCConfiguration) : NSObject + +/** If true, allows DSCP codes to be set on outgoing packets, configured using + * networkPriority field of RTCRtpEncodingParameters. Defaults to false. + */ +@property(nonatomic, assign) BOOL enableDscp; + +/** An array of Ice Servers available to be used by ICE. */ +@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCIceServer) *> *iceServers; + +/** An RTCCertificate for 're' use. */ +@property(nonatomic, nullable) RTC_OBJC_TYPE(RTCCertificate) * certificate; + +/** Which candidates the ICE agent is allowed to use. The W3C calls it + * `iceTransportPolicy`, while in C++ it is called `type`. */ +@property(nonatomic, assign) RTCIceTransportPolicy iceTransportPolicy; + +/** The media-bundling policy to use when gathering ICE candidates. */ +@property(nonatomic, assign) RTCBundlePolicy bundlePolicy; + +/** The rtcp-mux policy to use when gathering ICE candidates. */ +@property(nonatomic, assign) RTCRtcpMuxPolicy rtcpMuxPolicy; +@property(nonatomic, assign) RTCTcpCandidatePolicy tcpCandidatePolicy; +@property(nonatomic, assign) RTCCandidateNetworkPolicy candidateNetworkPolicy; +@property(nonatomic, assign) RTCContinualGatheringPolicy continualGatheringPolicy; + +/** If set to YES, don't gather IPv6 ICE candidates on Wi-Fi. + * Only intended to be used on specific devices. Certain phones disable IPv6 + * when the screen is turned off and it would be better to just disable the + * IPv6 ICE candidates on Wi-Fi in those cases. + * Default is NO. + */ +@property(nonatomic, assign) BOOL disableIPV6OnWiFi; + +/** By default, the PeerConnection will use a limited number of IPv6 network + * interfaces, in order to avoid too many ICE candidate pairs being created + * and delaying ICE completion. + * + * Can be set to INT_MAX to effectively disable the limit. + */ +@property(nonatomic, assign) int maxIPv6Networks; + +/** Exclude link-local network interfaces + * from considertaion for gathering ICE candidates. + * Defaults to NO. + */ +@property(nonatomic, assign) BOOL disableLinkLocalNetworks; + +@property(nonatomic, assign) int audioJitterBufferMaxPackets; +@property(nonatomic, assign) BOOL audioJitterBufferFastAccelerate; +@property(nonatomic, assign) int iceConnectionReceivingTimeout; +@property(nonatomic, assign) int iceBackupCandidatePairPingInterval; + +/** Key type used to generate SSL identity. Default is ECDSA. */ +@property(nonatomic, assign) RTCEncryptionKeyType keyType; + +/** ICE candidate pool size as defined in JSEP. Default is 0. */ +@property(nonatomic, assign) int iceCandidatePoolSize; + +/** Prune turn ports on the same network to the same turn server. + * Default is NO. + */ +@property(nonatomic, assign) BOOL shouldPruneTurnPorts; + +/** If set to YES, this means the ICE transport should presume TURN-to-TURN + * candidate pairs will succeed, even before a binding response is received. + */ +@property(nonatomic, assign) BOOL shouldPresumeWritableWhenFullyRelayed; + +/* This flag is only effective when `continualGatheringPolicy` is + * RTCContinualGatheringPolicyGatherContinually. + * + * If YES, after the ICE transport type is changed such that new types of + * ICE candidates are allowed by the new transport type, e.g. from + * RTCIceTransportPolicyRelay to RTCIceTransportPolicyAll, candidates that + * have been gathered by the ICE transport but not matching the previous + * transport type and as a result not observed by PeerConnectionDelegateAdapter, + * will be surfaced to the delegate. + */ +@property(nonatomic, assign) BOOL shouldSurfaceIceCandidatesOnIceTransportTypeChanged; + +/** If set to non-nil, controls the minimal interval between consecutive ICE + * check packets. + */ +@property(nonatomic, copy, nullable) NSNumber *iceCheckMinInterval; + +/** + * Configure the SDP semantics used by this PeerConnection. By default, this + * is RTCSdpSemanticsUnifiedPlan which is compliant to the WebRTC 1.0 + * specification. It is possible to overrwite this to the deprecated + * RTCSdpSemanticsPlanB SDP format, but note that RTCSdpSemanticsPlanB will be + * deleted at some future date, see https://crbug.com/webrtc/13528. + * + * RTCSdpSemanticsUnifiedPlan will cause RTCPeerConnection to create offers and + * answers with multiple m= sections where each m= section maps to one + * RTCRtpSender and one RTCRtpReceiver (an RTCRtpTransceiver), either both audio + * or both video. This will also cause RTCPeerConnection to ignore all but the + * first a=ssrc lines that form a Plan B stream. + * + * RTCSdpSemanticsPlanB will cause RTCPeerConnection to create offers and + * answers with at most one audio and one video m= section with multiple + * RTCRtpSenders and RTCRtpReceivers specified as multiple a=ssrc lines within + * the section. This will also cause RTCPeerConnection to ignore all but the + * first m= section of the same media type. + */ +@property(nonatomic, assign) RTCSdpSemantics sdpSemantics; + +/** Actively reset the SRTP parameters when the DTLS transports underneath are + * changed after offer/answer negotiation. This is only intended to be a + * workaround for crbug.com/835958 + */ +@property(nonatomic, assign) BOOL activeResetSrtpParams; + +/** If the remote side support mid-stream codec switches then allow encoder + * switching to be performed. + */ + +@property(nonatomic, assign) BOOL allowCodecSwitching; + +/** + * Defines advanced optional cryptographic settings related to SRTP and + * frame encryption for native WebRTC. Setting this will overwrite any + * options set through the PeerConnectionFactory (which is deprecated). + */ +@property(nonatomic, nullable) RTC_OBJC_TYPE(RTCCryptoOptions) * cryptoOptions; + +/** + * An optional string that will be attached to the TURN_ALLOCATE_REQUEST which + * which can be used to correlate client logs with backend logs. + */ +@property(nonatomic, nullable, copy) NSString *turnLoggingId; + +/** + * Time interval between audio RTCP reports. + */ +@property(nonatomic, assign) int rtcpAudioReportIntervalMs; + +/** + * Time interval between video RTCP reports. + */ +@property(nonatomic, assign) int rtcpVideoReportIntervalMs; + +/** + * Allow implicit rollback of local description when remote description + * conflicts with local description. + * See: https://w3c.github.io/webrtc-pc/#dom-peerconnection-setremotedescription + */ +@property(nonatomic, assign) BOOL enableImplicitRollback; + +/** + * Control if "a=extmap-allow-mixed" is included in the offer. + * See: https://www.chromestatus.com/feature/6269234631933952 + */ +@property(nonatomic, assign) BOOL offerExtmapAllowMixed; + +/** + * Defines the interval applied to ALL candidate pairs + * when ICE is strongly connected, and it overrides the + * default value of this interval in the ICE implementation; + */ +@property(nonatomic, copy, nullable) NSNumber *iceCheckIntervalStrongConnectivity; + +/** + * Defines the counterpart for ALL pairs when ICE is + * weakly connected, and it overrides the default value of + * this interval in the ICE implementation + */ +@property(nonatomic, copy, nullable) NSNumber *iceCheckIntervalWeakConnectivity; + +/** + * The min time period for which a candidate pair must wait for response to + * connectivity checks before it becomes unwritable. This parameter + * overrides the default value in the ICE implementation if set. + */ +@property(nonatomic, copy, nullable) NSNumber *iceUnwritableTimeout; + +/** + * The min number of connectivity checks that a candidate pair must sent + * without receiving response before it becomes unwritable. This parameter + * overrides the default value in the ICE implementation if set. + */ +@property(nonatomic, copy, nullable) NSNumber *iceUnwritableMinChecks; + +/** + * The min time period for which a candidate pair must wait for response to + * connectivity checks it becomes inactive. This parameter overrides the + * default value in the ICE implementation if set. + */ +@property(nonatomic, copy, nullable) NSNumber *iceInactiveTimeout; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration.mm new file mode 100644 index 0000000000..8e42cb2a82 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration.mm @@ -0,0 +1,544 @@ +/* + * Copyright 2015 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 "RTCConfiguration+Private.h" + +#include <memory> + +#import "RTCCertificate.h" +#import "RTCConfiguration+Native.h" +#import "RTCIceServer+Private.h" +#import "base/RTCLogging.h" + +#include "rtc_base/checks.h" +#include "rtc_base/rtc_certificate_generator.h" +#include "rtc_base/ssl_identity.h" + +@implementation RTC_OBJC_TYPE (RTCConfiguration) + +@synthesize enableDscp = _enableDscp; +@synthesize iceServers = _iceServers; +@synthesize certificate = _certificate; +@synthesize iceTransportPolicy = _iceTransportPolicy; +@synthesize bundlePolicy = _bundlePolicy; +@synthesize rtcpMuxPolicy = _rtcpMuxPolicy; +@synthesize tcpCandidatePolicy = _tcpCandidatePolicy; +@synthesize candidateNetworkPolicy = _candidateNetworkPolicy; +@synthesize continualGatheringPolicy = _continualGatheringPolicy; +@synthesize disableIPV6OnWiFi = _disableIPV6OnWiFi; +@synthesize maxIPv6Networks = _maxIPv6Networks; +@synthesize disableLinkLocalNetworks = _disableLinkLocalNetworks; +@synthesize audioJitterBufferMaxPackets = _audioJitterBufferMaxPackets; +@synthesize audioJitterBufferFastAccelerate = _audioJitterBufferFastAccelerate; +@synthesize iceConnectionReceivingTimeout = _iceConnectionReceivingTimeout; +@synthesize iceBackupCandidatePairPingInterval = + _iceBackupCandidatePairPingInterval; +@synthesize keyType = _keyType; +@synthesize iceCandidatePoolSize = _iceCandidatePoolSize; +@synthesize shouldPruneTurnPorts = _shouldPruneTurnPorts; +@synthesize shouldPresumeWritableWhenFullyRelayed = + _shouldPresumeWritableWhenFullyRelayed; +@synthesize shouldSurfaceIceCandidatesOnIceTransportTypeChanged = + _shouldSurfaceIceCandidatesOnIceTransportTypeChanged; +@synthesize iceCheckMinInterval = _iceCheckMinInterval; +@synthesize sdpSemantics = _sdpSemantics; +@synthesize turnCustomizer = _turnCustomizer; +@synthesize activeResetSrtpParams = _activeResetSrtpParams; +@synthesize allowCodecSwitching = _allowCodecSwitching; +@synthesize cryptoOptions = _cryptoOptions; +@synthesize turnLoggingId = _turnLoggingId; +@synthesize rtcpAudioReportIntervalMs = _rtcpAudioReportIntervalMs; +@synthesize rtcpVideoReportIntervalMs = _rtcpVideoReportIntervalMs; +@synthesize enableImplicitRollback = _enableImplicitRollback; +@synthesize offerExtmapAllowMixed = _offerExtmapAllowMixed; +@synthesize iceCheckIntervalStrongConnectivity = _iceCheckIntervalStrongConnectivity; +@synthesize iceCheckIntervalWeakConnectivity = _iceCheckIntervalWeakConnectivity; +@synthesize iceUnwritableTimeout = _iceUnwritableTimeout; +@synthesize iceUnwritableMinChecks = _iceUnwritableMinChecks; +@synthesize iceInactiveTimeout = _iceInactiveTimeout; + +- (instancetype)init { + // Copy defaults. + webrtc::PeerConnectionInterface::RTCConfiguration config; + config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; + return [self initWithNativeConfiguration:config]; +} + +- (instancetype)initWithNativeConfiguration: + (const webrtc::PeerConnectionInterface::RTCConfiguration &)config { + if (self = [super init]) { + _enableDscp = config.dscp(); + NSMutableArray *iceServers = [NSMutableArray array]; + for (const webrtc::PeerConnectionInterface::IceServer& server : config.servers) { + RTC_OBJC_TYPE(RTCIceServer) *iceServer = + [[RTC_OBJC_TYPE(RTCIceServer) alloc] initWithNativeServer:server]; + [iceServers addObject:iceServer]; + } + _iceServers = iceServers; + if (!config.certificates.empty()) { + rtc::scoped_refptr<rtc::RTCCertificate> native_cert; + native_cert = config.certificates[0]; + rtc::RTCCertificatePEM native_pem = native_cert->ToPEM(); + _certificate = [[RTC_OBJC_TYPE(RTCCertificate) alloc] + initWithPrivateKey:@(native_pem.private_key().c_str()) + certificate:@(native_pem.certificate().c_str())]; + } + _iceTransportPolicy = + [[self class] transportPolicyForTransportsType:config.type]; + _bundlePolicy = + [[self class] bundlePolicyForNativePolicy:config.bundle_policy]; + _rtcpMuxPolicy = + [[self class] rtcpMuxPolicyForNativePolicy:config.rtcp_mux_policy]; + _tcpCandidatePolicy = [[self class] tcpCandidatePolicyForNativePolicy: + config.tcp_candidate_policy]; + _candidateNetworkPolicy = [[self class] + candidateNetworkPolicyForNativePolicy:config.candidate_network_policy]; + webrtc::PeerConnectionInterface::ContinualGatheringPolicy nativePolicy = + config.continual_gathering_policy; + _continualGatheringPolicy = [[self class] continualGatheringPolicyForNativePolicy:nativePolicy]; + _disableIPV6OnWiFi = config.disable_ipv6_on_wifi; + _maxIPv6Networks = config.max_ipv6_networks; + _disableLinkLocalNetworks = config.disable_link_local_networks; + _audioJitterBufferMaxPackets = config.audio_jitter_buffer_max_packets; + _audioJitterBufferFastAccelerate = config.audio_jitter_buffer_fast_accelerate; + _iceConnectionReceivingTimeout = config.ice_connection_receiving_timeout; + _iceBackupCandidatePairPingInterval = + config.ice_backup_candidate_pair_ping_interval; + _keyType = RTCEncryptionKeyTypeECDSA; + _iceCandidatePoolSize = config.ice_candidate_pool_size; + _shouldPruneTurnPorts = config.prune_turn_ports; + _shouldPresumeWritableWhenFullyRelayed = + config.presume_writable_when_fully_relayed; + _shouldSurfaceIceCandidatesOnIceTransportTypeChanged = + config.surface_ice_candidates_on_ice_transport_type_changed; + if (config.ice_check_min_interval) { + _iceCheckMinInterval = + [NSNumber numberWithInt:*config.ice_check_min_interval]; + } + _sdpSemantics = [[self class] sdpSemanticsForNativeSdpSemantics:config.sdp_semantics]; + _turnCustomizer = config.turn_customizer; + _activeResetSrtpParams = config.active_reset_srtp_params; + if (config.crypto_options) { + _cryptoOptions = [[RTC_OBJC_TYPE(RTCCryptoOptions) alloc] + initWithSrtpEnableGcmCryptoSuites:config.crypto_options->srtp + .enable_gcm_crypto_suites + srtpEnableAes128Sha1_32CryptoCipher:config.crypto_options->srtp + .enable_aes128_sha1_32_crypto_cipher + srtpEnableEncryptedRtpHeaderExtensions:config.crypto_options->srtp + .enable_encrypted_rtp_header_extensions + sframeRequireFrameEncryption:config.crypto_options->sframe + .require_frame_encryption]; + } + _turnLoggingId = [NSString stringWithUTF8String:config.turn_logging_id.c_str()]; + _rtcpAudioReportIntervalMs = config.audio_rtcp_report_interval_ms(); + _rtcpVideoReportIntervalMs = config.video_rtcp_report_interval_ms(); + _allowCodecSwitching = config.allow_codec_switching.value_or(false); + _enableImplicitRollback = config.enable_implicit_rollback; + _offerExtmapAllowMixed = config.offer_extmap_allow_mixed; + _iceCheckIntervalStrongConnectivity = + config.ice_check_interval_strong_connectivity.has_value() ? + [NSNumber numberWithInt:*config.ice_check_interval_strong_connectivity] : + nil; + _iceCheckIntervalWeakConnectivity = config.ice_check_interval_weak_connectivity.has_value() ? + [NSNumber numberWithInt:*config.ice_check_interval_weak_connectivity] : + nil; + _iceUnwritableTimeout = config.ice_unwritable_timeout.has_value() ? + [NSNumber numberWithInt:*config.ice_unwritable_timeout] : + nil; + _iceUnwritableMinChecks = config.ice_unwritable_min_checks.has_value() ? + [NSNumber numberWithInt:*config.ice_unwritable_min_checks] : + nil; + _iceInactiveTimeout = config.ice_inactive_timeout.has_value() ? + [NSNumber numberWithInt:*config.ice_inactive_timeout] : + nil; + } + return self; +} + +- (NSString *)description { + static NSString *formatString = @"RTC_OBJC_TYPE(RTCConfiguration): " + @"{\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%d\n%d\n%d\n%d\n%d\n%d\n" + @"%d\n%@\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n}\n"; + + return [NSString + stringWithFormat:formatString, + _iceServers, + [[self class] stringForTransportPolicy:_iceTransportPolicy], + [[self class] stringForBundlePolicy:_bundlePolicy], + [[self class] stringForRtcpMuxPolicy:_rtcpMuxPolicy], + [[self class] stringForTcpCandidatePolicy:_tcpCandidatePolicy], + [[self class] stringForCandidateNetworkPolicy:_candidateNetworkPolicy], + [[self class] stringForContinualGatheringPolicy:_continualGatheringPolicy], + [[self class] stringForSdpSemantics:_sdpSemantics], + _audioJitterBufferMaxPackets, + _audioJitterBufferFastAccelerate, + _iceConnectionReceivingTimeout, + _iceBackupCandidatePairPingInterval, + _iceCandidatePoolSize, + _shouldPruneTurnPorts, + _shouldPresumeWritableWhenFullyRelayed, + _shouldSurfaceIceCandidatesOnIceTransportTypeChanged, + _iceCheckMinInterval, + _disableLinkLocalNetworks, + _disableIPV6OnWiFi, + _maxIPv6Networks, + _activeResetSrtpParams, + _enableDscp, + _enableImplicitRollback]; +} + +#pragma mark - Private + +- (webrtc::PeerConnectionInterface::RTCConfiguration *) + createNativeConfiguration { + std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> + nativeConfig(new webrtc::PeerConnectionInterface::RTCConfiguration( + webrtc::PeerConnectionInterface::RTCConfigurationType::kAggressive)); + + nativeConfig->set_dscp(_enableDscp); + for (RTC_OBJC_TYPE(RTCIceServer) * iceServer in _iceServers) { + nativeConfig->servers.push_back(iceServer.nativeServer); + } + nativeConfig->type = + [[self class] nativeTransportsTypeForTransportPolicy:_iceTransportPolicy]; + nativeConfig->bundle_policy = + [[self class] nativeBundlePolicyForPolicy:_bundlePolicy]; + nativeConfig->rtcp_mux_policy = + [[self class] nativeRtcpMuxPolicyForPolicy:_rtcpMuxPolicy]; + nativeConfig->tcp_candidate_policy = + [[self class] nativeTcpCandidatePolicyForPolicy:_tcpCandidatePolicy]; + nativeConfig->candidate_network_policy = [[self class] + nativeCandidateNetworkPolicyForPolicy:_candidateNetworkPolicy]; + nativeConfig->continual_gathering_policy = + [[self class] nativeContinualGatheringPolicyForPolicy:_continualGatheringPolicy]; + nativeConfig->disable_ipv6_on_wifi = _disableIPV6OnWiFi; + nativeConfig->max_ipv6_networks = _maxIPv6Networks; + nativeConfig->disable_link_local_networks = _disableLinkLocalNetworks; + nativeConfig->audio_jitter_buffer_max_packets = _audioJitterBufferMaxPackets; + nativeConfig->audio_jitter_buffer_fast_accelerate = + _audioJitterBufferFastAccelerate ? true : false; + nativeConfig->ice_connection_receiving_timeout = + _iceConnectionReceivingTimeout; + nativeConfig->ice_backup_candidate_pair_ping_interval = + _iceBackupCandidatePairPingInterval; + rtc::KeyType keyType = + [[self class] nativeEncryptionKeyTypeForKeyType:_keyType]; + if (_certificate != nullptr) { + // if offered a pemcert use it... + RTC_LOG(LS_INFO) << "Have configured cert - using it."; + std::string pem_private_key = [[_certificate private_key] UTF8String]; + std::string pem_certificate = [[_certificate certificate] UTF8String]; + rtc::RTCCertificatePEM pem = rtc::RTCCertificatePEM(pem_private_key, pem_certificate); + rtc::scoped_refptr<rtc::RTCCertificate> certificate = rtc::RTCCertificate::FromPEM(pem); + RTC_LOG(LS_INFO) << "Created cert from PEM strings."; + if (!certificate) { + RTC_LOG(LS_ERROR) << "Failed to generate certificate from PEM."; + return nullptr; + } + nativeConfig->certificates.push_back(certificate); + } else { + RTC_LOG(LS_INFO) << "Don't have configured cert."; + // Generate non-default certificate. + if (keyType != rtc::KT_DEFAULT) { + rtc::scoped_refptr<rtc::RTCCertificate> certificate = + rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType), + absl::optional<uint64_t>()); + if (!certificate) { + RTCLogError(@"Failed to generate certificate."); + return nullptr; + } + nativeConfig->certificates.push_back(certificate); + } + } + nativeConfig->ice_candidate_pool_size = _iceCandidatePoolSize; + nativeConfig->prune_turn_ports = _shouldPruneTurnPorts ? true : false; + nativeConfig->presume_writable_when_fully_relayed = + _shouldPresumeWritableWhenFullyRelayed ? true : false; + nativeConfig->surface_ice_candidates_on_ice_transport_type_changed = + _shouldSurfaceIceCandidatesOnIceTransportTypeChanged ? true : false; + if (_iceCheckMinInterval != nil) { + nativeConfig->ice_check_min_interval = absl::optional<int>(_iceCheckMinInterval.intValue); + } + nativeConfig->sdp_semantics = [[self class] nativeSdpSemanticsForSdpSemantics:_sdpSemantics]; + if (_turnCustomizer) { + nativeConfig->turn_customizer = _turnCustomizer; + } + nativeConfig->active_reset_srtp_params = _activeResetSrtpParams ? true : false; + if (_cryptoOptions) { + webrtc::CryptoOptions nativeCryptoOptions; + nativeCryptoOptions.srtp.enable_gcm_crypto_suites = + _cryptoOptions.srtpEnableGcmCryptoSuites ? true : false; + nativeCryptoOptions.srtp.enable_aes128_sha1_32_crypto_cipher = + _cryptoOptions.srtpEnableAes128Sha1_32CryptoCipher ? true : false; + nativeCryptoOptions.srtp.enable_encrypted_rtp_header_extensions = + _cryptoOptions.srtpEnableEncryptedRtpHeaderExtensions ? true : false; + nativeCryptoOptions.sframe.require_frame_encryption = + _cryptoOptions.sframeRequireFrameEncryption ? true : false; + nativeConfig->crypto_options = absl::optional<webrtc::CryptoOptions>(nativeCryptoOptions); + } + nativeConfig->turn_logging_id = [_turnLoggingId UTF8String]; + nativeConfig->set_audio_rtcp_report_interval_ms(_rtcpAudioReportIntervalMs); + nativeConfig->set_video_rtcp_report_interval_ms(_rtcpVideoReportIntervalMs); + nativeConfig->allow_codec_switching = _allowCodecSwitching; + nativeConfig->enable_implicit_rollback = _enableImplicitRollback; + nativeConfig->offer_extmap_allow_mixed = _offerExtmapAllowMixed; + if (_iceCheckIntervalStrongConnectivity != nil) { + nativeConfig->ice_check_interval_strong_connectivity = + absl::optional<int>(_iceCheckIntervalStrongConnectivity.intValue); + } + if (_iceCheckIntervalWeakConnectivity != nil) { + nativeConfig->ice_check_interval_weak_connectivity = + absl::optional<int>(_iceCheckIntervalWeakConnectivity.intValue); + } + if (_iceUnwritableTimeout != nil) { + nativeConfig->ice_unwritable_timeout = absl::optional<int>(_iceUnwritableTimeout.intValue); + } + if (_iceUnwritableMinChecks != nil) { + nativeConfig->ice_unwritable_min_checks = absl::optional<int>(_iceUnwritableMinChecks.intValue); + } + if (_iceInactiveTimeout != nil) { + nativeConfig->ice_inactive_timeout = absl::optional<int>(_iceInactiveTimeout.intValue); + } + return nativeConfig.release(); +} + ++ (webrtc::PeerConnectionInterface::IceTransportsType) + nativeTransportsTypeForTransportPolicy:(RTCIceTransportPolicy)policy { + switch (policy) { + case RTCIceTransportPolicyNone: + return webrtc::PeerConnectionInterface::kNone; + case RTCIceTransportPolicyRelay: + return webrtc::PeerConnectionInterface::kRelay; + case RTCIceTransportPolicyNoHost: + return webrtc::PeerConnectionInterface::kNoHost; + case RTCIceTransportPolicyAll: + return webrtc::PeerConnectionInterface::kAll; + } +} + ++ (RTCIceTransportPolicy)transportPolicyForTransportsType: + (webrtc::PeerConnectionInterface::IceTransportsType)nativeType { + switch (nativeType) { + case webrtc::PeerConnectionInterface::kNone: + return RTCIceTransportPolicyNone; + case webrtc::PeerConnectionInterface::kRelay: + return RTCIceTransportPolicyRelay; + case webrtc::PeerConnectionInterface::kNoHost: + return RTCIceTransportPolicyNoHost; + case webrtc::PeerConnectionInterface::kAll: + return RTCIceTransportPolicyAll; + } +} + ++ (NSString *)stringForTransportPolicy:(RTCIceTransportPolicy)policy { + switch (policy) { + case RTCIceTransportPolicyNone: + return @"NONE"; + case RTCIceTransportPolicyRelay: + return @"RELAY"; + case RTCIceTransportPolicyNoHost: + return @"NO_HOST"; + case RTCIceTransportPolicyAll: + return @"ALL"; + } +} + ++ (webrtc::PeerConnectionInterface::BundlePolicy)nativeBundlePolicyForPolicy: + (RTCBundlePolicy)policy { + switch (policy) { + case RTCBundlePolicyBalanced: + return webrtc::PeerConnectionInterface::kBundlePolicyBalanced; + case RTCBundlePolicyMaxCompat: + return webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat; + case RTCBundlePolicyMaxBundle: + return webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle; + } +} + ++ (RTCBundlePolicy)bundlePolicyForNativePolicy: + (webrtc::PeerConnectionInterface::BundlePolicy)nativePolicy { + switch (nativePolicy) { + case webrtc::PeerConnectionInterface::kBundlePolicyBalanced: + return RTCBundlePolicyBalanced; + case webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat: + return RTCBundlePolicyMaxCompat; + case webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle: + return RTCBundlePolicyMaxBundle; + } +} + ++ (NSString *)stringForBundlePolicy:(RTCBundlePolicy)policy { + switch (policy) { + case RTCBundlePolicyBalanced: + return @"BALANCED"; + case RTCBundlePolicyMaxCompat: + return @"MAX_COMPAT"; + case RTCBundlePolicyMaxBundle: + return @"MAX_BUNDLE"; + } +} + ++ (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativeRtcpMuxPolicyForPolicy: + (RTCRtcpMuxPolicy)policy { + switch (policy) { + case RTCRtcpMuxPolicyNegotiate: + return webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate; + case RTCRtcpMuxPolicyRequire: + return webrtc::PeerConnectionInterface::kRtcpMuxPolicyRequire; + } +} + ++ (RTCRtcpMuxPolicy)rtcpMuxPolicyForNativePolicy: + (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativePolicy { + switch (nativePolicy) { + case webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate: + return RTCRtcpMuxPolicyNegotiate; + case webrtc::PeerConnectionInterface::kRtcpMuxPolicyRequire: + return RTCRtcpMuxPolicyRequire; + } +} + ++ (NSString *)stringForRtcpMuxPolicy:(RTCRtcpMuxPolicy)policy { + switch (policy) { + case RTCRtcpMuxPolicyNegotiate: + return @"NEGOTIATE"; + case RTCRtcpMuxPolicyRequire: + return @"REQUIRE"; + } +} + ++ (webrtc::PeerConnectionInterface::TcpCandidatePolicy) + nativeTcpCandidatePolicyForPolicy:(RTCTcpCandidatePolicy)policy { + switch (policy) { + case RTCTcpCandidatePolicyEnabled: + return webrtc::PeerConnectionInterface::kTcpCandidatePolicyEnabled; + case RTCTcpCandidatePolicyDisabled: + return webrtc::PeerConnectionInterface::kTcpCandidatePolicyDisabled; + } +} + ++ (webrtc::PeerConnectionInterface::CandidateNetworkPolicy) + nativeCandidateNetworkPolicyForPolicy:(RTCCandidateNetworkPolicy)policy { + switch (policy) { + case RTCCandidateNetworkPolicyAll: + return webrtc::PeerConnectionInterface::kCandidateNetworkPolicyAll; + case RTCCandidateNetworkPolicyLowCost: + return webrtc::PeerConnectionInterface::kCandidateNetworkPolicyLowCost; + } +} + ++ (RTCTcpCandidatePolicy)tcpCandidatePolicyForNativePolicy: + (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativePolicy { + switch (nativePolicy) { + case webrtc::PeerConnectionInterface::kTcpCandidatePolicyEnabled: + return RTCTcpCandidatePolicyEnabled; + case webrtc::PeerConnectionInterface::kTcpCandidatePolicyDisabled: + return RTCTcpCandidatePolicyDisabled; + } +} + ++ (NSString *)stringForTcpCandidatePolicy:(RTCTcpCandidatePolicy)policy { + switch (policy) { + case RTCTcpCandidatePolicyEnabled: + return @"TCP_ENABLED"; + case RTCTcpCandidatePolicyDisabled: + return @"TCP_DISABLED"; + } +} + ++ (RTCCandidateNetworkPolicy)candidateNetworkPolicyForNativePolicy: + (webrtc::PeerConnectionInterface::CandidateNetworkPolicy)nativePolicy { + switch (nativePolicy) { + case webrtc::PeerConnectionInterface::kCandidateNetworkPolicyAll: + return RTCCandidateNetworkPolicyAll; + case webrtc::PeerConnectionInterface::kCandidateNetworkPolicyLowCost: + return RTCCandidateNetworkPolicyLowCost; + } +} + ++ (NSString *)stringForCandidateNetworkPolicy: + (RTCCandidateNetworkPolicy)policy { + switch (policy) { + case RTCCandidateNetworkPolicyAll: + return @"CANDIDATE_ALL_NETWORKS"; + case RTCCandidateNetworkPolicyLowCost: + return @"CANDIDATE_LOW_COST_NETWORKS"; + } +} + ++ (webrtc::PeerConnectionInterface::ContinualGatheringPolicy) + nativeContinualGatheringPolicyForPolicy: + (RTCContinualGatheringPolicy)policy { + switch (policy) { + case RTCContinualGatheringPolicyGatherOnce: + return webrtc::PeerConnectionInterface::GATHER_ONCE; + case RTCContinualGatheringPolicyGatherContinually: + return webrtc::PeerConnectionInterface::GATHER_CONTINUALLY; + } +} + ++ (RTCContinualGatheringPolicy)continualGatheringPolicyForNativePolicy: + (webrtc::PeerConnectionInterface::ContinualGatheringPolicy)nativePolicy { + switch (nativePolicy) { + case webrtc::PeerConnectionInterface::GATHER_ONCE: + return RTCContinualGatheringPolicyGatherOnce; + case webrtc::PeerConnectionInterface::GATHER_CONTINUALLY: + return RTCContinualGatheringPolicyGatherContinually; + } +} + ++ (NSString *)stringForContinualGatheringPolicy: + (RTCContinualGatheringPolicy)policy { + switch (policy) { + case RTCContinualGatheringPolicyGatherOnce: + return @"GATHER_ONCE"; + case RTCContinualGatheringPolicyGatherContinually: + return @"GATHER_CONTINUALLY"; + } +} + ++ (rtc::KeyType)nativeEncryptionKeyTypeForKeyType: + (RTCEncryptionKeyType)keyType { + switch (keyType) { + case RTCEncryptionKeyTypeRSA: + return rtc::KT_RSA; + case RTCEncryptionKeyTypeECDSA: + return rtc::KT_ECDSA; + } +} + ++ (webrtc::SdpSemantics)nativeSdpSemanticsForSdpSemantics:(RTCSdpSemantics)sdpSemantics { + switch (sdpSemantics) { + case RTCSdpSemanticsPlanB: + return webrtc::SdpSemantics::kPlanB_DEPRECATED; + case RTCSdpSemanticsUnifiedPlan: + return webrtc::SdpSemantics::kUnifiedPlan; + } +} + ++ (RTCSdpSemantics)sdpSemanticsForNativeSdpSemantics:(webrtc::SdpSemantics)sdpSemantics { + switch (sdpSemantics) { + case webrtc::SdpSemantics::kPlanB_DEPRECATED: + return RTCSdpSemanticsPlanB; + case webrtc::SdpSemantics::kUnifiedPlan: + return RTCSdpSemanticsUnifiedPlan; + } +} + ++ (NSString *)stringForSdpSemantics:(RTCSdpSemantics)sdpSemantics { + switch (sdpSemantics) { + case RTCSdpSemanticsPlanB: + return @"PLAN_B"; + case RTCSdpSemanticsUnifiedPlan: + return @"UNIFIED_PLAN"; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCryptoOptions.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCryptoOptions.h new file mode 100644 index 0000000000..7894c8d50c --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCryptoOptions.h @@ -0,0 +1,63 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Objective-C bindings for webrtc::CryptoOptions. This API had to be flattened + * as Objective-C doesn't support nested structures. + */ +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCCryptoOptions) : NSObject + +/** + * Enable GCM crypto suites from RFC 7714 for SRTP. GCM will only be used + * if both sides enable it + */ +@property(nonatomic, assign) BOOL srtpEnableGcmCryptoSuites; +/** + * If set to true, the (potentially insecure) crypto cipher + * kSrtpAes128CmSha1_32 will be included in the list of supported ciphers + * during negotiation. It will only be used if both peers support it and no + * other ciphers get preferred. + */ +@property(nonatomic, assign) BOOL srtpEnableAes128Sha1_32CryptoCipher; +/** + * If set to true, encrypted RTP header extensions as defined in RFC 6904 + * will be negotiated. They will only be used if both peers support them. + */ +@property(nonatomic, assign) BOOL srtpEnableEncryptedRtpHeaderExtensions; + +/** + * If set all RtpSenders must have an FrameEncryptor attached to them before + * they are allowed to send packets. All RtpReceivers must have a + * FrameDecryptor attached to them before they are able to receive packets. + */ +@property(nonatomic, assign) BOOL sframeRequireFrameEncryption; + +/** + * Initializes CryptoOptions with all possible options set explicitly. This + * is done when converting from a native RTCConfiguration.crypto_options. + */ +- (instancetype)initWithSrtpEnableGcmCryptoSuites:(BOOL)srtpEnableGcmCryptoSuites + srtpEnableAes128Sha1_32CryptoCipher:(BOOL)srtpEnableAes128Sha1_32CryptoCipher + srtpEnableEncryptedRtpHeaderExtensions:(BOOL)srtpEnableEncryptedRtpHeaderExtensions + sframeRequireFrameEncryption:(BOOL)sframeRequireFrameEncryption + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCryptoOptions.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCryptoOptions.mm new file mode 100644 index 0000000000..fbaa1de58d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCCryptoOptions.mm @@ -0,0 +1,33 @@ +/* + * 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 "RTCCryptoOptions.h" + +@implementation RTC_OBJC_TYPE (RTCCryptoOptions) + +@synthesize srtpEnableGcmCryptoSuites = _srtpEnableGcmCryptoSuites; +@synthesize srtpEnableAes128Sha1_32CryptoCipher = _srtpEnableAes128Sha1_32CryptoCipher; +@synthesize srtpEnableEncryptedRtpHeaderExtensions = _srtpEnableEncryptedRtpHeaderExtensions; +@synthesize sframeRequireFrameEncryption = _sframeRequireFrameEncryption; + +- (instancetype)initWithSrtpEnableGcmCryptoSuites:(BOOL)srtpEnableGcmCryptoSuites + srtpEnableAes128Sha1_32CryptoCipher:(BOOL)srtpEnableAes128Sha1_32CryptoCipher + srtpEnableEncryptedRtpHeaderExtensions:(BOOL)srtpEnableEncryptedRtpHeaderExtensions + sframeRequireFrameEncryption:(BOOL)sframeRequireFrameEncryption { + if (self = [super init]) { + _srtpEnableGcmCryptoSuites = srtpEnableGcmCryptoSuites; + _srtpEnableAes128Sha1_32CryptoCipher = srtpEnableAes128Sha1_32CryptoCipher; + _srtpEnableEncryptedRtpHeaderExtensions = srtpEnableEncryptedRtpHeaderExtensions; + _sframeRequireFrameEncryption = sframeRequireFrameEncryption; + } + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel+Private.h new file mode 100644 index 0000000000..2cdbdabec6 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel+Private.h @@ -0,0 +1,52 @@ +/* + * Copyright 2015 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 "RTCDataChannel.h" + +#include "api/data_channel_interface.h" +#include "api/scoped_refptr.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); + +@interface RTC_OBJC_TYPE (RTCDataBuffer) +() + + /** + * The native DataBuffer representation of this RTCDatabuffer object. This is + * needed to pass to the underlying C++ APIs. + */ + @property(nonatomic, readonly) const webrtc::DataBuffer *nativeDataBuffer; + +/** Initialize an RTCDataBuffer from a native DataBuffer. */ +- (instancetype)initWithNativeBuffer:(const webrtc::DataBuffer &)nativeBuffer; + +@end + +@interface RTC_OBJC_TYPE (RTCDataChannel) +() + + /** Initialize an RTCDataChannel from a native DataChannelInterface. */ + - (instancetype)initWithFactory + : (RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory nativeDataChannel + : (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel NS_DESIGNATED_INITIALIZER; + ++ (webrtc::DataChannelInterface::DataState)nativeDataChannelStateForState: + (RTCDataChannelState)state; + ++ (RTCDataChannelState)dataChannelStateForNativeState: + (webrtc::DataChannelInterface::DataState)nativeState; + ++ (NSString *)stringForState:(RTCDataChannelState)state; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel.h new file mode 100644 index 0000000000..89eb58bc3f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel.h @@ -0,0 +1,132 @@ +/* + * Copyright 2015 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 <AvailabilityMacros.h> +#import <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCDataBuffer) : NSObject + +/** NSData representation of the underlying buffer. */ +@property(nonatomic, readonly) NSData *data; + +/** Indicates whether `data` contains UTF-8 or binary data. */ +@property(nonatomic, readonly) BOOL isBinary; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initialize an RTCDataBuffer from NSData. `isBinary` indicates whether `data` + * contains UTF-8 or binary data. + */ +- (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary; + +@end + +@class RTC_OBJC_TYPE(RTCDataChannel); +RTC_OBJC_EXPORT +@protocol RTC_OBJC_TYPE +(RTCDataChannelDelegate)<NSObject> + + /** The data channel state changed. */ + - (void)dataChannelDidChangeState : (RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel; + +/** The data channel successfully received a data buffer. */ +- (void)dataChannel:(RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel + didReceiveMessageWithBuffer:(RTC_OBJC_TYPE(RTCDataBuffer) *)buffer; + +@optional +/** The data channel's `bufferedAmount` changed. */ +- (void)dataChannel:(RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel + didChangeBufferedAmount:(uint64_t)amount; + +@end + +/** Represents the state of the data channel. */ +typedef NS_ENUM(NSInteger, RTCDataChannelState) { + RTCDataChannelStateConnecting, + RTCDataChannelStateOpen, + RTCDataChannelStateClosing, + RTCDataChannelStateClosed, +}; + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCDataChannel) : NSObject + +/** + * A label that can be used to distinguish this data channel from other data + * channel objects. + */ +@property(nonatomic, readonly) NSString *label; + +/** Whether the data channel can send messages in unreliable mode. */ +@property(nonatomic, readonly) BOOL isReliable DEPRECATED_ATTRIBUTE; + +/** Returns whether this data channel is ordered or not. */ +@property(nonatomic, readonly) BOOL isOrdered; + +/** Deprecated. Use maxPacketLifeTime. */ +@property(nonatomic, readonly) NSUInteger maxRetransmitTime DEPRECATED_ATTRIBUTE; + +/** + * The length of the time window (in milliseconds) during which transmissions + * and retransmissions may occur in unreliable mode. + */ +@property(nonatomic, readonly) uint16_t maxPacketLifeTime; + +/** + * The maximum number of retransmissions that are attempted in unreliable mode. + */ +@property(nonatomic, readonly) uint16_t maxRetransmits; + +/** + * The name of the sub-protocol used with this data channel, if any. Otherwise + * this returns an empty string. + */ +@property(nonatomic, readonly) NSString *protocol; + +/** + * Returns whether this data channel was negotiated by the application or not. + */ +@property(nonatomic, readonly) BOOL isNegotiated; + +/** Deprecated. Use channelId. */ +@property(nonatomic, readonly) NSInteger streamId DEPRECATED_ATTRIBUTE; + +/** The identifier for this data channel. */ +@property(nonatomic, readonly) int channelId; + +/** The state of the data channel. */ +@property(nonatomic, readonly) RTCDataChannelState readyState; + +/** + * The number of bytes of application data that have been queued using + * `sendData:` but that have not yet been transmitted to the network. + */ +@property(nonatomic, readonly) uint64_t bufferedAmount; + +/** The delegate for this data channel. */ +@property(nonatomic, weak) id<RTC_OBJC_TYPE(RTCDataChannelDelegate)> delegate; + +- (instancetype)init NS_UNAVAILABLE; + +/** Closes the data channel. */ +- (void)close; + +/** Attempt to send `data` on this data channel's underlying data transport. */ +- (BOOL)sendData:(RTC_OBJC_TYPE(RTCDataBuffer) *)data; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel.mm new file mode 100644 index 0000000000..4a79cefdb4 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel.mm @@ -0,0 +1,220 @@ +/* + * Copyright 2015 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 "RTCDataChannel+Private.h" + +#import "helpers/NSString+StdString.h" + +#include <memory> + +namespace webrtc { + +class DataChannelDelegateAdapter : public DataChannelObserver { + public: + DataChannelDelegateAdapter(RTC_OBJC_TYPE(RTCDataChannel) * channel) { channel_ = channel; } + + void OnStateChange() override { + [channel_.delegate dataChannelDidChangeState:channel_]; + } + + void OnMessage(const DataBuffer& buffer) override { + RTC_OBJC_TYPE(RTCDataBuffer) *data_buffer = + [[RTC_OBJC_TYPE(RTCDataBuffer) alloc] initWithNativeBuffer:buffer]; + [channel_.delegate dataChannel:channel_ + didReceiveMessageWithBuffer:data_buffer]; + } + + void OnBufferedAmountChange(uint64_t previousAmount) override { + id<RTC_OBJC_TYPE(RTCDataChannelDelegate)> delegate = channel_.delegate; + SEL sel = @selector(dataChannel:didChangeBufferedAmount:); + if ([delegate respondsToSelector:sel]) { + [delegate dataChannel:channel_ didChangeBufferedAmount:previousAmount]; + } + } + + private: + __weak RTC_OBJC_TYPE(RTCDataChannel) * channel_; +}; +} + +@implementation RTC_OBJC_TYPE (RTCDataBuffer) { + std::unique_ptr<webrtc::DataBuffer> _dataBuffer; +} + +- (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary { + NSParameterAssert(data); + if (self = [super init]) { + rtc::CopyOnWriteBuffer buffer( + reinterpret_cast<const uint8_t*>(data.bytes), data.length); + _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary)); + } + return self; +} + +- (NSData *)data { + return [NSData dataWithBytes:_dataBuffer->data.data() + length:_dataBuffer->data.size()]; +} + +- (BOOL)isBinary { + return _dataBuffer->binary; +} + +#pragma mark - Private + +- (instancetype)initWithNativeBuffer:(const webrtc::DataBuffer&)nativeBuffer { + if (self = [super init]) { + _dataBuffer.reset(new webrtc::DataBuffer(nativeBuffer)); + } + return self; +} + +- (const webrtc::DataBuffer *)nativeDataBuffer { + return _dataBuffer.get(); +} + +@end + +@implementation RTC_OBJC_TYPE (RTCDataChannel) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel; + std::unique_ptr<webrtc::DataChannelDelegateAdapter> _observer; + BOOL _isObserverRegistered; +} + +@synthesize delegate = _delegate; + +- (void)dealloc { + // Handles unregistering the observer properly. We need to do this because + // there may still be other references to the underlying data channel. + _nativeDataChannel->UnregisterObserver(); +} + +- (NSString *)label { + return [NSString stringForStdString:_nativeDataChannel->label()]; +} + +- (BOOL)isReliable { + return _nativeDataChannel->reliable(); +} + +- (BOOL)isOrdered { + return _nativeDataChannel->ordered(); +} + +- (NSUInteger)maxRetransmitTime { + return self.maxPacketLifeTime; +} + +- (uint16_t)maxPacketLifeTime { + return _nativeDataChannel->maxRetransmitTime(); +} + +- (uint16_t)maxRetransmits { + return _nativeDataChannel->maxRetransmits(); +} + +- (NSString *)protocol { + return [NSString stringForStdString:_nativeDataChannel->protocol()]; +} + +- (BOOL)isNegotiated { + return _nativeDataChannel->negotiated(); +} + +- (NSInteger)streamId { + return self.channelId; +} + +- (int)channelId { + return _nativeDataChannel->id(); +} + +- (RTCDataChannelState)readyState { + return [[self class] dataChannelStateForNativeState: + _nativeDataChannel->state()]; +} + +- (uint64_t)bufferedAmount { + return _nativeDataChannel->buffered_amount(); +} + +- (void)close { + _nativeDataChannel->Close(); +} + +- (BOOL)sendData:(RTC_OBJC_TYPE(RTCDataBuffer) *)data { + return _nativeDataChannel->Send(*data.nativeDataBuffer); +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCDataChannel):\n%ld\n%@\n%@", + (long)self.channelId, + self.label, + [[self class] stringForState:self.readyState]]; +} + +#pragma mark - Private + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeDataChannel: + (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel { + NSParameterAssert(nativeDataChannel); + if (self = [super init]) { + _factory = factory; + _nativeDataChannel = nativeDataChannel; + _observer.reset(new webrtc::DataChannelDelegateAdapter(self)); + _nativeDataChannel->RegisterObserver(_observer.get()); + } + return self; +} + ++ (webrtc::DataChannelInterface::DataState) + nativeDataChannelStateForState:(RTCDataChannelState)state { + switch (state) { + case RTCDataChannelStateConnecting: + return webrtc::DataChannelInterface::DataState::kConnecting; + case RTCDataChannelStateOpen: + return webrtc::DataChannelInterface::DataState::kOpen; + case RTCDataChannelStateClosing: + return webrtc::DataChannelInterface::DataState::kClosing; + case RTCDataChannelStateClosed: + return webrtc::DataChannelInterface::DataState::kClosed; + } +} + ++ (RTCDataChannelState)dataChannelStateForNativeState: + (webrtc::DataChannelInterface::DataState)nativeState { + switch (nativeState) { + case webrtc::DataChannelInterface::DataState::kConnecting: + return RTCDataChannelStateConnecting; + case webrtc::DataChannelInterface::DataState::kOpen: + return RTCDataChannelStateOpen; + case webrtc::DataChannelInterface::DataState::kClosing: + return RTCDataChannelStateClosing; + case webrtc::DataChannelInterface::DataState::kClosed: + return RTCDataChannelStateClosed; + } +} + ++ (NSString *)stringForState:(RTCDataChannelState)state { + switch (state) { + case RTCDataChannelStateConnecting: + return @"Connecting"; + case RTCDataChannelStateOpen: + return @"Open"; + case RTCDataChannelStateClosing: + return @"Closing"; + case RTCDataChannelStateClosed: + return @"Closed"; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration+Private.h new file mode 100644 index 0000000000..5aef10fcef --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration+Private.h @@ -0,0 +1,24 @@ +/* + * Copyright 2015 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 "RTCDataChannelConfiguration.h" + +#include "api/data_channel_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCDataChannelConfiguration) +() + + @property(nonatomic, readonly) webrtc::DataChannelInit nativeDataChannelInit; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration.h new file mode 100644 index 0000000000..9459ae0a13 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration.h @@ -0,0 +1,52 @@ +/* + * Copyright 2015 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 <AvailabilityMacros.h> +#import <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCDataChannelConfiguration) : NSObject + +/** Set to YES if ordered delivery is required. */ +@property(nonatomic, assign) BOOL isOrdered; + +/** Deprecated. Use maxPacketLifeTime. */ +@property(nonatomic, assign) NSInteger maxRetransmitTimeMs DEPRECATED_ATTRIBUTE; + +/** + * Max period in milliseconds in which retransmissions will be sent. After this + * time, no more retransmissions will be sent. -1 if unset. + */ +@property(nonatomic, assign) int maxPacketLifeTime; + +/** The max number of retransmissions. -1 if unset. */ +@property(nonatomic, assign) int maxRetransmits; + +/** Set to YES if the channel has been externally negotiated and we do not send + * an in-band signalling in the form of an "open" message. + */ +@property(nonatomic, assign) BOOL isNegotiated; + +/** Deprecated. Use channelId. */ +@property(nonatomic, assign) int streamId DEPRECATED_ATTRIBUTE; + +/** The id of the data channel. */ +@property(nonatomic, assign) int channelId; + +/** Set by the application and opaque to the WebRTC implementation. */ +@property(nonatomic) NSString* protocol; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration.mm new file mode 100644 index 0000000000..bf775b1afd --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannelConfiguration.mm @@ -0,0 +1,87 @@ +/* + * Copyright 2015 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 "RTCDataChannelConfiguration+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCDataChannelConfiguration) + +@synthesize nativeDataChannelInit = _nativeDataChannelInit; + +- (BOOL)isOrdered { + return _nativeDataChannelInit.ordered; +} + +- (void)setIsOrdered:(BOOL)isOrdered { + _nativeDataChannelInit.ordered = isOrdered; +} + +- (NSInteger)maxRetransmitTimeMs { + return self.maxPacketLifeTime; +} + +- (void)setMaxRetransmitTimeMs:(NSInteger)maxRetransmitTimeMs { + self.maxPacketLifeTime = maxRetransmitTimeMs; +} + +- (int)maxPacketLifeTime { + return *_nativeDataChannelInit.maxRetransmitTime; +} + +- (void)setMaxPacketLifeTime:(int)maxPacketLifeTime { + _nativeDataChannelInit.maxRetransmitTime = maxPacketLifeTime; +} + +- (int)maxRetransmits { + if (_nativeDataChannelInit.maxRetransmits) { + return *_nativeDataChannelInit.maxRetransmits; + } else { + return -1; + } +} + +- (void)setMaxRetransmits:(int)maxRetransmits { + _nativeDataChannelInit.maxRetransmits = maxRetransmits; +} + +- (NSString *)protocol { + return [NSString stringForStdString:_nativeDataChannelInit.protocol]; +} + +- (void)setProtocol:(NSString *)protocol { + _nativeDataChannelInit.protocol = [NSString stdStringForString:protocol]; +} + +- (BOOL)isNegotiated { + return _nativeDataChannelInit.negotiated; +} + +- (void)setIsNegotiated:(BOOL)isNegotiated { + _nativeDataChannelInit.negotiated = isNegotiated; +} + +- (int)streamId { + return self.channelId; +} + +- (void)setStreamId:(int)streamId { + self.channelId = streamId; +} + +- (int)channelId { + return _nativeDataChannelInit.id; +} + +- (void)setChannelId:(int)channelId { + _nativeDataChannelInit.id = channelId; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender+Private.h new file mode 100644 index 0000000000..49a62164cd --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender+Private.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 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 "RTCDtmfSender.h" + +#include "api/dtmf_sender_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCDtmfSender) : NSObject <RTC_OBJC_TYPE(RTCDtmfSender)> + +@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::DtmfSenderInterface> nativeDtmfSender; + +- (instancetype)init NS_UNAVAILABLE; + +/** Initialize an RTCDtmfSender with a native DtmfSenderInterface. */ +- (instancetype)initWithNativeDtmfSender: + (rtc::scoped_refptr<webrtc::DtmfSenderInterface>)nativeDtmfSender NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender.h new file mode 100644 index 0000000000..0f1b6ba4da --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender.h @@ -0,0 +1,71 @@ +/* + * Copyright 2017 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@protocol RTC_OBJC_TYPE +(RTCDtmfSender)<NSObject> + + /** + * Returns true if this RTCDtmfSender is capable of sending DTMF. Otherwise + * returns false. To be able to send DTMF, the associated RTCRtpSender must be + * able to send packets, and a "telephone-event" codec must be negotiated. + */ + @property(nonatomic, readonly) BOOL canInsertDtmf; + +/** + * Queues a task that sends the DTMF tones. The tones parameter is treated + * as a series of characters. The characters 0 through 9, A through D, #, and * + * generate the associated DTMF tones. The characters a to d are equivalent + * to A to D. The character ',' indicates a delay of 2 seconds before + * processing the next character in the tones parameter. + * + * Unrecognized characters are ignored. + * + * @param duration The parameter indicates the duration to use for each + * character passed in the tones parameter. The duration cannot be more + * than 6000 or less than 70 ms. + * + * @param interToneGap The parameter indicates the gap between tones. + * This parameter must be at least 50 ms but should be as short as + * possible. + * + * If InsertDtmf is called on the same object while an existing task for this + * object to generate DTMF is still running, the previous task is canceled. + * Returns true on success and false on failure. + */ +- (BOOL)insertDtmf:(nonnull NSString *)tones + duration:(NSTimeInterval)duration + interToneGap:(NSTimeInterval)interToneGap; + +/** The tones remaining to be played out */ +- (nonnull NSString *)remainingTones; + +/** + * The current tone duration value. This value will be the value last set via the + * insertDtmf method, or the default value of 100 ms if insertDtmf was never called. + */ +- (NSTimeInterval)duration; + +/** + * The current value of the between-tone gap. This value will be the value last set + * via the insertDtmf() method, or the default value of 50 ms if insertDtmf() was never + * called. + */ +- (NSTimeInterval)interToneGap; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender.mm new file mode 100644 index 0000000000..ee3b79cd37 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender.mm @@ -0,0 +1,74 @@ +/* + * Copyright 2017 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 "RTCDtmfSender+Private.h" + +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +#include "rtc_base/time_utils.h" + +@implementation RTC_OBJC_TYPE (RTCDtmfSender) { + rtc::scoped_refptr<webrtc::DtmfSenderInterface> _nativeDtmfSender; +} + +- (BOOL)canInsertDtmf { + return _nativeDtmfSender->CanInsertDtmf(); +} + +- (BOOL)insertDtmf:(nonnull NSString *)tones + duration:(NSTimeInterval)duration + interToneGap:(NSTimeInterval)interToneGap { + RTC_DCHECK(tones != nil); + + int durationMs = static_cast<int>(duration * rtc::kNumMillisecsPerSec); + int interToneGapMs = static_cast<int>(interToneGap * rtc::kNumMillisecsPerSec); + return _nativeDtmfSender->InsertDtmf( + [NSString stdStringForString:tones], durationMs, interToneGapMs); +} + +- (nonnull NSString *)remainingTones { + return [NSString stringForStdString:_nativeDtmfSender->tones()]; +} + +- (NSTimeInterval)duration { + return static_cast<NSTimeInterval>(_nativeDtmfSender->duration()) / rtc::kNumMillisecsPerSec; +} + +- (NSTimeInterval)interToneGap { + return static_cast<NSTimeInterval>(_nativeDtmfSender->inter_tone_gap()) / + rtc::kNumMillisecsPerSec; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCDtmfSender) {\n remainingTones: %@\n " + @"duration: %f sec\n interToneGap: %f sec\n}", + [self remainingTones], + [self duration], + [self interToneGap]]; +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::DtmfSenderInterface>)nativeDtmfSender { + return _nativeDtmfSender; +} + +- (instancetype)initWithNativeDtmfSender: + (rtc::scoped_refptr<webrtc::DtmfSenderInterface>)nativeDtmfSender { + NSParameterAssert(nativeDtmfSender); + if (self = [super init]) { + _nativeDtmfSender = nativeDtmfSender; + RTCLogInfo( + @"RTC_OBJC_TYPE(RTCDtmfSender)(%p): created DTMF sender: %@", self, self.description); + } + return self; +} +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCEncodedImage+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCEncodedImage+Private.h new file mode 100644 index 0000000000..a078b0aded --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCEncodedImage+Private.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 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 "base/RTCEncodedImage.h" + +#include "api/video/encoded_image.h" + +NS_ASSUME_NONNULL_BEGIN + +/* Interfaces for converting to/from internal C++ formats. */ +@interface RTC_OBJC_TYPE (RTCEncodedImage) +(Private) + + - (instancetype)initWithNativeEncodedImage : (const webrtc::EncodedImage &)encodedImage; +- (webrtc::EncodedImage)nativeEncodedImage; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCEncodedImage+Private.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCEncodedImage+Private.mm new file mode 100644 index 0000000000..7f8ae739e0 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCEncodedImage+Private.mm @@ -0,0 +1,130 @@ +/* + * Copyright 2017 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 "RTCEncodedImage+Private.h" + +#import <objc/runtime.h> + +#include "rtc_base/numerics/safe_conversions.h" + +namespace { +// An implementation of EncodedImageBufferInterface that doesn't perform any copies. +class ObjCEncodedImageBuffer : public webrtc::EncodedImageBufferInterface { + public: + static rtc::scoped_refptr<ObjCEncodedImageBuffer> Create(NSData *data) { + return rtc::make_ref_counted<ObjCEncodedImageBuffer>(data); + } + const uint8_t *data() const override { return static_cast<const uint8_t *>(data_.bytes); } + // TODO(bugs.webrtc.org/9378): delete this non-const data method. + uint8_t *data() override { + return const_cast<uint8_t *>(static_cast<const uint8_t *>(data_.bytes)); + } + size_t size() const override { return data_.length; } + + protected: + explicit ObjCEncodedImageBuffer(NSData *data) : data_(data) {} + ~ObjCEncodedImageBuffer() {} + + NSData *data_; +}; +} + +// A simple wrapper around webrtc::EncodedImageBufferInterface to make it usable with associated +// objects. +@interface RTCWrappedEncodedImageBuffer : NSObject +@property(nonatomic) rtc::scoped_refptr<webrtc::EncodedImageBufferInterface> buffer; +- (instancetype)initWithEncodedImageBuffer: + (rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)buffer; +@end +@implementation RTCWrappedEncodedImageBuffer +@synthesize buffer = _buffer; +- (instancetype)initWithEncodedImageBuffer: + (rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)buffer { + self = [super init]; + if (self) { + _buffer = buffer; + } + return self; +} +@end + +@implementation RTC_OBJC_TYPE (RTCEncodedImage) +(Private) + + - (rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)encodedData { + RTCWrappedEncodedImageBuffer *wrappedBuffer = + objc_getAssociatedObject(self, @selector(encodedData)); + return wrappedBuffer.buffer; +} + +- (void)setEncodedData:(rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)buffer { + return objc_setAssociatedObject( + self, + @selector(encodedData), + [[RTCWrappedEncodedImageBuffer alloc] initWithEncodedImageBuffer:buffer], + OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (instancetype)initWithNativeEncodedImage:(const webrtc::EncodedImage &)encodedImage { + if (self = [super init]) { + // A reference to the encodedData must be stored so that it's kept alive as long + // self.buffer references its underlying data. + self.encodedData = encodedImage.GetEncodedData(); + // Wrap the buffer in NSData without copying, do not take ownership. + self.buffer = [NSData dataWithBytesNoCopy:self.encodedData->data() + length:encodedImage.size() + freeWhenDone:NO]; + self.encodedWidth = rtc::dchecked_cast<int32_t>(encodedImage._encodedWidth); + self.encodedHeight = rtc::dchecked_cast<int32_t>(encodedImage._encodedHeight); + self.timeStamp = encodedImage.Timestamp(); + self.captureTimeMs = encodedImage.capture_time_ms_; + self.ntpTimeMs = encodedImage.ntp_time_ms_; + self.flags = encodedImage.timing_.flags; + self.encodeStartMs = encodedImage.timing_.encode_start_ms; + self.encodeFinishMs = encodedImage.timing_.encode_finish_ms; + self.frameType = static_cast<RTCFrameType>(encodedImage._frameType); + self.rotation = static_cast<RTCVideoRotation>(encodedImage.rotation_); + self.qp = @(encodedImage.qp_); + self.contentType = (encodedImage.content_type_ == webrtc::VideoContentType::SCREENSHARE) ? + RTCVideoContentTypeScreenshare : + RTCVideoContentTypeUnspecified; + } + + return self; +} + +- (webrtc::EncodedImage)nativeEncodedImage { + // Return the pointer without copying. + webrtc::EncodedImage encodedImage; + if (self.encodedData) { + encodedImage.SetEncodedData(self.encodedData); + } else if (self.buffer) { + encodedImage.SetEncodedData(ObjCEncodedImageBuffer::Create(self.buffer)); + } + encodedImage.set_size(self.buffer.length); + encodedImage._encodedWidth = rtc::dchecked_cast<uint32_t>(self.encodedWidth); + encodedImage._encodedHeight = rtc::dchecked_cast<uint32_t>(self.encodedHeight); + encodedImage.SetTimestamp(self.timeStamp); + encodedImage.capture_time_ms_ = self.captureTimeMs; + encodedImage.ntp_time_ms_ = self.ntpTimeMs; + encodedImage.timing_.flags = self.flags; + encodedImage.timing_.encode_start_ms = self.encodeStartMs; + encodedImage.timing_.encode_finish_ms = self.encodeFinishMs; + encodedImage._frameType = webrtc::VideoFrameType(self.frameType); + encodedImage.rotation_ = webrtc::VideoRotation(self.rotation); + encodedImage.qp_ = self.qp ? self.qp.intValue : -1; + encodedImage.content_type_ = (self.contentType == RTCVideoContentTypeScreenshare) ? + webrtc::VideoContentType::SCREENSHARE : + webrtc::VideoContentType::UNSPECIFIED; + + return encodedImage; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.h new file mode 100644 index 0000000000..3e8fcc8075 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.h @@ -0,0 +1,30 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +/** The only valid value for the following if set is kRTCFieldTrialEnabledValue. */ +RTC_EXTERN NSString *const kRTCFieldTrialAudioForceABWENoTWCCKey; +RTC_EXTERN NSString * const kRTCFieldTrialFlexFec03AdvertisedKey; +RTC_EXTERN NSString * const kRTCFieldTrialFlexFec03Key; +RTC_EXTERN NSString * const kRTCFieldTrialH264HighProfileKey; +RTC_EXTERN NSString * const kRTCFieldTrialMinimizeResamplingOnMobileKey; +RTC_EXTERN NSString *const kRTCFieldTrialUseNWPathMonitor; + +/** The valid value for field trials above. */ +RTC_EXTERN NSString * const kRTCFieldTrialEnabledValue; + +/** Initialize field trials using a dictionary mapping field trial keys to their + * values. See above for valid keys and values. Must be called before any other + * call into WebRTC. See: webrtc/system_wrappers/include/field_trial.h + */ +RTC_EXTERN void RTCInitFieldTrialDictionary(NSDictionary<NSString *, NSString *> *fieldTrials); diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.mm new file mode 100644 index 0000000000..193da9e4f7 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.mm @@ -0,0 +1,56 @@ +/* + * 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 "RTCFieldTrials.h" + +#include <memory> + +#import "base/RTCLogging.h" + +#include "system_wrappers/include/field_trial.h" + +NSString *const kRTCFieldTrialAudioForceABWENoTWCCKey = @"WebRTC-Audio-ABWENoTWCC"; +NSString * const kRTCFieldTrialFlexFec03AdvertisedKey = @"WebRTC-FlexFEC-03-Advertised"; +NSString * const kRTCFieldTrialFlexFec03Key = @"WebRTC-FlexFEC-03"; +NSString * const kRTCFieldTrialH264HighProfileKey = @"WebRTC-H264HighProfile"; +NSString * const kRTCFieldTrialMinimizeResamplingOnMobileKey = + @"WebRTC-Audio-MinimizeResamplingOnMobile"; +NSString *const kRTCFieldTrialUseNWPathMonitor = @"WebRTC-Network-UseNWPathMonitor"; +NSString * const kRTCFieldTrialEnabledValue = @"Enabled"; + +// InitFieldTrialsFromString stores the char*, so the char array must outlive +// the application. +static char *gFieldTrialInitString = nullptr; + +void RTCInitFieldTrialDictionary(NSDictionary<NSString *, NSString *> *fieldTrials) { + if (!fieldTrials) { + RTCLogWarning(@"No fieldTrials provided."); + return; + } + // Assemble the keys and values into the field trial string. + // We don't perform any extra format checking. That should be done by the underlying WebRTC calls. + NSMutableString *fieldTrialInitString = [NSMutableString string]; + for (NSString *key in fieldTrials) { + NSString *fieldTrialEntry = [NSString stringWithFormat:@"%@/%@/", key, fieldTrials[key]]; + [fieldTrialInitString appendString:fieldTrialEntry]; + } + size_t len = fieldTrialInitString.length + 1; + if (gFieldTrialInitString != nullptr) { + delete[] gFieldTrialInitString; + } + gFieldTrialInitString = new char[len]; + if (![fieldTrialInitString getCString:gFieldTrialInitString + maxLength:len + encoding:NSUTF8StringEncoding]) { + RTCLogError(@"Failed to convert field trial string."); + return; + } + webrtc::field_trial::InitFieldTrialsFromString(gFieldTrialInitString); +} diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFileLogger.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFileLogger.h new file mode 100644 index 0000000000..cb397c9633 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFileLogger.h @@ -0,0 +1,74 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +typedef NS_ENUM(NSUInteger, RTCFileLoggerSeverity) { + RTCFileLoggerSeverityVerbose, + RTCFileLoggerSeverityInfo, + RTCFileLoggerSeverityWarning, + RTCFileLoggerSeverityError +}; + +typedef NS_ENUM(NSUInteger, RTCFileLoggerRotationType) { + RTCFileLoggerTypeCall, + RTCFileLoggerTypeApp, +}; + +NS_ASSUME_NONNULL_BEGIN + +// This class intercepts WebRTC logs and saves them to a file. The file size +// will not exceed the given maximum bytesize. When the maximum bytesize is +// reached, logs are rotated according to the rotationType specified. +// For kRTCFileLoggerTypeCall, logs from the beginning and the end +// are preserved while the middle section is overwritten instead. +// For kRTCFileLoggerTypeApp, the oldest log is overwritten. +// This class is not threadsafe. +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCFileLogger) : NSObject + +// The severity level to capture. The default is kRTCFileLoggerSeverityInfo. +@property(nonatomic, assign) RTCFileLoggerSeverity severity; + +// The rotation type for this file logger. The default is +// kRTCFileLoggerTypeCall. +@property(nonatomic, readonly) RTCFileLoggerRotationType rotationType; + +// Disables buffering disk writes. Should be set before `start`. Buffering +// is enabled by default for performance. +@property(nonatomic, assign) BOOL shouldDisableBuffering; + +// Default constructor provides default settings for dir path, file size and +// rotation type. +- (instancetype)init; + +// Create file logger with default rotation type. +- (instancetype)initWithDirPath:(NSString *)dirPath maxFileSize:(NSUInteger)maxFileSize; + +- (instancetype)initWithDirPath:(NSString *)dirPath + maxFileSize:(NSUInteger)maxFileSize + rotationType:(RTCFileLoggerRotationType)rotationType NS_DESIGNATED_INITIALIZER; + +// Starts writing WebRTC logs to disk if not already started. Overwrites any +// existing file(s). +- (void)start; + +// Stops writing WebRTC logs to disk. This method is also called on dealloc. +- (void)stop; + +// Returns the current contents of the logs, or nil if start has been called +// without a stop. +- (nullable NSData *)logData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFileLogger.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFileLogger.mm new file mode 100644 index 0000000000..9562245611 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFileLogger.mm @@ -0,0 +1,170 @@ +/* + * Copyright 2015 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 "RTCFileLogger.h" + +#include <memory> + +#include "rtc_base/checks.h" +#include "rtc_base/file_rotating_stream.h" +#include "rtc_base/log_sinks.h" +#include "rtc_base/logging.h" + +NSString *const kDefaultLogDirName = @"webrtc_logs"; +NSUInteger const kDefaultMaxFileSize = 10 * 1024 * 1024; // 10MB. +const char *kRTCFileLoggerRotatingLogPrefix = "rotating_log"; + +@implementation RTC_OBJC_TYPE (RTCFileLogger) { + BOOL _hasStarted; + NSString *_dirPath; + NSUInteger _maxFileSize; + std::unique_ptr<rtc::FileRotatingLogSink> _logSink; +} + +@synthesize severity = _severity; +@synthesize rotationType = _rotationType; +@synthesize shouldDisableBuffering = _shouldDisableBuffering; + +- (instancetype)init { + NSArray *paths = NSSearchPathForDirectoriesInDomains( + NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirPath = [paths firstObject]; + NSString *defaultDirPath = + [documentsDirPath stringByAppendingPathComponent:kDefaultLogDirName]; + return [self initWithDirPath:defaultDirPath + maxFileSize:kDefaultMaxFileSize]; +} + +- (instancetype)initWithDirPath:(NSString *)dirPath + maxFileSize:(NSUInteger)maxFileSize { + return [self initWithDirPath:dirPath + maxFileSize:maxFileSize + rotationType:RTCFileLoggerTypeCall]; +} + +- (instancetype)initWithDirPath:(NSString *)dirPath + maxFileSize:(NSUInteger)maxFileSize + rotationType:(RTCFileLoggerRotationType)rotationType { + NSParameterAssert(dirPath.length); + NSParameterAssert(maxFileSize); + if (self = [super init]) { + BOOL isDir = NO; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:dirPath isDirectory:&isDir]) { + if (!isDir) { + // Bail if something already exists there. + return nil; + } + } else { + if (![fileManager createDirectoryAtPath:dirPath + withIntermediateDirectories:NO + attributes:nil + error:nil]) { + // Bail if we failed to create a directory. + return nil; + } + } + _dirPath = dirPath; + _maxFileSize = maxFileSize; + _severity = RTCFileLoggerSeverityInfo; + } + return self; +} + +- (void)dealloc { + [self stop]; +} + +- (void)start { + if (_hasStarted) { + return; + } + switch (_rotationType) { + case RTCFileLoggerTypeApp: + _logSink.reset( + new rtc::FileRotatingLogSink(_dirPath.UTF8String, + kRTCFileLoggerRotatingLogPrefix, + _maxFileSize, + _maxFileSize / 10)); + break; + case RTCFileLoggerTypeCall: + _logSink.reset( + new rtc::CallSessionFileRotatingLogSink(_dirPath.UTF8String, + _maxFileSize)); + break; + } + if (!_logSink->Init()) { + RTC_LOG(LS_ERROR) << "Failed to open log files at path: " << _dirPath.UTF8String; + _logSink.reset(); + return; + } + if (_shouldDisableBuffering) { + _logSink->DisableBuffering(); + } + rtc::LogMessage::LogThreads(true); + rtc::LogMessage::LogTimestamps(true); + rtc::LogMessage::AddLogToStream(_logSink.get(), [self rtcSeverity]); + _hasStarted = YES; +} + +- (void)stop { + if (!_hasStarted) { + return; + } + RTC_DCHECK(_logSink); + rtc::LogMessage::RemoveLogToStream(_logSink.get()); + _hasStarted = NO; + _logSink.reset(); +} + +- (nullable NSData *)logData { + if (_hasStarted) { + return nil; + } + NSMutableData* logData = [NSMutableData data]; + std::unique_ptr<rtc::FileRotatingStreamReader> stream; + switch(_rotationType) { + case RTCFileLoggerTypeApp: + stream = std::make_unique<rtc::FileRotatingStreamReader>(_dirPath.UTF8String, + kRTCFileLoggerRotatingLogPrefix); + break; + case RTCFileLoggerTypeCall: + stream = std::make_unique<rtc::CallSessionFileRotatingStreamReader>(_dirPath.UTF8String); + break; + } + size_t bufferSize = stream->GetSize(); + if (bufferSize == 0) { + return logData; + } + // Allocate memory using malloc so we can pass it direcly to NSData without + // copying. + std::unique_ptr<uint8_t[]> buffer(static_cast<uint8_t*>(malloc(bufferSize))); + size_t read = stream->ReadAll(buffer.get(), bufferSize); + logData = [[NSMutableData alloc] initWithBytesNoCopy:buffer.release() + length:read]; + return logData; +} + +#pragma mark - Private + +- (rtc::LoggingSeverity)rtcSeverity { + switch (_severity) { + case RTCFileLoggerSeverityVerbose: + return rtc::LS_VERBOSE; + case RTCFileLoggerSeverityInfo: + return rtc::LS_INFO; + case RTCFileLoggerSeverityWarning: + return rtc::LS_WARNING; + case RTCFileLoggerSeverityError: + return rtc::LS_ERROR; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate+Private.h new file mode 100644 index 0000000000..409e16b608 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate+Private.h @@ -0,0 +1,36 @@ +/* + * Copyright 2015 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 "RTCIceCandidate.h" + +#include <memory> + +#include "api/jsep.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCIceCandidate) +() + + /** + * The native IceCandidateInterface representation of this RTCIceCandidate + * object. This is needed to pass to the underlying C++ APIs. + */ + @property(nonatomic, readonly) std::unique_ptr<webrtc::IceCandidateInterface> nativeCandidate; + +/** + * Initialize an RTCIceCandidate from a native IceCandidateInterface. No + * ownership is taken of the native candidate. + */ +- (instancetype)initWithNativeCandidate:(const webrtc::IceCandidateInterface *)candidate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate.h new file mode 100644 index 0000000000..f84843af6c --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate.h @@ -0,0 +1,49 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCIceCandidate) : NSObject + +/** + * If present, the identifier of the "media stream identification" for the media + * component this candidate is associated with. + */ +@property(nonatomic, readonly, nullable) NSString *sdpMid; + +/** + * The index (starting at zero) of the media description this candidate is + * associated with in the SDP. + */ +@property(nonatomic, readonly) int sdpMLineIndex; + +/** The SDP string for this candidate. */ +@property(nonatomic, readonly) NSString *sdp; + +/** The URL of the ICE server which this candidate is gathered from. */ +@property(nonatomic, readonly, nullable) NSString *serverUrl; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initialize an RTCIceCandidate from SDP. + */ +- (instancetype)initWithSdp:(NSString *)sdp + sdpMLineIndex:(int)sdpMLineIndex + sdpMid:(nullable NSString *)sdpMid NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate.mm new file mode 100644 index 0000000000..48385ef5b4 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidate.mm @@ -0,0 +1,76 @@ +/* + * Copyright 2015 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 "RTCIceCandidate+Private.h" + +#include <memory> + +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCIceCandidate) + +@synthesize sdpMid = _sdpMid; +@synthesize sdpMLineIndex = _sdpMLineIndex; +@synthesize sdp = _sdp; +@synthesize serverUrl = _serverUrl; + +- (instancetype)initWithSdp:(NSString *)sdp + sdpMLineIndex:(int)sdpMLineIndex + sdpMid:(NSString *)sdpMid { + NSParameterAssert(sdp.length); + if (self = [super init]) { + _sdpMid = [sdpMid copy]; + _sdpMLineIndex = sdpMLineIndex; + _sdp = [sdp copy]; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCIceCandidate):\n%@\n%d\n%@\n%@", + _sdpMid, + _sdpMLineIndex, + _sdp, + _serverUrl]; +} + +#pragma mark - Private + +- (instancetype)initWithNativeCandidate: + (const webrtc::IceCandidateInterface *)candidate { + NSParameterAssert(candidate); + std::string sdp; + candidate->ToString(&sdp); + + RTC_OBJC_TYPE(RTCIceCandidate) *rtcCandidate = + [self initWithSdp:[NSString stringForStdString:sdp] + sdpMLineIndex:candidate->sdp_mline_index() + sdpMid:[NSString stringForStdString:candidate->sdp_mid()]]; + rtcCandidate->_serverUrl = [NSString stringForStdString:candidate->server_url()]; + return rtcCandidate; +} + +- (std::unique_ptr<webrtc::IceCandidateInterface>)nativeCandidate { + webrtc::SdpParseError error; + + webrtc::IceCandidateInterface *candidate = webrtc::CreateIceCandidate( + _sdpMid.stdString, _sdpMLineIndex, _sdp.stdString, &error); + + if (!candidate) { + RTCLog(@"Failed to create ICE candidate: %s\nline: %s", + error.description.c_str(), + error.line.c_str()); + } + + return std::unique_ptr<webrtc::IceCandidateInterface>(candidate); +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent+Private.h new file mode 100644 index 0000000000..8502da08a8 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent+Private.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 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 "RTCIceCandidateErrorEvent.h" + +#include <string> + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCIceCandidateErrorEvent) +() + + - (instancetype)initWithAddress : (const std::string&)address port : (const int)port url + : (const std::string&)url errorCode : (const int)errorCode errorText + : (const std::string&)errorText; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent.h new file mode 100644 index 0000000000..e0906fdbdd --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCIceCandidateErrorEvent) : NSObject + +/** The local IP address used to communicate with the STUN or TURN server. */ +@property(nonatomic, readonly) NSString *address; + +/** The port used to communicate with the STUN or TURN server. */ +@property(nonatomic, readonly) int port; + +/** The STUN or TURN URL that identifies the STUN or TURN server for which the failure occurred. */ +@property(nonatomic, readonly) NSString *url; + +/** The numeric STUN error code returned by the STUN or TURN server. If no host candidate can reach + * the server, errorCode will be set to the value 701 which is outside the STUN error code range. + * This error is only fired once per server URL while in the RTCIceGatheringState of "gathering". */ +@property(nonatomic, readonly) int errorCode; + +/** The STUN reason text returned by the STUN or TURN server. If the server could not be reached, + * errorText will be set to an implementation-specific value providing details about the error. */ +@property(nonatomic, readonly) NSString *errorText; + +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent.mm new file mode 100644 index 0000000000..573e30642b --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceCandidateErrorEvent.mm @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 "RTCIceCandidateErrorEvent+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCIceCandidateErrorEvent) + +@synthesize address = _address; +@synthesize port = _port; +@synthesize url = _url; +@synthesize errorCode = _errorCode; +@synthesize errorText = _errorText; + +- (instancetype)init { + return [super init]; +} + +- (instancetype)initWithAddress:(const std::string&)address + port:(const int)port + url:(const std::string&)url + errorCode:(const int)errorCode + errorText:(const std::string&)errorText { + if (self = [self init]) { + _address = [NSString stringForStdString:address]; + _port = port; + _url = [NSString stringForStdString:url]; + _errorCode = errorCode; + _errorText = [NSString stringForStdString:errorText]; + } + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer+Private.h new file mode 100644 index 0000000000..3eee819965 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer+Private.h @@ -0,0 +1,31 @@ +/* + * Copyright 2015 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 "RTCIceServer.h" + +#include "api/peer_connection_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCIceServer) +() + + /** + * IceServer struct representation of this RTCIceServer object's data. + * This is needed to pass to the underlying C++ APIs. + */ + @property(nonatomic, readonly) webrtc::PeerConnectionInterface::IceServer nativeServer; + +/** Initialize an RTCIceServer from a native IceServer. */ +- (instancetype)initWithNativeServer:(webrtc::PeerConnectionInterface::IceServer)nativeServer; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer.h new file mode 100644 index 0000000000..7ddcbc1a1f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer.h @@ -0,0 +1,114 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +typedef NS_ENUM(NSUInteger, RTCTlsCertPolicy) { + RTCTlsCertPolicySecure, + RTCTlsCertPolicyInsecureNoCheck +}; + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCIceServer) : NSObject + +/** URI(s) for this server represented as NSStrings. */ +@property(nonatomic, readonly) NSArray<NSString *> *urlStrings; + +/** Username to use if this RTCIceServer object is a TURN server. */ +@property(nonatomic, readonly, nullable) NSString *username; + +/** Credential to use if this RTCIceServer object is a TURN server. */ +@property(nonatomic, readonly, nullable) NSString *credential; + +/** + * TLS certificate policy to use if this RTCIceServer object is a TURN server. + */ +@property(nonatomic, readonly) RTCTlsCertPolicy tlsCertPolicy; + +/** + If the URIs in `urls` only contain IP addresses, this field can be used + to indicate the hostname, which may be necessary for TLS (using the SNI + extension). If `urls` itself contains the hostname, this isn't necessary. + */ +@property(nonatomic, readonly, nullable) NSString *hostname; + +/** List of protocols to be used in the TLS ALPN extension. */ +@property(nonatomic, readonly) NSArray<NSString *> *tlsAlpnProtocols; + +/** + List elliptic curves to be used in the TLS elliptic curves extension. + Only curve names supported by OpenSSL should be used (eg. "P-256","X25519"). + */ +@property(nonatomic, readonly) NSArray<NSString *> *tlsEllipticCurves; + +- (nonnull instancetype)init NS_UNAVAILABLE; + +/** Convenience initializer for a server with no authentication (e.g. STUN). */ +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings; + +/** + * Initialize an RTCIceServer with its associated URLs, optional username, + * optional credential, and credentialType. + */ +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(nullable NSString *)username + credential:(nullable NSString *)credential; + +/** + * Initialize an RTCIceServer with its associated URLs, optional username, + * optional credential, and TLS cert policy. + */ +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(nullable NSString *)username + credential:(nullable NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy; + +/** + * Initialize an RTCIceServer with its associated URLs, optional username, + * optional credential, TLS cert policy and hostname. + */ +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(nullable NSString *)username + credential:(nullable NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy + hostname:(nullable NSString *)hostname; + +/** + * Initialize an RTCIceServer with its associated URLs, optional username, + * optional credential, TLS cert policy, hostname and ALPN protocols. + */ +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(nullable NSString *)username + credential:(nullable NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy + hostname:(nullable NSString *)hostname + tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols; + +/** + * Initialize an RTCIceServer with its associated URLs, optional username, + * optional credential, TLS cert policy, hostname, ALPN protocols and + * elliptic curves. + */ +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(nullable NSString *)username + credential:(nullable NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy + hostname:(nullable NSString *)hostname + tlsAlpnProtocols:(nullable NSArray<NSString *> *)tlsAlpnProtocols + tlsEllipticCurves:(nullable NSArray<NSString *> *)tlsEllipticCurves + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer.mm new file mode 100644 index 0000000000..19a0a7e9e8 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCIceServer.mm @@ -0,0 +1,196 @@ +/* + * Copyright 2015 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 "RTCIceServer+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCIceServer) + +@synthesize urlStrings = _urlStrings; +@synthesize username = _username; +@synthesize credential = _credential; +@synthesize tlsCertPolicy = _tlsCertPolicy; +@synthesize hostname = _hostname; +@synthesize tlsAlpnProtocols = _tlsAlpnProtocols; +@synthesize tlsEllipticCurves = _tlsEllipticCurves; + +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings { + return [self initWithURLStrings:urlStrings + username:nil + credential:nil]; +} + +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(NSString *)username + credential:(NSString *)credential { + return [self initWithURLStrings:urlStrings + username:username + credential:credential + tlsCertPolicy:RTCTlsCertPolicySecure]; +} + +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(NSString *)username + credential:(NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy { + return [self initWithURLStrings:urlStrings + username:username + credential:credential + tlsCertPolicy:tlsCertPolicy + hostname:nil]; +} + +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(NSString *)username + credential:(NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy + hostname:(NSString *)hostname { + return [self initWithURLStrings:urlStrings + username:username + credential:credential + tlsCertPolicy:tlsCertPolicy + hostname:hostname + tlsAlpnProtocols:[NSArray array]]; +} + +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(NSString *)username + credential:(NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy + hostname:(NSString *)hostname + tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols { + return [self initWithURLStrings:urlStrings + username:username + credential:credential + tlsCertPolicy:tlsCertPolicy + hostname:hostname + tlsAlpnProtocols:tlsAlpnProtocols + tlsEllipticCurves:[NSArray array]]; +} + +- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings + username:(NSString *)username + credential:(NSString *)credential + tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy + hostname:(NSString *)hostname + tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols + tlsEllipticCurves:(NSArray<NSString *> *)tlsEllipticCurves { + NSParameterAssert(urlStrings.count); + if (self = [super init]) { + _urlStrings = [[NSArray alloc] initWithArray:urlStrings copyItems:YES]; + _username = [username copy]; + _credential = [credential copy]; + _tlsCertPolicy = tlsCertPolicy; + _hostname = [hostname copy]; + _tlsAlpnProtocols = [[NSArray alloc] initWithArray:tlsAlpnProtocols copyItems:YES]; + _tlsEllipticCurves = [[NSArray alloc] initWithArray:tlsEllipticCurves copyItems:YES]; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCIceServer):\n%@\n%@\n%@\n%@\n%@\n%@\n%@", + _urlStrings, + _username, + _credential, + [self stringForTlsCertPolicy:_tlsCertPolicy], + _hostname, + _tlsAlpnProtocols, + _tlsEllipticCurves]; +} + +#pragma mark - Private + +- (NSString *)stringForTlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy { + switch (tlsCertPolicy) { + case RTCTlsCertPolicySecure: + return @"RTCTlsCertPolicySecure"; + case RTCTlsCertPolicyInsecureNoCheck: + return @"RTCTlsCertPolicyInsecureNoCheck"; + } +} + +- (webrtc::PeerConnectionInterface::IceServer)nativeServer { + __block webrtc::PeerConnectionInterface::IceServer iceServer; + + iceServer.username = [NSString stdStringForString:_username]; + iceServer.password = [NSString stdStringForString:_credential]; + iceServer.hostname = [NSString stdStringForString:_hostname]; + + [_tlsAlpnProtocols enumerateObjectsUsingBlock:^(NSString *proto, NSUInteger idx, BOOL *stop) { + iceServer.tls_alpn_protocols.push_back(proto.stdString); + }]; + + [_tlsEllipticCurves enumerateObjectsUsingBlock:^(NSString *curve, NSUInteger idx, BOOL *stop) { + iceServer.tls_elliptic_curves.push_back(curve.stdString); + }]; + + [_urlStrings enumerateObjectsUsingBlock:^(NSString *url, + NSUInteger idx, + BOOL *stop) { + iceServer.urls.push_back(url.stdString); + }]; + + switch (_tlsCertPolicy) { + case RTCTlsCertPolicySecure: + iceServer.tls_cert_policy = + webrtc::PeerConnectionInterface::kTlsCertPolicySecure; + break; + case RTCTlsCertPolicyInsecureNoCheck: + iceServer.tls_cert_policy = + webrtc::PeerConnectionInterface::kTlsCertPolicyInsecureNoCheck; + break; + } + return iceServer; +} + +- (instancetype)initWithNativeServer: + (webrtc::PeerConnectionInterface::IceServer)nativeServer { + NSMutableArray *urls = + [NSMutableArray arrayWithCapacity:nativeServer.urls.size()]; + for (auto const &url : nativeServer.urls) { + [urls addObject:[NSString stringForStdString:url]]; + } + NSString *username = [NSString stringForStdString:nativeServer.username]; + NSString *credential = [NSString stringForStdString:nativeServer.password]; + NSString *hostname = [NSString stringForStdString:nativeServer.hostname]; + NSMutableArray *tlsAlpnProtocols = + [NSMutableArray arrayWithCapacity:nativeServer.tls_alpn_protocols.size()]; + for (auto const &proto : nativeServer.tls_alpn_protocols) { + [tlsAlpnProtocols addObject:[NSString stringForStdString:proto]]; + } + NSMutableArray *tlsEllipticCurves = + [NSMutableArray arrayWithCapacity:nativeServer.tls_elliptic_curves.size()]; + for (auto const &curve : nativeServer.tls_elliptic_curves) { + [tlsEllipticCurves addObject:[NSString stringForStdString:curve]]; + } + RTCTlsCertPolicy tlsCertPolicy; + + switch (nativeServer.tls_cert_policy) { + case webrtc::PeerConnectionInterface::kTlsCertPolicySecure: + tlsCertPolicy = RTCTlsCertPolicySecure; + break; + case webrtc::PeerConnectionInterface::kTlsCertPolicyInsecureNoCheck: + tlsCertPolicy = RTCTlsCertPolicyInsecureNoCheck; + break; + } + + self = [self initWithURLStrings:urls + username:username + credential:credential + tlsCertPolicy:tlsCertPolicy + hostname:hostname + tlsAlpnProtocols:tlsAlpnProtocols + tlsEllipticCurves:tlsEllipticCurves]; + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport+Private.h new file mode 100644 index 0000000000..7374b2b72f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport+Private.h @@ -0,0 +1,25 @@ +/* + * Copyright 2015 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 "RTCLegacyStatsReport.h" + +#include "api/legacy_stats_types.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCLegacyStatsReport) +() + + /** Initialize an RTCLegacyStatsReport object from a native StatsReport. */ + - (instancetype)initWithNativeReport : (const webrtc::StatsReport &)nativeReport; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport.h new file mode 100644 index 0000000000..b3bd12c5d7 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +/** This does not currently conform to the spec. */ +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCLegacyStatsReport) : NSObject + +/** Time since 1970-01-01T00:00:00Z in milliseconds. */ +@property(nonatomic, readonly) CFTimeInterval timestamp; + +/** The type of stats held by this object. */ +@property(nonatomic, readonly) NSString *type; + +/** The identifier for this object. */ +@property(nonatomic, readonly) NSString *reportId; + +/** A dictionary holding the actual stats. */ +@property(nonatomic, readonly) NSDictionary<NSString *, NSString *> *values; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport.mm new file mode 100644 index 0000000000..bd7a1ad9c9 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCLegacyStatsReport.mm @@ -0,0 +1,60 @@ +/* + * Copyright 2015 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 "RTCLegacyStatsReport+Private.h" + +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +#include "rtc_base/checks.h" + +@implementation RTC_OBJC_TYPE (RTCLegacyStatsReport) + +@synthesize timestamp = _timestamp; +@synthesize type = _type; +@synthesize reportId = _reportId; +@synthesize values = _values; + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCLegacyStatsReport):\n%@\n%@\n%f\n%@", + _reportId, + _type, + _timestamp, + _values]; +} + +#pragma mark - Private + +- (instancetype)initWithNativeReport:(const webrtc::StatsReport &)nativeReport { + if (self = [super init]) { + _timestamp = nativeReport.timestamp(); + _type = [NSString stringForStdString:nativeReport.TypeToString()]; + _reportId = [NSString stringForStdString: + nativeReport.id()->ToString()]; + + NSUInteger capacity = nativeReport.values().size(); + NSMutableDictionary *values = + [NSMutableDictionary dictionaryWithCapacity:capacity]; + for (auto const &valuePair : nativeReport.values()) { + NSString *key = [NSString stringForStdString: + valuePair.second->display_name()]; + NSString *value = [NSString stringForStdString: + valuePair.second->ToString()]; + + // Not expecting duplicate keys. + RTC_DCHECK(![values objectForKey:key]); + [values setObject:value forKey:key]; + } + _values = values; + } + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints+Private.h new file mode 100644 index 0000000000..97eee8307d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints+Private.h @@ -0,0 +1,34 @@ +/* + * Copyright 2015 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 "RTCMediaConstraints.h" + +#include <memory> + +#include "sdk/media_constraints.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCMediaConstraints) +() + + /** + * A MediaConstraints representation of this RTCMediaConstraints object. This is + * needed to pass to the underlying C++ APIs. + */ + - (std::unique_ptr<webrtc::MediaConstraints>)nativeConstraints; + +/** Return a native Constraints object representing these constraints */ ++ (webrtc::MediaConstraints::Constraints)nativeConstraintsForConstraints: + (NSDictionary<NSString*, NSString*>*)constraints; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints.h new file mode 100644 index 0000000000..c5baf20c1d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints.h @@ -0,0 +1,46 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Constraint keys for media sources. */ +/** The value for this key should be a base64 encoded string containing + * the data from the serialized configuration proto. + */ +RTC_EXTERN NSString *const kRTCMediaConstraintsAudioNetworkAdaptorConfig; + +/** Constraint keys for generating offers and answers. */ +RTC_EXTERN NSString *const kRTCMediaConstraintsIceRestart; +RTC_EXTERN NSString *const kRTCMediaConstraintsOfferToReceiveAudio; +RTC_EXTERN NSString *const kRTCMediaConstraintsOfferToReceiveVideo; +RTC_EXTERN NSString *const kRTCMediaConstraintsVoiceActivityDetection; + +/** Constraint values for Boolean parameters. */ +RTC_EXTERN NSString *const kRTCMediaConstraintsValueTrue; +RTC_EXTERN NSString *const kRTCMediaConstraintsValueFalse; + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCMediaConstraints) : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** Initialize with mandatory and/or optional constraints. */ +- (instancetype) + initWithMandatoryConstraints:(nullable NSDictionary<NSString *, NSString *> *)mandatory + optionalConstraints:(nullable NSDictionary<NSString *, NSString *> *)optional + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints.mm new file mode 100644 index 0000000000..0f46e4b8fe --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaConstraints.mm @@ -0,0 +1,90 @@ +/* + * Copyright 2015 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 "RTCMediaConstraints+Private.h" + +#import "helpers/NSString+StdString.h" + +#include <memory> + +NSString *const kRTCMediaConstraintsAudioNetworkAdaptorConfig = + @(webrtc::MediaConstraints::kAudioNetworkAdaptorConfig); + +NSString *const kRTCMediaConstraintsIceRestart = @(webrtc::MediaConstraints::kIceRestart); +NSString *const kRTCMediaConstraintsOfferToReceiveAudio = + @(webrtc::MediaConstraints::kOfferToReceiveAudio); +NSString *const kRTCMediaConstraintsOfferToReceiveVideo = + @(webrtc::MediaConstraints::kOfferToReceiveVideo); +NSString *const kRTCMediaConstraintsVoiceActivityDetection = + @(webrtc::MediaConstraints::kVoiceActivityDetection); + +NSString *const kRTCMediaConstraintsValueTrue = @(webrtc::MediaConstraints::kValueTrue); +NSString *const kRTCMediaConstraintsValueFalse = @(webrtc::MediaConstraints::kValueFalse); + +@implementation RTC_OBJC_TYPE (RTCMediaConstraints) { + NSDictionary<NSString *, NSString *> *_mandatory; + NSDictionary<NSString *, NSString *> *_optional; +} + +- (instancetype)initWithMandatoryConstraints: + (NSDictionary<NSString *, NSString *> *)mandatory + optionalConstraints: + (NSDictionary<NSString *, NSString *> *)optional { + if (self = [super init]) { + _mandatory = [[NSDictionary alloc] initWithDictionary:mandatory + copyItems:YES]; + _optional = [[NSDictionary alloc] initWithDictionary:optional + copyItems:YES]; + } + return self; +} + +- (NSString *)description { + return [NSString + stringWithFormat:@"RTC_OBJC_TYPE(RTCMediaConstraints):\n%@\n%@", _mandatory, _optional]; +} + +#pragma mark - Private + +- (std::unique_ptr<webrtc::MediaConstraints>)nativeConstraints { + webrtc::MediaConstraints::Constraints mandatory = + [[self class] nativeConstraintsForConstraints:_mandatory]; + webrtc::MediaConstraints::Constraints optional = + [[self class] nativeConstraintsForConstraints:_optional]; + + webrtc::MediaConstraints *nativeConstraints = + new webrtc::MediaConstraints(mandatory, optional); + return std::unique_ptr<webrtc::MediaConstraints>(nativeConstraints); +} + ++ (webrtc::MediaConstraints::Constraints)nativeConstraintsForConstraints: + (NSDictionary<NSString *, NSString *> *)constraints { + webrtc::MediaConstraints::Constraints nativeConstraints; + for (NSString *key in constraints) { + NSAssert([key isKindOfClass:[NSString class]], + @"%@ is not an NSString.", key); + NSString *value = [constraints objectForKey:key]; + NSAssert([value isKindOfClass:[NSString class]], + @"%@ is not an NSString.", value); + if ([kRTCMediaConstraintsAudioNetworkAdaptorConfig isEqualToString:key]) { + // This value is base64 encoded. + NSData *charData = [[NSData alloc] initWithBase64EncodedString:value options:0]; + std::string configValue = + std::string(reinterpret_cast<const char *>(charData.bytes), charData.length); + nativeConstraints.push_back(webrtc::MediaConstraints::Constraint(key.stdString, configValue)); + } else { + nativeConstraints.push_back( + webrtc::MediaConstraints::Constraint(key.stdString, value.stdString)); + } + } + return nativeConstraints; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource+Private.h new file mode 100644 index 0000000000..edda892e50 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource+Private.h @@ -0,0 +1,42 @@ +/* + * 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 "RTCMediaSource.h" + +#include "api/media_stream_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); + +typedef NS_ENUM(NSInteger, RTCMediaSourceType) { + RTCMediaSourceTypeAudio, + RTCMediaSourceTypeVideo, +}; + +@interface RTC_OBJC_TYPE (RTCMediaSource) +() + + @property(nonatomic, + readonly) rtc::scoped_refptr<webrtc::MediaSourceInterface> nativeMediaSource; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource + type:(RTCMediaSourceType)type NS_DESIGNATED_INITIALIZER; + ++ (webrtc::MediaSourceInterface::SourceState)nativeSourceStateForState:(RTCSourceState)state; + ++ (RTCSourceState)sourceStateForNativeState:(webrtc::MediaSourceInterface::SourceState)nativeState; + ++ (NSString *)stringForState:(RTCSourceState)state; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource.h new file mode 100644 index 0000000000..ba19c2a352 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource.h @@ -0,0 +1,34 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +typedef NS_ENUM(NSInteger, RTCSourceState) { + RTCSourceStateInitializing, + RTCSourceStateLive, + RTCSourceStateEnded, + RTCSourceStateMuted, +}; + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCMediaSource) : NSObject + +/** The current state of the RTCMediaSource. */ +@property(nonatomic, readonly) RTCSourceState state; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource.mm new file mode 100644 index 0000000000..61472a782a --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaSource.mm @@ -0,0 +1,82 @@ +/* + * 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 "RTCMediaSource+Private.h" + +#include "rtc_base/checks.h" + +@implementation RTC_OBJC_TYPE (RTCMediaSource) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + RTCMediaSourceType _type; +} + +@synthesize nativeMediaSource = _nativeMediaSource; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource + type:(RTCMediaSourceType)type { + RTC_DCHECK(factory); + RTC_DCHECK(nativeMediaSource); + if (self = [super init]) { + _factory = factory; + _nativeMediaSource = nativeMediaSource; + _type = type; + } + return self; +} + +- (RTCSourceState)state { + return [[self class] sourceStateForNativeState:_nativeMediaSource->state()]; +} + +#pragma mark - Private + ++ (webrtc::MediaSourceInterface::SourceState)nativeSourceStateForState: + (RTCSourceState)state { + switch (state) { + case RTCSourceStateInitializing: + return webrtc::MediaSourceInterface::kInitializing; + case RTCSourceStateLive: + return webrtc::MediaSourceInterface::kLive; + case RTCSourceStateEnded: + return webrtc::MediaSourceInterface::kEnded; + case RTCSourceStateMuted: + return webrtc::MediaSourceInterface::kMuted; + } +} + ++ (RTCSourceState)sourceStateForNativeState: + (webrtc::MediaSourceInterface::SourceState)nativeState { + switch (nativeState) { + case webrtc::MediaSourceInterface::kInitializing: + return RTCSourceStateInitializing; + case webrtc::MediaSourceInterface::kLive: + return RTCSourceStateLive; + case webrtc::MediaSourceInterface::kEnded: + return RTCSourceStateEnded; + case webrtc::MediaSourceInterface::kMuted: + return RTCSourceStateMuted; + } +} + ++ (NSString *)stringForState:(RTCSourceState)state { + switch (state) { + case RTCSourceStateInitializing: + return @"Initializing"; + case RTCSourceStateLive: + return @"Live"; + case RTCSourceStateEnded: + return @"Ended"; + case RTCSourceStateMuted: + return @"Muted"; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream+Private.h new file mode 100644 index 0000000000..6c8a602766 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream+Private.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 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 "RTCMediaStream.h" + +#include "api/media_stream_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCMediaStream) +() + + /** + * MediaStreamInterface representation of this RTCMediaStream object. This is + * needed to pass to the underlying C++ APIs. + */ + @property(nonatomic, + readonly) rtc::scoped_refptr<webrtc::MediaStreamInterface> nativeMediaStream; + +/** Initialize an RTCMediaStream with an id. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + streamId:(NSString *)streamId; + +/** Initialize an RTCMediaStream from a native MediaStreamInterface. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaStream:(rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream.h new file mode 100644 index 0000000000..2d56f15c7d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream.h @@ -0,0 +1,49 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCAudioTrack); +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); +@class RTC_OBJC_TYPE(RTCVideoTrack); + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCMediaStream) : NSObject + +/** The audio tracks in this stream. */ +@property(nonatomic, strong, readonly) NSArray<RTC_OBJC_TYPE(RTCAudioTrack) *> *audioTracks; + +/** The video tracks in this stream. */ +@property(nonatomic, strong, readonly) NSArray<RTC_OBJC_TYPE(RTCVideoTrack) *> *videoTracks; + +/** An identifier for this media stream. */ +@property(nonatomic, readonly) NSString *streamId; + +- (instancetype)init NS_UNAVAILABLE; + +/** Adds the given audio track to this media stream. */ +- (void)addAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack; + +/** Adds the given video track to this media stream. */ +- (void)addVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack; + +/** Removes the given audio track to this media stream. */ +- (void)removeAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack; + +/** Removes the given video track to this media stream. */ +- (void)removeVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream.mm new file mode 100644 index 0000000000..0018dd6945 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStream.mm @@ -0,0 +1,155 @@ +/* + * Copyright 2015 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 "RTCMediaStream+Private.h" + +#import "RTCAudioTrack+Private.h" +#import "RTCMediaStreamTrack+Private.h" +#import "RTCPeerConnectionFactory+Private.h" +#import "RTCVideoTrack+Private.h" +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCMediaStream) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + rtc::Thread *_signalingThread; + NSMutableArray *_audioTracks /* accessed on _signalingThread */; + NSMutableArray *_videoTracks /* accessed on _signalingThread */; + rtc::scoped_refptr<webrtc::MediaStreamInterface> _nativeMediaStream; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + streamId:(NSString *)streamId { + NSParameterAssert(factory); + NSParameterAssert(streamId.length); + std::string nativeId = [NSString stdStringForString:streamId]; + rtc::scoped_refptr<webrtc::MediaStreamInterface> stream = + factory.nativeFactory->CreateLocalMediaStream(nativeId); + return [self initWithFactory:factory nativeMediaStream:stream]; +} + +- (NSArray<RTC_OBJC_TYPE(RTCAudioTrack) *> *)audioTracks { + if (!_signalingThread->IsCurrent()) { + return _signalingThread->BlockingCall([self]() { return self.audioTracks; }); + } + return [_audioTracks copy]; +} + +- (NSArray<RTC_OBJC_TYPE(RTCVideoTrack) *> *)videoTracks { + if (!_signalingThread->IsCurrent()) { + return _signalingThread->BlockingCall([self]() { return self.videoTracks; }); + } + return [_videoTracks copy]; +} + +- (NSString *)streamId { + return [NSString stringForStdString:_nativeMediaStream->id()]; +} + +- (void)addAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack { + if (!_signalingThread->IsCurrent()) { + return _signalingThread->BlockingCall( + [audioTrack, self]() { return [self addAudioTrack:audioTrack]; }); + } + if (_nativeMediaStream->AddTrack(audioTrack.nativeAudioTrack)) { + [_audioTracks addObject:audioTrack]; + } +} + +- (void)addVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack { + if (!_signalingThread->IsCurrent()) { + return _signalingThread->BlockingCall( + [videoTrack, self]() { return [self addVideoTrack:videoTrack]; }); + } + if (_nativeMediaStream->AddTrack(videoTrack.nativeVideoTrack)) { + [_videoTracks addObject:videoTrack]; + } +} + +- (void)removeAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack { + if (!_signalingThread->IsCurrent()) { + return _signalingThread->BlockingCall( + [audioTrack, self]() { return [self removeAudioTrack:audioTrack]; }); + } + NSUInteger index = [_audioTracks indexOfObjectIdenticalTo:audioTrack]; + if (index == NSNotFound) { + RTC_LOG(LS_INFO) << "|removeAudioTrack| called on unexpected RTC_OBJC_TYPE(RTCAudioTrack)"; + return; + } + if (_nativeMediaStream->RemoveTrack(audioTrack.nativeAudioTrack)) { + [_audioTracks removeObjectAtIndex:index]; + } +} + +- (void)removeVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack { + if (!_signalingThread->IsCurrent()) { + return _signalingThread->BlockingCall( + [videoTrack, self]() { return [self removeVideoTrack:videoTrack]; }); + } + NSUInteger index = [_videoTracks indexOfObjectIdenticalTo:videoTrack]; + if (index == NSNotFound) { + RTC_LOG(LS_INFO) << "|removeVideoTrack| called on unexpected RTC_OBJC_TYPE(RTCVideoTrack)"; + return; + } + + if (_nativeMediaStream->RemoveTrack(videoTrack.nativeVideoTrack)) { + [_videoTracks removeObjectAtIndex:index]; + } +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCMediaStream):\n%@\nA=%lu\nV=%lu", + self.streamId, + (unsigned long)self.audioTracks.count, + (unsigned long)self.videoTracks.count]; +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream { + return _nativeMediaStream; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaStream: + (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream { + NSParameterAssert(nativeMediaStream); + if (self = [super init]) { + _factory = factory; + _signalingThread = factory.signalingThread; + + webrtc::AudioTrackVector audioTracks = nativeMediaStream->GetAudioTracks(); + webrtc::VideoTrackVector videoTracks = nativeMediaStream->GetVideoTracks(); + + _audioTracks = [NSMutableArray arrayWithCapacity:audioTracks.size()]; + _videoTracks = [NSMutableArray arrayWithCapacity:videoTracks.size()]; + _nativeMediaStream = nativeMediaStream; + + for (auto &track : audioTracks) { + RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeAudio; + RTC_OBJC_TYPE(RTCAudioTrack) *audioTrack = + [[RTC_OBJC_TYPE(RTCAudioTrack) alloc] initWithFactory:_factory + nativeTrack:track + type:type]; + [_audioTracks addObject:audioTrack]; + } + + for (auto &track : videoTracks) { + RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeVideo; + RTC_OBJC_TYPE(RTCVideoTrack) *videoTrack = + [[RTC_OBJC_TYPE(RTCVideoTrack) alloc] initWithFactory:_factory + nativeTrack:track + type:type]; + [_videoTracks addObject:videoTrack]; + } + } + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack+Private.h new file mode 100644 index 0000000000..ee51e27b2d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack+Private.h @@ -0,0 +1,62 @@ +/* + * Copyright 2015 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 "RTCMediaStreamTrack.h" + +#include "api/media_stream_interface.h" + +typedef NS_ENUM(NSInteger, RTCMediaStreamTrackType) { + RTCMediaStreamTrackTypeAudio, + RTCMediaStreamTrackTypeVideo, +}; + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); + +@interface RTC_OBJC_TYPE (RTCMediaStreamTrack) +() + + @property(nonatomic, readonly) RTC_OBJC_TYPE(RTCPeerConnectionFactory) * + factory; + +/** + * The native MediaStreamTrackInterface passed in or created during + * construction. + */ +@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack; + +/** + * Initialize an RTCMediaStreamTrack from a native MediaStreamTrackInterface. + */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack + type:(RTCMediaStreamTrackType)type NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack; + +- (BOOL)isEqualToTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track; + ++ (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState: + (RTCMediaStreamTrackState)state; + ++ (RTCMediaStreamTrackState)trackStateForNativeState: + (webrtc::MediaStreamTrackInterface::TrackState)nativeState; + ++ (NSString *)stringForState:(RTCMediaStreamTrackState)state; + ++ (RTC_OBJC_TYPE(RTCMediaStreamTrack) *) + mediaTrackForNativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack + factory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack.h new file mode 100644 index 0000000000..2200122ccd --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack.h @@ -0,0 +1,50 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +/** + * Represents the state of the track. This exposes the same states in C++. + */ +typedef NS_ENUM(NSInteger, RTCMediaStreamTrackState) { + RTCMediaStreamTrackStateLive, + RTCMediaStreamTrackStateEnded +}; + +NS_ASSUME_NONNULL_BEGIN + +RTC_EXTERN NSString *const kRTCMediaStreamTrackKindAudio; +RTC_EXTERN NSString *const kRTCMediaStreamTrackKindVideo; + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCMediaStreamTrack) : NSObject + +/** + * The kind of track. For example, "audio" if this track represents an audio + * track and "video" if this track represents a video track. + */ +@property(nonatomic, readonly) NSString *kind; + +/** An identifier string. */ +@property(nonatomic, readonly) NSString *trackId; + +/** The enabled state of the track. */ +@property(nonatomic, assign) BOOL isEnabled; + +/** The state of the track. */ +@property(nonatomic, readonly) RTCMediaStreamTrackState readyState; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack.mm new file mode 100644 index 0000000000..f1e128ca60 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack.mm @@ -0,0 +1,161 @@ +/* + * Copyright 2015 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 "RTCAudioTrack+Private.h" +#import "RTCMediaStreamTrack+Private.h" +#import "RTCVideoTrack+Private.h" + +#import "helpers/NSString+StdString.h" + +NSString * const kRTCMediaStreamTrackKindAudio = + @(webrtc::MediaStreamTrackInterface::kAudioKind); +NSString * const kRTCMediaStreamTrackKindVideo = + @(webrtc::MediaStreamTrackInterface::kVideoKind); + +@implementation RTC_OBJC_TYPE (RTCMediaStreamTrack) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> _nativeTrack; + RTCMediaStreamTrackType _type; +} + +- (NSString *)kind { + return [NSString stringForStdString:_nativeTrack->kind()]; +} + +- (NSString *)trackId { + return [NSString stringForStdString:_nativeTrack->id()]; +} + +- (BOOL)isEnabled { + return _nativeTrack->enabled(); +} + +- (void)setIsEnabled:(BOOL)isEnabled { + _nativeTrack->set_enabled(isEnabled); +} + +- (RTCMediaStreamTrackState)readyState { + return [[self class] trackStateForNativeState:_nativeTrack->state()]; +} + +- (NSString *)description { + NSString *readyState = [[self class] stringForState:self.readyState]; + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCMediaStreamTrack):\n%@\n%@\n%@\n%@", + self.kind, + self.trackId, + self.isEnabled ? @"enabled" : @"disabled", + readyState]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isMemberOfClass:[self class]]) { + return NO; + } + return [self isEqualToTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)object]; +} + +- (NSUInteger)hash { + return (NSUInteger)_nativeTrack.get(); +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack { + return _nativeTrack; +} + +@synthesize factory = _factory; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack + type:(RTCMediaStreamTrackType)type { + NSParameterAssert(nativeTrack); + NSParameterAssert(factory); + if (self = [super init]) { + _factory = factory; + _nativeTrack = nativeTrack; + _type = type; + } + return self; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack { + NSParameterAssert(nativeTrack); + if (nativeTrack->kind() == + std::string(webrtc::MediaStreamTrackInterface::kAudioKind)) { + return [self initWithFactory:factory nativeTrack:nativeTrack type:RTCMediaStreamTrackTypeAudio]; + } + if (nativeTrack->kind() == + std::string(webrtc::MediaStreamTrackInterface::kVideoKind)) { + return [self initWithFactory:factory nativeTrack:nativeTrack type:RTCMediaStreamTrackTypeVideo]; + } + return nil; +} + +- (BOOL)isEqualToTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track { + if (!track) { + return NO; + } + return _nativeTrack == track.nativeTrack; +} + ++ (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState: + (RTCMediaStreamTrackState)state { + switch (state) { + case RTCMediaStreamTrackStateLive: + return webrtc::MediaStreamTrackInterface::kLive; + case RTCMediaStreamTrackStateEnded: + return webrtc::MediaStreamTrackInterface::kEnded; + } +} + ++ (RTCMediaStreamTrackState)trackStateForNativeState: + (webrtc::MediaStreamTrackInterface::TrackState)nativeState { + switch (nativeState) { + case webrtc::MediaStreamTrackInterface::kLive: + return RTCMediaStreamTrackStateLive; + case webrtc::MediaStreamTrackInterface::kEnded: + return RTCMediaStreamTrackStateEnded; + } +} + ++ (NSString *)stringForState:(RTCMediaStreamTrackState)state { + switch (state) { + case RTCMediaStreamTrackStateLive: + return @"Live"; + case RTCMediaStreamTrackStateEnded: + return @"Ended"; + } +} + ++ (RTC_OBJC_TYPE(RTCMediaStreamTrack) *) + mediaTrackForNativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack + factory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory { + NSParameterAssert(nativeTrack); + NSParameterAssert(factory); + if (nativeTrack->kind() == webrtc::MediaStreamTrackInterface::kAudioKind) { + return [[RTC_OBJC_TYPE(RTCAudioTrack) alloc] initWithFactory:factory + nativeTrack:nativeTrack + type:RTCMediaStreamTrackTypeAudio]; + } else if (nativeTrack->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { + return [[RTC_OBJC_TYPE(RTCVideoTrack) alloc] initWithFactory:factory + nativeTrack:nativeTrack + type:RTCMediaStreamTrackTypeVideo]; + } else { + return [[RTC_OBJC_TYPE(RTCMediaStreamTrack) alloc] initWithFactory:factory + nativeTrack:nativeTrack]; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetrics.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetrics.h new file mode 100644 index 0000000000..fddbb27c90 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetrics.h @@ -0,0 +1,23 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" +#import "RTCMetricsSampleInfo.h" + +/** + * Enables gathering of metrics (which can be fetched with + * RTCGetAndResetMetrics). Must be called before any other call into WebRTC. + */ +RTC_EXTERN void RTCEnableMetrics(void); + +/** Gets and clears native histograms. */ +RTC_EXTERN NSArray<RTC_OBJC_TYPE(RTCMetricsSampleInfo) *>* RTCGetAndResetMetrics(void); diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetrics.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetrics.mm new file mode 100644 index 0000000000..87eb8c0210 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetrics.mm @@ -0,0 +1,34 @@ +/* + * 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 "RTCMetrics.h" + +#import "RTCMetricsSampleInfo+Private.h" + +#include "rtc_base/string_utils.h" + +void RTCEnableMetrics(void) { + webrtc::metrics::Enable(); +} + +NSArray<RTC_OBJC_TYPE(RTCMetricsSampleInfo) *> *RTCGetAndResetMetrics(void) { + std::map<std::string, std::unique_ptr<webrtc::metrics::SampleInfo>, rtc::AbslStringViewCmp> + histograms; + webrtc::metrics::GetAndReset(&histograms); + + NSMutableArray *metrics = + [NSMutableArray arrayWithCapacity:histograms.size()]; + for (auto const &histogram : histograms) { + RTC_OBJC_TYPE(RTCMetricsSampleInfo) *metric = + [[RTC_OBJC_TYPE(RTCMetricsSampleInfo) alloc] initWithNativeSampleInfo:*histogram.second]; + [metrics addObject:metric]; + } + return metrics; +} diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo+Private.h new file mode 100644 index 0000000000..e4aa41f6c7 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo+Private.h @@ -0,0 +1,25 @@ +/* + * 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 "RTCMetricsSampleInfo.h" + +#include "system_wrappers/include/metrics.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCMetricsSampleInfo) +() + + /** Initialize an RTCMetricsSampleInfo object from native SampleInfo. */ + - (instancetype)initWithNativeSampleInfo : (const webrtc::metrics::SampleInfo &)info; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo.h new file mode 100644 index 0000000000..47a877b6fb --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo.h @@ -0,0 +1,48 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCMetricsSampleInfo) : NSObject + +/** + * Example of RTCMetricsSampleInfo: + * name: "WebRTC.Video.InputFramesPerSecond" + * min: 1 + * max: 100 + * bucketCount: 50 + * samples: [29]:2 [30]:1 + */ + +/** The name of the histogram. */ +@property(nonatomic, readonly) NSString *name; + +/** The minimum bucket value. */ +@property(nonatomic, readonly) int min; + +/** The maximum bucket value. */ +@property(nonatomic, readonly) int max; + +/** The number of buckets. */ +@property(nonatomic, readonly) int bucketCount; + +/** A dictionary holding the samples <value, # of events>. */ +@property(nonatomic, readonly) NSDictionary<NSNumber *, NSNumber *> *samples; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo.mm new file mode 100644 index 0000000000..e4be94e90a --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMetricsSampleInfo.mm @@ -0,0 +1,43 @@ +/* + * 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 "RTCMetricsSampleInfo+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCMetricsSampleInfo) + +@synthesize name = _name; +@synthesize min = _min; +@synthesize max = _max; +@synthesize bucketCount = _bucketCount; +@synthesize samples = _samples; + +#pragma mark - Private + +- (instancetype)initWithNativeSampleInfo: + (const webrtc::metrics::SampleInfo &)info { + if (self = [super init]) { + _name = [NSString stringForStdString:info.name]; + _min = info.min; + _max = info.max; + _bucketCount = info.bucket_count; + + NSMutableDictionary *samples = + [NSMutableDictionary dictionaryWithCapacity:info.samples.size()]; + for (auto const &sample : info.samples) { + [samples setObject:@(sample.second) forKey:@(sample.first)]; + } + _samples = samples; + } + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+DataChannel.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+DataChannel.mm new file mode 100644 index 0000000000..cb75f061d8 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+DataChannel.mm @@ -0,0 +1,34 @@ +/* + * Copyright 2015 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 "RTCPeerConnection+Private.h" + +#import "RTCDataChannel+Private.h" +#import "RTCDataChannelConfiguration+Private.h" +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCPeerConnection) +(DataChannel) + + - (nullable RTC_OBJC_TYPE(RTCDataChannel) *)dataChannelForLabel + : (NSString *)label configuration + : (RTC_OBJC_TYPE(RTCDataChannelConfiguration) *)configuration { + std::string labelString = [NSString stdStringForString:label]; + const webrtc::DataChannelInit nativeInit = + configuration.nativeDataChannelInit; + auto result = self.nativePeerConnection->CreateDataChannelOrError(labelString, &nativeInit); + if (!result.ok()) { + return nil; + } + return [[RTC_OBJC_TYPE(RTCDataChannel) alloc] initWithFactory:self.factory + nativeDataChannel:result.MoveValue()]; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Private.h new file mode 100644 index 0000000000..00f2ef7834 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Private.h @@ -0,0 +1,143 @@ +/* + * Copyright 2015 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 "RTCPeerConnection.h" + +#include "api/peer_connection_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace webrtc { + +/** + * These objects are created by RTCPeerConnectionFactory to wrap an + * id<RTCPeerConnectionDelegate> and call methods on that interface. + */ +class PeerConnectionDelegateAdapter : public PeerConnectionObserver { + public: + PeerConnectionDelegateAdapter(RTC_OBJC_TYPE(RTCPeerConnection) * peerConnection); + ~PeerConnectionDelegateAdapter() override; + + void OnSignalingChange(PeerConnectionInterface::SignalingState new_state) override; + + void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override; + + void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream) override; + + void OnTrack(rtc::scoped_refptr<RtpTransceiverInterface> transceiver) override; + + void OnDataChannel(rtc::scoped_refptr<DataChannelInterface> data_channel) override; + + void OnRenegotiationNeeded() override; + + void OnIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state) override; + + void OnStandardizedIceConnectionChange( + PeerConnectionInterface::IceConnectionState new_state) override; + + void OnConnectionChange(PeerConnectionInterface::PeerConnectionState new_state) override; + + void OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state) override; + + void OnIceCandidate(const IceCandidateInterface *candidate) override; + + void OnIceCandidateError(const std::string &address, + int port, + const std::string &url, + int error_code, + const std::string &error_text) override; + + void OnIceCandidatesRemoved(const std::vector<cricket::Candidate> &candidates) override; + + void OnIceSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent &event) override; + + void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver, + const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) override; + + void OnRemoveTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver) override; + + private: + __weak RTC_OBJC_TYPE(RTCPeerConnection) * peer_connection_; +}; + +} // namespace webrtc +@protocol RTC_OBJC_TYPE +(RTCSSLCertificateVerifier); + +@interface RTC_OBJC_TYPE (RTCPeerConnection) +() + + /** The factory used to create this RTCPeerConnection */ + @property(nonatomic, readonly) RTC_OBJC_TYPE(RTCPeerConnectionFactory) * + factory; + +/** The native PeerConnectionInterface created during construction. */ +@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::PeerConnectionInterface> + nativePeerConnection; + +/** Initialize an RTCPeerConnection with a configuration, constraints, and + * delegate. + */ +- (nullable instancetype) + initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + certificateVerifier:(nullable id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier + delegate:(nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate; + +/** Initialize an RTCPeerConnection with a configuration, constraints, + * delegate and PeerConnectionDependencies. + */ +- (nullable instancetype) + initWithDependencies:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies + delegate:(nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate + NS_DESIGNATED_INITIALIZER; + ++ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState: + (RTCSignalingState)state; + ++ (RTCSignalingState)signalingStateForNativeState: + (webrtc::PeerConnectionInterface::SignalingState)nativeState; + ++ (NSString *)stringForSignalingState:(RTCSignalingState)state; + ++ (webrtc::PeerConnectionInterface::IceConnectionState)nativeIceConnectionStateForState: + (RTCIceConnectionState)state; + ++ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState: + (RTCPeerConnectionState)state; + ++ (RTCIceConnectionState)iceConnectionStateForNativeState: + (webrtc::PeerConnectionInterface::IceConnectionState)nativeState; + ++ (RTCPeerConnectionState)connectionStateForNativeState: + (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState; + ++ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state; + ++ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state; + ++ (webrtc::PeerConnectionInterface::IceGatheringState)nativeIceGatheringStateForState: + (RTCIceGatheringState)state; + ++ (RTCIceGatheringState)iceGatheringStateForNativeState: + (webrtc::PeerConnectionInterface::IceGatheringState)nativeState; + ++ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state; + ++ (webrtc::PeerConnectionInterface::StatsOutputLevel)nativeStatsOutputLevelForLevel: + (RTCStatsOutputLevel)level; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Stats.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Stats.mm new file mode 100644 index 0000000000..f8d38143f3 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Stats.mm @@ -0,0 +1,102 @@ +/* + * Copyright 2015 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 "RTCPeerConnection+Private.h" + +#import "RTCLegacyStatsReport+Private.h" +#import "RTCMediaStreamTrack+Private.h" +#import "RTCRtpReceiver+Private.h" +#import "RTCRtpSender+Private.h" +#import "RTCStatisticsReport+Private.h" +#import "helpers/NSString+StdString.h" + +#include "rtc_base/checks.h" + +namespace webrtc { + +class StatsCollectorCallbackAdapter : public RTCStatsCollectorCallback { + public: + StatsCollectorCallbackAdapter(RTCStatisticsCompletionHandler completion_handler) + : completion_handler_(completion_handler) {} + + void OnStatsDelivered(const rtc::scoped_refptr<const RTCStatsReport> &report) override { + RTC_DCHECK(completion_handler_); + RTC_OBJC_TYPE(RTCStatisticsReport) *statisticsReport = + [[RTC_OBJC_TYPE(RTCStatisticsReport) alloc] initWithReport:*report]; + completion_handler_(statisticsReport); + completion_handler_ = nil; + } + + private: + RTCStatisticsCompletionHandler completion_handler_; +}; + +class StatsObserverAdapter : public StatsObserver { + public: + StatsObserverAdapter( + void (^completionHandler)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats)) { + completion_handler_ = completionHandler; + } + + ~StatsObserverAdapter() override { completion_handler_ = nil; } + + void OnComplete(const StatsReports& reports) override { + RTC_DCHECK(completion_handler_); + NSMutableArray *stats = [NSMutableArray arrayWithCapacity:reports.size()]; + for (const auto* report : reports) { + RTC_OBJC_TYPE(RTCLegacyStatsReport) *statsReport = + [[RTC_OBJC_TYPE(RTCLegacyStatsReport) alloc] initWithNativeReport:*report]; + [stats addObject:statsReport]; + } + completion_handler_(stats); + completion_handler_ = nil; + } + + private: + void (^completion_handler_)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats); +}; +} // namespace webrtc + +@implementation RTC_OBJC_TYPE (RTCPeerConnection) +(Stats) + + - (void)statisticsForSender : (RTC_OBJC_TYPE(RTCRtpSender) *)sender completionHandler + : (RTCStatisticsCompletionHandler)completionHandler { + rtc::scoped_refptr<webrtc::StatsCollectorCallbackAdapter> collector = + rtc::make_ref_counted<webrtc::StatsCollectorCallbackAdapter>(completionHandler); + self.nativePeerConnection->GetStats(sender.nativeRtpSender, collector); +} + +- (void)statisticsForReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver + completionHandler:(RTCStatisticsCompletionHandler)completionHandler { + rtc::scoped_refptr<webrtc::StatsCollectorCallbackAdapter> collector = + rtc::make_ref_counted<webrtc::StatsCollectorCallbackAdapter>(completionHandler); + self.nativePeerConnection->GetStats(receiver.nativeRtpReceiver, collector); +} + +- (void)statisticsWithCompletionHandler:(RTCStatisticsCompletionHandler)completionHandler { + rtc::scoped_refptr<webrtc::StatsCollectorCallbackAdapter> collector = + rtc::make_ref_counted<webrtc::StatsCollectorCallbackAdapter>(completionHandler); + self.nativePeerConnection->GetStats(collector.get()); +} + +- (void)statsForTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)mediaStreamTrack + statsOutputLevel:(RTCStatsOutputLevel)statsOutputLevel + completionHandler: + (void (^)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats))completionHandler { + rtc::scoped_refptr<webrtc::StatsObserverAdapter> observer = + rtc::make_ref_counted<webrtc::StatsObserverAdapter>(completionHandler); + webrtc::PeerConnectionInterface::StatsOutputLevel nativeOutputLevel = + [[self class] nativeStatsOutputLevelForLevel:statsOutputLevel]; + self.nativePeerConnection->GetStats( + observer.get(), mediaStreamTrack.nativeTrack.get(), nativeOutputLevel); +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.h new file mode 100644 index 0000000000..55af6868fd --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.h @@ -0,0 +1,398 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +@class RTC_OBJC_TYPE(RTCConfiguration); +@class RTC_OBJC_TYPE(RTCDataChannel); +@class RTC_OBJC_TYPE(RTCDataChannelConfiguration); +@class RTC_OBJC_TYPE(RTCIceCandidate); +@class RTC_OBJC_TYPE(RTCIceCandidateErrorEvent); +@class RTC_OBJC_TYPE(RTCMediaConstraints); +@class RTC_OBJC_TYPE(RTCMediaStream); +@class RTC_OBJC_TYPE(RTCMediaStreamTrack); +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); +@class RTC_OBJC_TYPE(RTCRtpReceiver); +@class RTC_OBJC_TYPE(RTCRtpSender); +@class RTC_OBJC_TYPE(RTCRtpTransceiver); +@class RTC_OBJC_TYPE(RTCRtpTransceiverInit); +@class RTC_OBJC_TYPE(RTCSessionDescription); +@class RTC_OBJC_TYPE(RTCStatisticsReport); +@class RTC_OBJC_TYPE(RTCLegacyStatsReport); + +typedef NS_ENUM(NSInteger, RTCRtpMediaType); + +NS_ASSUME_NONNULL_BEGIN + +extern NSString *const kRTCPeerConnectionErrorDomain; +extern int const kRTCSessionDescriptionErrorCode; + +/** Represents the signaling state of the peer connection. */ +typedef NS_ENUM(NSInteger, RTCSignalingState) { + RTCSignalingStateStable, + RTCSignalingStateHaveLocalOffer, + RTCSignalingStateHaveLocalPrAnswer, + RTCSignalingStateHaveRemoteOffer, + RTCSignalingStateHaveRemotePrAnswer, + // Not an actual state, represents the total number of states. + RTCSignalingStateClosed, +}; + +/** Represents the ice connection state of the peer connection. */ +typedef NS_ENUM(NSInteger, RTCIceConnectionState) { + RTCIceConnectionStateNew, + RTCIceConnectionStateChecking, + RTCIceConnectionStateConnected, + RTCIceConnectionStateCompleted, + RTCIceConnectionStateFailed, + RTCIceConnectionStateDisconnected, + RTCIceConnectionStateClosed, + RTCIceConnectionStateCount, +}; + +/** Represents the combined ice+dtls connection state of the peer connection. */ +typedef NS_ENUM(NSInteger, RTCPeerConnectionState) { + RTCPeerConnectionStateNew, + RTCPeerConnectionStateConnecting, + RTCPeerConnectionStateConnected, + RTCPeerConnectionStateDisconnected, + RTCPeerConnectionStateFailed, + RTCPeerConnectionStateClosed, +}; + +/** Represents the ice gathering state of the peer connection. */ +typedef NS_ENUM(NSInteger, RTCIceGatheringState) { + RTCIceGatheringStateNew, + RTCIceGatheringStateGathering, + RTCIceGatheringStateComplete, +}; + +/** Represents the stats output level. */ +typedef NS_ENUM(NSInteger, RTCStatsOutputLevel) { + RTCStatsOutputLevelStandard, + RTCStatsOutputLevelDebug, +}; + +typedef void (^RTCCreateSessionDescriptionCompletionHandler)(RTC_OBJC_TYPE(RTCSessionDescription) * + _Nullable sdp, + NSError *_Nullable error); + +typedef void (^RTCSetSessionDescriptionCompletionHandler)(NSError *_Nullable error); + +@class RTC_OBJC_TYPE(RTCPeerConnection); + +RTC_OBJC_EXPORT +@protocol RTC_OBJC_TYPE +(RTCPeerConnectionDelegate)<NSObject> + + /** Called when the SignalingState changed. */ + - (void)peerConnection + : (RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection didChangeSignalingState + : (RTCSignalingState)stateChanged; + +/** Called when media is received on a new stream from remote peer. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didAddStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream; + +/** Called when a remote peer closes a stream. + * This is not called when RTCSdpSemanticsUnifiedPlan is specified. + */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didRemoveStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream; + +/** Called when negotiation is needed, for example ICE has restarted. */ +- (void)peerConnectionShouldNegotiate:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection; + +/** Called any time the IceConnectionState changes. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didChangeIceConnectionState:(RTCIceConnectionState)newState; + +/** Called any time the IceGatheringState changes. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didChangeIceGatheringState:(RTCIceGatheringState)newState; + +/** New ice candidate has been found. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didGenerateIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate; + +/** Called when a group of local Ice candidates have been removed. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didRemoveIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)candidates; + +/** New data channel has been opened. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didOpenDataChannel:(RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel; + +/** Called when signaling indicates a transceiver will be receiving media from + * the remote endpoint. + * This is only called with RTCSdpSemanticsUnifiedPlan specified. + */ +@optional +/** Called any time the IceConnectionState changes following standardized + * transition. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didChangeStandardizedIceConnectionState:(RTCIceConnectionState)newState; + +/** Called any time the PeerConnectionState changes. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didChangeConnectionState:(RTCPeerConnectionState)newState; + +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didStartReceivingOnTransceiver:(RTC_OBJC_TYPE(RTCRtpTransceiver) *)transceiver; + +/** Called when a receiver and its track are created. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didAddReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)rtpReceiver + streams:(NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *)mediaStreams; + +/** Called when the receiver and its track are removed. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didRemoveReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)rtpReceiver; + +/** Called when the selected ICE candidate pair is changed. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didChangeLocalCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)local + remoteCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)remote + lastReceivedMs:(int)lastDataReceivedMs + changeReason:(NSString *)reason; + +/** Called when gathering of an ICE candidate failed. */ +- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection + didFailToGatherIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *)event; + +@end + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCPeerConnection) : NSObject + +/** The object that will be notifed about events such as state changes and + * streams being added or removed. + */ +@property(nonatomic, weak, nullable) id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate; +/** This property is not available with RTCSdpSemanticsUnifiedPlan. Please use + * `senders` instead. + */ +@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *localStreams; +@property(nonatomic, readonly, nullable) RTC_OBJC_TYPE(RTCSessionDescription) * localDescription; +@property(nonatomic, readonly, nullable) RTC_OBJC_TYPE(RTCSessionDescription) * remoteDescription; +@property(nonatomic, readonly) RTCSignalingState signalingState; +@property(nonatomic, readonly) RTCIceConnectionState iceConnectionState; +@property(nonatomic, readonly) RTCPeerConnectionState connectionState; +@property(nonatomic, readonly) RTCIceGatheringState iceGatheringState; +@property(nonatomic, readonly, copy) RTC_OBJC_TYPE(RTCConfiguration) * configuration; + +/** Gets all RTCRtpSenders associated with this peer connection. + * Note: reading this property returns different instances of RTCRtpSender. + * Use isEqual: instead of == to compare RTCRtpSender instances. + */ +@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *senders; + +/** Gets all RTCRtpReceivers associated with this peer connection. + * Note: reading this property returns different instances of RTCRtpReceiver. + * Use isEqual: instead of == to compare RTCRtpReceiver instances. + */ +@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *receivers; + +/** Gets all RTCRtpTransceivers associated with this peer connection. + * Note: reading this property returns different instances of + * RTCRtpTransceiver. Use isEqual: instead of == to compare + * RTCRtpTransceiver instances. This is only available with + * RTCSdpSemanticsUnifiedPlan specified. + */ +@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *transceivers; + +- (instancetype)init NS_UNAVAILABLE; + +/** Sets the PeerConnection's global configuration to `configuration`. + * Any changes to STUN/TURN servers or ICE candidate policy will affect the + * next gathering phase, and cause the next call to createOffer to generate + * new ICE credentials. Note that the BUNDLE and RTCP-multiplexing policies + * cannot be changed with this method. + */ +- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration; + +/** Terminate all media and close the transport. */ +- (void)close; + +/** Provide a remote candidate to the ICE Agent. */ +- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate + DEPRECATED_MSG_ATTRIBUTE("Please use addIceCandidate:completionHandler: instead"); + +/** Provide a remote candidate to the ICE Agent. */ +- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate + completionHandler:(void (^)(NSError *_Nullable error))completionHandler; + +/** Remove a group of remote candidates from the ICE Agent. */ +- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)candidates; + +/** Add a new media stream to be sent on this peer connection. + * This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use + * addTrack instead. + */ +- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream; + +/** Remove the given media stream from this peer connection. + * This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use + * removeTrack instead. + */ +- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream; + +/** Add a new media stream track to be sent on this peer connection, and return + * the newly created RTCRtpSender. The RTCRtpSender will be + * associated with the streams specified in the `streamIds` list. + * + * Errors: If an error occurs, returns nil. An error can occur if: + * - A sender already exists for the track. + * - The peer connection is closed. + */ +- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track + streamIds:(NSArray<NSString *> *)streamIds; + +/** With PlanB semantics, removes an RTCRtpSender from this peer connection. + * + * With UnifiedPlan semantics, sets sender's track to null and removes the + * send component from the associated RTCRtpTransceiver's direction. + * + * Returns YES on success. + */ +- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender; + +/** addTransceiver creates a new RTCRtpTransceiver and adds it to the set of + * transceivers. Adding a transceiver will cause future calls to CreateOffer + * to add a media description for the corresponding transceiver. + * + * The initial value of `mid` in the returned transceiver is nil. Setting a + * new session description may change it to a non-nil value. + * + * https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver + * + * Optionally, an RtpTransceiverInit structure can be specified to configure + * the transceiver from construction. If not specified, the transceiver will + * default to having a direction of kSendRecv and not be part of any streams. + * + * These methods are only available when Unified Plan is enabled (see + * RTCConfiguration). + */ + +/** Adds a transceiver with a sender set to transmit the given track. The kind + * of the transceiver (and sender/receiver) will be derived from the kind of + * the track. + */ +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack: + (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track; +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *) + addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track + init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init; + +/** Adds a transceiver with the given kind. Can either be RTCRtpMediaTypeAudio + * or RTCRtpMediaTypeVideo. + */ +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType; +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *) + addTransceiverOfType:(RTCRtpMediaType)mediaType + init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init; + +/** Tells the PeerConnection that ICE should be restarted. This triggers a need + * for negotiation and subsequent offerForConstraints:completionHandler call will act as if + * RTCOfferAnswerOptions::ice_restart is true. + */ +- (void)restartIce; + +/** Generate an SDP offer. */ +- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler; + +/** Generate an SDP answer. */ +- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler; + +/** Apply the supplied RTCSessionDescription as the local description. */ +- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp + completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler; + +/** Creates an offer or answer (depending on current signaling state) and sets + * it as the local session description. */ +- (void)setLocalDescriptionWithCompletionHandler: + (RTCSetSessionDescriptionCompletionHandler)completionHandler; + +/** Apply the supplied RTCSessionDescription as the remote description. */ +- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp + completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler; + +/** Limits the bandwidth allocated for all RTP streams sent by this + * PeerConnection. Nil parameters will be unchanged. Setting + * `currentBitrateBps` will force the available bitrate estimate to the given + * value. Returns YES if the parameters were successfully updated. + */ +- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps + currentBitrateBps:(nullable NSNumber *)currentBitrateBps + maxBitrateBps:(nullable NSNumber *)maxBitrateBps; + +/** Start or stop recording an Rtc EventLog. */ +- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath maxSizeInBytes:(int64_t)maxSizeInBytes; +- (void)stopRtcEventLog; + +@end + +@interface RTC_OBJC_TYPE (RTCPeerConnection) +(Media) + + /** Create an RTCRtpSender with the specified kind and media stream ID. + * See RTCMediaStreamTrack.h for available kinds. + * This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use + * addTransceiver instead. + */ + - (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind : (NSString *)kind streamId + : (NSString *)streamId; + +@end + +@interface RTC_OBJC_TYPE (RTCPeerConnection) +(DataChannel) + + /** Create a new data channel with the given label and configuration. */ + - (nullable RTC_OBJC_TYPE(RTCDataChannel) *)dataChannelForLabel + : (NSString *)label configuration : (RTC_OBJC_TYPE(RTCDataChannelConfiguration) *)configuration; + +@end + +typedef void (^RTCStatisticsCompletionHandler)(RTC_OBJC_TYPE(RTCStatisticsReport) *); + +@interface RTC_OBJC_TYPE (RTCPeerConnection) +(Stats) + + /** Gather stats for the given RTCMediaStreamTrack. If `mediaStreamTrack` is nil + * statistics are gathered for all tracks. + */ + - (void)statsForTrack + : (nullable RTC_OBJC_TYPE(RTCMediaStreamTrack) *)mediaStreamTrack statsOutputLevel + : (RTCStatsOutputLevel)statsOutputLevel completionHandler + : (nullable void (^)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats))completionHandler; + +/** Gather statistic through the v2 statistics API. */ +- (void)statisticsWithCompletionHandler:(RTCStatisticsCompletionHandler)completionHandler; + +/** Spec-compliant getStats() performing the stats selection algorithm with the + * sender. + */ +- (void)statisticsForSender:(RTC_OBJC_TYPE(RTCRtpSender) *)sender + completionHandler:(RTCStatisticsCompletionHandler)completionHandler; + +/** Spec-compliant getStats() performing the stats selection algorithm with the + * receiver. + */ +- (void)statisticsForReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver + completionHandler:(RTCStatisticsCompletionHandler)completionHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.mm new file mode 100644 index 0000000000..df99030111 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.mm @@ -0,0 +1,935 @@ +/* + * Copyright 2015 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 "RTCPeerConnection+Private.h" + +#import "RTCConfiguration+Private.h" +#import "RTCDataChannel+Private.h" +#import "RTCIceCandidate+Private.h" +#import "RTCIceCandidateErrorEvent+Private.h" +#import "RTCLegacyStatsReport+Private.h" +#import "RTCMediaConstraints+Private.h" +#import "RTCMediaStream+Private.h" +#import "RTCMediaStreamTrack+Private.h" +#import "RTCPeerConnectionFactory+Private.h" +#import "RTCRtpReceiver+Private.h" +#import "RTCRtpSender+Private.h" +#import "RTCRtpTransceiver+Private.h" +#import "RTCSessionDescription+Private.h" +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +#include <memory> + +#include "api/jsep_ice_candidate.h" +#include "api/rtc_event_log_output_file.h" +#include "api/set_local_description_observer_interface.h" +#include "api/set_remote_description_observer_interface.h" +#include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_conversions.h" +#include "sdk/objc/native/api/ssl_certificate_verifier.h" + +NSString *const kRTCPeerConnectionErrorDomain = @"org.webrtc.RTC_OBJC_TYPE(RTCPeerConnection)"; +int const kRTCPeerConnnectionSessionDescriptionError = -1; + +namespace { + +class SetSessionDescriptionObserver : public webrtc::SetLocalDescriptionObserverInterface, + public webrtc::SetRemoteDescriptionObserverInterface { + public: + SetSessionDescriptionObserver(RTCSetSessionDescriptionCompletionHandler completionHandler) { + completion_handler_ = completionHandler; + } + + virtual void OnSetLocalDescriptionComplete(webrtc::RTCError error) override { + OnCompelete(error); + } + + virtual void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override { + OnCompelete(error); + } + + private: + void OnCompelete(webrtc::RTCError error) { + RTC_DCHECK(completion_handler_ != nil); + if (error.ok()) { + completion_handler_(nil); + } else { + // TODO(hta): Add handling of error.type() + NSString *str = [NSString stringForStdString:error.message()]; + NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain + code:kRTCPeerConnnectionSessionDescriptionError + userInfo:@{NSLocalizedDescriptionKey : str}]; + completion_handler_(err); + } + completion_handler_ = nil; + } + RTCSetSessionDescriptionCompletionHandler completion_handler_; +}; + +} // anonymous namespace + +namespace webrtc { + +class CreateSessionDescriptionObserverAdapter + : public CreateSessionDescriptionObserver { + public: + CreateSessionDescriptionObserverAdapter(void (^completionHandler)( + RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription, NSError *error)) { + completion_handler_ = completionHandler; + } + + ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; } + + void OnSuccess(SessionDescriptionInterface *desc) override { + RTC_DCHECK(completion_handler_); + std::unique_ptr<webrtc::SessionDescriptionInterface> description = + std::unique_ptr<webrtc::SessionDescriptionInterface>(desc); + RTC_OBJC_TYPE(RTCSessionDescription) *session = + [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description.get()]; + completion_handler_(session, nil); + completion_handler_ = nil; + } + + void OnFailure(RTCError error) override { + RTC_DCHECK(completion_handler_); + // TODO(hta): Add handling of error.type() + NSString *str = [NSString stringForStdString:error.message()]; + NSError* err = + [NSError errorWithDomain:kRTCPeerConnectionErrorDomain + code:kRTCPeerConnnectionSessionDescriptionError + userInfo:@{ NSLocalizedDescriptionKey : str }]; + completion_handler_(nil, err); + completion_handler_ = nil; + } + + private: + void (^completion_handler_)(RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription, + NSError *error); +}; + +PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(RTC_OBJC_TYPE(RTCPeerConnection) * + peerConnection) { + peer_connection_ = peerConnection; +} + +PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() { + peer_connection_ = nil; +} + +void PeerConnectionDelegateAdapter::OnSignalingChange( + PeerConnectionInterface::SignalingState new_state) { + RTCSignalingState state = + [[RTC_OBJC_TYPE(RTCPeerConnection) class] signalingStateForNativeState:new_state]; + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + [peer_connection.delegate peerConnection:peer_connection + didChangeSignalingState:state]; +} + +void PeerConnectionDelegateAdapter::OnAddStream( + rtc::scoped_refptr<MediaStreamInterface> stream) { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + RTC_OBJC_TYPE(RTCMediaStream) *mediaStream = + [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory + nativeMediaStream:stream]; + [peer_connection.delegate peerConnection:peer_connection + didAddStream:mediaStream]; +} + +void PeerConnectionDelegateAdapter::OnRemoveStream( + rtc::scoped_refptr<MediaStreamInterface> stream) { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + RTC_OBJC_TYPE(RTCMediaStream) *mediaStream = + [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory + nativeMediaStream:stream]; + + [peer_connection.delegate peerConnection:peer_connection + didRemoveStream:mediaStream]; +} + +void PeerConnectionDelegateAdapter::OnTrack( + rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver = + [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:peer_connection.factory + nativeRtpTransceiver:nativeTransceiver]; + if ([peer_connection.delegate + respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) { + [peer_connection.delegate peerConnection:peer_connection + didStartReceivingOnTransceiver:transceiver]; + } +} + +void PeerConnectionDelegateAdapter::OnDataChannel( + rtc::scoped_refptr<DataChannelInterface> data_channel) { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + RTC_OBJC_TYPE(RTCDataChannel) *dataChannel = + [[RTC_OBJC_TYPE(RTCDataChannel) alloc] initWithFactory:peer_connection.factory + nativeDataChannel:data_channel]; + [peer_connection.delegate peerConnection:peer_connection + didOpenDataChannel:dataChannel]; +} + +void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection]; +} + +void PeerConnectionDelegateAdapter::OnIceConnectionChange( + PeerConnectionInterface::IceConnectionState new_state) { + RTCIceConnectionState state = + [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state]; + [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state]; +} + +void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange( + PeerConnectionInterface::IceConnectionState new_state) { + if ([peer_connection_.delegate + respondsToSelector:@selector(peerConnection:didChangeStandardizedIceConnectionState:)]) { + RTCIceConnectionState state = + [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state]; + [peer_connection_.delegate peerConnection:peer_connection_ + didChangeStandardizedIceConnectionState:state]; + } +} + +void PeerConnectionDelegateAdapter::OnConnectionChange( + PeerConnectionInterface::PeerConnectionState new_state) { + if ([peer_connection_.delegate + respondsToSelector:@selector(peerConnection:didChangeConnectionState:)]) { + RTCPeerConnectionState state = + [RTC_OBJC_TYPE(RTCPeerConnection) connectionStateForNativeState:new_state]; + [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state]; + } +} + +void PeerConnectionDelegateAdapter::OnIceGatheringChange( + PeerConnectionInterface::IceGatheringState new_state) { + RTCIceGatheringState state = + [[RTC_OBJC_TYPE(RTCPeerConnection) class] iceGatheringStateForNativeState:new_state]; + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + [peer_connection.delegate peerConnection:peer_connection + didChangeIceGatheringState:state]; +} + +void PeerConnectionDelegateAdapter::OnIceCandidate( + const IceCandidateInterface *candidate) { + RTC_OBJC_TYPE(RTCIceCandidate) *iceCandidate = + [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate]; + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + [peer_connection.delegate peerConnection:peer_connection + didGenerateIceCandidate:iceCandidate]; +} + +void PeerConnectionDelegateAdapter::OnIceCandidateError(const std::string &address, + int port, + const std::string &url, + int error_code, + const std::string &error_text) { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *event = + [[RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) alloc] initWithAddress:address + port:port + url:url + errorCode:error_code + errorText:error_text]; + if ([peer_connection.delegate respondsToSelector:@selector(peerConnection: + didFailToGatherIceCandidate:)]) { + [peer_connection.delegate peerConnection:peer_connection didFailToGatherIceCandidate:event]; + } +} + +void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved( + const std::vector<cricket::Candidate>& candidates) { + NSMutableArray* ice_candidates = + [NSMutableArray arrayWithCapacity:candidates.size()]; + for (const auto& candidate : candidates) { + std::unique_ptr<JsepIceCandidate> candidate_wrapper( + new JsepIceCandidate(candidate.transport_name(), -1, candidate)); + RTC_OBJC_TYPE(RTCIceCandidate) *ice_candidate = + [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate_wrapper.get()]; + [ice_candidates addObject:ice_candidate]; + } + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + [peer_connection.delegate peerConnection:peer_connection + didRemoveIceCandidates:ice_candidates]; +} + +void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged( + const cricket::CandidatePairChangeEvent &event) { + const auto &selected_pair = event.selected_candidate_pair; + auto local_candidate_wrapper = std::make_unique<JsepIceCandidate>( + selected_pair.local_candidate().transport_name(), -1, selected_pair.local_candidate()); + RTC_OBJC_TYPE(RTCIceCandidate) *local_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] + initWithNativeCandidate:local_candidate_wrapper.release()]; + auto remote_candidate_wrapper = std::make_unique<JsepIceCandidate>( + selected_pair.remote_candidate().transport_name(), -1, selected_pair.remote_candidate()); + RTC_OBJC_TYPE(RTCIceCandidate) *remote_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] + initWithNativeCandidate:remote_candidate_wrapper.release()]; + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + NSString *nsstr_reason = [NSString stringForStdString:event.reason]; + if ([peer_connection.delegate + respondsToSelector:@selector + (peerConnection:didChangeLocalCandidate:remoteCandidate:lastReceivedMs:changeReason:)]) { + [peer_connection.delegate peerConnection:peer_connection + didChangeLocalCandidate:local_candidate + remoteCandidate:remote_candidate + lastReceivedMs:event.last_data_received_ms + changeReason:nsstr_reason]; + } +} + +void PeerConnectionDelegateAdapter::OnAddTrack( + rtc::scoped_refptr<RtpReceiverInterface> receiver, + const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + if ([peer_connection.delegate respondsToSelector:@selector(peerConnection: + didAddReceiver:streams:)]) { + NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()]; + for (const auto &nativeStream : streams) { + RTC_OBJC_TYPE(RTCMediaStream) *mediaStream = + [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory + nativeMediaStream:nativeStream]; + [mediaStreams addObject:mediaStream]; + } + RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver = + [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory + nativeRtpReceiver:receiver]; + + [peer_connection.delegate peerConnection:peer_connection + didAddReceiver:rtpReceiver + streams:mediaStreams]; + } +} + +void PeerConnectionDelegateAdapter::OnRemoveTrack( + rtc::scoped_refptr<RtpReceiverInterface> receiver) { + RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; + if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) { + RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver = + [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory + nativeRtpReceiver:receiver]; + [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver]; + } +} + +} // namespace webrtc + +@implementation RTC_OBJC_TYPE (RTCPeerConnection) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + NSMutableArray<RTC_OBJC_TYPE(RTCMediaStream) *> *_localStreams; + std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer; + rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection; + std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints; + BOOL _hasStartedRtcEventLog; +} + +@synthesize delegate = _delegate; +@synthesize factory = _factory; + +- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + certificateVerifier: + (nullable id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier + delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { + NSParameterAssert(factory); + std::unique_ptr<webrtc::PeerConnectionDependencies> dependencies = + std::make_unique<webrtc::PeerConnectionDependencies>(nullptr); + if (certificateVerifier != nil) { + dependencies->tls_cert_verifier = webrtc::ObjCToNativeCertificateVerifier(certificateVerifier); + } + return [self initWithDependencies:factory + configuration:configuration + constraints:constraints + dependencies:std::move(dependencies) + delegate:delegate]; +} + +- (nullable instancetype) + initWithDependencies:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies + delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { + NSParameterAssert(factory); + NSParameterAssert(dependencies.get()); + std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config( + [configuration createNativeConfiguration]); + if (!config) { + return nil; + } + if (self = [super init]) { + _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self)); + _nativeConstraints = constraints.nativeConstraints; + CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), config.get()); + + webrtc::PeerConnectionDependencies deps = std::move(*dependencies.release()); + deps.observer = _observer.get(); + auto result = factory.nativeFactory->CreatePeerConnectionOrError(*config, std::move(deps)); + + if (!result.ok()) { + return nil; + } + _peerConnection = result.MoveValue(); + _factory = factory; + _localStreams = [[NSMutableArray alloc] init]; + _delegate = delegate; + } + return self; +} + +- (NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *)localStreams { + return [_localStreams copy]; +} + +- (RTC_OBJC_TYPE(RTCSessionDescription) *)localDescription { + // It's only safe to operate on SessionDescriptionInterface on the signaling thread. + return _peerConnection->signaling_thread()->BlockingCall([self] { + const webrtc::SessionDescriptionInterface *description = _peerConnection->local_description(); + return description ? + [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] : + nil; + }); +} + +- (RTC_OBJC_TYPE(RTCSessionDescription) *)remoteDescription { + // It's only safe to operate on SessionDescriptionInterface on the signaling thread. + return _peerConnection->signaling_thread()->BlockingCall([self] { + const webrtc::SessionDescriptionInterface *description = _peerConnection->remote_description(); + return description ? + [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] : + nil; + }); +} + +- (RTCSignalingState)signalingState { + return [[self class] + signalingStateForNativeState:_peerConnection->signaling_state()]; +} + +- (RTCIceConnectionState)iceConnectionState { + return [[self class] iceConnectionStateForNativeState: + _peerConnection->ice_connection_state()]; +} + +- (RTCPeerConnectionState)connectionState { + return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()]; +} + +- (RTCIceGatheringState)iceGatheringState { + return [[self class] iceGatheringStateForNativeState: + _peerConnection->ice_gathering_state()]; +} + +- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration { + std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config( + [configuration createNativeConfiguration]); + if (!config) { + return NO; + } + CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), + config.get()); + return _peerConnection->SetConfiguration(*config).ok(); +} + +- (RTC_OBJC_TYPE(RTCConfiguration) *)configuration { + webrtc::PeerConnectionInterface::RTCConfiguration config = + _peerConnection->GetConfiguration(); + return [[RTC_OBJC_TYPE(RTCConfiguration) alloc] initWithNativeConfiguration:config]; +} + +- (void)close { + _peerConnection->Close(); +} + +- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate { + std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate( + candidate.nativeCandidate); + _peerConnection->AddIceCandidate(iceCandidate.get()); +} +- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate + completionHandler:(void (^)(NSError *_Nullable error))completionHandler { + RTC_DCHECK(completionHandler != nil); + _peerConnection->AddIceCandidate( + candidate.nativeCandidate, [completionHandler](const auto &error) { + if (error.ok()) { + completionHandler(nil); + } else { + NSString *str = [NSString stringForStdString:error.message()]; + NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain + code:static_cast<NSInteger>(error.type()) + userInfo:@{NSLocalizedDescriptionKey : str}]; + completionHandler(err); + } + }); +} +- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)iceCandidates { + std::vector<cricket::Candidate> candidates; + for (RTC_OBJC_TYPE(RTCIceCandidate) * iceCandidate in iceCandidates) { + std::unique_ptr<const webrtc::IceCandidateInterface> candidate( + iceCandidate.nativeCandidate); + if (candidate) { + candidates.push_back(candidate->candidate()); + // Need to fill the transport name from the sdp_mid. + candidates.back().set_transport_name(candidate->sdp_mid()); + } + } + if (!candidates.empty()) { + _peerConnection->RemoveIceCandidates(candidates); + } +} + +- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream { + if (!_peerConnection->AddStream(stream.nativeMediaStream.get())) { + RTCLogError(@"Failed to add stream: %@", stream); + return; + } + [_localStreams addObject:stream]; +} + +- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream { + _peerConnection->RemoveStream(stream.nativeMediaStream.get()); + [_localStreams removeObject:stream]; +} + +- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track + streamIds:(NSArray<NSString *> *)streamIds { + std::vector<std::string> nativeStreamIds; + for (NSString *streamId in streamIds) { + nativeStreamIds.push_back([streamId UTF8String]); + } + webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError = + _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds); + if (!nativeSenderOrError.ok()) { + RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message()); + return nil; + } + return [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory + nativeRtpSender:nativeSenderOrError.MoveValue()]; +} + +- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender { + bool result = _peerConnection->RemoveTrackOrError(sender.nativeRtpSender).ok(); + if (!result) { + RTCLogError(@"Failed to remote track %@", sender); + } + return result; +} + +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack: + (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track { + return [self addTransceiverWithTrack:track + init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]]; +} + +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *) + addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track + init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init { + webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError = + _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit); + if (!nativeTransceiverOrError.ok()) { + RTCLogError( + @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message()); + return nil; + } + return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] + initWithFactory:self.factory + nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; +} + +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType { + return [self addTransceiverOfType:mediaType + init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]]; +} + +- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *) + addTransceiverOfType:(RTCRtpMediaType)mediaType + init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init { + webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError = + _peerConnection->AddTransceiver( + [RTC_OBJC_TYPE(RTCRtpReceiver) nativeMediaTypeForMediaType:mediaType], init.nativeInit); + if (!nativeTransceiverOrError.ok()) { + RTCLogError(@"Failed to add transceiver %@: %s", + [RTC_OBJC_TYPE(RTCRtpReceiver) stringForMediaType:mediaType], + nativeTransceiverOrError.error().message()); + return nil; + } + return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] + initWithFactory:self.factory + nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; +} + +- (void)restartIce { + _peerConnection->RestartIce(); +} + +- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler { + RTC_DCHECK(completionHandler != nil); + rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer = + rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler); + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; + CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options); + + _peerConnection->CreateOffer(observer.get(), options); +} + +- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler { + RTC_DCHECK(completionHandler != nil); + rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer = + rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler); + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; + CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options); + + _peerConnection->CreateAnswer(observer.get(), options); +} + +- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp + completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler { + RTC_DCHECK(completionHandler != nil); + rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer = + rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler); + _peerConnection->SetLocalDescription(sdp.nativeDescription, observer); +} + +- (void)setLocalDescriptionWithCompletionHandler: + (RTCSetSessionDescriptionCompletionHandler)completionHandler { + RTC_DCHECK(completionHandler != nil); + rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer = + rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler); + _peerConnection->SetLocalDescription(observer); +} + +- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp + completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler { + RTC_DCHECK(completionHandler != nil); + rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> observer = + rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler); + _peerConnection->SetRemoteDescription(sdp.nativeDescription, observer); +} + +- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps + currentBitrateBps:(nullable NSNumber *)currentBitrateBps + maxBitrateBps:(nullable NSNumber *)maxBitrateBps { + webrtc::BitrateSettings params; + if (minBitrateBps != nil) { + params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue); + } + if (currentBitrateBps != nil) { + params.start_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue); + } + if (maxBitrateBps != nil) { + params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue); + } + return _peerConnection->SetBitrate(params).ok(); +} + +- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath + maxSizeInBytes:(int64_t)maxSizeInBytes { + RTC_DCHECK(filePath.length); + RTC_DCHECK_GT(maxSizeInBytes, 0); + RTC_DCHECK(!_hasStartedRtcEventLog); + if (_hasStartedRtcEventLog) { + RTCLogError(@"Event logging already started."); + return NO; + } + FILE *f = fopen(filePath.UTF8String, "wb"); + if (!f) { + RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno); + return NO; + } + // TODO(eladalon): It would be better to not allow negative values into PC. + const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput : + rtc::saturated_cast<size_t>(maxSizeInBytes); + + _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog( + std::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size)); + return _hasStartedRtcEventLog; +} + +- (void)stopRtcEventLog { + _peerConnection->StopRtcEventLog(); + _hasStartedRtcEventLog = NO; +} + +- (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind:(NSString *)kind streamId:(NSString *)streamId { + std::string nativeKind = [NSString stdStringForString:kind]; + std::string nativeStreamId = [NSString stdStringForString:streamId]; + rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender( + _peerConnection->CreateSender(nativeKind, nativeStreamId)); + return nativeSender ? [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory + nativeRtpSender:nativeSender] : + nil; +} + +- (NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *)senders { + std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders( + _peerConnection->GetSenders()); + NSMutableArray *senders = [[NSMutableArray alloc] init]; + for (const auto &nativeSender : nativeSenders) { + RTC_OBJC_TYPE(RTCRtpSender) *sender = + [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory + nativeRtpSender:nativeSender]; + [senders addObject:sender]; + } + return senders; +} + +- (NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *)receivers { + std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers( + _peerConnection->GetReceivers()); + NSMutableArray *receivers = [[NSMutableArray alloc] init]; + for (const auto &nativeReceiver : nativeReceivers) { + RTC_OBJC_TYPE(RTCRtpReceiver) *receiver = + [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:self.factory + nativeRtpReceiver:nativeReceiver]; + [receivers addObject:receiver]; + } + return receivers; +} + +- (NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *)transceivers { + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers( + _peerConnection->GetTransceivers()); + NSMutableArray *transceivers = [[NSMutableArray alloc] init]; + for (const auto &nativeTransceiver : nativeTransceivers) { + RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver = + [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:self.factory + nativeRtpTransceiver:nativeTransceiver]; + [transceivers addObject:transceiver]; + } + return transceivers; +} + +#pragma mark - Private + ++ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState: + (RTCSignalingState)state { + switch (state) { + case RTCSignalingStateStable: + return webrtc::PeerConnectionInterface::kStable; + case RTCSignalingStateHaveLocalOffer: + return webrtc::PeerConnectionInterface::kHaveLocalOffer; + case RTCSignalingStateHaveLocalPrAnswer: + return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer; + case RTCSignalingStateHaveRemoteOffer: + return webrtc::PeerConnectionInterface::kHaveRemoteOffer; + case RTCSignalingStateHaveRemotePrAnswer: + return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer; + case RTCSignalingStateClosed: + return webrtc::PeerConnectionInterface::kClosed; + } +} + ++ (RTCSignalingState)signalingStateForNativeState: + (webrtc::PeerConnectionInterface::SignalingState)nativeState { + switch (nativeState) { + case webrtc::PeerConnectionInterface::kStable: + return RTCSignalingStateStable; + case webrtc::PeerConnectionInterface::kHaveLocalOffer: + return RTCSignalingStateHaveLocalOffer; + case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer: + return RTCSignalingStateHaveLocalPrAnswer; + case webrtc::PeerConnectionInterface::kHaveRemoteOffer: + return RTCSignalingStateHaveRemoteOffer; + case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer: + return RTCSignalingStateHaveRemotePrAnswer; + case webrtc::PeerConnectionInterface::kClosed: + return RTCSignalingStateClosed; + } +} + ++ (NSString *)stringForSignalingState:(RTCSignalingState)state { + switch (state) { + case RTCSignalingStateStable: + return @"STABLE"; + case RTCSignalingStateHaveLocalOffer: + return @"HAVE_LOCAL_OFFER"; + case RTCSignalingStateHaveLocalPrAnswer: + return @"HAVE_LOCAL_PRANSWER"; + case RTCSignalingStateHaveRemoteOffer: + return @"HAVE_REMOTE_OFFER"; + case RTCSignalingStateHaveRemotePrAnswer: + return @"HAVE_REMOTE_PRANSWER"; + case RTCSignalingStateClosed: + return @"CLOSED"; + } +} + ++ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState: + (RTCPeerConnectionState)state { + switch (state) { + case RTCPeerConnectionStateNew: + return webrtc::PeerConnectionInterface::PeerConnectionState::kNew; + case RTCPeerConnectionStateConnecting: + return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting; + case RTCPeerConnectionStateConnected: + return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected; + case RTCPeerConnectionStateFailed: + return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed; + case RTCPeerConnectionStateDisconnected: + return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected; + case RTCPeerConnectionStateClosed: + return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed; + } +} + ++ (RTCPeerConnectionState)connectionStateForNativeState: + (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState { + switch (nativeState) { + case webrtc::PeerConnectionInterface::PeerConnectionState::kNew: + return RTCPeerConnectionStateNew; + case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting: + return RTCPeerConnectionStateConnecting; + case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected: + return RTCPeerConnectionStateConnected; + case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed: + return RTCPeerConnectionStateFailed; + case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected: + return RTCPeerConnectionStateDisconnected; + case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed: + return RTCPeerConnectionStateClosed; + } +} + ++ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state { + switch (state) { + case RTCPeerConnectionStateNew: + return @"NEW"; + case RTCPeerConnectionStateConnecting: + return @"CONNECTING"; + case RTCPeerConnectionStateConnected: + return @"CONNECTED"; + case RTCPeerConnectionStateFailed: + return @"FAILED"; + case RTCPeerConnectionStateDisconnected: + return @"DISCONNECTED"; + case RTCPeerConnectionStateClosed: + return @"CLOSED"; + } +} + ++ (webrtc::PeerConnectionInterface::IceConnectionState) + nativeIceConnectionStateForState:(RTCIceConnectionState)state { + switch (state) { + case RTCIceConnectionStateNew: + return webrtc::PeerConnectionInterface::kIceConnectionNew; + case RTCIceConnectionStateChecking: + return webrtc::PeerConnectionInterface::kIceConnectionChecking; + case RTCIceConnectionStateConnected: + return webrtc::PeerConnectionInterface::kIceConnectionConnected; + case RTCIceConnectionStateCompleted: + return webrtc::PeerConnectionInterface::kIceConnectionCompleted; + case RTCIceConnectionStateFailed: + return webrtc::PeerConnectionInterface::kIceConnectionFailed; + case RTCIceConnectionStateDisconnected: + return webrtc::PeerConnectionInterface::kIceConnectionDisconnected; + case RTCIceConnectionStateClosed: + return webrtc::PeerConnectionInterface::kIceConnectionClosed; + case RTCIceConnectionStateCount: + return webrtc::PeerConnectionInterface::kIceConnectionMax; + } +} + ++ (RTCIceConnectionState)iceConnectionStateForNativeState: + (webrtc::PeerConnectionInterface::IceConnectionState)nativeState { + switch (nativeState) { + case webrtc::PeerConnectionInterface::kIceConnectionNew: + return RTCIceConnectionStateNew; + case webrtc::PeerConnectionInterface::kIceConnectionChecking: + return RTCIceConnectionStateChecking; + case webrtc::PeerConnectionInterface::kIceConnectionConnected: + return RTCIceConnectionStateConnected; + case webrtc::PeerConnectionInterface::kIceConnectionCompleted: + return RTCIceConnectionStateCompleted; + case webrtc::PeerConnectionInterface::kIceConnectionFailed: + return RTCIceConnectionStateFailed; + case webrtc::PeerConnectionInterface::kIceConnectionDisconnected: + return RTCIceConnectionStateDisconnected; + case webrtc::PeerConnectionInterface::kIceConnectionClosed: + return RTCIceConnectionStateClosed; + case webrtc::PeerConnectionInterface::kIceConnectionMax: + return RTCIceConnectionStateCount; + } +} + ++ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state { + switch (state) { + case RTCIceConnectionStateNew: + return @"NEW"; + case RTCIceConnectionStateChecking: + return @"CHECKING"; + case RTCIceConnectionStateConnected: + return @"CONNECTED"; + case RTCIceConnectionStateCompleted: + return @"COMPLETED"; + case RTCIceConnectionStateFailed: + return @"FAILED"; + case RTCIceConnectionStateDisconnected: + return @"DISCONNECTED"; + case RTCIceConnectionStateClosed: + return @"CLOSED"; + case RTCIceConnectionStateCount: + return @"COUNT"; + } +} + ++ (webrtc::PeerConnectionInterface::IceGatheringState) + nativeIceGatheringStateForState:(RTCIceGatheringState)state { + switch (state) { + case RTCIceGatheringStateNew: + return webrtc::PeerConnectionInterface::kIceGatheringNew; + case RTCIceGatheringStateGathering: + return webrtc::PeerConnectionInterface::kIceGatheringGathering; + case RTCIceGatheringStateComplete: + return webrtc::PeerConnectionInterface::kIceGatheringComplete; + } +} + ++ (RTCIceGatheringState)iceGatheringStateForNativeState: + (webrtc::PeerConnectionInterface::IceGatheringState)nativeState { + switch (nativeState) { + case webrtc::PeerConnectionInterface::kIceGatheringNew: + return RTCIceGatheringStateNew; + case webrtc::PeerConnectionInterface::kIceGatheringGathering: + return RTCIceGatheringStateGathering; + case webrtc::PeerConnectionInterface::kIceGatheringComplete: + return RTCIceGatheringStateComplete; + } +} + ++ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state { + switch (state) { + case RTCIceGatheringStateNew: + return @"NEW"; + case RTCIceGatheringStateGathering: + return @"GATHERING"; + case RTCIceGatheringStateComplete: + return @"COMPLETE"; + } +} + ++ (webrtc::PeerConnectionInterface::StatsOutputLevel) + nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level { + switch (level) { + case RTCStatsOutputLevelStandard: + return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard; + case RTCStatsOutputLevelDebug: + return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug; + } +} + +- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection { + return _peerConnection; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Native.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Native.h new file mode 100644 index 0000000000..f361b9f0ea --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Native.h @@ -0,0 +1,85 @@ +/* + * Copyright 2017 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 "RTCPeerConnectionFactory.h" + +#include "api/scoped_refptr.h" + +namespace webrtc { + +class AudioDeviceModule; +class AudioEncoderFactory; +class AudioDecoderFactory; +class NetworkControllerFactoryInterface; +class VideoEncoderFactory; +class VideoDecoderFactory; +class AudioProcessing; +struct PeerConnectionDependencies; + +} // namespace webrtc + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class extension exposes methods that work directly with injectable C++ components. + */ +@interface RTC_OBJC_TYPE (RTCPeerConnectionFactory) +() + + - (instancetype)initNative NS_DESIGNATED_INITIALIZER; + +/* Initializer used when WebRTC is compiled with no media support */ +- (instancetype)initWithNoMedia; + +/* Initialize object with injectable native audio/video encoder/decoder factories */ +- (instancetype)initWithNativeAudioEncoderFactory: + (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory + nativeAudioDecoderFactory: + (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory + nativeVideoEncoderFactory: + (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory + nativeVideoDecoderFactory: + (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory + audioDeviceModule: + (nullable webrtc::AudioDeviceModule *)audioDeviceModule + audioProcessingModule: + (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule; + +- (instancetype) + initWithNativeAudioEncoderFactory: + (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory + nativeAudioDecoderFactory: + (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory + nativeVideoEncoderFactory: + (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory + nativeVideoDecoderFactory: + (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory + audioDeviceModule:(nullable webrtc::AudioDeviceModule *)audioDeviceModule + audioProcessingModule: + (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule + networkControllerFactory:(std::unique_ptr<webrtc::NetworkControllerFactoryInterface>) + networkControllerFactory; + +- (instancetype) + initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory + decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory; + +/** Initialize an RTCPeerConnection with a configuration, constraints, and + * dependencies. + */ +- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) + peerConnectionWithDependencies:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies + delegate:(nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Private.h new file mode 100644 index 0000000000..9613646270 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Private.h @@ -0,0 +1,35 @@ +/* + * Copyright 2015 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 "RTCPeerConnectionFactory.h" + +#include "api/peer_connection_interface.h" +#include "api/scoped_refptr.h" +#include "rtc_base/thread.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCPeerConnectionFactory) +() + + /** + * PeerConnectionFactoryInterface created and held by this + * RTCPeerConnectionFactory object. This is needed to pass to the underlying + * C++ APIs. + */ + @property(nonatomic, + readonly) rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> nativeFactory; + +@property(nonatomic, readonly) rtc::Thread* signalingThread; +@property(nonatomic, readonly) rtc::Thread* workerThread; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h new file mode 100644 index 0000000000..5575af98c9 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h @@ -0,0 +1,113 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCAudioSource); +@class RTC_OBJC_TYPE(RTCAudioTrack); +@class RTC_OBJC_TYPE(RTCConfiguration); +@class RTC_OBJC_TYPE(RTCMediaConstraints); +@class RTC_OBJC_TYPE(RTCMediaStream); +@class RTC_OBJC_TYPE(RTCPeerConnection); +@class RTC_OBJC_TYPE(RTCVideoSource); +@class RTC_OBJC_TYPE(RTCVideoTrack); +@class RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions); +@protocol RTC_OBJC_TYPE +(RTCPeerConnectionDelegate); +@protocol RTC_OBJC_TYPE +(RTCVideoDecoderFactory); +@protocol RTC_OBJC_TYPE +(RTCVideoEncoderFactory); +@protocol RTC_OBJC_TYPE +(RTCSSLCertificateVerifier); +@protocol RTC_OBJC_TYPE +(RTCAudioDevice); + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCPeerConnectionFactory) : NSObject + +/* Initialize object with default H264 video encoder/decoder factories and default ADM */ +- (instancetype)init; + +/* Initialize object with injectable video encoder/decoder factories and default ADM */ +- (instancetype) + initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory + decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory; + +/* Initialize object with injectable video encoder/decoder factories and injectable ADM */ +- (instancetype) + initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory + decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory + audioDevice:(nullable id<RTC_OBJC_TYPE(RTCAudioDevice)>)audioDevice; + +/** Initialize an RTCAudioSource with constraints. */ +- (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints: + (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints; + +/** Initialize an RTCAudioTrack with an id. Convenience ctor to use an audio source + * with no constraints. + */ +- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithTrackId:(NSString *)trackId; + +/** Initialize an RTCAudioTrack with a source and an id. */ +- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithSource:(RTC_OBJC_TYPE(RTCAudioSource) *)source + trackId:(NSString *)trackId; + +/** Initialize a generic RTCVideoSource. The RTCVideoSource should be + * passed to a RTCVideoCapturer implementation, e.g. + * RTCCameraVideoCapturer, in order to produce frames. + */ +- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSource; + +/** Initialize a generic RTCVideoSource with he posibility of marking + * it as usable for screen sharing. The RTCVideoSource should be + * passed to a RTCVideoCapturer implementation, e.g. + * RTCCameraVideoCapturer, in order to produce frames. + */ +- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSourceForScreenCast:(BOOL)forScreenCast; + +/** Initialize an RTCVideoTrack with a source and an id. */ +- (RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrackWithSource:(RTC_OBJC_TYPE(RTCVideoSource) *)source + trackId:(NSString *)trackId; + +/** Initialize an RTCMediaStream with an id. */ +- (RTC_OBJC_TYPE(RTCMediaStream) *)mediaStreamWithStreamId:(NSString *)streamId; + +/** Initialize an RTCPeerConnection with a configuration, constraints, and + * delegate. + */ +- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) + peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + delegate:(nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate; + +- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) + peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + certificateVerifier: + (id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier + delegate:(nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate; + +/** Set the options to be used for subsequently created RTCPeerConnections */ +- (void)setOptions:(nonnull RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions) *)options; + +/** Start an AecDump recording. This API call will likely change in the future. */ +- (BOOL)startAecDumpWithFilePath:(NSString *)filePath maxSizeInBytes:(int64_t)maxSizeInBytes; + +/* Stop an active AecDump recording */ +- (void)stopAecDump; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm new file mode 100644 index 0000000000..c4d89e911d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm @@ -0,0 +1,342 @@ +/* + * Copyright 2015 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. + */ + +#include <memory> + +#import "RTCPeerConnectionFactory+Native.h" +#import "RTCPeerConnectionFactory+Private.h" +#import "RTCPeerConnectionFactoryOptions+Private.h" + +#import "RTCAudioSource+Private.h" +#import "RTCAudioTrack+Private.h" +#import "RTCMediaConstraints+Private.h" +#import "RTCMediaStream+Private.h" +#import "RTCPeerConnection+Private.h" +#import "RTCVideoSource+Private.h" +#import "RTCVideoTrack+Private.h" +#import "base/RTCLogging.h" +#import "base/RTCVideoDecoderFactory.h" +#import "base/RTCVideoEncoderFactory.h" +#import "helpers/NSString+StdString.h" +#include "rtc_base/checks.h" +#include "sdk/objc/native/api/network_monitor_factory.h" +#include "sdk/objc/native/api/ssl_certificate_verifier.h" +#include "system_wrappers/include/field_trial.h" + +#include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/rtc_event_log/rtc_event_log_factory.h" +#include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" +#import "components/video_codec/RTCVideoDecoderFactoryH264.h" +#import "components/video_codec/RTCVideoEncoderFactoryH264.h" +#include "media/engine/webrtc_media_engine.h" +#include "modules/audio_device/include/audio_device.h" +#include "modules/audio_processing/include/audio_processing.h" + +#include "sdk/objc/native/api/objc_audio_device_module.h" +#include "sdk/objc/native/api/video_decoder_factory.h" +#include "sdk/objc/native/api/video_encoder_factory.h" +#include "sdk/objc/native/src/objc_video_decoder_factory.h" +#include "sdk/objc/native/src/objc_video_encoder_factory.h" + +#if defined(WEBRTC_IOS) +#import "sdk/objc/native/api/audio_device_module.h" +#endif + +@implementation RTC_OBJC_TYPE (RTCPeerConnectionFactory) { + std::unique_ptr<rtc::Thread> _networkThread; + std::unique_ptr<rtc::Thread> _workerThread; + std::unique_ptr<rtc::Thread> _signalingThread; + BOOL _hasStartedAecDump; +} + +@synthesize nativeFactory = _nativeFactory; + +- (rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule { +#if defined(WEBRTC_IOS) + return webrtc::CreateAudioDeviceModule(); +#else + return nullptr; +#endif +} + +- (instancetype)init { + return [self + initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory() + nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory() + nativeVideoEncoderFactory:webrtc::ObjCToNativeVideoEncoderFactory([[RTC_OBJC_TYPE( + RTCVideoEncoderFactoryH264) alloc] init]) + nativeVideoDecoderFactory:webrtc::ObjCToNativeVideoDecoderFactory([[RTC_OBJC_TYPE( + RTCVideoDecoderFactoryH264) alloc] init]) + audioDeviceModule:[self audioDeviceModule].get() + audioProcessingModule:nullptr]; +} + +- (instancetype) + initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory + decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory { + return [self initWithEncoderFactory:encoderFactory decoderFactory:decoderFactory audioDevice:nil]; +} + +- (instancetype) + initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory + decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory + audioDevice:(nullable id<RTC_OBJC_TYPE(RTCAudioDevice)>)audioDevice { +#ifdef HAVE_NO_MEDIA + return [self initWithNoMedia]; +#else + std::unique_ptr<webrtc::VideoEncoderFactory> native_encoder_factory; + std::unique_ptr<webrtc::VideoDecoderFactory> native_decoder_factory; + if (encoderFactory) { + native_encoder_factory = webrtc::ObjCToNativeVideoEncoderFactory(encoderFactory); + } + if (decoderFactory) { + native_decoder_factory = webrtc::ObjCToNativeVideoDecoderFactory(decoderFactory); + } + rtc::scoped_refptr<webrtc::AudioDeviceModule> audio_device_module; + if (audioDevice) { + audio_device_module = webrtc::CreateAudioDeviceModule(audioDevice); + } else { + audio_device_module = [self audioDeviceModule]; + } + return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory() + nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory() + nativeVideoEncoderFactory:std::move(native_encoder_factory) + nativeVideoDecoderFactory:std::move(native_decoder_factory) + audioDeviceModule:audio_device_module.get() + audioProcessingModule:nullptr]; +#endif +} + +- (instancetype)initNative { + if (self = [super init]) { + _networkThread = rtc::Thread::CreateWithSocketServer(); + _networkThread->SetName("network_thread", _networkThread.get()); + BOOL result = _networkThread->Start(); + RTC_DCHECK(result) << "Failed to start network thread."; + + _workerThread = rtc::Thread::Create(); + _workerThread->SetName("worker_thread", _workerThread.get()); + result = _workerThread->Start(); + RTC_DCHECK(result) << "Failed to start worker thread."; + + _signalingThread = rtc::Thread::Create(); + _signalingThread->SetName("signaling_thread", _signalingThread.get()); + result = _signalingThread->Start(); + RTC_DCHECK(result) << "Failed to start signaling thread."; + } + return self; +} + +- (instancetype)initWithNoMedia { + if (self = [self initNative]) { + webrtc::PeerConnectionFactoryDependencies dependencies; + dependencies.network_thread = _networkThread.get(); + dependencies.worker_thread = _workerThread.get(); + dependencies.signaling_thread = _signalingThread.get(); + if (webrtc::field_trial::IsEnabled("WebRTC-Network-UseNWPathMonitor")) { + dependencies.network_monitor_factory = webrtc::CreateNetworkMonitorFactory(); + } + _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies)); + NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!"); + } + return self; +} + +- (instancetype)initWithNativeAudioEncoderFactory: + (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory + nativeAudioDecoderFactory: + (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory + nativeVideoEncoderFactory: + (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory + nativeVideoDecoderFactory: + (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory + audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule + audioProcessingModule: + (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule { + return [self initWithNativeAudioEncoderFactory:audioEncoderFactory + nativeAudioDecoderFactory:audioDecoderFactory + nativeVideoEncoderFactory:std::move(videoEncoderFactory) + nativeVideoDecoderFactory:std::move(videoDecoderFactory) + audioDeviceModule:audioDeviceModule + audioProcessingModule:audioProcessingModule + networkControllerFactory:nullptr]; +} +- (instancetype)initWithNativeAudioEncoderFactory: + (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory + nativeAudioDecoderFactory: + (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory + nativeVideoEncoderFactory: + (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory + nativeVideoDecoderFactory: + (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory + audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule + audioProcessingModule: + (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule + networkControllerFactory: + (std::unique_ptr<webrtc::NetworkControllerFactoryInterface>) + networkControllerFactory { + if (self = [self initNative]) { + webrtc::PeerConnectionFactoryDependencies dependencies; + dependencies.network_thread = _networkThread.get(); + dependencies.worker_thread = _workerThread.get(); + dependencies.signaling_thread = _signalingThread.get(); + if (webrtc::field_trial::IsEnabled("WebRTC-Network-UseNWPathMonitor")) { + dependencies.network_monitor_factory = webrtc::CreateNetworkMonitorFactory(); + } + dependencies.trials = std::make_unique<webrtc::FieldTrialBasedConfig>(); + dependencies.task_queue_factory = + webrtc::CreateDefaultTaskQueueFactory(dependencies.trials.get()); + cricket::MediaEngineDependencies media_deps; + media_deps.adm = std::move(audioDeviceModule); + media_deps.task_queue_factory = dependencies.task_queue_factory.get(); + media_deps.audio_encoder_factory = std::move(audioEncoderFactory); + media_deps.audio_decoder_factory = std::move(audioDecoderFactory); + media_deps.video_encoder_factory = std::move(videoEncoderFactory); + media_deps.video_decoder_factory = std::move(videoDecoderFactory); + if (audioProcessingModule) { + media_deps.audio_processing = std::move(audioProcessingModule); + } else { + media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); + } + media_deps.trials = dependencies.trials.get(); + dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); + dependencies.call_factory = webrtc::CreateCallFactory(); + dependencies.event_log_factory = + std::make_unique<webrtc::RtcEventLogFactory>(dependencies.task_queue_factory.get()); + dependencies.network_controller_factory = std::move(networkControllerFactory); + _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies)); + NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!"); + } + return self; +} + +- (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints: + (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints { + std::unique_ptr<webrtc::MediaConstraints> nativeConstraints; + if (constraints) { + nativeConstraints = constraints.nativeConstraints; + } + cricket::AudioOptions options; + CopyConstraintsIntoAudioOptions(nativeConstraints.get(), &options); + + rtc::scoped_refptr<webrtc::AudioSourceInterface> source = + _nativeFactory->CreateAudioSource(options); + return [[RTC_OBJC_TYPE(RTCAudioSource) alloc] initWithFactory:self nativeAudioSource:source]; +} + +- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithTrackId:(NSString *)trackId { + RTC_OBJC_TYPE(RTCAudioSource) *audioSource = [self audioSourceWithConstraints:nil]; + return [self audioTrackWithSource:audioSource trackId:trackId]; +} + +- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithSource:(RTC_OBJC_TYPE(RTCAudioSource) *)source + trackId:(NSString *)trackId { + return [[RTC_OBJC_TYPE(RTCAudioTrack) alloc] initWithFactory:self source:source trackId:trackId]; +} + +- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSource { + return [[RTC_OBJC_TYPE(RTCVideoSource) alloc] initWithFactory:self + signalingThread:_signalingThread.get() + workerThread:_workerThread.get()]; +} + +- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSourceForScreenCast:(BOOL)forScreenCast { + return [[RTC_OBJC_TYPE(RTCVideoSource) alloc] initWithFactory:self + signalingThread:_signalingThread.get() + workerThread:_workerThread.get() + isScreenCast:forScreenCast]; +} + +- (RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrackWithSource:(RTC_OBJC_TYPE(RTCVideoSource) *)source + trackId:(NSString *)trackId { + return [[RTC_OBJC_TYPE(RTCVideoTrack) alloc] initWithFactory:self source:source trackId:trackId]; +} + +- (RTC_OBJC_TYPE(RTCMediaStream) *)mediaStreamWithStreamId:(NSString *)streamId { + return [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:self streamId:streamId]; +} + +- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) + peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + delegate: + (nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { + return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithFactory:self + configuration:configuration + constraints:constraints + certificateVerifier:nil + delegate:delegate]; +} + +- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) + peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + certificateVerifier: + (id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier + delegate: + (nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { + return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithFactory:self + configuration:configuration + constraints:constraints + certificateVerifier:certificateVerifier + delegate:delegate]; +} + +- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) + peerConnectionWithDependencies:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration + constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints + dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies + delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { + return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithDependencies:self + configuration:configuration + constraints:constraints + dependencies:std::move(dependencies) + delegate:delegate]; +} + +- (void)setOptions:(nonnull RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions) *)options { + RTC_DCHECK(options != nil); + _nativeFactory->SetOptions(options.nativeOptions); +} + +- (BOOL)startAecDumpWithFilePath:(NSString *)filePath + maxSizeInBytes:(int64_t)maxSizeInBytes { + RTC_DCHECK(filePath.length); + RTC_DCHECK_GT(maxSizeInBytes, 0); + + if (_hasStartedAecDump) { + RTCLogError(@"Aec dump already started."); + return NO; + } + FILE *f = fopen(filePath.UTF8String, "wb"); + if (!f) { + RTCLogError(@"Error opening file: %@. Error: %s", filePath, strerror(errno)); + return NO; + } + _hasStartedAecDump = _nativeFactory->StartAecDump(f, maxSizeInBytes); + return _hasStartedAecDump; +} + +- (void)stopAecDump { + _nativeFactory->StopAecDump(); + _hasStartedAecDump = NO; +} + +- (rtc::Thread *)signalingThread { + return _signalingThread.get(); +} + +- (rtc::Thread *)workerThread { + return _workerThread.get(); +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h new file mode 100644 index 0000000000..070a0e74a5 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h @@ -0,0 +1,21 @@ +/* + * 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 "RTCPeerConnectionFactoryBuilder.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTCPeerConnectionFactoryBuilder (DefaultComponents) + ++ (RTCPeerConnectionFactoryBuilder *)defaultBuilder; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.mm new file mode 100644 index 0000000000..522e520e12 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.mm @@ -0,0 +1,49 @@ +/* + * 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 "RTCPeerConnectionFactory+Native.h" +#import "RTCPeerConnectionFactoryBuilder+DefaultComponents.h" + +#include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#import "components/video_codec/RTCVideoDecoderFactoryH264.h" +#import "components/video_codec/RTCVideoEncoderFactoryH264.h" +#include "sdk/objc/native/api/video_decoder_factory.h" +#include "sdk/objc/native/api/video_encoder_factory.h" + +#if defined(WEBRTC_IOS) +#import "sdk/objc/native/api/audio_device_module.h" +#endif + +@implementation RTCPeerConnectionFactoryBuilder (DefaultComponents) + ++ (RTCPeerConnectionFactoryBuilder *)defaultBuilder { + RTCPeerConnectionFactoryBuilder *builder = [[RTCPeerConnectionFactoryBuilder alloc] init]; + auto audioEncoderFactory = webrtc::CreateBuiltinAudioEncoderFactory(); + [builder setAudioEncoderFactory:audioEncoderFactory]; + + auto audioDecoderFactory = webrtc::CreateBuiltinAudioDecoderFactory(); + [builder setAudioDecoderFactory:audioDecoderFactory]; + + auto videoEncoderFactory = webrtc::ObjCToNativeVideoEncoderFactory( + [[RTC_OBJC_TYPE(RTCVideoEncoderFactoryH264) alloc] init]); + [builder setVideoEncoderFactory:std::move(videoEncoderFactory)]; + + auto videoDecoderFactory = webrtc::ObjCToNativeVideoDecoderFactory( + [[RTC_OBJC_TYPE(RTCVideoDecoderFactoryH264) alloc] init]); + [builder setVideoDecoderFactory:std::move(videoDecoderFactory)]; + +#if defined(WEBRTC_IOS) + [builder setAudioDeviceModule:webrtc::CreateAudioDeviceModule()]; +#endif + return builder; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.h new file mode 100644 index 0000000000..f0b0de156a --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.h @@ -0,0 +1,48 @@ +/* + * 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 "RTCPeerConnectionFactory.h" + +#include "api/scoped_refptr.h" + +namespace webrtc { + +class AudioDeviceModule; +class AudioEncoderFactory; +class AudioDecoderFactory; +class VideoEncoderFactory; +class VideoDecoderFactory; +class AudioProcessing; + +} // namespace webrtc + +NS_ASSUME_NONNULL_BEGIN + +@interface RTCPeerConnectionFactoryBuilder : NSObject + ++ (RTCPeerConnectionFactoryBuilder *)builder; + +- (RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)createPeerConnectionFactory; + +- (void)setVideoEncoderFactory:(std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory; + +- (void)setVideoDecoderFactory:(std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory; + +- (void)setAudioEncoderFactory:(rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory; + +- (void)setAudioDecoderFactory:(rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory; + +- (void)setAudioDeviceModule:(rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule; + +- (void)setAudioProcessingModule:(rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.mm new file mode 100644 index 0000000000..627909a0e3 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.mm @@ -0,0 +1,72 @@ +/* + * 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 "RTCPeerConnectionFactoryBuilder.h" +#import "RTCPeerConnectionFactory+Native.h" + +#include "api/audio_codecs/audio_decoder_factory.h" +#include "api/audio_codecs/audio_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" +#include "modules/audio_device/include/audio_device.h" +#include "modules/audio_processing/include/audio_processing.h" + +@implementation RTCPeerConnectionFactoryBuilder { + std::unique_ptr<webrtc::VideoEncoderFactory> _videoEncoderFactory; + std::unique_ptr<webrtc::VideoDecoderFactory> _videoDecoderFactory; + rtc::scoped_refptr<webrtc::AudioEncoderFactory> _audioEncoderFactory; + rtc::scoped_refptr<webrtc::AudioDecoderFactory> _audioDecoderFactory; + rtc::scoped_refptr<webrtc::AudioDeviceModule> _audioDeviceModule; + rtc::scoped_refptr<webrtc::AudioProcessing> _audioProcessingModule; +} + ++ (RTCPeerConnectionFactoryBuilder *)builder { + return [[RTCPeerConnectionFactoryBuilder alloc] init]; +} + +- (RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)createPeerConnectionFactory { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) *factory = + [RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc]; + return [factory initWithNativeAudioEncoderFactory:_audioEncoderFactory + nativeAudioDecoderFactory:_audioDecoderFactory + nativeVideoEncoderFactory:std::move(_videoEncoderFactory) + nativeVideoDecoderFactory:std::move(_videoDecoderFactory) + audioDeviceModule:_audioDeviceModule.get() + audioProcessingModule:_audioProcessingModule]; +} + +- (void)setVideoEncoderFactory:(std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory { + _videoEncoderFactory = std::move(videoEncoderFactory); +} + +- (void)setVideoDecoderFactory:(std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory { + _videoDecoderFactory = std::move(videoDecoderFactory); +} + +- (void)setAudioEncoderFactory: + (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory { + _audioEncoderFactory = audioEncoderFactory; +} + +- (void)setAudioDecoderFactory: + (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory { + _audioDecoderFactory = audioDecoderFactory; +} + +- (void)setAudioDeviceModule:(rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule { + _audioDeviceModule = audioDeviceModule; +} + +- (void)setAudioProcessingModule: + (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule { + _audioProcessingModule = audioProcessingModule; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions+Private.h new file mode 100644 index 0000000000..8832b23695 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions+Private.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 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 "RTCPeerConnectionFactoryOptions.h" + +#include "api/peer_connection_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCPeerConnectionFactoryOptions) +() + + /** Returns the equivalent native PeerConnectionFactoryInterface::Options + * structure. */ + @property(nonatomic, readonly) webrtc::PeerConnectionFactoryInterface::Options nativeOptions; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions.h new file mode 100644 index 0000000000..bfc54a5d7b --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCPeerConnectionFactoryOptions) : NSObject + +@property(nonatomic, assign) BOOL disableEncryption; + +@property(nonatomic, assign) BOOL disableNetworkMonitor; + +@property(nonatomic, assign) BOOL ignoreLoopbackNetworkAdapter; + +@property(nonatomic, assign) BOOL ignoreVPNNetworkAdapter; + +@property(nonatomic, assign) BOOL ignoreCellularNetworkAdapter; + +@property(nonatomic, assign) BOOL ignoreWiFiNetworkAdapter; + +@property(nonatomic, assign) BOOL ignoreEthernetNetworkAdapter; + +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions.mm new file mode 100644 index 0000000000..5467bd5fc9 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryOptions.mm @@ -0,0 +1,56 @@ +/* + * Copyright 2017 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 "RTCPeerConnectionFactoryOptions+Private.h" + +#include "rtc_base/network_constants.h" + +namespace { + +void setNetworkBit(webrtc::PeerConnectionFactoryInterface::Options* options, + rtc::AdapterType type, + bool ignore) { + if (ignore) { + options->network_ignore_mask |= type; + } else { + options->network_ignore_mask &= ~type; + } +} +} // namespace + +@implementation RTC_OBJC_TYPE (RTCPeerConnectionFactoryOptions) + +@synthesize disableEncryption = _disableEncryption; +@synthesize disableNetworkMonitor = _disableNetworkMonitor; +@synthesize ignoreLoopbackNetworkAdapter = _ignoreLoopbackNetworkAdapter; +@synthesize ignoreVPNNetworkAdapter = _ignoreVPNNetworkAdapter; +@synthesize ignoreCellularNetworkAdapter = _ignoreCellularNetworkAdapter; +@synthesize ignoreWiFiNetworkAdapter = _ignoreWiFiNetworkAdapter; +@synthesize ignoreEthernetNetworkAdapter = _ignoreEthernetNetworkAdapter; + +- (instancetype)init { + return [super init]; +} + +- (webrtc::PeerConnectionFactoryInterface::Options)nativeOptions { + webrtc::PeerConnectionFactoryInterface::Options options; + options.disable_encryption = self.disableEncryption; + options.disable_network_monitor = self.disableNetworkMonitor; + + setNetworkBit(&options, rtc::ADAPTER_TYPE_LOOPBACK, self.ignoreLoopbackNetworkAdapter); + setNetworkBit(&options, rtc::ADAPTER_TYPE_VPN, self.ignoreVPNNetworkAdapter); + setNetworkBit(&options, rtc::ADAPTER_TYPE_CELLULAR, self.ignoreCellularNetworkAdapter); + setNetworkBit(&options, rtc::ADAPTER_TYPE_WIFI, self.ignoreWiFiNetworkAdapter); + setNetworkBit(&options, rtc::ADAPTER_TYPE_ETHERNET, self.ignoreEthernetNetworkAdapter); + + return options; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters+Private.h new file mode 100644 index 0000000000..c4d196cf79 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters+Private.h @@ -0,0 +1,29 @@ +/* + * 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 "RTCRtcpParameters.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtcpParameters) +() + + /** Returns the equivalent native RtcpParameters structure. */ + @property(nonatomic, readonly) webrtc::RtcpParameters nativeParameters; + +/** Initialize the object with a native RtcpParameters structure. */ +- (instancetype)initWithNativeParameters:(const webrtc::RtcpParameters &)nativeParameters + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters.h new file mode 100644 index 0000000000..2f7aad3aef --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters.h @@ -0,0 +1,30 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtcpParameters) : NSObject + +/** The Canonical Name used by RTCP. */ +@property(nonatomic, readonly, copy) NSString *cname; + +/** Whether reduced size RTCP is configured or compound RTCP. */ +@property(nonatomic, assign) BOOL isReducedSize; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters.mm new file mode 100644 index 0000000000..e92ee4b3e7 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtcpParameters.mm @@ -0,0 +1,40 @@ +/* + * 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 "RTCRtcpParameters+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtcpParameters) + +@synthesize cname = _cname; +@synthesize isReducedSize = _isReducedSize; + +- (instancetype)init { + webrtc::RtcpParameters nativeParameters; + return [self initWithNativeParameters:nativeParameters]; +} + +- (instancetype)initWithNativeParameters:(const webrtc::RtcpParameters &)nativeParameters { + if (self = [super init]) { + _cname = [NSString stringForStdString:nativeParameters.cname]; + _isReducedSize = nativeParameters.reduced_size; + } + return self; +} + +- (webrtc::RtcpParameters)nativeParameters { + webrtc::RtcpParameters parameters; + parameters.cname = [NSString stdStringForString:_cname]; + parameters.reduced_size = _isReducedSize; + return parameters; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters+Private.h new file mode 100644 index 0000000000..ff23cfd642 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters+Private.h @@ -0,0 +1,29 @@ +/* + * 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 "RTCRtpCodecParameters.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpCodecParameters) +() + + /** Returns the equivalent native RtpCodecParameters structure. */ + @property(nonatomic, readonly) webrtc::RtpCodecParameters nativeParameters; + +/** Initialize the object with a native RtpCodecParameters structure. */ +- (instancetype)initWithNativeParameters:(const webrtc::RtpCodecParameters &)nativeParameters + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters.h new file mode 100644 index 0000000000..6135223720 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters.h @@ -0,0 +1,73 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_EXTERN const NSString *const kRTCRtxCodecName; +RTC_EXTERN const NSString *const kRTCRedCodecName; +RTC_EXTERN const NSString *const kRTCUlpfecCodecName; +RTC_EXTERN const NSString *const kRTCFlexfecCodecName; +RTC_EXTERN const NSString *const kRTCOpusCodecName; +RTC_EXTERN const NSString *const kRTCIsacCodecName; +RTC_EXTERN const NSString *const kRTCL16CodecName; +RTC_EXTERN const NSString *const kRTCG722CodecName; +RTC_EXTERN const NSString *const kRTCIlbcCodecName; +RTC_EXTERN const NSString *const kRTCPcmuCodecName; +RTC_EXTERN const NSString *const kRTCPcmaCodecName; +RTC_EXTERN const NSString *const kRTCDtmfCodecName; +RTC_EXTERN const NSString *const kRTCComfortNoiseCodecName; +RTC_EXTERN const NSString *const kRTCVp8CodecName; +RTC_EXTERN const NSString *const kRTCVp9CodecName; +RTC_EXTERN const NSString *const kRTCH264CodecName; + +/** Defined in https://www.w3.org/TR/webrtc/#idl-def-rtcrtpcodecparameters */ +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpCodecParameters) : NSObject + +/** The RTP payload type. */ +@property(nonatomic, assign) int payloadType; + +/** + * 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, nonnull) NSString *name; + +/** + * The media type of this codec. Equivalent to MIME top-level type. + * + * Valid values are kRTCMediaStreamTrackKindAudio and + * kRTCMediaStreamTrackKindVideo. + */ +@property(nonatomic, readonly, nonnull) NSString *kind; + +/** The codec clock rate expressed in Hertz. */ +@property(nonatomic, readonly, nullable) NSNumber *clockRate; + +/** + * The number of 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, nonnull) NSDictionary *parameters; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm new file mode 100644 index 0000000000..753667b635 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm @@ -0,0 +1,113 @@ +/* + * 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 "RTCRtpCodecParameters+Private.h" + +#import "RTCMediaStreamTrack.h" +#import "helpers/NSString+StdString.h" + +#include "media/base/media_constants.h" +#include "rtc_base/checks.h" + +const NSString * const kRTCRtxCodecName = @(cricket::kRtxCodecName); +const NSString * const kRTCRedCodecName = @(cricket::kRedCodecName); +const NSString * const kRTCUlpfecCodecName = @(cricket::kUlpfecCodecName); +const NSString * const kRTCFlexfecCodecName = @(cricket::kFlexfecCodecName); +const NSString * const kRTCOpusCodecName = @(cricket::kOpusCodecName); +const NSString * const kRTCIsacCodecName = @(cricket::kIsacCodecName); +const NSString * const kRTCL16CodecName = @(cricket::kL16CodecName); +const NSString * const kRTCG722CodecName = @(cricket::kG722CodecName); +const NSString * const kRTCIlbcCodecName = @(cricket::kIlbcCodecName); +const NSString * const kRTCPcmuCodecName = @(cricket::kPcmuCodecName); +const NSString * const kRTCPcmaCodecName = @(cricket::kPcmaCodecName); +const NSString * const kRTCDtmfCodecName = @(cricket::kDtmfCodecName); +const NSString * const kRTCComfortNoiseCodecName = + @(cricket::kComfortNoiseCodecName); +const NSString * const kRTCVp8CodecName = @(cricket::kVp8CodecName); +const NSString * const kRTCVp9CodecName = @(cricket::kVp9CodecName); +const NSString * const kRTCH264CodecName = @(cricket::kH264CodecName); + +@implementation RTC_OBJC_TYPE (RTCRtpCodecParameters) + +@synthesize payloadType = _payloadType; +@synthesize name = _name; +@synthesize kind = _kind; +@synthesize clockRate = _clockRate; +@synthesize numChannels = _numChannels; +@synthesize parameters = _parameters; + +- (instancetype)init { + webrtc::RtpCodecParameters nativeParameters; + return [self initWithNativeParameters:nativeParameters]; +} + +- (instancetype)initWithNativeParameters: + (const webrtc::RtpCodecParameters &)nativeParameters { + if (self = [super init]) { + _payloadType = nativeParameters.payload_type; + _name = [NSString stringForStdString:nativeParameters.name]; + switch (nativeParameters.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 (nativeParameters.clock_rate) { + _clockRate = [NSNumber numberWithInt:*nativeParameters.clock_rate]; + } + if (nativeParameters.num_channels) { + _numChannels = [NSNumber numberWithInt:*nativeParameters.num_channels]; + } + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + for (const auto ¶meter : nativeParameters.parameters) { + [parameters setObject:[NSString stringForStdString:parameter.second] + forKey:[NSString stringForStdString:parameter.first]]; + } + _parameters = parameters; + } + return self; +} + +- (webrtc::RtpCodecParameters)nativeParameters { + webrtc::RtpCodecParameters parameters; + parameters.payload_type = _payloadType; + parameters.name = [NSString stdStringForString:_name]; + // NSString pointer comparison is safe here since "kind" is readonly and only + // populated above. + if (_kind == kRTCMediaStreamTrackKindAudio) { + parameters.kind = cricket::MEDIA_TYPE_AUDIO; + } else if (_kind == kRTCMediaStreamTrackKindVideo) { + parameters.kind = cricket::MEDIA_TYPE_VIDEO; + } else { + RTC_DCHECK_NOTREACHED(); + } + if (_clockRate != nil) { + parameters.clock_rate = absl::optional<int>(_clockRate.intValue); + } + if (_numChannels != nil) { + parameters.num_channels = absl::optional<int>(_numChannels.intValue); + } + for (NSString *paramKey in _parameters.allKeys) { + std::string key = [NSString stdStringForString:paramKey]; + std::string value = [NSString stdStringForString:_parameters[paramKey]]; + parameters.parameters[key] = value; + } + return parameters; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters+Private.h new file mode 100644 index 0000000000..d12ca624e3 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters+Private.h @@ -0,0 +1,29 @@ +/* + * 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 "RTCRtpEncodingParameters.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpEncodingParameters) +() + + /** Returns the equivalent native RtpEncodingParameters structure. */ + @property(nonatomic, readonly) webrtc::RtpEncodingParameters nativeParameters; + +/** Initialize the object with a native RtpEncodingParameters structure. */ +- (instancetype)initWithNativeParameters:(const webrtc::RtpEncodingParameters &)nativeParameters + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.h new file mode 100644 index 0000000000..07f6b7a39c --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.h @@ -0,0 +1,76 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Corresponds to webrtc::Priority. */ +typedef NS_ENUM(NSInteger, RTCPriority) { + RTCPriorityVeryLow, + RTCPriorityLow, + RTCPriorityMedium, + RTCPriorityHigh +}; + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpEncodingParameters) : NSObject + +/** The idenfifier for the encoding layer. This is used in simulcast. */ +@property(nonatomic, copy, nullable) NSString *rid; + +/** Controls whether the encoding is currently transmitted. */ +@property(nonatomic, assign) BOOL isActive; + +/** The maximum bitrate to use for the encoding, or nil if there is no + * limit. + */ +@property(nonatomic, copy, nullable) NSNumber *maxBitrateBps; + +/** The minimum bitrate to use for the encoding, or nil if there is no + * limit. + */ +@property(nonatomic, copy, nullable) NSNumber *minBitrateBps; + +/** The maximum framerate to use for the encoding, or nil if there is no + * limit. + */ +@property(nonatomic, copy, nullable) NSNumber *maxFramerate; + +/** The requested number of temporal layers to use for the encoding, or nil + * if the default should be used. + */ +@property(nonatomic, copy, nullable) NSNumber *numTemporalLayers; + +/** Scale the width and height down by this factor for video. If nil, + * implementation default scaling factor will be used. + */ +@property(nonatomic, copy, nullable) NSNumber *scaleResolutionDownBy; + +/** The SSRC being used by this encoding. */ +@property(nonatomic, readonly, nullable) NSNumber *ssrc; + +/** The relative bitrate priority. */ +@property(nonatomic, assign) double bitratePriority; + +/** The relative DiffServ Code Point priority. */ +@property(nonatomic, assign) RTCPriority networkPriority; + +/** Allow dynamic frame length changes for audio: + https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime */ +@property(nonatomic, assign) BOOL adaptiveAudioPacketTime; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm new file mode 100644 index 0000000000..d6087dafb0 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm @@ -0,0 +1,128 @@ +/* + * 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 "RTCRtpEncodingParameters+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtpEncodingParameters) + +@synthesize rid = _rid; +@synthesize isActive = _isActive; +@synthesize maxBitrateBps = _maxBitrateBps; +@synthesize minBitrateBps = _minBitrateBps; +@synthesize maxFramerate = _maxFramerate; +@synthesize numTemporalLayers = _numTemporalLayers; +@synthesize scaleResolutionDownBy = _scaleResolutionDownBy; +@synthesize ssrc = _ssrc; +@synthesize bitratePriority = _bitratePriority; +@synthesize networkPriority = _networkPriority; +@synthesize adaptiveAudioPacketTime = _adaptiveAudioPacketTime; + +- (instancetype)init { + webrtc::RtpEncodingParameters nativeParameters; + return [self initWithNativeParameters:nativeParameters]; +} + +- (instancetype)initWithNativeParameters: + (const webrtc::RtpEncodingParameters &)nativeParameters { + if (self = [super init]) { + if (!nativeParameters.rid.empty()) { + _rid = [NSString stringForStdString:nativeParameters.rid]; + } + _isActive = nativeParameters.active; + if (nativeParameters.max_bitrate_bps) { + _maxBitrateBps = + [NSNumber numberWithInt:*nativeParameters.max_bitrate_bps]; + } + if (nativeParameters.min_bitrate_bps) { + _minBitrateBps = + [NSNumber numberWithInt:*nativeParameters.min_bitrate_bps]; + } + if (nativeParameters.max_framerate) { + _maxFramerate = [NSNumber numberWithInt:*nativeParameters.max_framerate]; + } + if (nativeParameters.num_temporal_layers) { + _numTemporalLayers = [NSNumber numberWithInt:*nativeParameters.num_temporal_layers]; + } + if (nativeParameters.scale_resolution_down_by) { + _scaleResolutionDownBy = + [NSNumber numberWithDouble:*nativeParameters.scale_resolution_down_by]; + } + if (nativeParameters.ssrc) { + _ssrc = [NSNumber numberWithUnsignedLong:*nativeParameters.ssrc]; + } + _bitratePriority = nativeParameters.bitrate_priority; + _networkPriority = [RTC_OBJC_TYPE(RTCRtpEncodingParameters) + priorityFromNativePriority:nativeParameters.network_priority]; + _adaptiveAudioPacketTime = nativeParameters.adaptive_ptime; + } + return self; +} + +- (webrtc::RtpEncodingParameters)nativeParameters { + webrtc::RtpEncodingParameters parameters; + if (_rid != nil) { + parameters.rid = [NSString stdStringForString:_rid]; + } + parameters.active = _isActive; + if (_maxBitrateBps != nil) { + parameters.max_bitrate_bps = absl::optional<int>(_maxBitrateBps.intValue); + } + if (_minBitrateBps != nil) { + parameters.min_bitrate_bps = absl::optional<int>(_minBitrateBps.intValue); + } + if (_maxFramerate != nil) { + parameters.max_framerate = absl::optional<int>(_maxFramerate.intValue); + } + if (_numTemporalLayers != nil) { + parameters.num_temporal_layers = absl::optional<int>(_numTemporalLayers.intValue); + } + if (_scaleResolutionDownBy != nil) { + parameters.scale_resolution_down_by = + absl::optional<double>(_scaleResolutionDownBy.doubleValue); + } + if (_ssrc != nil) { + parameters.ssrc = absl::optional<uint32_t>(_ssrc.unsignedLongValue); + } + parameters.bitrate_priority = _bitratePriority; + parameters.network_priority = + [RTC_OBJC_TYPE(RTCRtpEncodingParameters) nativePriorityFromPriority:_networkPriority]; + parameters.adaptive_ptime = _adaptiveAudioPacketTime; + return parameters; +} + ++ (webrtc::Priority)nativePriorityFromPriority:(RTCPriority)networkPriority { + switch (networkPriority) { + case RTCPriorityVeryLow: + return webrtc::Priority::kVeryLow; + case RTCPriorityLow: + return webrtc::Priority::kLow; + case RTCPriorityMedium: + return webrtc::Priority::kMedium; + case RTCPriorityHigh: + return webrtc::Priority::kHigh; + } +} + ++ (RTCPriority)priorityFromNativePriority:(webrtc::Priority)nativePriority { + switch (nativePriority) { + case webrtc::Priority::kVeryLow: + return RTCPriorityVeryLow; + case webrtc::Priority::kLow: + return RTCPriorityLow; + case webrtc::Priority::kMedium: + return RTCPriorityMedium; + case webrtc::Priority::kHigh: + return RTCPriorityHigh; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension+Private.h new file mode 100644 index 0000000000..0e0fbba5ac --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension+Private.h @@ -0,0 +1,29 @@ +/* + * 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 "RTCRtpHeaderExtension.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpHeaderExtension) +() + + /** Returns the equivalent native RtpExtension structure. */ + @property(nonatomic, readonly) webrtc::RtpExtension nativeParameters; + +/** Initialize the object with a native RtpExtension structure. */ +- (instancetype)initWithNativeParameters:(const webrtc::RtpExtension &)nativeParameters + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension.h new file mode 100644 index 0000000000..4000bf5372 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension.h @@ -0,0 +1,33 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpHeaderExtension) : 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) int id; + +/** Whether the header extension is encrypted or not. */ +@property(nonatomic, readonly, getter=isEncrypted) BOOL encrypted; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension.mm new file mode 100644 index 0000000000..68093e92ea --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtension.mm @@ -0,0 +1,43 @@ +/* + * 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 "RTCRtpHeaderExtension+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtpHeaderExtension) + +@synthesize uri = _uri; +@synthesize id = _id; +@synthesize encrypted = _encrypted; + +- (instancetype)init { + webrtc::RtpExtension nativeExtension; + return [self initWithNativeParameters:nativeExtension]; +} + +- (instancetype)initWithNativeParameters:(const webrtc::RtpExtension &)nativeParameters { + if (self = [super init]) { + _uri = [NSString stringForStdString:nativeParameters.uri]; + _id = nativeParameters.id; + _encrypted = nativeParameters.encrypt; + } + return self; +} + +- (webrtc::RtpExtension)nativeParameters { + webrtc::RtpExtension extension; + extension.uri = [NSString stdStringForString:_uri]; + extension.id = _id; + extension.encrypt = _encrypted; + return extension; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters+Private.h new file mode 100644 index 0000000000..139617f727 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters+Private.h @@ -0,0 +1,29 @@ +/* + * 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 "RTCRtpParameters.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpParameters) +() + + /** Returns the equivalent native RtpParameters structure. */ + @property(nonatomic, readonly) webrtc::RtpParameters nativeParameters; + +/** Initialize the object with a native RtpParameters structure. */ +- (instancetype)initWithNativeParameters:(const webrtc::RtpParameters &)nativeParameters + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters.h new file mode 100644 index 0000000000..3d71c55ab9 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters.h @@ -0,0 +1,58 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" +#import "RTCRtcpParameters.h" +#import "RTCRtpCodecParameters.h" +#import "RTCRtpEncodingParameters.h" +#import "RTCRtpHeaderExtension.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Corresponds to webrtc::DegradationPreference. */ +typedef NS_ENUM(NSInteger, RTCDegradationPreference) { + RTCDegradationPreferenceDisabled, + RTCDegradationPreferenceMaintainFramerate, + RTCDegradationPreferenceMaintainResolution, + RTCDegradationPreferenceBalanced +}; + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpParameters) : NSObject + +/** A unique identifier for the last set of parameters applied. */ +@property(nonatomic, copy) NSString *transactionId; + +/** Parameters used for RTCP. */ +@property(nonatomic, readonly, copy) RTC_OBJC_TYPE(RTCRtcpParameters) * rtcp; + +/** An array containing parameters for RTP header extensions. */ +@property(nonatomic, readonly, copy) + NSArray<RTC_OBJC_TYPE(RTCRtpHeaderExtension) *> *headerExtensions; + +/** The currently active encodings in the order of preference. */ +@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCRtpEncodingParameters) *> *encodings; + +/** The negotiated set of send codecs in order of preference. */ +@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCRtpCodecParameters) *> *codecs; + +/** + * Degradation preference in case of CPU adaptation or constrained bandwidth. + * If nil, implementation default degradation preference will be used. + */ +@property(nonatomic, copy, nullable) NSNumber *degradationPreference; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters.mm new file mode 100644 index 0000000000..2baf0ecd80 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpParameters.mm @@ -0,0 +1,121 @@ +/* + * 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 "RTCRtpParameters+Private.h" + +#import "RTCRtcpParameters+Private.h" +#import "RTCRtpCodecParameters+Private.h" +#import "RTCRtpEncodingParameters+Private.h" +#import "RTCRtpHeaderExtension+Private.h" +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtpParameters) + +@synthesize transactionId = _transactionId; +@synthesize rtcp = _rtcp; +@synthesize headerExtensions = _headerExtensions; +@synthesize encodings = _encodings; +@synthesize codecs = _codecs; +@synthesize degradationPreference = _degradationPreference; + +- (instancetype)init { + webrtc::RtpParameters nativeParameters; + return [self initWithNativeParameters:nativeParameters]; +} + +- (instancetype)initWithNativeParameters: + (const webrtc::RtpParameters &)nativeParameters { + if (self = [super init]) { + _transactionId = [NSString stringForStdString:nativeParameters.transaction_id]; + _rtcp = + [[RTC_OBJC_TYPE(RTCRtcpParameters) alloc] initWithNativeParameters:nativeParameters.rtcp]; + + NSMutableArray *headerExtensions = [[NSMutableArray alloc] init]; + for (const auto &headerExtension : nativeParameters.header_extensions) { + [headerExtensions addObject:[[RTC_OBJC_TYPE(RTCRtpHeaderExtension) alloc] + initWithNativeParameters:headerExtension]]; + } + _headerExtensions = headerExtensions; + + NSMutableArray *encodings = [[NSMutableArray alloc] init]; + for (const auto &encoding : nativeParameters.encodings) { + [encodings addObject:[[RTC_OBJC_TYPE(RTCRtpEncodingParameters) alloc] + initWithNativeParameters:encoding]]; + } + _encodings = encodings; + + NSMutableArray *codecs = [[NSMutableArray alloc] init]; + for (const auto &codec : nativeParameters.codecs) { + [codecs + addObject:[[RTC_OBJC_TYPE(RTCRtpCodecParameters) alloc] initWithNativeParameters:codec]]; + } + _codecs = codecs; + + _degradationPreference = [RTC_OBJC_TYPE(RTCRtpParameters) + degradationPreferenceFromNativeDegradationPreference:nativeParameters + .degradation_preference]; + } + return self; +} + +- (webrtc::RtpParameters)nativeParameters { + webrtc::RtpParameters parameters; + parameters.transaction_id = [NSString stdStringForString:_transactionId]; + parameters.rtcp = [_rtcp nativeParameters]; + for (RTC_OBJC_TYPE(RTCRtpHeaderExtension) * headerExtension in _headerExtensions) { + parameters.header_extensions.push_back(headerExtension.nativeParameters); + } + for (RTC_OBJC_TYPE(RTCRtpEncodingParameters) * encoding in _encodings) { + parameters.encodings.push_back(encoding.nativeParameters); + } + for (RTC_OBJC_TYPE(RTCRtpCodecParameters) * codec in _codecs) { + parameters.codecs.push_back(codec.nativeParameters); + } + if (_degradationPreference) { + parameters.degradation_preference = [RTC_OBJC_TYPE(RTCRtpParameters) + nativeDegradationPreferenceFromDegradationPreference:(RTCDegradationPreference) + _degradationPreference.intValue]; + } + return parameters; +} + ++ (webrtc::DegradationPreference)nativeDegradationPreferenceFromDegradationPreference: + (RTCDegradationPreference)degradationPreference { + switch (degradationPreference) { + case RTCDegradationPreferenceDisabled: + return webrtc::DegradationPreference::DISABLED; + case RTCDegradationPreferenceMaintainFramerate: + return webrtc::DegradationPreference::MAINTAIN_FRAMERATE; + case RTCDegradationPreferenceMaintainResolution: + return webrtc::DegradationPreference::MAINTAIN_RESOLUTION; + case RTCDegradationPreferenceBalanced: + return webrtc::DegradationPreference::BALANCED; + } +} + ++ (NSNumber *)degradationPreferenceFromNativeDegradationPreference: + (absl::optional<webrtc::DegradationPreference>)nativeDegradationPreference { + if (!nativeDegradationPreference.has_value()) { + return nil; + } + + switch (*nativeDegradationPreference) { + case webrtc::DegradationPreference::DISABLED: + return @(RTCDegradationPreferenceDisabled); + case webrtc::DegradationPreference::MAINTAIN_FRAMERATE: + return @(RTCDegradationPreferenceMaintainFramerate); + case webrtc::DegradationPreference::MAINTAIN_RESOLUTION: + return @(RTCDegradationPreferenceMaintainResolution); + case webrtc::DegradationPreference::BALANCED: + return @(RTCDegradationPreferenceBalanced); + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Native.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Native.h new file mode 100644 index 0000000000..c15ce70079 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Native.h @@ -0,0 +1,32 @@ +/* + * 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 "RTCRtpReceiver.h" + +#include "api/crypto/frame_decryptor_interface.h" +#include "api/scoped_refptr.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class extension exposes methods that work directly with injectable C++ components. + */ +@interface RTC_OBJC_TYPE (RTCRtpReceiver) +() + + /** Sets a user defined frame decryptor that will decrypt the entire frame. + * This will decrypt the entire frame using the user provided decryption + * mechanism regardless of whether SRTP is enabled or not. + */ + - (void)setFrameDecryptor : (rtc::scoped_refptr<webrtc::FrameDecryptorInterface>)frameDecryptor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Private.h new file mode 100644 index 0000000000..6aed0b4bc5 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Private.h @@ -0,0 +1,52 @@ +/* + * 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 "RTCRtpReceiver.h" + +#include "api/rtp_receiver_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); + +namespace webrtc { + +class RtpReceiverDelegateAdapter : public RtpReceiverObserverInterface { + public: + RtpReceiverDelegateAdapter(RTC_OBJC_TYPE(RTCRtpReceiver) * receiver); + + void OnFirstPacketReceived(cricket::MediaType media_type) override; + + private: + __weak RTC_OBJC_TYPE(RTCRtpReceiver) * receiver_; +}; + +} // namespace webrtc + +@interface RTC_OBJC_TYPE (RTCRtpReceiver) +() + + @property(nonatomic, + readonly) rtc::scoped_refptr<webrtc::RtpReceiverInterface> nativeRtpReceiver; + +/** Initialize an RTCRtpReceiver with a native RtpReceiverInterface. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeRtpReceiver:(rtc::scoped_refptr<webrtc::RtpReceiverInterface>)nativeRtpReceiver + NS_DESIGNATED_INITIALIZER; + ++ (RTCRtpMediaType)mediaTypeForNativeMediaType:(cricket::MediaType)nativeMediaType; + ++ (cricket::MediaType)nativeMediaTypeForMediaType:(RTCRtpMediaType)mediaType; + ++ (NSString*)stringForMediaType:(RTCRtpMediaType)mediaType; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver.h new file mode 100644 index 0000000000..1e407fd71b --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver.h @@ -0,0 +1,86 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" +#import "RTCMediaStreamTrack.h" +#import "RTCRtpParameters.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Represents the media type of the RtpReceiver. */ +typedef NS_ENUM(NSInteger, RTCRtpMediaType) { + RTCRtpMediaTypeAudio, + RTCRtpMediaTypeVideo, + RTCRtpMediaTypeData, + RTCRtpMediaTypeUnsupported, +}; + +@class RTC_OBJC_TYPE(RTCRtpReceiver); + +RTC_OBJC_EXPORT +@protocol RTC_OBJC_TYPE +(RTCRtpReceiverDelegate)<NSObject> + + /** Called when the first RTP packet is received. + * + * Note: Currently if there are multiple RtpReceivers of the same media type, + * they will all call OnFirstPacketReceived at once. + * + * For example, if we create three audio receivers, A/B/C, they will listen to + * the same signal from the underneath network layer. Whenever the first audio packet + * is received, the underneath signal will be fired. All the receivers A/B/C will be + * notified and the callback of the receiver's delegate will be called. + * + * The process is the same for video receivers. + */ + - (void)rtpReceiver + : (RTC_OBJC_TYPE(RTCRtpReceiver) *)rtpReceiver didReceiveFirstPacketForMediaType + : (RTCRtpMediaType)mediaType; + +@end + +RTC_OBJC_EXPORT +@protocol RTC_OBJC_TYPE +(RTCRtpReceiver)<NSObject> + + /** A unique identifier for this receiver. */ + @property(nonatomic, readonly) NSString *receiverId; + +/** The currently active RTCRtpParameters, as defined in + * https://www.w3.org/TR/webrtc/#idl-def-RTCRtpParameters. + * + * The WebRTC specification only defines RTCRtpParameters in terms of senders, + * but this API also applies them to receivers, similar to ORTC: + * http://ortc.org/wp-content/uploads/2016/03/ortc.html#rtcrtpparameters*. + */ +@property(nonatomic, readonly) RTC_OBJC_TYPE(RTCRtpParameters) * parameters; + +/** The RTCMediaStreamTrack associated with the receiver. + * Note: reading this property returns a new instance of + * RTCMediaStreamTrack. Use isEqual: instead of == to compare + * RTCMediaStreamTrack instances. + */ +@property(nonatomic, readonly, nullable) RTC_OBJC_TYPE(RTCMediaStreamTrack) * track; + +/** The delegate for this RtpReceiver. */ +@property(nonatomic, weak) id<RTC_OBJC_TYPE(RTCRtpReceiverDelegate)> delegate; + +@end + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpReceiver) : NSObject <RTC_OBJC_TYPE(RTCRtpReceiver)> + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver.mm new file mode 100644 index 0000000000..60af86ac1b --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver.mm @@ -0,0 +1,159 @@ +/* + * 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 "RTCRtpReceiver+Private.h" + +#import "RTCMediaStreamTrack+Private.h" +#import "RTCRtpParameters+Private.h" +#import "RTCRtpReceiver+Native.h" +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +#include "api/media_stream_interface.h" + +namespace webrtc { + +RtpReceiverDelegateAdapter::RtpReceiverDelegateAdapter(RTC_OBJC_TYPE(RTCRtpReceiver) * receiver) { + RTC_CHECK(receiver); + receiver_ = receiver; +} + +void RtpReceiverDelegateAdapter::OnFirstPacketReceived( + cricket::MediaType media_type) { + RTCRtpMediaType packet_media_type = + [RTC_OBJC_TYPE(RTCRtpReceiver) mediaTypeForNativeMediaType:media_type]; + RTC_OBJC_TYPE(RTCRtpReceiver) *receiver = receiver_; + [receiver.delegate rtpReceiver:receiver didReceiveFirstPacketForMediaType:packet_media_type]; +} + +} // namespace webrtc + +@implementation RTC_OBJC_TYPE (RTCRtpReceiver) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + rtc::scoped_refptr<webrtc::RtpReceiverInterface> _nativeRtpReceiver; + std::unique_ptr<webrtc::RtpReceiverDelegateAdapter> _observer; +} + +@synthesize delegate = _delegate; + +- (NSString *)receiverId { + return [NSString stringForStdString:_nativeRtpReceiver->id()]; +} + +- (RTC_OBJC_TYPE(RTCRtpParameters) *)parameters { + return [[RTC_OBJC_TYPE(RTCRtpParameters) alloc] + initWithNativeParameters:_nativeRtpReceiver->GetParameters()]; +} + +- (nullable RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track { + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack( + _nativeRtpReceiver->track()); + if (nativeTrack) { + return [RTC_OBJC_TYPE(RTCMediaStreamTrack) mediaTrackForNativeTrack:nativeTrack + factory:_factory]; + } + return nil; +} + +- (NSString *)description { + return [NSString + stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpReceiver) {\n receiverId: %@\n}", self.receiverId]; +} + +- (void)dealloc { + if (_nativeRtpReceiver) { + _nativeRtpReceiver->SetObserver(nullptr); + } +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (object == nil) { + return NO; + } + if (![object isMemberOfClass:[self class]]) { + return NO; + } + RTC_OBJC_TYPE(RTCRtpReceiver) *receiver = (RTC_OBJC_TYPE(RTCRtpReceiver) *)object; + return _nativeRtpReceiver == receiver.nativeRtpReceiver; +} + +- (NSUInteger)hash { + return (NSUInteger)_nativeRtpReceiver.get(); +} + +#pragma mark - Native + +- (void)setFrameDecryptor:(rtc::scoped_refptr<webrtc::FrameDecryptorInterface>)frameDecryptor { + _nativeRtpReceiver->SetFrameDecryptor(frameDecryptor); +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::RtpReceiverInterface>)nativeRtpReceiver { + return _nativeRtpReceiver; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeRtpReceiver: + (rtc::scoped_refptr<webrtc::RtpReceiverInterface>)nativeRtpReceiver { + if (self = [super init]) { + _factory = factory; + _nativeRtpReceiver = nativeRtpReceiver; + RTCLogInfo(@"RTC_OBJC_TYPE(RTCRtpReceiver)(%p): created receiver: %@", self, self.description); + _observer.reset(new webrtc::RtpReceiverDelegateAdapter(self)); + _nativeRtpReceiver->SetObserver(_observer.get()); + } + return self; +} + ++ (RTCRtpMediaType)mediaTypeForNativeMediaType: + (cricket::MediaType)nativeMediaType { + switch (nativeMediaType) { + case cricket::MEDIA_TYPE_AUDIO: + return RTCRtpMediaTypeAudio; + case cricket::MEDIA_TYPE_VIDEO: + return RTCRtpMediaTypeVideo; + case cricket::MEDIA_TYPE_DATA: + return RTCRtpMediaTypeData; + case cricket::MEDIA_TYPE_UNSUPPORTED: + return RTCRtpMediaTypeUnsupported; + } +} + ++ (cricket::MediaType)nativeMediaTypeForMediaType:(RTCRtpMediaType)mediaType { + switch (mediaType) { + case RTCRtpMediaTypeAudio: + return cricket::MEDIA_TYPE_AUDIO; + case RTCRtpMediaTypeVideo: + return cricket::MEDIA_TYPE_VIDEO; + case RTCRtpMediaTypeData: + return cricket::MEDIA_TYPE_DATA; + case RTCRtpMediaTypeUnsupported: + return cricket::MEDIA_TYPE_UNSUPPORTED; + } +} + ++ (NSString *)stringForMediaType:(RTCRtpMediaType)mediaType { + switch (mediaType) { + case RTCRtpMediaTypeAudio: + return @"AUDIO"; + case RTCRtpMediaTypeVideo: + return @"VIDEO"; + case RTCRtpMediaTypeData: + return @"DATA"; + case RTCRtpMediaTypeUnsupported: + return @"UNSUPPORTED"; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender+Native.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender+Native.h new file mode 100644 index 0000000000..249d5c5e09 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender+Native.h @@ -0,0 +1,33 @@ +/* + * 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 "RTCRtpSender.h" + +#include "api/crypto/frame_encryptor_interface.h" +#include "api/scoped_refptr.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class extension exposes methods that work directly with injectable C++ components. + */ +@interface RTC_OBJC_TYPE (RTCRtpSender) +() + + /** Sets a defined frame encryptor that will encrypt the entire frame + * before it is sent across the network. This will encrypt the entire frame + * using the user provided encryption mechanism regardless of whether SRTP is + * enabled or not. + */ + - (void)setFrameEncryptor : (rtc::scoped_refptr<webrtc::FrameEncryptorInterface>)frameEncryptor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender+Private.h new file mode 100644 index 0000000000..6fdb42bb22 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender+Private.h @@ -0,0 +1,31 @@ +/* + * 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 "RTCRtpSender.h" + +#include "api/rtp_sender_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); + +@interface RTC_OBJC_TYPE (RTCRtpSender) +() + + @property(nonatomic, readonly) rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeRtpSender; + +/** Initialize an RTCRtpSender with a native RtpSenderInterface. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeRtpSender:(rtc::scoped_refptr<webrtc::RtpSenderInterface>)nativeRtpSender + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.h new file mode 100644 index 0000000000..fcdf199869 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.h @@ -0,0 +1,54 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCDtmfSender.h" +#import "RTCMacros.h" +#import "RTCMediaStreamTrack.h" +#import "RTCRtpParameters.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@protocol RTC_OBJC_TYPE +(RTCRtpSender)<NSObject> + +/** A unique identifier for this sender. */ +@property(nonatomic, readonly) NSString *senderId; + +/** The currently active RTCRtpParameters, as defined in + * https://www.w3.org/TR/webrtc/#idl-def-RTCRtpParameters. + */ +@property(nonatomic, copy) RTC_OBJC_TYPE(RTCRtpParameters) * parameters; + +/** The RTCMediaStreamTrack associated with the sender. + * Note: reading this property returns a new instance of + * RTCMediaStreamTrack. Use isEqual: instead of == to compare + * RTCMediaStreamTrack instances. + */ +@property(nonatomic, copy, nullable) RTC_OBJC_TYPE(RTCMediaStreamTrack) * track; + +/** IDs of streams associated with the RTP sender */ +@property(nonatomic, copy) NSArray<NSString *> *streamIds; + +/** The RTCDtmfSender accociated with the RTP sender. */ +@property(nonatomic, readonly, nullable) id<RTC_OBJC_TYPE(RTCDtmfSender)> dtmfSender; + +@end + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpSender) : NSObject <RTC_OBJC_TYPE(RTCRtpSender)> + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.mm new file mode 100644 index 0000000000..4fadb30f49 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.mm @@ -0,0 +1,132 @@ +/* + * 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 "RTCRtpSender+Private.h" + +#import "RTCDtmfSender+Private.h" +#import "RTCMediaStreamTrack+Private.h" +#import "RTCRtpParameters+Private.h" +#import "RTCRtpSender+Native.h" +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +#include "api/media_stream_interface.h" + +@implementation RTC_OBJC_TYPE (RTCRtpSender) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + rtc::scoped_refptr<webrtc::RtpSenderInterface> _nativeRtpSender; +} + +@synthesize dtmfSender = _dtmfSender; + +- (NSString *)senderId { + return [NSString stringForStdString:_nativeRtpSender->id()]; +} + +- (RTC_OBJC_TYPE(RTCRtpParameters) *)parameters { + return [[RTC_OBJC_TYPE(RTCRtpParameters) alloc] + initWithNativeParameters:_nativeRtpSender->GetParameters()]; +} + +- (void)setParameters:(RTC_OBJC_TYPE(RTCRtpParameters) *)parameters { + if (!_nativeRtpSender->SetParameters(parameters.nativeParameters).ok()) { + RTCLogError(@"RTC_OBJC_TYPE(RTCRtpSender)(%p): Failed to set parameters: %@", self, parameters); + } +} + +- (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track { + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack( + _nativeRtpSender->track()); + if (nativeTrack) { + return [RTC_OBJC_TYPE(RTCMediaStreamTrack) mediaTrackForNativeTrack:nativeTrack + factory:_factory]; + } + return nil; +} + +- (void)setTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track { + if (!_nativeRtpSender->SetTrack(track.nativeTrack.get())) { + RTCLogError(@"RTC_OBJC_TYPE(RTCRtpSender)(%p): Failed to set track %@", self, track); + } +} + +- (NSArray<NSString *> *)streamIds { + std::vector<std::string> nativeStreamIds = _nativeRtpSender->stream_ids(); + NSMutableArray *streamIds = [NSMutableArray arrayWithCapacity:nativeStreamIds.size()]; + for (const auto &s : nativeStreamIds) { + [streamIds addObject:[NSString stringForStdString:s]]; + } + return streamIds; +} + +- (void)setStreamIds:(NSArray<NSString *> *)streamIds { + std::vector<std::string> nativeStreamIds; + for (NSString *streamId in streamIds) { + nativeStreamIds.push_back([streamId UTF8String]); + } + _nativeRtpSender->SetStreams(nativeStreamIds); +} + +- (NSString *)description { + return [NSString + stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpSender) {\n senderId: %@\n}", self.senderId]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (object == nil) { + return NO; + } + if (![object isMemberOfClass:[self class]]) { + return NO; + } + RTC_OBJC_TYPE(RTCRtpSender) *sender = (RTC_OBJC_TYPE(RTCRtpSender) *)object; + return _nativeRtpSender == sender.nativeRtpSender; +} + +- (NSUInteger)hash { + return (NSUInteger)_nativeRtpSender.get(); +} + +#pragma mark - Native + +- (void)setFrameEncryptor:(rtc::scoped_refptr<webrtc::FrameEncryptorInterface>)frameEncryptor { + _nativeRtpSender->SetFrameEncryptor(frameEncryptor); +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::RtpSenderInterface>)nativeRtpSender { + return _nativeRtpSender; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeRtpSender:(rtc::scoped_refptr<webrtc::RtpSenderInterface>)nativeRtpSender { + NSParameterAssert(factory); + NSParameterAssert(nativeRtpSender); + if (self = [super init]) { + _factory = factory; + _nativeRtpSender = nativeRtpSender; + if (_nativeRtpSender->media_type() == cricket::MEDIA_TYPE_AUDIO) { + rtc::scoped_refptr<webrtc::DtmfSenderInterface> nativeDtmfSender( + _nativeRtpSender->GetDtmfSender()); + if (nativeDtmfSender) { + _dtmfSender = + [[RTC_OBJC_TYPE(RTCDtmfSender) alloc] initWithNativeDtmfSender:nativeDtmfSender]; + } + } + RTCLogInfo(@"RTC_OBJC_TYPE(RTCRtpSender)(%p): created sender: %@", self, self.description); + } + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver+Private.h new file mode 100644 index 0000000000..65d45fb88e --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver+Private.h @@ -0,0 +1,46 @@ +/* + * 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 "RTCRtpTransceiver.h" + +#include "api/rtp_transceiver_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); + +@interface RTC_OBJC_TYPE (RTCRtpTransceiverInit) +() + + @property(nonatomic, readonly) webrtc::RtpTransceiverInit nativeInit; + +@end + +@interface RTC_OBJC_TYPE (RTCRtpTransceiver) +() + + @property(nonatomic, + readonly) rtc::scoped_refptr<webrtc::RtpTransceiverInterface> nativeRtpTransceiver; + +/** Initialize an RTCRtpTransceiver with a native RtpTransceiverInterface. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeRtpTransceiver: + (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver + NS_DESIGNATED_INITIALIZER; + ++ (webrtc::RtpTransceiverDirection)nativeRtpTransceiverDirectionFromDirection: + (RTCRtpTransceiverDirection)direction; + ++ (RTCRtpTransceiverDirection)rtpTransceiverDirectionFromNativeDirection: + (webrtc::RtpTransceiverDirection)nativeDirection; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h new file mode 100644 index 0000000000..fd59013639 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h @@ -0,0 +1,137 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" +#import "RTCRtpReceiver.h" +#import "RTCRtpSender.h" + +NS_ASSUME_NONNULL_BEGIN + +extern NSString *const kRTCRtpTransceiverErrorDomain; + +/** https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverdirection */ +typedef NS_ENUM(NSInteger, RTCRtpTransceiverDirection) { + RTCRtpTransceiverDirectionSendRecv, + RTCRtpTransceiverDirectionSendOnly, + RTCRtpTransceiverDirectionRecvOnly, + RTCRtpTransceiverDirectionInactive, + RTCRtpTransceiverDirectionStopped +}; + +/** Structure for initializing an RTCRtpTransceiver in a call to + * RTCPeerConnection.addTransceiver. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit + */ +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpTransceiverInit) : NSObject + +/** Direction of the RTCRtpTransceiver. See RTCRtpTransceiver.direction. */ +@property(nonatomic) RTCRtpTransceiverDirection direction; + +/** The added RTCRtpTransceiver will be added to these streams. */ +@property(nonatomic) NSArray<NSString *> *streamIds; + +/** TODO(bugs.webrtc.org/7600): Not implemented. */ +@property(nonatomic) NSArray<RTC_OBJC_TYPE(RTCRtpEncodingParameters) *> *sendEncodings; + +@end + +@class RTC_OBJC_TYPE(RTCRtpTransceiver); + +/** The RTCRtpTransceiver maps to the RTCRtpTransceiver defined by the + * WebRTC specification. A transceiver represents a combination of an RTCRtpSender + * and an RTCRtpReceiver that share a common mid. As defined in JSEP, an + * RTCRtpTransceiver is said to be associated with a media description if its + * mid property is non-nil; otherwise, it is said to be disassociated. + * JSEP: https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24 + * + * Note that RTCRtpTransceivers are only supported when using + * RTCPeerConnection with Unified Plan SDP. + * + * WebRTC specification for RTCRtpTransceiver, the JavaScript analog: + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver + */ +RTC_OBJC_EXPORT +@protocol RTC_OBJC_TYPE +(RTCRtpTransceiver)<NSObject> + + /** Media type of the transceiver. The sender and receiver will also have this + * type. + */ + @property(nonatomic, readonly) RTCRtpMediaType mediaType; + +/** The mid attribute is the mid negotiated and present in the local and + * remote descriptions. Before negotiation is complete, the mid value may be + * nil. After rollbacks, the value may change from a non-nil value to nil. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid + */ +@property(nonatomic, readonly) NSString *mid; + +/** The sender attribute exposes the RTCRtpSender corresponding to the RTP + * media that may be sent with the transceiver's mid. The sender is always + * present, regardless of the direction of media. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-sender + */ +@property(nonatomic, readonly) RTC_OBJC_TYPE(RTCRtpSender) * sender; + +/** The receiver attribute exposes the RTCRtpReceiver corresponding to the RTP + * media that may be received with the transceiver's mid. The receiver is + * always present, regardless of the direction of media. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-receiver + */ +@property(nonatomic, readonly) RTC_OBJC_TYPE(RTCRtpReceiver) * receiver; + +/** The isStopped attribute indicates that the sender of this transceiver will + * no longer send, and that the receiver will no longer receive. It is true if + * either stop has been called or if setting the local or remote description + * has caused the RTCRtpTransceiver to be stopped. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped + */ +@property(nonatomic, readonly) BOOL isStopped; + +/** The direction attribute indicates the preferred direction of this + * transceiver, which will be used in calls to createOffer and createAnswer. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction + */ +@property(nonatomic, readonly) RTCRtpTransceiverDirection direction; + +/** The currentDirection attribute indicates the current direction negotiated + * for this transceiver. If this transceiver has never been represented in an + * offer/answer exchange, or if the transceiver is stopped, the value is not + * present and this method returns NO. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection + */ +- (BOOL)currentDirection:(RTCRtpTransceiverDirection *)currentDirectionOut; + +/** The stop method irreversibly stops the RTCRtpTransceiver. The sender of + * this transceiver will no longer send, the receiver will no longer receive. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop + */ +- (void)stopInternal; + +/** 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. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction + */ +- (void)setDirection:(RTCRtpTransceiverDirection)direction error:(NSError **)error; + +@end + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpTransceiver) : NSObject <RTC_OBJC_TYPE(RTCRtpTransceiver)> + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm new file mode 100644 index 0000000000..ae1cf79864 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm @@ -0,0 +1,190 @@ +/* + * 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 "RTCRtpTransceiver+Private.h" + +#import "RTCRtpEncodingParameters+Private.h" +#import "RTCRtpParameters+Private.h" +#import "RTCRtpReceiver+Private.h" +#import "RTCRtpSender+Private.h" +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +NSString *const kRTCRtpTransceiverErrorDomain = @"org.webrtc.RTCRtpTranceiver"; + +@implementation RTC_OBJC_TYPE (RTCRtpTransceiverInit) + +@synthesize direction = _direction; +@synthesize streamIds = _streamIds; +@synthesize sendEncodings = _sendEncodings; + +- (instancetype)init { + if (self = [super init]) { + _direction = RTCRtpTransceiverDirectionSendRecv; + } + return self; +} + +- (webrtc::RtpTransceiverInit)nativeInit { + webrtc::RtpTransceiverInit init; + init.direction = + [RTC_OBJC_TYPE(RTCRtpTransceiver) nativeRtpTransceiverDirectionFromDirection:_direction]; + for (NSString *streamId in _streamIds) { + init.stream_ids.push_back([streamId UTF8String]); + } + for (RTC_OBJC_TYPE(RTCRtpEncodingParameters) * sendEncoding in _sendEncodings) { + init.send_encodings.push_back(sendEncoding.nativeParameters); + } + return init; +} + +@end + +@implementation RTC_OBJC_TYPE (RTCRtpTransceiver) { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory; + rtc::scoped_refptr<webrtc::RtpTransceiverInterface> _nativeRtpTransceiver; +} + +- (RTCRtpMediaType)mediaType { + return [RTC_OBJC_TYPE(RTCRtpReceiver) + mediaTypeForNativeMediaType:_nativeRtpTransceiver->media_type()]; +} + +- (NSString *)mid { + if (_nativeRtpTransceiver->mid()) { + return [NSString stringForStdString:*_nativeRtpTransceiver->mid()]; + } else { + return nil; + } +} + +@synthesize sender = _sender; +@synthesize receiver = _receiver; + +- (BOOL)isStopped { + return _nativeRtpTransceiver->stopped(); +} + +- (RTCRtpTransceiverDirection)direction { + return [RTC_OBJC_TYPE(RTCRtpTransceiver) + rtpTransceiverDirectionFromNativeDirection:_nativeRtpTransceiver->direction()]; +} + +- (void)setDirection:(RTCRtpTransceiverDirection)direction error:(NSError **)error { + webrtc::RTCError nativeError = _nativeRtpTransceiver->SetDirectionWithError( + [RTC_OBJC_TYPE(RTCRtpTransceiver) nativeRtpTransceiverDirectionFromDirection:direction]); + + if (!nativeError.ok() && error) { + *error = [NSError errorWithDomain:kRTCRtpTransceiverErrorDomain + code:static_cast<int>(nativeError.type()) + userInfo:@{ + @"message" : [NSString stringWithCString:nativeError.message() + encoding:NSUTF8StringEncoding] + }]; + } +} + +- (BOOL)currentDirection:(RTCRtpTransceiverDirection *)currentDirectionOut { + if (_nativeRtpTransceiver->current_direction()) { + *currentDirectionOut = [RTC_OBJC_TYPE(RTCRtpTransceiver) + rtpTransceiverDirectionFromNativeDirection:*_nativeRtpTransceiver->current_direction()]; + return YES; + } else { + return NO; + } +} + +- (void)stopInternal { + _nativeRtpTransceiver->StopInternal(); +} + +- (NSString *)description { + return [NSString + stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpTransceiver) {\n sender: %@\n receiver: %@\n}", + _sender, + _receiver]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (object == nil) { + return NO; + } + if (![object isMemberOfClass:[self class]]) { + return NO; + } + RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver = (RTC_OBJC_TYPE(RTCRtpTransceiver) *)object; + return _nativeRtpTransceiver == transceiver.nativeRtpTransceiver; +} + +- (NSUInteger)hash { + return (NSUInteger)_nativeRtpTransceiver.get(); +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver { + return _nativeRtpTransceiver; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeRtpTransceiver: + (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver { + NSParameterAssert(factory); + NSParameterAssert(nativeRtpTransceiver); + if (self = [super init]) { + _factory = factory; + _nativeRtpTransceiver = nativeRtpTransceiver; + _sender = [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:_factory + nativeRtpSender:nativeRtpTransceiver->sender()]; + _receiver = + [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:_factory + nativeRtpReceiver:nativeRtpTransceiver->receiver()]; + RTCLogInfo( + @"RTC_OBJC_TYPE(RTCRtpTransceiver)(%p): created transceiver: %@", self, self.description); + } + return self; +} + ++ (webrtc::RtpTransceiverDirection)nativeRtpTransceiverDirectionFromDirection: + (RTCRtpTransceiverDirection)direction { + switch (direction) { + case RTCRtpTransceiverDirectionSendRecv: + return webrtc::RtpTransceiverDirection::kSendRecv; + case RTCRtpTransceiverDirectionSendOnly: + return webrtc::RtpTransceiverDirection::kSendOnly; + case RTCRtpTransceiverDirectionRecvOnly: + return webrtc::RtpTransceiverDirection::kRecvOnly; + case RTCRtpTransceiverDirectionInactive: + return webrtc::RtpTransceiverDirection::kInactive; + case RTCRtpTransceiverDirectionStopped: + return webrtc::RtpTransceiverDirection::kStopped; + } +} + ++ (RTCRtpTransceiverDirection)rtpTransceiverDirectionFromNativeDirection: + (webrtc::RtpTransceiverDirection)nativeDirection { + switch (nativeDirection) { + case webrtc::RtpTransceiverDirection::kSendRecv: + return RTCRtpTransceiverDirectionSendRecv; + case webrtc::RtpTransceiverDirection::kSendOnly: + return RTCRtpTransceiverDirectionSendOnly; + case webrtc::RtpTransceiverDirection::kRecvOnly: + return RTCRtpTransceiverDirectionRecvOnly; + case webrtc::RtpTransceiverDirection::kInactive: + return RTCRtpTransceiverDirectionInactive; + case webrtc::RtpTransceiverDirection::kStopped: + return RTCRtpTransceiverDirectionStopped; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSSLAdapter.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSSLAdapter.h new file mode 100644 index 0000000000..f68bc5e9e3 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSSLAdapter.h @@ -0,0 +1,20 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +/** + * Initialize and clean up the SSL library. Failure is fatal. These call the + * corresponding functions in webrtc/rtc_base/ssladapter.h. + */ +RTC_EXTERN BOOL RTCInitializeSSL(void); +RTC_EXTERN BOOL RTCCleanupSSL(void); diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSSLAdapter.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSSLAdapter.mm new file mode 100644 index 0000000000..430249577b --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSSLAdapter.mm @@ -0,0 +1,26 @@ +/* + * 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 "RTCSSLAdapter.h" + +#include "rtc_base/checks.h" +#include "rtc_base/ssl_adapter.h" + +BOOL RTCInitializeSSL(void) { + BOOL initialized = rtc::InitializeSSL(); + RTC_DCHECK(initialized); + return initialized; +} + +BOOL RTCCleanupSSL(void) { + BOOL cleanedUp = rtc::CleanupSSL(); + RTC_DCHECK(cleanedUp); + return cleanedUp; +} diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h new file mode 100644 index 0000000000..aa087e557f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h @@ -0,0 +1,42 @@ +/* + * Copyright 2015 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 "RTCSessionDescription.h" + +#include "api/jsep.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCSessionDescription) +() + + /** + * The native SessionDescriptionInterface representation of this + * RTCSessionDescription object. This is needed to pass to the underlying C++ + * APIs. + */ + @property(nonatomic, + readonly) std::unique_ptr<webrtc::SessionDescriptionInterface> nativeDescription; + +/** + * Initialize an RTCSessionDescription from a native + * SessionDescriptionInterface. No ownership is taken of the native session + * description. + */ +- (instancetype)initWithNativeDescription: + (const webrtc::SessionDescriptionInterface *)nativeDescription; + ++ (std::string)stdStringForType:(RTCSdpType)type; + ++ (RTCSdpType)typeForStdString:(const std::string &)string; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription.h new file mode 100644 index 0000000000..8a9479d5cf --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription.h @@ -0,0 +1,48 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +/** + * Represents the session description type. This exposes the same types that are + * in C++, which doesn't include the rollback type that is in the W3C spec. + */ +typedef NS_ENUM(NSInteger, RTCSdpType) { + RTCSdpTypeOffer, + RTCSdpTypePrAnswer, + RTCSdpTypeAnswer, + RTCSdpTypeRollback, +}; + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCSessionDescription) : NSObject + +/** The type of session description. */ +@property(nonatomic, readonly) RTCSdpType type; + +/** The SDP string representation of this session description. */ +@property(nonatomic, readonly) NSString *sdp; + +- (instancetype)init NS_UNAVAILABLE; + +/** Initialize a session description with a type and SDP string. */ +- (instancetype)initWithType:(RTCSdpType)type sdp:(NSString *)sdp NS_DESIGNATED_INITIALIZER; + ++ (NSString *)stringForType:(RTCSdpType)type; + ++ (RTCSdpType)typeForString:(NSString *)string; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription.mm new file mode 100644 index 0000000000..539c90b14c --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription.mm @@ -0,0 +1,103 @@ +/* + * Copyright 2015 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 "RTCSessionDescription+Private.h" + +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +#include "rtc_base/checks.h" + +@implementation RTC_OBJC_TYPE (RTCSessionDescription) + +@synthesize type = _type; +@synthesize sdp = _sdp; + ++ (NSString *)stringForType:(RTCSdpType)type { + std::string string = [[self class] stdStringForType:type]; + return [NSString stringForStdString:string]; +} + ++ (RTCSdpType)typeForString:(NSString *)string { + std::string typeString = string.stdString; + return [[self class] typeForStdString:typeString]; +} + +- (instancetype)initWithType:(RTCSdpType)type sdp:(NSString *)sdp { + if (self = [super init]) { + _type = type; + _sdp = [sdp copy]; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCSessionDescription):\n%@\n%@", + [[self class] stringForType:_type], + _sdp]; +} + +#pragma mark - Private + +- (std::unique_ptr<webrtc::SessionDescriptionInterface>)nativeDescription { + webrtc::SdpParseError error; + + std::unique_ptr<webrtc::SessionDescriptionInterface> description(webrtc::CreateSessionDescription( + [[self class] stdStringForType:_type], _sdp.stdString, &error)); + + if (!description) { + RTCLogError(@"Failed to create session description: %s\nline: %s", + error.description.c_str(), + error.line.c_str()); + } + + return description; +} + +- (instancetype)initWithNativeDescription: + (const webrtc::SessionDescriptionInterface *)nativeDescription { + NSParameterAssert(nativeDescription); + std::string sdp; + nativeDescription->ToString(&sdp); + RTCSdpType type = [[self class] typeForStdString:nativeDescription->type()]; + + return [self initWithType:type + sdp:[NSString stringForStdString:sdp]]; +} + ++ (std::string)stdStringForType:(RTCSdpType)type { + switch (type) { + case RTCSdpTypeOffer: + return webrtc::SessionDescriptionInterface::kOffer; + case RTCSdpTypePrAnswer: + return webrtc::SessionDescriptionInterface::kPrAnswer; + case RTCSdpTypeAnswer: + return webrtc::SessionDescriptionInterface::kAnswer; + case RTCSdpTypeRollback: + return webrtc::SessionDescriptionInterface::kRollback; + } +} + ++ (RTCSdpType)typeForStdString:(const std::string &)string { + if (string == webrtc::SessionDescriptionInterface::kOffer) { + return RTCSdpTypeOffer; + } else if (string == webrtc::SessionDescriptionInterface::kPrAnswer) { + return RTCSdpTypePrAnswer; + } else if (string == webrtc::SessionDescriptionInterface::kAnswer) { + return RTCSdpTypeAnswer; + } else if (string == webrtc::SessionDescriptionInterface::kRollback) { + return RTCSdpTypeRollback; + } else { + RTC_DCHECK_NOTREACHED(); + return RTCSdpTypeOffer; + } +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport+Private.h new file mode 100644 index 0000000000..47c5241d51 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport+Private.h @@ -0,0 +1,19 @@ +/* + * Copyright 2019 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 "RTCStatisticsReport.h" + +#include "api/stats/rtc_stats_report.h" + +@interface RTC_OBJC_TYPE (RTCStatisticsReport) (Private) + +- (instancetype)initWithReport : (const webrtc::RTCStatsReport &)report; + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport.h new file mode 100644 index 0000000000..06dbf48d88 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport.h @@ -0,0 +1,55 @@ +/* + * Copyright 2019 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +@class RTC_OBJC_TYPE(RTCStatistics); + +NS_ASSUME_NONNULL_BEGIN + +/** A statistics report. Encapsulates a number of RTCStatistics objects. */ +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCStatisticsReport) : NSObject + +/** The timestamp of the report in microseconds since 1970-01-01T00:00:00Z. */ +@property(nonatomic, readonly) CFTimeInterval timestamp_us; + +/** RTCStatistics objects by id. */ +@property(nonatomic, readonly) NSDictionary<NSString *, RTC_OBJC_TYPE(RTCStatistics) *> *statistics; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +/** A part of a report (a subreport) covering a certain area. */ +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCStatistics) : NSObject + +/** The id of this subreport, e.g. "RTCMediaStreamTrack_receiver_2". */ +@property(nonatomic, readonly) NSString *id; + +/** The timestamp of the subreport in microseconds since 1970-01-01T00:00:00Z. */ +@property(nonatomic, readonly) CFTimeInterval timestamp_us; + +/** The type of the subreport, e.g. "track", "codec". */ +@property(nonatomic, readonly) NSString *type; + +/** The keys and values of the subreport, e.g. "totalFramesDuration = 5.551". + The values are either NSNumbers or NSStrings or NSArrays encapsulating NSNumbers + or NSStrings, or NSDictionary of NSString keys to NSNumber values. */ +@property(nonatomic, readonly) NSDictionary<NSString *, NSObject *> *values; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport.mm new file mode 100644 index 0000000000..bfe2424553 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport.mm @@ -0,0 +1,193 @@ +/* + * Copyright 2019 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 "RTCStatisticsReport+Private.h" + +#include "helpers/NSString+StdString.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +/** Converts a single value to a suitable NSNumber, NSString or NSArray containing NSNumbers + or NSStrings, or NSDictionary of NSString keys to NSNumber values.*/ +NSObject *ValueFromStatsMember(const RTCStatsMemberInterface *member) { + if (member->is_defined()) { + switch (member->type()) { + case RTCStatsMemberInterface::kBool: + return [NSNumber numberWithBool:*member->cast_to<RTCStatsMember<bool>>()]; + case RTCStatsMemberInterface::kInt32: + return [NSNumber numberWithInt:*member->cast_to<RTCStatsMember<int32_t>>()]; + case RTCStatsMemberInterface::kUint32: + return [NSNumber numberWithUnsignedInt:*member->cast_to<RTCStatsMember<uint32_t>>()]; + case RTCStatsMemberInterface::kInt64: + return [NSNumber numberWithLong:*member->cast_to<RTCStatsMember<int64_t>>()]; + case RTCStatsMemberInterface::kUint64: + return [NSNumber numberWithUnsignedLong:*member->cast_to<RTCStatsMember<uint64_t>>()]; + case RTCStatsMemberInterface::kDouble: + return [NSNumber numberWithDouble:*member->cast_to<RTCStatsMember<double>>()]; + case RTCStatsMemberInterface::kString: + return [NSString stringForStdString:*member->cast_to<RTCStatsMember<std::string>>()]; + case RTCStatsMemberInterface::kSequenceBool: { + std::vector<bool> sequence = *member->cast_to<RTCStatsMember<std::vector<bool>>>(); + NSMutableArray *array = [NSMutableArray arrayWithCapacity:sequence.size()]; + for (auto item : sequence) { + [array addObject:[NSNumber numberWithBool:item]]; + } + return [array copy]; + } + case RTCStatsMemberInterface::kSequenceInt32: { + std::vector<int32_t> sequence = *member->cast_to<RTCStatsMember<std::vector<int32_t>>>(); + NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()]; + for (const auto &item : sequence) { + [array addObject:[NSNumber numberWithInt:item]]; + } + return [array copy]; + } + case RTCStatsMemberInterface::kSequenceUint32: { + std::vector<uint32_t> sequence = *member->cast_to<RTCStatsMember<std::vector<uint32_t>>>(); + NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()]; + for (const auto &item : sequence) { + [array addObject:[NSNumber numberWithUnsignedInt:item]]; + } + return [array copy]; + } + case RTCStatsMemberInterface::kSequenceInt64: { + std::vector<int64_t> sequence = *member->cast_to<RTCStatsMember<std::vector<int64_t>>>(); + NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()]; + for (const auto &item : sequence) { + [array addObject:[NSNumber numberWithLong:item]]; + } + return [array copy]; + } + case RTCStatsMemberInterface::kSequenceUint64: { + std::vector<uint64_t> sequence = *member->cast_to<RTCStatsMember<std::vector<uint64_t>>>(); + NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()]; + for (const auto &item : sequence) { + [array addObject:[NSNumber numberWithUnsignedLong:item]]; + } + return [array copy]; + } + case RTCStatsMemberInterface::kSequenceDouble: { + std::vector<double> sequence = *member->cast_to<RTCStatsMember<std::vector<double>>>(); + NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()]; + for (const auto &item : sequence) { + [array addObject:[NSNumber numberWithDouble:item]]; + } + return [array copy]; + } + case RTCStatsMemberInterface::kSequenceString: { + std::vector<std::string> sequence = + *member->cast_to<RTCStatsMember<std::vector<std::string>>>(); + NSMutableArray<NSString *> *array = [NSMutableArray arrayWithCapacity:sequence.size()]; + for (const auto &item : sequence) { + [array addObject:[NSString stringForStdString:item]]; + } + return [array copy]; + } + case RTCStatsMemberInterface::kMapStringUint64: { + std::map<std::string, uint64_t> map = + *member->cast_to<RTCStatsMember<std::map<std::string, uint64_t>>>(); + NSMutableDictionary<NSString *, NSNumber *> *dictionary = + [NSMutableDictionary dictionaryWithCapacity:map.size()]; + for (const auto &item : map) { + dictionary[[NSString stringForStdString:item.first]] = @(item.second); + } + return [dictionary copy]; + } + case RTCStatsMemberInterface::kMapStringDouble: { + std::map<std::string, double> map = + *member->cast_to<RTCStatsMember<std::map<std::string, double>>>(); + NSMutableDictionary<NSString *, NSNumber *> *dictionary = + [NSMutableDictionary dictionaryWithCapacity:map.size()]; + for (const auto &item : map) { + dictionary[[NSString stringForStdString:item.first]] = @(item.second); + } + return [dictionary copy]; + } + default: + RTC_DCHECK_NOTREACHED(); + } + } + + return nil; +} +} // namespace webrtc + +@implementation RTC_OBJC_TYPE (RTCStatistics) + +@synthesize id = _id; +@synthesize timestamp_us = _timestamp_us; +@synthesize type = _type; +@synthesize values = _values; + +- (instancetype)initWithStatistics:(const webrtc::RTCStats &)statistics { + if (self = [super init]) { + _id = [NSString stringForStdString:statistics.id()]; + _timestamp_us = statistics.timestamp().us(); + _type = [NSString stringWithCString:statistics.type() encoding:NSUTF8StringEncoding]; + + NSMutableDictionary<NSString *, NSObject *> *values = [NSMutableDictionary dictionary]; + for (const webrtc::RTCStatsMemberInterface *member : statistics.Members()) { + NSObject *value = ValueFromStatsMember(member); + if (value) { + NSString *name = [NSString stringWithCString:member->name() encoding:NSUTF8StringEncoding]; + RTC_DCHECK(name.length > 0); + RTC_DCHECK(!values[name]); + values[name] = value; + } + } + _values = [values copy]; + } + + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"id = %@, type = %@, timestamp = %.0f, values = %@", + self.id, + self.type, + self.timestamp_us, + self.values]; +} + +@end + +@implementation RTC_OBJC_TYPE (RTCStatisticsReport) + +@synthesize timestamp_us = _timestamp_us; +@synthesize statistics = _statistics; + +- (NSString *)description { + return [NSString + stringWithFormat:@"timestamp = %.0f, statistics = %@", self.timestamp_us, self.statistics]; +} + +@end + +@implementation RTC_OBJC_TYPE (RTCStatisticsReport) (Private) + +- (instancetype)initWithReport : (const webrtc::RTCStatsReport &)report { + if (self = [super init]) { + _timestamp_us = report.timestamp().us(); + + NSMutableDictionary *statisticsById = + [NSMutableDictionary dictionaryWithCapacity:report.size()]; + for (const auto &stat : report) { + RTC_OBJC_TYPE(RTCStatistics) *statistics = + [[RTC_OBJC_TYPE(RTCStatistics) alloc] initWithStatistics:stat]; + statisticsById[statistics.id] = statistics; + } + _statistics = [statisticsById copy]; + } + + return self; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCTracing.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCTracing.h new file mode 100644 index 0000000000..5c66e5a63a --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCTracing.h @@ -0,0 +1,21 @@ +/* + * 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" + +RTC_EXTERN void RTCSetupInternalTracer(void); +/** Starts capture to specified file. Must be a valid writable path. + * Returns YES if capture starts. + */ +RTC_EXTERN BOOL RTCStartInternalCapture(NSString* filePath); +RTC_EXTERN void RTCStopInternalCapture(void); +RTC_EXTERN void RTCShutdownInternalTracer(void); diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCTracing.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCTracing.mm new file mode 100644 index 0000000000..72f9f4da13 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCTracing.mm @@ -0,0 +1,29 @@ +/* + * 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 "RTCTracing.h" + +#include "rtc_base/event_tracer.h" + +void RTCSetupInternalTracer(void) { + rtc::tracing::SetupInternalTracer(); +} + +BOOL RTCStartInternalCapture(NSString *filePath) { + return rtc::tracing::StartInternalCapture(filePath.UTF8String); +} + +void RTCStopInternalCapture(void) { + rtc::tracing::StopInternalCapture(); +} + +void RTCShutdownInternalTracer(void) { + rtc::tracing::ShutdownInternalTracer(); +} diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.h new file mode 100644 index 0000000000..5eff996c4f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 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 "base/RTCVideoCodecInfo.h" + +#include "api/video_codecs/sdp_video_format.h" + +NS_ASSUME_NONNULL_BEGIN + +/* Interface for converting to/from internal C++ formats. */ +@interface RTC_OBJC_TYPE (RTCVideoCodecInfo) +(Private) + + - (instancetype)initWithNativeSdpVideoFormat : (webrtc::SdpVideoFormat)format; +- (webrtc::SdpVideoFormat)nativeSdpVideoFormat; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.mm new file mode 100644 index 0000000000..2eb8d366d2 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoCodecInfo+Private.mm @@ -0,0 +1,38 @@ +/* + * Copyright 2017 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 "RTCVideoCodecInfo+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCVideoCodecInfo) +(Private) + + - (instancetype)initWithNativeSdpVideoFormat : (webrtc::SdpVideoFormat)format { + NSMutableDictionary *params = [NSMutableDictionary dictionary]; + for (auto it = format.parameters.begin(); it != format.parameters.end(); ++it) { + [params setObject:[NSString stringForStdString:it->second] + forKey:[NSString stringForStdString:it->first]]; + } + return [self initWithName:[NSString stringForStdString:format.name] parameters:params]; +} + +- (webrtc::SdpVideoFormat)nativeSdpVideoFormat { + std::map<std::string, std::string> parameters; + for (NSString *paramKey in self.parameters.allKeys) { + std::string key = [NSString stdStringForString:paramKey]; + std::string value = [NSString stdStringForString:self.parameters[paramKey]]; + parameters[key] = value; + } + + return webrtc::SdpVideoFormat([NSString stdStringForString:self.name], parameters); +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoEncoderSettings+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoEncoderSettings+Private.h new file mode 100644 index 0000000000..8323b18dc1 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoEncoderSettings+Private.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 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 "base/RTCVideoEncoderSettings.h" + +#include "modules/video_coding/include/video_codec_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +/* Interfaces for converting to/from internal C++ formats. */ +@interface RTC_OBJC_TYPE (RTCVideoEncoderSettings) +(Private) + + - (instancetype)initWithNativeVideoCodec : (const webrtc::VideoCodec *__nullable)videoCodec; +- (webrtc::VideoCodec)nativeVideoCodec; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoEncoderSettings+Private.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoEncoderSettings+Private.mm new file mode 100644 index 0000000000..dec3a61090 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoEncoderSettings+Private.mm @@ -0,0 +1,52 @@ +/* + * Copyright 2017 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 "RTCVideoEncoderSettings+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCVideoEncoderSettings) +(Private) + + - (instancetype)initWithNativeVideoCodec : (const webrtc::VideoCodec *)videoCodec { + if (self = [super init]) { + if (videoCodec) { + const char *codecName = CodecTypeToPayloadString(videoCodec->codecType); + self.name = [NSString stringWithUTF8String:codecName]; + + self.width = videoCodec->width; + self.height = videoCodec->height; + self.startBitrate = videoCodec->startBitrate; + self.maxBitrate = videoCodec->maxBitrate; + self.minBitrate = videoCodec->minBitrate; + self.maxFramerate = videoCodec->maxFramerate; + self.qpMax = videoCodec->qpMax; + self.mode = (RTCVideoCodecMode)videoCodec->mode; + } + } + + return self; +} + +- (webrtc::VideoCodec)nativeVideoCodec { + webrtc::VideoCodec videoCodec; + videoCodec.width = self.width; + videoCodec.height = self.height; + videoCodec.startBitrate = self.startBitrate; + videoCodec.maxBitrate = self.maxBitrate; + videoCodec.minBitrate = self.minBitrate; + videoCodec.maxBitrate = self.maxBitrate; + videoCodec.qpMax = self.qpMax; + videoCodec.mode = (webrtc::VideoCodecMode)self.mode; + + return videoCodec; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource+Private.h new file mode 100644 index 0000000000..8e475dd21e --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource+Private.h @@ -0,0 +1,51 @@ +/* + * Copyright 2015 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 "RTCVideoSource.h" + +#import "RTCMediaSource+Private.h" + +#include "api/media_stream_interface.h" +#include "rtc_base/thread.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCVideoSource) +() + + /** + * The VideoTrackSourceInterface object passed to this RTCVideoSource during + * construction. + */ + @property(nonatomic, + readonly) rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> nativeVideoSource; + +/** Initialize an RTCVideoSource from a native VideoTrackSourceInterface. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeVideoSource: + (rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource + type:(RTCMediaSourceType)type NS_UNAVAILABLE; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + signalingThread:(rtc::Thread *)signalingThread + workerThread:(rtc::Thread *)workerThread; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + signalingThread:(rtc::Thread *)signalingThread + workerThread:(rtc::Thread *)workerThread + isScreenCast:(BOOL)isScreenCast; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource.h new file mode 100644 index 0000000000..cdef8b89a1 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 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 <Foundation/Foundation.h> + +#import "RTCMacros.h" +#import "RTCMediaSource.h" +#import "RTCVideoCapturer.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT + +@interface RTC_OBJC_TYPE (RTCVideoSource) : RTC_OBJC_TYPE(RTCMediaSource) <RTC_OBJC_TYPE(RTCVideoCapturerDelegate)> + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Calling this function will cause frames to be scaled down to the + * requested resolution. Also, frames will be cropped to match the + * requested aspect ratio, and frames will be dropped to match the + * requested fps. The requested aspect ratio is orientation agnostic and + * will be adjusted to maintain the input orientation, so it doesn't + * matter if e.g. 1280x720 or 720x1280 is requested. + */ +- (void)adaptOutputFormatToWidth:(int)width height:(int)height fps:(int)fps; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource.mm new file mode 100644 index 0000000000..486ca93771 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoSource.mm @@ -0,0 +1,92 @@ +/* + * Copyright 2015 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 "RTCVideoSource+Private.h" + +#include "pc/video_track_source_proxy.h" +#include "rtc_base/checks.h" +#include "sdk/objc/native/src/objc_video_track_source.h" + +static webrtc::ObjCVideoTrackSource *getObjCVideoSource( + const rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> nativeSource) { + webrtc::VideoTrackSourceProxy *proxy_source = + static_cast<webrtc::VideoTrackSourceProxy *>(nativeSource.get()); + return static_cast<webrtc::ObjCVideoTrackSource *>(proxy_source->internal()); +} + +// TODO(magjed): Refactor this class and target ObjCVideoTrackSource only once +// RTCAVFoundationVideoSource is gone. See http://crbug/webrtc/7177 for more +// info. +@implementation RTC_OBJC_TYPE (RTCVideoSource) { + rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> _nativeVideoSource; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeVideoSource: + (rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource { + RTC_DCHECK(factory); + RTC_DCHECK(nativeVideoSource); + if (self = [super initWithFactory:factory + nativeMediaSource:nativeVideoSource + type:RTCMediaSourceTypeVideo]) { + _nativeVideoSource = nativeVideoSource; + } + return self; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource + type:(RTCMediaSourceType)type { + RTC_DCHECK_NOTREACHED(); + return nil; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + signalingThread:(rtc::Thread *)signalingThread + workerThread:(rtc::Thread *)workerThread { + return [self initWithFactory:factory + signalingThread:signalingThread + workerThread:workerThread + isScreenCast:NO]; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + signalingThread:(rtc::Thread *)signalingThread + workerThread:(rtc::Thread *)workerThread + isScreenCast:(BOOL)isScreenCast { + rtc::scoped_refptr<webrtc::ObjCVideoTrackSource> objCVideoTrackSource = + rtc::make_ref_counted<webrtc::ObjCVideoTrackSource>(isScreenCast); + + return [self initWithFactory:factory + nativeVideoSource:webrtc::VideoTrackSourceProxy::Create( + signalingThread, workerThread, objCVideoTrackSource)]; +} + +- (NSString *)description { + NSString *stateString = [[self class] stringForState:self.state]; + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCVideoSource)( %p ): %@", self, stateString]; +} + +- (void)capturer:(RTC_OBJC_TYPE(RTCVideoCapturer) *)capturer + didCaptureVideoFrame:(RTC_OBJC_TYPE(RTCVideoFrame) *)frame { + getObjCVideoSource(_nativeVideoSource)->OnCapturedFrame(frame); +} + +- (void)adaptOutputFormatToWidth:(int)width height:(int)height fps:(int)fps { + getObjCVideoSource(_nativeVideoSource)->OnOutputFormatRequest(width, height, fps); +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource { + return _nativeVideoSource; +} + +@end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack+Private.h new file mode 100644 index 0000000000..f1a8d7e4ed --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack+Private.h @@ -0,0 +1,30 @@ +/* + * Copyright 2015 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 "RTCVideoTrack.h" + +#include "api/media_stream_interface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCVideoTrack) +() + + /** VideoTrackInterface created or passed in at construction. */ + @property(nonatomic, readonly) rtc::scoped_refptr<webrtc::VideoTrackInterface> nativeVideoTrack; + +/** Initialize an RTCVideoTrack with its source and an id. */ +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + source:(RTC_OBJC_TYPE(RTCVideoSource) *)source + trackId:(NSString *)trackId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack.h new file mode 100644 index 0000000000..5382b7169f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack.h @@ -0,0 +1,38 @@ +/* + * Copyright 2015 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 "RTCMediaStreamTrack.h" + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol RTC_OBJC_TYPE +(RTCVideoRenderer); +@class RTC_OBJC_TYPE(RTCPeerConnectionFactory); +@class RTC_OBJC_TYPE(RTCVideoSource); + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCVideoTrack) : RTC_OBJC_TYPE(RTCMediaStreamTrack) + +/** The video source for this video track. */ +@property(nonatomic, readonly) RTC_OBJC_TYPE(RTCVideoSource) *source; + +- (instancetype)init NS_UNAVAILABLE; + +/** Register a renderer that will render all frames received on this track. */ +- (void)addRenderer:(id<RTC_OBJC_TYPE(RTCVideoRenderer)>)renderer; + +/** Deregister a renderer. */ +- (void)removeRenderer:(id<RTC_OBJC_TYPE(RTCVideoRenderer)>)renderer; + +@end + +NS_ASSUME_NONNULL_END diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack.mm new file mode 100644 index 0000000000..d4862e3748 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCVideoTrack.mm @@ -0,0 +1,125 @@ +/* + * Copyright 2015 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 "RTCVideoTrack+Private.h" + +#import "RTCMediaStreamTrack+Private.h" +#import "RTCPeerConnectionFactory+Private.h" +#import "RTCVideoSource+Private.h" +#import "api/RTCVideoRendererAdapter+Private.h" +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCVideoTrack) { + rtc::Thread *_workerThread; + NSMutableArray *_adapters /* accessed on _workerThread */; +} + +@synthesize source = _source; + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + source:(RTC_OBJC_TYPE(RTCVideoSource) *)source + trackId:(NSString *)trackId { + NSParameterAssert(factory); + NSParameterAssert(source); + NSParameterAssert(trackId.length); + std::string nativeId = [NSString stdStringForString:trackId]; + rtc::scoped_refptr<webrtc::VideoTrackInterface> track = + factory.nativeFactory->CreateVideoTrack(nativeId, source.nativeVideoSource.get()); + if (self = [self initWithFactory:factory nativeTrack:track type:RTCMediaStreamTrackTypeVideo]) { + _source = source; + } + return self; +} + +- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory + nativeTrack: + (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeMediaTrack + type:(RTCMediaStreamTrackType)type { + NSParameterAssert(factory); + NSParameterAssert(nativeMediaTrack); + NSParameterAssert(type == RTCMediaStreamTrackTypeVideo); + if (self = [super initWithFactory:factory nativeTrack:nativeMediaTrack type:type]) { + _adapters = [NSMutableArray array]; + _workerThread = factory.workerThread; + } + return self; +} + +- (void)dealloc { + for (RTCVideoRendererAdapter *adapter in _adapters) { + self.nativeVideoTrack->RemoveSink(adapter.nativeVideoRenderer); + } +} + +- (RTC_OBJC_TYPE(RTCVideoSource) *)source { + if (!_source) { + rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source( + self.nativeVideoTrack->GetSource()); + if (source) { + _source = [[RTC_OBJC_TYPE(RTCVideoSource) alloc] initWithFactory:self.factory + nativeVideoSource:source]; + } + } + return _source; +} + +- (void)addRenderer:(id<RTC_OBJC_TYPE(RTCVideoRenderer)>)renderer { + if (!_workerThread->IsCurrent()) { + _workerThread->BlockingCall([renderer, self] { [self addRenderer:renderer]; }); + return; + } + + // Make sure we don't have this renderer yet. + for (RTCVideoRendererAdapter *adapter in _adapters) { + if (adapter.videoRenderer == renderer) { + RTC_LOG(LS_INFO) << "|renderer| is already attached to this track"; + return; + } + } + // Create a wrapper that provides a native pointer for us. + RTCVideoRendererAdapter* adapter = + [[RTCVideoRendererAdapter alloc] initWithNativeRenderer:renderer]; + [_adapters addObject:adapter]; + self.nativeVideoTrack->AddOrUpdateSink(adapter.nativeVideoRenderer, + rtc::VideoSinkWants()); +} + +- (void)removeRenderer:(id<RTC_OBJC_TYPE(RTCVideoRenderer)>)renderer { + if (!_workerThread->IsCurrent()) { + _workerThread->BlockingCall([renderer, self] { [self removeRenderer:renderer]; }); + return; + } + __block NSUInteger indexToRemove = NSNotFound; + [_adapters enumerateObjectsUsingBlock:^(RTCVideoRendererAdapter *adapter, + NSUInteger idx, + BOOL *stop) { + if (adapter.videoRenderer == renderer) { + indexToRemove = idx; + *stop = YES; + } + }]; + if (indexToRemove == NSNotFound) { + RTC_LOG(LS_INFO) << "removeRenderer called with a renderer that has not been previously added"; + return; + } + RTCVideoRendererAdapter *adapterToRemove = + [_adapters objectAtIndex:indexToRemove]; + self.nativeVideoTrack->RemoveSink(adapterToRemove.nativeVideoRenderer); + [_adapters removeObjectAtIndex:indexToRemove]; +} + +#pragma mark - Private + +- (rtc::scoped_refptr<webrtc::VideoTrackInterface>)nativeVideoTrack { + return rtc::scoped_refptr<webrtc::VideoTrackInterface>( + static_cast<webrtc::VideoTrackInterface *>(self.nativeTrack.get())); +} + +@end |