Add new PeerConnection APIs to the ObjC SDK
This CL adds wrappers for the following PeerConnection native
APIs to the Objective C API:
- SdpSemantics enum added to the RTCConfiguration
- RTCRtpTransceiver
- RTCPeerConnection.addTrack
- RTCPeerConnection.removeTrack
- RTCPeerConnection.addTransceiver
- RTCPeerConnection.transceivers
Bug: webrtc:8870
Change-Id: I9449df9742a59e90894712dc7749ca30b569d94b
Reviewed-on: https://webrtc-review.googlesource.com/54780
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22214}
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration+Private.h
index d9a9916..c572d63 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration+Private.h
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration+Private.h
@@ -58,6 +58,12 @@
+ (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.
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration.mm
index 92b334b..ceaac86 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCConfiguration.mm
@@ -43,6 +43,7 @@
_shouldPresumeWritableWhenFullyRelayed;
@synthesize iceCheckMinInterval = _iceCheckMinInterval;
@synthesize iceRegatherIntervalRange = _iceRegatherIntervalRange;
+@synthesize sdpSemantics = _sdpSemantics;
@synthesize turnCustomizer = _turnCustomizer;
- (instancetype)init {
@@ -96,35 +97,38 @@
_iceRegatherIntervalRange =
[[RTCIntervalRange alloc] initWithNativeIntervalRange:nativeIntervalRange];
}
+ _sdpSemantics = [[self class] sdpSemanticsForNativeSdpSemantics:config.sdp_semantics];
_turnCustomizer = config.turn_customizer;
}
return self;
}
- (NSString *)description {
- static NSString *formatString = @"RTCConfiguration: "
- @"{\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%@\n%@\n%d\n%d\n}\n";
+ static NSString *formatString =
+ @"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%@\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],
- _audioJitterBufferMaxPackets,
- _audioJitterBufferFastAccelerate,
- _iceConnectionReceivingTimeout,
- _iceBackupCandidatePairPingInterval,
- _iceCandidatePoolSize,
- _shouldPruneTurnPorts,
- _shouldPresumeWritableWhenFullyRelayed,
- _iceCheckMinInterval,
- _iceRegatherIntervalRange,
- _disableLinkLocalNetworks,
- _maxIPv6Networks];
+ 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,
+ _iceCheckMinInterval,
+ _iceRegatherIntervalRange,
+ _disableLinkLocalNetworks,
+ _maxIPv6Networks];
}
#pragma mark - Private
@@ -186,6 +190,7 @@
nativeConfig->ice_regather_interval_range =
rtc::Optional<rtc::IntervalRange>(*nativeIntervalRange);
}
+ nativeConfig->sdp_semantics = [[self class] nativeSdpSemanticsForSdpSemantics:_sdpSemantics];
if (_turnCustomizer) {
nativeConfig->turn_customizer = _turnCustomizer;
}
@@ -397,4 +402,37 @@
}
}
++ (webrtc::SdpSemantics)nativeSdpSemanticsForSdpSemantics:(RTCSdpSemantics)sdpSemantics {
+ switch (sdpSemantics) {
+ case RTCSdpSemanticsDefault:
+ return webrtc::SdpSemantics::kDefault;
+ case RTCSdpSemanticsPlanB:
+ return webrtc::SdpSemantics::kPlanB;
+ case RTCSdpSemanticsUnifiedPlan:
+ return webrtc::SdpSemantics::kUnifiedPlan;
+ }
+}
+
++ (RTCSdpSemantics)sdpSemanticsForNativeSdpSemantics:(webrtc::SdpSemantics)sdpSemantics {
+ switch (sdpSemantics) {
+ case webrtc::SdpSemantics::kDefault:
+ return RTCSdpSemanticsDefault;
+ case webrtc::SdpSemantics::kPlanB:
+ return RTCSdpSemanticsPlanB;
+ case webrtc::SdpSemantics::kUnifiedPlan:
+ return RTCSdpSemanticsUnifiedPlan;
+ }
+}
+
++ (NSString *)stringForSdpSemantics:(RTCSdpSemantics)sdpSemantics {
+ switch (sdpSemantics) {
+ case RTCSdpSemanticsDefault:
+ return @"DEFAULT";
+ case RTCSdpSemanticsPlanB:
+ return @"PLAN_B";
+ case RTCSdpSemanticsUnifiedPlan:
+ return @"UNIFIED_PLAN";
+ }
+}
+
@end
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h
index e1017f5..4b46dea 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h
@@ -33,6 +33,8 @@
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;
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
index 6376ea0..08b9047 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
@@ -17,10 +17,12 @@
#import "RTCLegacyStatsReport+Private.h"
#import "RTCMediaConstraints+Private.h"
#import "RTCMediaStream+Private.h"
+#import "RTCMediaStreamTrack+Private.h"
#import "RTCPeerConnection+Native.h"
#import "RTCPeerConnectionFactory+Private.h"
#import "RTCRtpReceiver+Private.h"
#import "RTCRtpSender+Private.h"
+#import "RTCRtpTransceiver+Private.h"
#import "RTCSessionDescription+Private.h"
#import "WebRTC/RTCLogging.h"
@@ -144,6 +146,18 @@
didRemoveStream:mediaStream];
}
+void PeerConnectionDelegateAdapter::OnTrack(
+ rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
+ RTCRtpTransceiver *transceiver =
+ [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
+ RTCPeerConnection *peer_connection = peer_connection_;
+ 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) {
RTCDataChannel *dataChannel =
@@ -334,6 +348,65 @@
[_localStreams removeObject:stream];
}
+- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track
+ streamLabels:(NSArray<NSString *> *)streamLabels {
+ std::vector<std::string> nativeStreamLabels;
+ for (NSString *label in streamLabels) {
+ nativeStreamLabels.push_back([label UTF8String]);
+ }
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
+ _peerConnection->AddTrack(track.nativeTrack, nativeStreamLabels);
+ if (!nativeSenderOrError.ok()) {
+ RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
+ return nil;
+ }
+ return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
+}
+
+- (BOOL)removeTrack:(RTCRtpSender *)sender {
+ bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
+ if (!result) {
+ RTCLogError(@"Failed to remote track %@", sender);
+ }
+ return result;
+}
+
+- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
+ return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
+}
+
+- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
+ init:(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
+ [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
+}
+
+- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
+ return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
+}
+
+- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
+ init:(RTCRtpTransceiverInit *)init {
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
+ _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
+ init.nativeInit);
+ if (!nativeTransceiverOrError.ok()) {
+ RTCLogError(@"Failed to add transceiver %@: %s",
+ [RTCRtpReceiver stringForMediaType:mediaType],
+ nativeTransceiverOrError.error().message());
+ return nil;
+ }
+ return
+ [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
+}
+
- (void)offerForConstraints:(RTCMediaConstraints *)constraints
completionHandler:
(void (^)(RTCSessionDescription *sessionDescription,
@@ -451,6 +524,18 @@
return receivers;
}
+- (NSArray<RTCRtpTransceiver *> *)transceivers {
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
+ _peerConnection->GetTransceivers());
+ NSMutableArray *transceivers = [[NSMutableArray alloc] init];
+ for (auto nativeTransceiver : nativeTransceivers) {
+ RTCRtpTransceiver *transceiver =
+ [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
+ [transceivers addObject:transceiver];
+ }
+ return transceivers;
+}
+
#pragma mark - Private
+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver+Private.h
index 9873811..63bdfa3 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver+Private.h
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver+Private.h
@@ -40,6 +40,10 @@
+ (RTCRtpMediaType)mediaTypeForNativeMediaType:(cricket::MediaType)nativeMediaType;
++ (cricket::MediaType)nativeMediaTypeForMediaType:(RTCRtpMediaType)mediaType;
+
++ (NSString*)stringForMediaType:(RTCRtpMediaType)mediaType;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver.mm
index 12f3ab6..b1f5be9 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpReceiver.mm
@@ -126,4 +126,26 @@
}
}
++ (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;
+ }
+}
+
++ (NSString *)stringForMediaType:(RTCRtpMediaType)mediaType {
+ switch (mediaType) {
+ case RTCRtpMediaTypeAudio:
+ return @"AUDIO";
+ case RTCRtpMediaTypeVideo:
+ return @"VIDEO";
+ case RTCRtpMediaTypeData:
+ return @"DATA";
+ }
+}
+
@end
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver+Private.h
new file mode 100644
index 0000000..cc1f4fe
--- /dev/null
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver+Private.h
@@ -0,0 +1,41 @@
+/*
+ * 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 "WebRTC/RTCRtpTransceiver.h"
+
+#include "api/rtptransceiverinterface.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCRtpTransceiverInit ()
+
+@property(nonatomic, readonly) webrtc::RtpTransceiverInit nativeInit;
+
+@end
+
+@interface RTCRtpTransceiver ()
+
+@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::RtpTransceiverInterface>
+ nativeRtpTransceiver;
+
+/** Initialize an RTCRtpTransceiver with a native RtpTransceiverInterface. */
+- (instancetype)initWithNativeRtpTransceiver:
+ (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/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver.mm
new file mode 100644
index 0000000..ce182bc
--- /dev/null
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver.mm
@@ -0,0 +1,163 @@
+/*
+ * 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 "NSString+StdString.h"
+#import "RTCRtpEncodingParameters+Private.h"
+#import "RTCRtpParameters+Private.h"
+#import "RTCRtpReceiver+Private.h"
+#import "RTCRtpSender+Private.h"
+#import "WebRTC/RTCLogging.h"
+
+@implementation RTCRtpTransceiverInit
+
+@synthesize direction = _direction;
+@synthesize streamLabels = _streamLabels;
+@synthesize sendEncodings = _sendEncodings;
+
+- (instancetype)init {
+ if (self = [super init]) {
+ _direction = RTCRtpTransceiverDirectionSendRecv;
+ }
+ return self;
+}
+
+- (webrtc::RtpTransceiverInit)nativeInit {
+ webrtc::RtpTransceiverInit init;
+ init.direction = [RTCRtpTransceiver nativeRtpTransceiverDirectionFromDirection:_direction];
+ for (NSString *streamLabel in _streamLabels) {
+ init.stream_labels.push_back([streamLabel UTF8String]);
+ }
+ for (RTCRtpEncodingParameters *sendEncoding in _sendEncodings) {
+ init.send_encodings.push_back(sendEncoding.nativeParameters);
+ }
+ return init;
+}
+
+@end
+
+@implementation RTCRtpTransceiver {
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> _nativeRtpTransceiver;
+}
+
+- (RTCRtpMediaType)mediaType {
+ return [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 [RTCRtpTransceiver
+ rtpTransceiverDirectionFromNativeDirection:_nativeRtpTransceiver->direction()];
+}
+
+- (void)setDirection:(RTCRtpTransceiverDirection)direction {
+ _nativeRtpTransceiver->SetDirection(
+ [RTCRtpTransceiver nativeRtpTransceiverDirectionFromDirection:direction]);
+}
+
+- (BOOL)currentDirection:(RTCRtpTransceiverDirection *)currentDirectionOut {
+ if (_nativeRtpTransceiver->current_direction()) {
+ *currentDirectionOut = [RTCRtpTransceiver
+ rtpTransceiverDirectionFromNativeDirection:*_nativeRtpTransceiver->current_direction()];
+ return YES;
+ } else {
+ return NO;
+ }
+}
+
+- (void)stop {
+ _nativeRtpTransceiver->Stop();
+}
+
+- (NSString *)description {
+ return [NSString
+ stringWithFormat:@"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;
+ }
+ RTCRtpTransceiver *transceiver = (RTCRtpTransceiver *)object;
+ return _nativeRtpTransceiver == transceiver.nativeRtpTransceiver;
+}
+
+- (NSUInteger)hash {
+ return (NSUInteger)_nativeRtpTransceiver.get();
+}
+
+#pragma mark - Private
+
+- (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver {
+ return _nativeRtpTransceiver;
+}
+
+- (instancetype)initWithNativeRtpTransceiver:
+ (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver {
+ NSParameterAssert(nativeRtpTransceiver);
+ if (self = [super init]) {
+ _nativeRtpTransceiver = nativeRtpTransceiver;
+ _sender = [[RTCRtpSender alloc] initWithNativeRtpSender:nativeRtpTransceiver->sender()];
+ _receiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeRtpTransceiver->receiver()];
+ RTCLogInfo(@"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;
+ }
+}
+
++ (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;
+ }
+}
+
+@end