1/*
2 *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import "RTCRtpTransceiver+Private.h"
12
13#import "RTCRtpEncodingParameters+Private.h"
14#import "RTCRtpParameters+Private.h"
15#import "RTCRtpReceiver+Private.h"
16#import "RTCRtpSender+Private.h"
17#import "base/RTCLogging.h"
18#import "helpers/NSString+StdString.h"
19
20@implementation RTC_OBJC_TYPE (RTCRtpTransceiverInit)
21
22@synthesize direction = _direction;
23@synthesize streamIds = _streamIds;
24@synthesize sendEncodings = _sendEncodings;
25
26- (instancetype)init {
27  if (self = [super init]) {
28    _direction = RTCRtpTransceiverDirectionSendRecv;
29  }
30  return self;
31}
32
33- (webrtc::RtpTransceiverInit)nativeInit {
34  webrtc::RtpTransceiverInit init;
35  init.direction =
36      [RTC_OBJC_TYPE(RTCRtpTransceiver) nativeRtpTransceiverDirectionFromDirection:_direction];
37  for (NSString *streamId in _streamIds) {
38    init.stream_ids.push_back([streamId UTF8String]);
39  }
40  for (RTC_OBJC_TYPE(RTCRtpEncodingParameters) * sendEncoding in _sendEncodings) {
41    init.send_encodings.push_back(sendEncoding.nativeParameters);
42  }
43  return init;
44}
45
46@end
47
48@implementation RTC_OBJC_TYPE (RTCRtpTransceiver) {
49  RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
50  rtc::scoped_refptr<webrtc::RtpTransceiverInterface> _nativeRtpTransceiver;
51}
52
53- (RTCRtpMediaType)mediaType {
54  return [RTC_OBJC_TYPE(RTCRtpReceiver)
55      mediaTypeForNativeMediaType:_nativeRtpTransceiver->media_type()];
56}
57
58- (NSString *)mid {
59  if (_nativeRtpTransceiver->mid()) {
60    return [NSString stringForStdString:*_nativeRtpTransceiver->mid()];
61  } else {
62    return nil;
63  }
64}
65
66@synthesize sender = _sender;
67@synthesize receiver = _receiver;
68
69- (BOOL)isStopped {
70  return _nativeRtpTransceiver->stopped();
71}
72
73- (RTCRtpTransceiverDirection)direction {
74  return [RTC_OBJC_TYPE(RTCRtpTransceiver)
75      rtpTransceiverDirectionFromNativeDirection:_nativeRtpTransceiver->direction()];
76}
77
78- (void)setDirection:(RTCRtpTransceiverDirection)direction {
79  _nativeRtpTransceiver->SetDirection(
80      [RTC_OBJC_TYPE(RTCRtpTransceiver) nativeRtpTransceiverDirectionFromDirection:direction]);
81}
82
83- (BOOL)currentDirection:(RTCRtpTransceiverDirection *)currentDirectionOut {
84  if (_nativeRtpTransceiver->current_direction()) {
85    *currentDirectionOut = [RTC_OBJC_TYPE(RTCRtpTransceiver)
86        rtpTransceiverDirectionFromNativeDirection:*_nativeRtpTransceiver->current_direction()];
87    return YES;
88  } else {
89    return NO;
90  }
91}
92
93- (void)stop {
94  _nativeRtpTransceiver->Stop();
95}
96
97- (NSString *)description {
98  return [NSString
99      stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpTransceiver) {\n  sender: %@\n  receiver: %@\n}",
100                       _sender,
101                       _receiver];
102}
103
104- (BOOL)isEqual:(id)object {
105  if (self == object) {
106    return YES;
107  }
108  if (object == nil) {
109    return NO;
110  }
111  if (![object isMemberOfClass:[self class]]) {
112    return NO;
113  }
114  RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver = (RTC_OBJC_TYPE(RTCRtpTransceiver) *)object;
115  return _nativeRtpTransceiver == transceiver.nativeRtpTransceiver;
116}
117
118- (NSUInteger)hash {
119  return (NSUInteger)_nativeRtpTransceiver.get();
120}
121
122#pragma mark - Private
123
124- (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver {
125  return _nativeRtpTransceiver;
126}
127
128- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
129           nativeRtpTransceiver:
130               (rtc::scoped_refptr<webrtc::RtpTransceiverInterface>)nativeRtpTransceiver {
131  NSParameterAssert(factory);
132  NSParameterAssert(nativeRtpTransceiver);
133  if (self = [super init]) {
134    _factory = factory;
135    _nativeRtpTransceiver = nativeRtpTransceiver;
136    _sender = [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:_factory
137                                                   nativeRtpSender:nativeRtpTransceiver->sender()];
138    _receiver =
139        [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:_factory
140                                             nativeRtpReceiver:nativeRtpTransceiver->receiver()];
141    RTCLogInfo(
142        @"RTC_OBJC_TYPE(RTCRtpTransceiver)(%p): created transceiver: %@", self, self.description);
143  }
144  return self;
145}
146
147+ (webrtc::RtpTransceiverDirection)nativeRtpTransceiverDirectionFromDirection:
148        (RTCRtpTransceiverDirection)direction {
149  switch (direction) {
150    case RTCRtpTransceiverDirectionSendRecv:
151      return webrtc::RtpTransceiverDirection::kSendRecv;
152    case RTCRtpTransceiverDirectionSendOnly:
153      return webrtc::RtpTransceiverDirection::kSendOnly;
154    case RTCRtpTransceiverDirectionRecvOnly:
155      return webrtc::RtpTransceiverDirection::kRecvOnly;
156    case RTCRtpTransceiverDirectionInactive:
157      return webrtc::RtpTransceiverDirection::kInactive;
158    case RTCRtpTransceiverDirectionStopped:
159      return webrtc::RtpTransceiverDirection::kStopped;
160  }
161}
162
163+ (RTCRtpTransceiverDirection)rtpTransceiverDirectionFromNativeDirection:
164        (webrtc::RtpTransceiverDirection)nativeDirection {
165  switch (nativeDirection) {
166    case webrtc::RtpTransceiverDirection::kSendRecv:
167      return RTCRtpTransceiverDirectionSendRecv;
168    case webrtc::RtpTransceiverDirection::kSendOnly:
169      return RTCRtpTransceiverDirectionSendOnly;
170    case webrtc::RtpTransceiverDirection::kRecvOnly:
171      return RTCRtpTransceiverDirectionRecvOnly;
172    case webrtc::RtpTransceiverDirection::kInactive:
173      return RTCRtpTransceiverDirectionInactive;
174    case webrtc::RtpTransceiverDirection::kStopped:
175      return RTCRtpTransceiverDirectionStopped;
176  }
177}
178
179@end
180