blob: 3e54e24819046a746f20021b63605beaf8f79835 [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
Seth Hampson513449e2018-03-06 09:35:56 -0800370- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
371 std::vector<std::string> nativeStreamIds;
372 for (NSString *streamId in streamIds) {
373 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800374 }
375 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800376 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800377 if (!nativeSenderOrError.ok()) {
378 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
379 return nil;
380 }
381 return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
382}
383
384- (BOOL)removeTrack:(RTCRtpSender *)sender {
385 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
386 if (!result) {
387 RTCLogError(@"Failed to remote track %@", sender);
388 }
389 return result;
390}
391
392- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
393 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
394}
395
396- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
397 init:(RTCRtpTransceiverInit *)init {
398 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
399 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
400 if (!nativeTransceiverOrError.ok()) {
401 RTCLogError(
402 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
403 return nil;
404 }
405 return
406 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
407}
408
409- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
410 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
411}
412
413- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
414 init:(RTCRtpTransceiverInit *)init {
415 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
416 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
417 init.nativeInit);
418 if (!nativeTransceiverOrError.ok()) {
419 RTCLogError(@"Failed to add transceiver %@: %s",
420 [RTCRtpReceiver stringForMediaType:mediaType],
421 nativeTransceiverOrError.error().message());
422 return nil;
423 }
424 return
425 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
426}
427
hjonf396f602016-02-11 16:19:06 -0800428- (void)offerForConstraints:(RTCMediaConstraints *)constraints
429 completionHandler:
430 (void (^)(RTCSessionDescription *sessionDescription,
431 NSError *error))completionHandler {
432 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
433 observer(new rtc::RefCountedObject
434 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
435 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
436}
437
438- (void)answerForConstraints:(RTCMediaConstraints *)constraints
439 completionHandler:
440 (void (^)(RTCSessionDescription *sessionDescription,
441 NSError *error))completionHandler {
442 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
443 observer(new rtc::RefCountedObject
444 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
445 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
446}
447
448- (void)setLocalDescription:(RTCSessionDescription *)sdp
449 completionHandler:(void (^)(NSError *error))completionHandler {
450 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
451 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
452 completionHandler));
453 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
454}
455
456- (void)setRemoteDescription:(RTCSessionDescription *)sdp
457 completionHandler:(void (^)(NSError *error))completionHandler {
458 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
459 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
460 completionHandler));
461 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
462}
463
zstein8b476172017-09-05 14:43:03 -0700464- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
465 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
466 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700467 webrtc::PeerConnectionInterface::BitrateParameters params;
468 if (minBitrateBps != nil) {
469 params.min_bitrate_bps = rtc::Optional<int>(minBitrateBps.intValue);
470 }
471 if (currentBitrateBps != nil) {
472 params.current_bitrate_bps = rtc::Optional<int>(currentBitrateBps.intValue);
473 }
474 if (maxBitrateBps != nil) {
475 params.max_bitrate_bps = rtc::Optional<int>(maxBitrateBps.intValue);
476 }
477 return _peerConnection->SetBitrate(params).ok();
478}
479
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200480- (void)setBitrateAllocationStrategy:
481 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
482 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
483}
484
ivoc14d5dbe2016-07-04 07:06:55 -0700485- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
486 maxSizeInBytes:(int64_t)maxSizeInBytes {
487 RTC_DCHECK(filePath.length);
488 RTC_DCHECK_GT(maxSizeInBytes, 0);
489 RTC_DCHECK(!_hasStartedRtcEventLog);
490 if (_hasStartedRtcEventLog) {
491 RTCLogError(@"Event logging already started.");
492 return NO;
493 }
494 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
495 S_IRUSR | S_IWUSR);
496 if (fd < 0) {
497 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
498 return NO;
499 }
500 _hasStartedRtcEventLog =
501 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
502 return _hasStartedRtcEventLog;
503}
504
505- (void)stopRtcEventLog {
506 _peerConnection->StopRtcEventLog();
507 _hasStartedRtcEventLog = NO;
508}
509
skvladf3569c82016-04-29 15:30:16 -0700510- (RTCRtpSender *)senderWithKind:(NSString *)kind
511 streamId:(NSString *)streamId {
512 std::string nativeKind = [NSString stdStringForString:kind];
513 std::string nativeStreamId = [NSString stdStringForString:streamId];
514 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
515 _peerConnection->CreateSender(nativeKind, nativeStreamId));
516 return nativeSender ?
517 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
518 : nil;
519}
520
skvlad79b4b872016-04-08 17:28:55 -0700521- (NSArray<RTCRtpSender *> *)senders {
522 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
523 _peerConnection->GetSenders());
524 NSMutableArray *senders = [[NSMutableArray alloc] init];
525 for (const auto &nativeSender : nativeSenders) {
526 RTCRtpSender *sender =
527 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
528 [senders addObject:sender];
529 }
530 return senders;
531}
532
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700533- (NSArray<RTCRtpReceiver *> *)receivers {
534 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
535 _peerConnection->GetReceivers());
536 NSMutableArray *receivers = [[NSMutableArray alloc] init];
537 for (const auto &nativeReceiver : nativeReceivers) {
538 RTCRtpReceiver *receiver =
539 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
540 [receivers addObject:receiver];
541 }
542 return receivers;
543}
544
Steve Anton8cb344a2018-02-27 15:34:53 -0800545- (NSArray<RTCRtpTransceiver *> *)transceivers {
546 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
547 _peerConnection->GetTransceivers());
548 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
549 for (auto nativeTransceiver : nativeTransceivers) {
550 RTCRtpTransceiver *transceiver =
551 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
552 [transceivers addObject:transceiver];
553 }
554 return transceivers;
555}
556
hjonf396f602016-02-11 16:19:06 -0800557#pragma mark - Private
558
559+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
560 (RTCSignalingState)state {
561 switch (state) {
562 case RTCSignalingStateStable:
563 return webrtc::PeerConnectionInterface::kStable;
564 case RTCSignalingStateHaveLocalOffer:
565 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
566 case RTCSignalingStateHaveLocalPrAnswer:
567 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
568 case RTCSignalingStateHaveRemoteOffer:
569 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
570 case RTCSignalingStateHaveRemotePrAnswer:
571 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
572 case RTCSignalingStateClosed:
573 return webrtc::PeerConnectionInterface::kClosed;
574 }
575}
576
577+ (RTCSignalingState)signalingStateForNativeState:
578 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
579 switch (nativeState) {
580 case webrtc::PeerConnectionInterface::kStable:
581 return RTCSignalingStateStable;
582 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
583 return RTCSignalingStateHaveLocalOffer;
584 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
585 return RTCSignalingStateHaveLocalPrAnswer;
586 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
587 return RTCSignalingStateHaveRemoteOffer;
588 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
589 return RTCSignalingStateHaveRemotePrAnswer;
590 case webrtc::PeerConnectionInterface::kClosed:
591 return RTCSignalingStateClosed;
592 }
593}
594
595+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
596 switch (state) {
597 case RTCSignalingStateStable:
598 return @"STABLE";
599 case RTCSignalingStateHaveLocalOffer:
600 return @"HAVE_LOCAL_OFFER";
601 case RTCSignalingStateHaveLocalPrAnswer:
602 return @"HAVE_LOCAL_PRANSWER";
603 case RTCSignalingStateHaveRemoteOffer:
604 return @"HAVE_REMOTE_OFFER";
605 case RTCSignalingStateHaveRemotePrAnswer:
606 return @"HAVE_REMOTE_PRANSWER";
607 case RTCSignalingStateClosed:
608 return @"CLOSED";
609 }
610}
611
612+ (webrtc::PeerConnectionInterface::IceConnectionState)
613 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
614 switch (state) {
615 case RTCIceConnectionStateNew:
616 return webrtc::PeerConnectionInterface::kIceConnectionNew;
617 case RTCIceConnectionStateChecking:
618 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
619 case RTCIceConnectionStateConnected:
620 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
621 case RTCIceConnectionStateCompleted:
622 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
623 case RTCIceConnectionStateFailed:
624 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
625 case RTCIceConnectionStateDisconnected:
626 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
627 case RTCIceConnectionStateClosed:
628 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700629 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800630 return webrtc::PeerConnectionInterface::kIceConnectionMax;
631 }
632}
633
634+ (RTCIceConnectionState)iceConnectionStateForNativeState:
635 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
636 switch (nativeState) {
637 case webrtc::PeerConnectionInterface::kIceConnectionNew:
638 return RTCIceConnectionStateNew;
639 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
640 return RTCIceConnectionStateChecking;
641 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
642 return RTCIceConnectionStateConnected;
643 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
644 return RTCIceConnectionStateCompleted;
645 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
646 return RTCIceConnectionStateFailed;
647 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
648 return RTCIceConnectionStateDisconnected;
649 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
650 return RTCIceConnectionStateClosed;
651 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700652 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800653 }
654}
655
656+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
657 switch (state) {
658 case RTCIceConnectionStateNew:
659 return @"NEW";
660 case RTCIceConnectionStateChecking:
661 return @"CHECKING";
662 case RTCIceConnectionStateConnected:
663 return @"CONNECTED";
664 case RTCIceConnectionStateCompleted:
665 return @"COMPLETED";
666 case RTCIceConnectionStateFailed:
667 return @"FAILED";
668 case RTCIceConnectionStateDisconnected:
669 return @"DISCONNECTED";
670 case RTCIceConnectionStateClosed:
671 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700672 case RTCIceConnectionStateCount:
673 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800674 }
675}
676
677+ (webrtc::PeerConnectionInterface::IceGatheringState)
678 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
679 switch (state) {
680 case RTCIceGatheringStateNew:
681 return webrtc::PeerConnectionInterface::kIceGatheringNew;
682 case RTCIceGatheringStateGathering:
683 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
684 case RTCIceGatheringStateComplete:
685 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
686 }
687}
688
689+ (RTCIceGatheringState)iceGatheringStateForNativeState:
690 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
691 switch (nativeState) {
692 case webrtc::PeerConnectionInterface::kIceGatheringNew:
693 return RTCIceGatheringStateNew;
694 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
695 return RTCIceGatheringStateGathering;
696 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
697 return RTCIceGatheringStateComplete;
698 }
699}
700
701+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
702 switch (state) {
703 case RTCIceGatheringStateNew:
704 return @"NEW";
705 case RTCIceGatheringStateGathering:
706 return @"GATHERING";
707 case RTCIceGatheringStateComplete:
708 return @"COMPLETE";
709 }
710}
711
712+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
713 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
714 switch (level) {
715 case RTCStatsOutputLevelStandard:
716 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
717 case RTCStatsOutputLevelDebug:
718 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
719 }
720}
721
hjonf396f602016-02-11 16:19:06 -0800722- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
723 return _peerConnection;
724}
725
726@end