blob: 9b2462e2774ecf0669ed88fd10e43521f39efd89 [file] [log] [blame]
hjonf396f602016-02-11 16:19:06 -08001/*
2 * Copyright 2015 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
tkchin9eeb6242016-04-27 01:54:20 -070011#import "RTCPeerConnection+Private.h"
12
13#import "NSString+StdString.h"
14#import "RTCConfiguration+Private.h"
15#import "RTCDataChannel+Private.h"
16#import "RTCIceCandidate+Private.h"
hbosbd3dda62016-09-09 01:36:28 -070017#import "RTCLegacyStatsReport+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070018#import "RTCMediaConstraints+Private.h"
19#import "RTCMediaStream+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080020#import "RTCMediaStreamTrack+Private.h"
Magnus Jedvert0af86d12017-10-28 16:26:55 +020021#import "RTCPeerConnection+Native.h"
tkchin9eeb6242016-04-27 01:54:20 -070022#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070023#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070024#import "RTCRtpSender+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080025#import "RTCRtpTransceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070026#import "RTCSessionDescription+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070027#import "WebRTC/RTCLogging.h"
hjonf396f602016-02-11 16:19:06 -080028
kwibergbfefb032016-05-01 14:53:46 -070029#include <memory>
30
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "api/jsepicecandidate.h"
32#include "rtc_base/checks.h"
hjonf396f602016-02-11 16:19:06 -080033
hjonf396f602016-02-11 16:19:06 -080034NSString * const kRTCPeerConnectionErrorDomain =
35 @"org.webrtc.RTCPeerConnection";
36int const kRTCPeerConnnectionSessionDescriptionError = -1;
37
38namespace webrtc {
39
40class CreateSessionDescriptionObserverAdapter
41 : public CreateSessionDescriptionObserver {
42 public:
43 CreateSessionDescriptionObserverAdapter(
44 void (^completionHandler)(RTCSessionDescription *sessionDescription,
45 NSError *error)) {
46 completion_handler_ = completionHandler;
47 }
48
49 ~CreateSessionDescriptionObserverAdapter() {
50 completion_handler_ = nil;
51 }
52
53 void OnSuccess(SessionDescriptionInterface *desc) override {
54 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070055 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
56 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080057 RTCSessionDescription* session =
58 [[RTCSessionDescription alloc] initWithNativeDescription:
59 description.get()];
60 completion_handler_(session, nil);
61 completion_handler_ = nil;
62 }
63
Harald Alvestrand73771a82018-05-24 10:53:49 +020064 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080065 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +020066 // TODO(hta): Add handling of error.type()
67 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -080068 NSError* err =
69 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
70 code:kRTCPeerConnnectionSessionDescriptionError
71 userInfo:@{ NSLocalizedDescriptionKey : str }];
72 completion_handler_(nil, err);
73 completion_handler_ = nil;
74 }
75
76 private:
77 void (^completion_handler_)
78 (RTCSessionDescription *sessionDescription, NSError *error);
79};
80
81class SetSessionDescriptionObserverAdapter :
82 public SetSessionDescriptionObserver {
83 public:
84 SetSessionDescriptionObserverAdapter(void (^completionHandler)
85 (NSError *error)) {
86 completion_handler_ = completionHandler;
87 }
88
89 ~SetSessionDescriptionObserverAdapter() {
90 completion_handler_ = nil;
91 }
92
93 void OnSuccess() override {
94 RTC_DCHECK(completion_handler_);
95 completion_handler_(nil);
96 completion_handler_ = nil;
97 }
98
Harald Alvestrand73771a82018-05-24 10:53:49 +020099 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -0800100 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +0200101 // TODO(hta): Add handling of error.type()
102 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -0800103 NSError* err =
104 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
105 code:kRTCPeerConnnectionSessionDescriptionError
106 userInfo:@{ NSLocalizedDescriptionKey : str }];
107 completion_handler_(err);
108 completion_handler_ = nil;
109 }
110
111 private:
112 void (^completion_handler_)(NSError *error);
113};
114
115PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
116 RTCPeerConnection *peerConnection) {
117 peer_connection_ = peerConnection;
118}
119
120PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
121 peer_connection_ = nil;
122}
123
124void PeerConnectionDelegateAdapter::OnSignalingChange(
125 PeerConnectionInterface::SignalingState new_state) {
126 RTCSignalingState state =
127 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
128 RTCPeerConnection *peer_connection = peer_connection_;
129 [peer_connection.delegate peerConnection:peer_connection
130 didChangeSignalingState:state];
131}
132
133void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700134 rtc::scoped_refptr<MediaStreamInterface> stream) {
magjed63bafd62017-02-27 07:04:25 -0800135 RTCMediaStream *mediaStream =
136 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800137 RTCPeerConnection *peer_connection = peer_connection_;
138 [peer_connection.delegate peerConnection:peer_connection
139 didAddStream:mediaStream];
140}
141
142void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700143 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800144 RTCMediaStream *mediaStream =
145 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
146 RTCPeerConnection *peer_connection = peer_connection_;
147 [peer_connection.delegate peerConnection:peer_connection
148 didRemoveStream:mediaStream];
149}
150
Steve Anton8cb344a2018-02-27 15:34:53 -0800151void PeerConnectionDelegateAdapter::OnTrack(
152 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
153 RTCRtpTransceiver *transceiver =
154 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
155 RTCPeerConnection *peer_connection = peer_connection_;
156 if ([peer_connection.delegate
157 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
158 [peer_connection.delegate peerConnection:peer_connection
159 didStartReceivingOnTransceiver:transceiver];
160 }
161}
162
hjonf396f602016-02-11 16:19:06 -0800163void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700164 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800165 RTCDataChannel *dataChannel =
166 [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel];
167 RTCPeerConnection *peer_connection = peer_connection_;
168 [peer_connection.delegate peerConnection:peer_connection
169 didOpenDataChannel:dataChannel];
170}
171
172void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
173 RTCPeerConnection *peer_connection = peer_connection_;
174 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
175}
176
177void PeerConnectionDelegateAdapter::OnIceConnectionChange(
178 PeerConnectionInterface::IceConnectionState new_state) {
179 RTCIceConnectionState state =
180 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
181 RTCPeerConnection *peer_connection = peer_connection_;
182 [peer_connection.delegate peerConnection:peer_connection
183 didChangeIceConnectionState:state];
184}
185
186void PeerConnectionDelegateAdapter::OnIceGatheringChange(
187 PeerConnectionInterface::IceGatheringState new_state) {
188 RTCIceGatheringState state =
189 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
190 RTCPeerConnection *peer_connection = peer_connection_;
191 [peer_connection.delegate peerConnection:peer_connection
192 didChangeIceGatheringState:state];
193}
194
195void PeerConnectionDelegateAdapter::OnIceCandidate(
196 const IceCandidateInterface *candidate) {
197 RTCIceCandidate *iceCandidate =
198 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
199 RTCPeerConnection *peer_connection = peer_connection_;
200 [peer_connection.delegate peerConnection:peer_connection
201 didGenerateIceCandidate:iceCandidate];
202}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700203
204void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
205 const std::vector<cricket::Candidate>& candidates) {
206 NSMutableArray* ice_candidates =
207 [NSMutableArray arrayWithCapacity:candidates.size()];
208 for (const auto& candidate : candidates) {
209 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
210 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
211 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
212 initWithNativeCandidate:candidate_wrapper.get()];
213 [ice_candidates addObject:ice_candidate];
214 }
215 RTCPeerConnection* peer_connection = peer_connection_;
216 [peer_connection.delegate peerConnection:peer_connection
217 didRemoveIceCandidates:ice_candidates];
218}
219
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300220void PeerConnectionDelegateAdapter::OnAddTrack(
221 rtc::scoped_refptr<RtpReceiverInterface> receiver,
222 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
223 RTCPeerConnection *peer_connection = peer_connection_;
224 if ([peer_connection.delegate
225 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
226 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
227 for (const auto& nativeStream : streams) {
228 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithNativeMediaStream:nativeStream];
229 [mediaStreams addObject:mediaStream];
230 }
231 RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:receiver];
232
233 [peer_connection.delegate peerConnection:peer_connection
234 didAddReceiver:rtpReceiver
235 streams:mediaStreams];
236 }
237}
238
hjonf396f602016-02-11 16:19:06 -0800239} // namespace webrtc
240
241
242@implementation RTCPeerConnection {
vopatop.skam96b6b832016-08-18 14:21:20 -0700243 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700244 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800245 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800246 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700247 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800248}
249
250@synthesize delegate = _delegate;
251
252- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
253 configuration:(RTCConfiguration *)configuration
254 constraints:(RTCMediaConstraints *)constraints
255 delegate:(id<RTCPeerConnectionDelegate>)delegate {
256 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200257 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700258 [configuration createNativeConfiguration]);
259 if (!config) {
260 return nil;
261 }
hjonf396f602016-02-11 16:19:06 -0800262 if (self = [super init]) {
263 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800264 _nativeConstraints = constraints.nativeConstraints;
265 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
266 config.get());
hjonf396f602016-02-11 16:19:06 -0800267 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700268 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700269 nullptr,
270 nullptr,
271 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700272 if (!_peerConnection) {
273 return nil;
274 }
hjonf396f602016-02-11 16:19:06 -0800275 _localStreams = [[NSMutableArray alloc] init];
276 _delegate = delegate;
277 }
278 return self;
279}
280
vopatop.skam96b6b832016-08-18 14:21:20 -0700281- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800282 return [_localStreams copy];
283}
284
285- (RTCSessionDescription *)localDescription {
286 const webrtc::SessionDescriptionInterface *description =
287 _peerConnection->local_description();
288 return description ?
289 [[RTCSessionDescription alloc] initWithNativeDescription:description]
290 : nil;
291}
292
293- (RTCSessionDescription *)remoteDescription {
294 const webrtc::SessionDescriptionInterface *description =
295 _peerConnection->remote_description();
296 return description ?
297 [[RTCSessionDescription alloc] initWithNativeDescription:description]
298 : nil;
299}
300
301- (RTCSignalingState)signalingState {
302 return [[self class]
303 signalingStateForNativeState:_peerConnection->signaling_state()];
304}
305
306- (RTCIceConnectionState)iceConnectionState {
307 return [[self class] iceConnectionStateForNativeState:
308 _peerConnection->ice_connection_state()];
309}
310
311- (RTCIceGatheringState)iceGatheringState {
312 return [[self class] iceGatheringStateForNativeState:
313 _peerConnection->ice_gathering_state()];
314}
315
tkchinaac3eb22016-03-09 21:49:40 -0800316- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200317 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700318 [configuration createNativeConfiguration]);
319 if (!config) {
320 return NO;
321 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800322 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
323 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200324 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800325}
326
jtteh4eeb5372017-04-03 15:06:37 -0700327- (RTCConfiguration *)configuration {
328 webrtc::PeerConnectionInterface::RTCConfiguration config =
329 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700330 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700331}
332
hjonf396f602016-02-11 16:19:06 -0800333- (void)close {
334 _peerConnection->Close();
335}
336
337- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700338 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800339 candidate.nativeCandidate);
340 _peerConnection->AddIceCandidate(iceCandidate.get());
341}
342
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700343- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
344 std::vector<cricket::Candidate> candidates;
345 for (RTCIceCandidate *iceCandidate in iceCandidates) {
346 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
347 iceCandidate.nativeCandidate);
348 if (candidate) {
349 candidates.push_back(candidate->candidate());
350 // Need to fill the transport name from the sdp_mid.
351 candidates.back().set_transport_name(candidate->sdp_mid());
352 }
353 }
354 if (!candidates.empty()) {
355 _peerConnection->RemoveIceCandidates(candidates);
356 }
357}
358
hjonf396f602016-02-11 16:19:06 -0800359- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800360 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800361 RTCLogError(@"Failed to add stream: %@", stream);
362 return;
363 }
364 [_localStreams addObject:stream];
365}
366
367- (void)removeStream:(RTCMediaStream *)stream {
368 _peerConnection->RemoveStream(stream.nativeMediaStream);
369 [_localStreams removeObject:stream];
370}
371
Seth Hampson513449e2018-03-06 09:35:56 -0800372- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
373 std::vector<std::string> nativeStreamIds;
374 for (NSString *streamId in streamIds) {
375 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800376 }
377 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800378 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800379 if (!nativeSenderOrError.ok()) {
380 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
381 return nil;
382 }
383 return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
384}
385
386- (BOOL)removeTrack:(RTCRtpSender *)sender {
387 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
388 if (!result) {
389 RTCLogError(@"Failed to remote track %@", sender);
390 }
391 return result;
392}
393
394- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
395 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
396}
397
398- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
399 init:(RTCRtpTransceiverInit *)init {
400 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
401 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
402 if (!nativeTransceiverOrError.ok()) {
403 RTCLogError(
404 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
405 return nil;
406 }
407 return
408 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
409}
410
411- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
412 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
413}
414
415- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
416 init:(RTCRtpTransceiverInit *)init {
417 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
418 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
419 init.nativeInit);
420 if (!nativeTransceiverOrError.ok()) {
421 RTCLogError(@"Failed to add transceiver %@: %s",
422 [RTCRtpReceiver stringForMediaType:mediaType],
423 nativeTransceiverOrError.error().message());
424 return nil;
425 }
426 return
427 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
428}
429
hjonf396f602016-02-11 16:19:06 -0800430- (void)offerForConstraints:(RTCMediaConstraints *)constraints
431 completionHandler:
432 (void (^)(RTCSessionDescription *sessionDescription,
433 NSError *error))completionHandler {
434 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
435 observer(new rtc::RefCountedObject
436 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
437 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
438}
439
440- (void)answerForConstraints:(RTCMediaConstraints *)constraints
441 completionHandler:
442 (void (^)(RTCSessionDescription *sessionDescription,
443 NSError *error))completionHandler {
444 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
445 observer(new rtc::RefCountedObject
446 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
447 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
448}
449
450- (void)setLocalDescription:(RTCSessionDescription *)sdp
451 completionHandler:(void (^)(NSError *error))completionHandler {
452 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
453 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
454 completionHandler));
455 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
456}
457
458- (void)setRemoteDescription:(RTCSessionDescription *)sdp
459 completionHandler:(void (^)(NSError *error))completionHandler {
460 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
461 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
462 completionHandler));
463 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
464}
465
zstein8b476172017-09-05 14:43:03 -0700466- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
467 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
468 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700469 webrtc::PeerConnectionInterface::BitrateParameters params;
470 if (minBitrateBps != nil) {
471 params.min_bitrate_bps = rtc::Optional<int>(minBitrateBps.intValue);
472 }
473 if (currentBitrateBps != nil) {
474 params.current_bitrate_bps = rtc::Optional<int>(currentBitrateBps.intValue);
475 }
476 if (maxBitrateBps != nil) {
477 params.max_bitrate_bps = rtc::Optional<int>(maxBitrateBps.intValue);
478 }
479 return _peerConnection->SetBitrate(params).ok();
480}
481
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200482- (void)setBitrateAllocationStrategy:
483 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
484 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
485}
486
ivoc14d5dbe2016-07-04 07:06:55 -0700487- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
488 maxSizeInBytes:(int64_t)maxSizeInBytes {
489 RTC_DCHECK(filePath.length);
490 RTC_DCHECK_GT(maxSizeInBytes, 0);
491 RTC_DCHECK(!_hasStartedRtcEventLog);
492 if (_hasStartedRtcEventLog) {
493 RTCLogError(@"Event logging already started.");
494 return NO;
495 }
496 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
497 S_IRUSR | S_IWUSR);
498 if (fd < 0) {
499 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
500 return NO;
501 }
502 _hasStartedRtcEventLog =
503 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
504 return _hasStartedRtcEventLog;
505}
506
507- (void)stopRtcEventLog {
508 _peerConnection->StopRtcEventLog();
509 _hasStartedRtcEventLog = NO;
510}
511
skvladf3569c82016-04-29 15:30:16 -0700512- (RTCRtpSender *)senderWithKind:(NSString *)kind
513 streamId:(NSString *)streamId {
514 std::string nativeKind = [NSString stdStringForString:kind];
515 std::string nativeStreamId = [NSString stdStringForString:streamId];
516 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
517 _peerConnection->CreateSender(nativeKind, nativeStreamId));
518 return nativeSender ?
519 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
520 : nil;
521}
522
skvlad79b4b872016-04-08 17:28:55 -0700523- (NSArray<RTCRtpSender *> *)senders {
524 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
525 _peerConnection->GetSenders());
526 NSMutableArray *senders = [[NSMutableArray alloc] init];
527 for (const auto &nativeSender : nativeSenders) {
528 RTCRtpSender *sender =
529 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
530 [senders addObject:sender];
531 }
532 return senders;
533}
534
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700535- (NSArray<RTCRtpReceiver *> *)receivers {
536 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
537 _peerConnection->GetReceivers());
538 NSMutableArray *receivers = [[NSMutableArray alloc] init];
539 for (const auto &nativeReceiver : nativeReceivers) {
540 RTCRtpReceiver *receiver =
541 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
542 [receivers addObject:receiver];
543 }
544 return receivers;
545}
546
Steve Anton8cb344a2018-02-27 15:34:53 -0800547- (NSArray<RTCRtpTransceiver *> *)transceivers {
548 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
549 _peerConnection->GetTransceivers());
550 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
551 for (auto nativeTransceiver : nativeTransceivers) {
552 RTCRtpTransceiver *transceiver =
553 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
554 [transceivers addObject:transceiver];
555 }
556 return transceivers;
557}
558
hjonf396f602016-02-11 16:19:06 -0800559#pragma mark - Private
560
561+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
562 (RTCSignalingState)state {
563 switch (state) {
564 case RTCSignalingStateStable:
565 return webrtc::PeerConnectionInterface::kStable;
566 case RTCSignalingStateHaveLocalOffer:
567 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
568 case RTCSignalingStateHaveLocalPrAnswer:
569 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
570 case RTCSignalingStateHaveRemoteOffer:
571 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
572 case RTCSignalingStateHaveRemotePrAnswer:
573 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
574 case RTCSignalingStateClosed:
575 return webrtc::PeerConnectionInterface::kClosed;
576 }
577}
578
579+ (RTCSignalingState)signalingStateForNativeState:
580 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
581 switch (nativeState) {
582 case webrtc::PeerConnectionInterface::kStable:
583 return RTCSignalingStateStable;
584 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
585 return RTCSignalingStateHaveLocalOffer;
586 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
587 return RTCSignalingStateHaveLocalPrAnswer;
588 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
589 return RTCSignalingStateHaveRemoteOffer;
590 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
591 return RTCSignalingStateHaveRemotePrAnswer;
592 case webrtc::PeerConnectionInterface::kClosed:
593 return RTCSignalingStateClosed;
594 }
595}
596
597+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
598 switch (state) {
599 case RTCSignalingStateStable:
600 return @"STABLE";
601 case RTCSignalingStateHaveLocalOffer:
602 return @"HAVE_LOCAL_OFFER";
603 case RTCSignalingStateHaveLocalPrAnswer:
604 return @"HAVE_LOCAL_PRANSWER";
605 case RTCSignalingStateHaveRemoteOffer:
606 return @"HAVE_REMOTE_OFFER";
607 case RTCSignalingStateHaveRemotePrAnswer:
608 return @"HAVE_REMOTE_PRANSWER";
609 case RTCSignalingStateClosed:
610 return @"CLOSED";
611 }
612}
613
614+ (webrtc::PeerConnectionInterface::IceConnectionState)
615 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
616 switch (state) {
617 case RTCIceConnectionStateNew:
618 return webrtc::PeerConnectionInterface::kIceConnectionNew;
619 case RTCIceConnectionStateChecking:
620 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
621 case RTCIceConnectionStateConnected:
622 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
623 case RTCIceConnectionStateCompleted:
624 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
625 case RTCIceConnectionStateFailed:
626 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
627 case RTCIceConnectionStateDisconnected:
628 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
629 case RTCIceConnectionStateClosed:
630 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700631 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800632 return webrtc::PeerConnectionInterface::kIceConnectionMax;
633 }
634}
635
636+ (RTCIceConnectionState)iceConnectionStateForNativeState:
637 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
638 switch (nativeState) {
639 case webrtc::PeerConnectionInterface::kIceConnectionNew:
640 return RTCIceConnectionStateNew;
641 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
642 return RTCIceConnectionStateChecking;
643 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
644 return RTCIceConnectionStateConnected;
645 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
646 return RTCIceConnectionStateCompleted;
647 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
648 return RTCIceConnectionStateFailed;
649 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
650 return RTCIceConnectionStateDisconnected;
651 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
652 return RTCIceConnectionStateClosed;
653 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700654 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800655 }
656}
657
658+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
659 switch (state) {
660 case RTCIceConnectionStateNew:
661 return @"NEW";
662 case RTCIceConnectionStateChecking:
663 return @"CHECKING";
664 case RTCIceConnectionStateConnected:
665 return @"CONNECTED";
666 case RTCIceConnectionStateCompleted:
667 return @"COMPLETED";
668 case RTCIceConnectionStateFailed:
669 return @"FAILED";
670 case RTCIceConnectionStateDisconnected:
671 return @"DISCONNECTED";
672 case RTCIceConnectionStateClosed:
673 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700674 case RTCIceConnectionStateCount:
675 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800676 }
677}
678
679+ (webrtc::PeerConnectionInterface::IceGatheringState)
680 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
681 switch (state) {
682 case RTCIceGatheringStateNew:
683 return webrtc::PeerConnectionInterface::kIceGatheringNew;
684 case RTCIceGatheringStateGathering:
685 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
686 case RTCIceGatheringStateComplete:
687 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
688 }
689}
690
691+ (RTCIceGatheringState)iceGatheringStateForNativeState:
692 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
693 switch (nativeState) {
694 case webrtc::PeerConnectionInterface::kIceGatheringNew:
695 return RTCIceGatheringStateNew;
696 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
697 return RTCIceGatheringStateGathering;
698 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
699 return RTCIceGatheringStateComplete;
700 }
701}
702
703+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
704 switch (state) {
705 case RTCIceGatheringStateNew:
706 return @"NEW";
707 case RTCIceGatheringStateGathering:
708 return @"GATHERING";
709 case RTCIceGatheringStateComplete:
710 return @"COMPLETE";
711 }
712}
713
714+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
715 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
716 switch (level) {
717 case RTCStatsOutputLevelStandard:
718 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
719 case RTCStatsOutputLevelDebug:
720 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
721 }
722}
723
hjonf396f602016-02-11 16:19:06 -0800724- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
725 return _peerConnection;
726}
727
728@end