blob: 35e82158fde6fe6aebb8a0537e31258e539d4ba1 [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
64 void OnFailure(const std::string& error) override {
65 RTC_DCHECK(completion_handler_);
66 NSString* str = [NSString stringForStdString:error];
67 NSError* err =
68 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
69 code:kRTCPeerConnnectionSessionDescriptionError
70 userInfo:@{ NSLocalizedDescriptionKey : str }];
71 completion_handler_(nil, err);
72 completion_handler_ = nil;
73 }
74
75 private:
76 void (^completion_handler_)
77 (RTCSessionDescription *sessionDescription, NSError *error);
78};
79
80class SetSessionDescriptionObserverAdapter :
81 public SetSessionDescriptionObserver {
82 public:
83 SetSessionDescriptionObserverAdapter(void (^completionHandler)
84 (NSError *error)) {
85 completion_handler_ = completionHandler;
86 }
87
88 ~SetSessionDescriptionObserverAdapter() {
89 completion_handler_ = nil;
90 }
91
92 void OnSuccess() override {
93 RTC_DCHECK(completion_handler_);
94 completion_handler_(nil);
95 completion_handler_ = nil;
96 }
97
98 void OnFailure(const std::string& error) override {
99 RTC_DCHECK(completion_handler_);
100 NSString* str = [NSString stringForStdString:error];
101 NSError* err =
102 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
103 code:kRTCPeerConnnectionSessionDescriptionError
104 userInfo:@{ NSLocalizedDescriptionKey : str }];
105 completion_handler_(err);
106 completion_handler_ = nil;
107 }
108
109 private:
110 void (^completion_handler_)(NSError *error);
111};
112
113PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
114 RTCPeerConnection *peerConnection) {
115 peer_connection_ = peerConnection;
116}
117
118PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
119 peer_connection_ = nil;
120}
121
122void PeerConnectionDelegateAdapter::OnSignalingChange(
123 PeerConnectionInterface::SignalingState new_state) {
124 RTCSignalingState state =
125 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
126 RTCPeerConnection *peer_connection = peer_connection_;
127 [peer_connection.delegate peerConnection:peer_connection
128 didChangeSignalingState:state];
129}
130
131void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700132 rtc::scoped_refptr<MediaStreamInterface> stream) {
magjed63bafd62017-02-27 07:04:25 -0800133 RTCMediaStream *mediaStream =
134 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800135 RTCPeerConnection *peer_connection = peer_connection_;
136 [peer_connection.delegate peerConnection:peer_connection
137 didAddStream:mediaStream];
138}
139
140void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700141 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800142 RTCMediaStream *mediaStream =
143 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
144 RTCPeerConnection *peer_connection = peer_connection_;
145 [peer_connection.delegate peerConnection:peer_connection
146 didRemoveStream:mediaStream];
147}
148
Steve Anton8cb344a2018-02-27 15:34:53 -0800149void PeerConnectionDelegateAdapter::OnTrack(
150 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
151 RTCRtpTransceiver *transceiver =
152 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
153 RTCPeerConnection *peer_connection = peer_connection_;
154 if ([peer_connection.delegate
155 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
156 [peer_connection.delegate peerConnection:peer_connection
157 didStartReceivingOnTransceiver:transceiver];
158 }
159}
160
hjonf396f602016-02-11 16:19:06 -0800161void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700162 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800163 RTCDataChannel *dataChannel =
164 [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel];
165 RTCPeerConnection *peer_connection = peer_connection_;
166 [peer_connection.delegate peerConnection:peer_connection
167 didOpenDataChannel:dataChannel];
168}
169
170void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
171 RTCPeerConnection *peer_connection = peer_connection_;
172 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
173}
174
175void PeerConnectionDelegateAdapter::OnIceConnectionChange(
176 PeerConnectionInterface::IceConnectionState new_state) {
177 RTCIceConnectionState state =
178 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
179 RTCPeerConnection *peer_connection = peer_connection_;
180 [peer_connection.delegate peerConnection:peer_connection
181 didChangeIceConnectionState:state];
182}
183
184void PeerConnectionDelegateAdapter::OnIceGatheringChange(
185 PeerConnectionInterface::IceGatheringState new_state) {
186 RTCIceGatheringState state =
187 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
188 RTCPeerConnection *peer_connection = peer_connection_;
189 [peer_connection.delegate peerConnection:peer_connection
190 didChangeIceGatheringState:state];
191}
192
193void PeerConnectionDelegateAdapter::OnIceCandidate(
194 const IceCandidateInterface *candidate) {
195 RTCIceCandidate *iceCandidate =
196 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
197 RTCPeerConnection *peer_connection = peer_connection_;
198 [peer_connection.delegate peerConnection:peer_connection
199 didGenerateIceCandidate:iceCandidate];
200}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700201
202void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
203 const std::vector<cricket::Candidate>& candidates) {
204 NSMutableArray* ice_candidates =
205 [NSMutableArray arrayWithCapacity:candidates.size()];
206 for (const auto& candidate : candidates) {
207 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
208 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
209 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
210 initWithNativeCandidate:candidate_wrapper.get()];
211 [ice_candidates addObject:ice_candidate];
212 }
213 RTCPeerConnection* peer_connection = peer_connection_;
214 [peer_connection.delegate peerConnection:peer_connection
215 didRemoveIceCandidates:ice_candidates];
216}
217
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300218void PeerConnectionDelegateAdapter::OnAddTrack(
219 rtc::scoped_refptr<RtpReceiverInterface> receiver,
220 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
221 RTCPeerConnection *peer_connection = peer_connection_;
222 if ([peer_connection.delegate
223 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
224 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
225 for (const auto& nativeStream : streams) {
226 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithNativeMediaStream:nativeStream];
227 [mediaStreams addObject:mediaStream];
228 }
229 RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:receiver];
230
231 [peer_connection.delegate peerConnection:peer_connection
232 didAddReceiver:rtpReceiver
233 streams:mediaStreams];
234 }
235}
236
hjonf396f602016-02-11 16:19:06 -0800237} // namespace webrtc
238
239
240@implementation RTCPeerConnection {
vopatop.skam96b6b832016-08-18 14:21:20 -0700241 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700242 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800243 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800244 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700245 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800246}
247
248@synthesize delegate = _delegate;
249
250- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
251 configuration:(RTCConfiguration *)configuration
252 constraints:(RTCMediaConstraints *)constraints
253 delegate:(id<RTCPeerConnectionDelegate>)delegate {
254 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200255 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700256 [configuration createNativeConfiguration]);
257 if (!config) {
258 return nil;
259 }
hjonf396f602016-02-11 16:19:06 -0800260 if (self = [super init]) {
261 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800262 _nativeConstraints = constraints.nativeConstraints;
263 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
264 config.get());
hjonf396f602016-02-11 16:19:06 -0800265 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700266 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700267 nullptr,
268 nullptr,
269 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700270 if (!_peerConnection) {
271 return nil;
272 }
hjonf396f602016-02-11 16:19:06 -0800273 _localStreams = [[NSMutableArray alloc] init];
274 _delegate = delegate;
275 }
276 return self;
277}
278
vopatop.skam96b6b832016-08-18 14:21:20 -0700279- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800280 return [_localStreams copy];
281}
282
283- (RTCSessionDescription *)localDescription {
284 const webrtc::SessionDescriptionInterface *description =
285 _peerConnection->local_description();
286 return description ?
287 [[RTCSessionDescription alloc] initWithNativeDescription:description]
288 : nil;
289}
290
291- (RTCSessionDescription *)remoteDescription {
292 const webrtc::SessionDescriptionInterface *description =
293 _peerConnection->remote_description();
294 return description ?
295 [[RTCSessionDescription alloc] initWithNativeDescription:description]
296 : nil;
297}
298
299- (RTCSignalingState)signalingState {
300 return [[self class]
301 signalingStateForNativeState:_peerConnection->signaling_state()];
302}
303
304- (RTCIceConnectionState)iceConnectionState {
305 return [[self class] iceConnectionStateForNativeState:
306 _peerConnection->ice_connection_state()];
307}
308
309- (RTCIceGatheringState)iceGatheringState {
310 return [[self class] iceGatheringStateForNativeState:
311 _peerConnection->ice_gathering_state()];
312}
313
tkchinaac3eb22016-03-09 21:49:40 -0800314- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200315 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700316 [configuration createNativeConfiguration]);
317 if (!config) {
318 return NO;
319 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800320 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
321 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200322 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800323}
324
jtteh4eeb5372017-04-03 15:06:37 -0700325- (RTCConfiguration *)configuration {
326 webrtc::PeerConnectionInterface::RTCConfiguration config =
327 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700328 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700329}
330
hjonf396f602016-02-11 16:19:06 -0800331- (void)close {
332 _peerConnection->Close();
333}
334
335- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700336 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800337 candidate.nativeCandidate);
338 _peerConnection->AddIceCandidate(iceCandidate.get());
339}
340
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700341- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
342 std::vector<cricket::Candidate> candidates;
343 for (RTCIceCandidate *iceCandidate in iceCandidates) {
344 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
345 iceCandidate.nativeCandidate);
346 if (candidate) {
347 candidates.push_back(candidate->candidate());
348 // Need to fill the transport name from the sdp_mid.
349 candidates.back().set_transport_name(candidate->sdp_mid());
350 }
351 }
352 if (!candidates.empty()) {
353 _peerConnection->RemoveIceCandidates(candidates);
354 }
355}
356
hjonf396f602016-02-11 16:19:06 -0800357- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800358 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800359 RTCLogError(@"Failed to add stream: %@", stream);
360 return;
361 }
362 [_localStreams addObject:stream];
363}
364
365- (void)removeStream:(RTCMediaStream *)stream {
366 _peerConnection->RemoveStream(stream.nativeMediaStream);
367 [_localStreams removeObject:stream];
368}
369
Steve Anton8cb344a2018-02-27 15:34:53 -0800370- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track
371 streamLabels:(NSArray<NSString *> *)streamLabels {
372 std::vector<std::string> nativeStreamLabels;
373 for (NSString *label in streamLabels) {
374 nativeStreamLabels.push_back([label UTF8String]);
375 }
376 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
377 _peerConnection->AddTrack(track.nativeTrack, nativeStreamLabels);
378 if (!nativeSenderOrError.ok()) {
379 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
380 return nil;
381 }
382 return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
383}
384
385- (BOOL)removeTrack:(RTCRtpSender *)sender {
386 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
387 if (!result) {
388 RTCLogError(@"Failed to remote track %@", sender);
389 }
390 return result;
391}
392
393- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
394 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
395}
396
397- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
398 init:(RTCRtpTransceiverInit *)init {
399 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
400 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
401 if (!nativeTransceiverOrError.ok()) {
402 RTCLogError(
403 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
404 return nil;
405 }
406 return
407 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
408}
409
410- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
411 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
412}
413
414- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
415 init:(RTCRtpTransceiverInit *)init {
416 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
417 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
418 init.nativeInit);
419 if (!nativeTransceiverOrError.ok()) {
420 RTCLogError(@"Failed to add transceiver %@: %s",
421 [RTCRtpReceiver stringForMediaType:mediaType],
422 nativeTransceiverOrError.error().message());
423 return nil;
424 }
425 return
426 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
427}
428
hjonf396f602016-02-11 16:19:06 -0800429- (void)offerForConstraints:(RTCMediaConstraints *)constraints
430 completionHandler:
431 (void (^)(RTCSessionDescription *sessionDescription,
432 NSError *error))completionHandler {
433 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
434 observer(new rtc::RefCountedObject
435 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
436 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
437}
438
439- (void)answerForConstraints:(RTCMediaConstraints *)constraints
440 completionHandler:
441 (void (^)(RTCSessionDescription *sessionDescription,
442 NSError *error))completionHandler {
443 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
444 observer(new rtc::RefCountedObject
445 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
446 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
447}
448
449- (void)setLocalDescription:(RTCSessionDescription *)sdp
450 completionHandler:(void (^)(NSError *error))completionHandler {
451 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
452 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
453 completionHandler));
454 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
455}
456
457- (void)setRemoteDescription:(RTCSessionDescription *)sdp
458 completionHandler:(void (^)(NSError *error))completionHandler {
459 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
460 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
461 completionHandler));
462 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
463}
464
zstein8b476172017-09-05 14:43:03 -0700465- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
466 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
467 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700468 webrtc::PeerConnectionInterface::BitrateParameters params;
469 if (minBitrateBps != nil) {
470 params.min_bitrate_bps = rtc::Optional<int>(minBitrateBps.intValue);
471 }
472 if (currentBitrateBps != nil) {
473 params.current_bitrate_bps = rtc::Optional<int>(currentBitrateBps.intValue);
474 }
475 if (maxBitrateBps != nil) {
476 params.max_bitrate_bps = rtc::Optional<int>(maxBitrateBps.intValue);
477 }
478 return _peerConnection->SetBitrate(params).ok();
479}
480
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200481- (void)setBitrateAllocationStrategy:
482 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
483 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
484}
485
ivoc14d5dbe2016-07-04 07:06:55 -0700486- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
487 maxSizeInBytes:(int64_t)maxSizeInBytes {
488 RTC_DCHECK(filePath.length);
489 RTC_DCHECK_GT(maxSizeInBytes, 0);
490 RTC_DCHECK(!_hasStartedRtcEventLog);
491 if (_hasStartedRtcEventLog) {
492 RTCLogError(@"Event logging already started.");
493 return NO;
494 }
495 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
496 S_IRUSR | S_IWUSR);
497 if (fd < 0) {
498 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
499 return NO;
500 }
501 _hasStartedRtcEventLog =
502 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
503 return _hasStartedRtcEventLog;
504}
505
506- (void)stopRtcEventLog {
507 _peerConnection->StopRtcEventLog();
508 _hasStartedRtcEventLog = NO;
509}
510
skvladf3569c82016-04-29 15:30:16 -0700511- (RTCRtpSender *)senderWithKind:(NSString *)kind
512 streamId:(NSString *)streamId {
513 std::string nativeKind = [NSString stdStringForString:kind];
514 std::string nativeStreamId = [NSString stdStringForString:streamId];
515 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
516 _peerConnection->CreateSender(nativeKind, nativeStreamId));
517 return nativeSender ?
518 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
519 : nil;
520}
521
skvlad79b4b872016-04-08 17:28:55 -0700522- (NSArray<RTCRtpSender *> *)senders {
523 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
524 _peerConnection->GetSenders());
525 NSMutableArray *senders = [[NSMutableArray alloc] init];
526 for (const auto &nativeSender : nativeSenders) {
527 RTCRtpSender *sender =
528 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
529 [senders addObject:sender];
530 }
531 return senders;
532}
533
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700534- (NSArray<RTCRtpReceiver *> *)receivers {
535 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
536 _peerConnection->GetReceivers());
537 NSMutableArray *receivers = [[NSMutableArray alloc] init];
538 for (const auto &nativeReceiver : nativeReceivers) {
539 RTCRtpReceiver *receiver =
540 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
541 [receivers addObject:receiver];
542 }
543 return receivers;
544}
545
Steve Anton8cb344a2018-02-27 15:34:53 -0800546- (NSArray<RTCRtpTransceiver *> *)transceivers {
547 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
548 _peerConnection->GetTransceivers());
549 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
550 for (auto nativeTransceiver : nativeTransceivers) {
551 RTCRtpTransceiver *transceiver =
552 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
553 [transceivers addObject:transceiver];
554 }
555 return transceivers;
556}
557
hjonf396f602016-02-11 16:19:06 -0800558#pragma mark - Private
559
560+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
561 (RTCSignalingState)state {
562 switch (state) {
563 case RTCSignalingStateStable:
564 return webrtc::PeerConnectionInterface::kStable;
565 case RTCSignalingStateHaveLocalOffer:
566 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
567 case RTCSignalingStateHaveLocalPrAnswer:
568 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
569 case RTCSignalingStateHaveRemoteOffer:
570 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
571 case RTCSignalingStateHaveRemotePrAnswer:
572 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
573 case RTCSignalingStateClosed:
574 return webrtc::PeerConnectionInterface::kClosed;
575 }
576}
577
578+ (RTCSignalingState)signalingStateForNativeState:
579 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
580 switch (nativeState) {
581 case webrtc::PeerConnectionInterface::kStable:
582 return RTCSignalingStateStable;
583 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
584 return RTCSignalingStateHaveLocalOffer;
585 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
586 return RTCSignalingStateHaveLocalPrAnswer;
587 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
588 return RTCSignalingStateHaveRemoteOffer;
589 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
590 return RTCSignalingStateHaveRemotePrAnswer;
591 case webrtc::PeerConnectionInterface::kClosed:
592 return RTCSignalingStateClosed;
593 }
594}
595
596+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
597 switch (state) {
598 case RTCSignalingStateStable:
599 return @"STABLE";
600 case RTCSignalingStateHaveLocalOffer:
601 return @"HAVE_LOCAL_OFFER";
602 case RTCSignalingStateHaveLocalPrAnswer:
603 return @"HAVE_LOCAL_PRANSWER";
604 case RTCSignalingStateHaveRemoteOffer:
605 return @"HAVE_REMOTE_OFFER";
606 case RTCSignalingStateHaveRemotePrAnswer:
607 return @"HAVE_REMOTE_PRANSWER";
608 case RTCSignalingStateClosed:
609 return @"CLOSED";
610 }
611}
612
613+ (webrtc::PeerConnectionInterface::IceConnectionState)
614 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
615 switch (state) {
616 case RTCIceConnectionStateNew:
617 return webrtc::PeerConnectionInterface::kIceConnectionNew;
618 case RTCIceConnectionStateChecking:
619 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
620 case RTCIceConnectionStateConnected:
621 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
622 case RTCIceConnectionStateCompleted:
623 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
624 case RTCIceConnectionStateFailed:
625 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
626 case RTCIceConnectionStateDisconnected:
627 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
628 case RTCIceConnectionStateClosed:
629 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700630 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800631 return webrtc::PeerConnectionInterface::kIceConnectionMax;
632 }
633}
634
635+ (RTCIceConnectionState)iceConnectionStateForNativeState:
636 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
637 switch (nativeState) {
638 case webrtc::PeerConnectionInterface::kIceConnectionNew:
639 return RTCIceConnectionStateNew;
640 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
641 return RTCIceConnectionStateChecking;
642 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
643 return RTCIceConnectionStateConnected;
644 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
645 return RTCIceConnectionStateCompleted;
646 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
647 return RTCIceConnectionStateFailed;
648 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
649 return RTCIceConnectionStateDisconnected;
650 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
651 return RTCIceConnectionStateClosed;
652 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700653 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800654 }
655}
656
657+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
658 switch (state) {
659 case RTCIceConnectionStateNew:
660 return @"NEW";
661 case RTCIceConnectionStateChecking:
662 return @"CHECKING";
663 case RTCIceConnectionStateConnected:
664 return @"CONNECTED";
665 case RTCIceConnectionStateCompleted:
666 return @"COMPLETED";
667 case RTCIceConnectionStateFailed:
668 return @"FAILED";
669 case RTCIceConnectionStateDisconnected:
670 return @"DISCONNECTED";
671 case RTCIceConnectionStateClosed:
672 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700673 case RTCIceConnectionStateCount:
674 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800675 }
676}
677
678+ (webrtc::PeerConnectionInterface::IceGatheringState)
679 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
680 switch (state) {
681 case RTCIceGatheringStateNew:
682 return webrtc::PeerConnectionInterface::kIceGatheringNew;
683 case RTCIceGatheringStateGathering:
684 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
685 case RTCIceGatheringStateComplete:
686 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
687 }
688}
689
690+ (RTCIceGatheringState)iceGatheringStateForNativeState:
691 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
692 switch (nativeState) {
693 case webrtc::PeerConnectionInterface::kIceGatheringNew:
694 return RTCIceGatheringStateNew;
695 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
696 return RTCIceGatheringStateGathering;
697 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
698 return RTCIceGatheringStateComplete;
699 }
700}
701
702+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
703 switch (state) {
704 case RTCIceGatheringStateNew:
705 return @"NEW";
706 case RTCIceGatheringStateGathering:
707 return @"GATHERING";
708 case RTCIceGatheringStateComplete:
709 return @"COMPLETE";
710 }
711}
712
713+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
714 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
715 switch (level) {
716 case RTCStatsOutputLevelStandard:
717 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
718 case RTCStatsOutputLevelDebug:
719 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
720 }
721}
722
hjonf396f602016-02-11 16:19:06 -0800723- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
724 return _peerConnection;
725}
726
727@end