OLD | NEW |
| (Empty) |
1 /* | |
2 * libjingle | |
3 * Copyright 2013 Google Inc. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions are met: | |
7 * | |
8 * 1. Redistributions of source code must retain the above copyright notice, | |
9 * this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
11 * this list of conditions and the following disclaimer in the documentation | |
12 * and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
29 #error "This file requires ARC support." | |
30 #endif | |
31 | |
32 #import "RTCPeerConnection+Internal.h" | |
33 | |
34 #import "RTCDataChannel+Internal.h" | |
35 #import "RTCEnumConverter.h" | |
36 #import "RTCICECandidate+Internal.h" | |
37 #import "RTCICEServer+Internal.h" | |
38 #import "RTCMediaConstraints+Internal.h" | |
39 #import "RTCMediaStream+Internal.h" | |
40 #import "RTCMediaStreamTrack+Internal.h" | |
41 #import "RTCPeerConnectionObserver.h" | |
42 #import "RTCSessionDescription+Internal.h" | |
43 #import "RTCSessionDescription.h" | |
44 #import "RTCSessionDescriptionDelegate.h" | |
45 #import "RTCStatsDelegate.h" | |
46 #import "RTCStatsReport+Internal.h" | |
47 | |
48 #include <memory> | |
49 | |
50 #include "webrtc/api/jsep.h" | |
51 | |
52 NSString* const kRTCSessionDescriptionDelegateErrorDomain = @"RTCSDPError"; | |
53 int const kRTCSessionDescriptionDelegateErrorCode = -1; | |
54 | |
55 namespace webrtc { | |
56 | |
57 class RTCCreateSessionDescriptionObserver | |
58 : public CreateSessionDescriptionObserver { | |
59 public: | |
60 RTCCreateSessionDescriptionObserver( | |
61 id<RTCSessionDescriptionDelegate> delegate, | |
62 RTCPeerConnection* peerConnection) { | |
63 _delegate = delegate; | |
64 _peerConnection = peerConnection; | |
65 } | |
66 | |
67 void OnSuccess(SessionDescriptionInterface* desc) override { | |
68 RTCSessionDescription* session = | |
69 [[RTCSessionDescription alloc] initWithSessionDescription:desc]; | |
70 [_delegate peerConnection:_peerConnection | |
71 didCreateSessionDescription:session | |
72 error:nil]; | |
73 delete desc; | |
74 } | |
75 | |
76 void OnFailure(const std::string& error) override { | |
77 NSString* str = @(error.c_str()); | |
78 NSError* err = | |
79 [NSError errorWithDomain:kRTCSessionDescriptionDelegateErrorDomain | |
80 code:kRTCSessionDescriptionDelegateErrorCode | |
81 userInfo:@{@"error" : str}]; | |
82 [_delegate peerConnection:_peerConnection | |
83 didCreateSessionDescription:nil | |
84 error:err]; | |
85 } | |
86 | |
87 private: | |
88 id<RTCSessionDescriptionDelegate> _delegate; | |
89 RTCPeerConnection* _peerConnection; | |
90 }; | |
91 | |
92 class RTCSetSessionDescriptionObserver : public SetSessionDescriptionObserver { | |
93 public: | |
94 RTCSetSessionDescriptionObserver(id<RTCSessionDescriptionDelegate> delegate, | |
95 RTCPeerConnection* peerConnection) { | |
96 _delegate = delegate; | |
97 _peerConnection = peerConnection; | |
98 } | |
99 | |
100 void OnSuccess() override { | |
101 [_delegate peerConnection:_peerConnection | |
102 didSetSessionDescriptionWithError:nil]; | |
103 } | |
104 | |
105 void OnFailure(const std::string& error) override { | |
106 NSString* str = @(error.c_str()); | |
107 NSError* err = | |
108 [NSError errorWithDomain:kRTCSessionDescriptionDelegateErrorDomain | |
109 code:kRTCSessionDescriptionDelegateErrorCode | |
110 userInfo:@{@"error" : str}]; | |
111 [_delegate peerConnection:_peerConnection | |
112 didSetSessionDescriptionWithError:err]; | |
113 } | |
114 | |
115 private: | |
116 id<RTCSessionDescriptionDelegate> _delegate; | |
117 RTCPeerConnection* _peerConnection; | |
118 }; | |
119 | |
120 class RTCStatsObserver : public StatsObserver { | |
121 public: | |
122 RTCStatsObserver(id<RTCStatsDelegate> delegate, | |
123 RTCPeerConnection* peerConnection) { | |
124 _delegate = delegate; | |
125 _peerConnection = peerConnection; | |
126 } | |
127 | |
128 void OnComplete(const StatsReports& reports) override { | |
129 NSMutableArray* stats = [NSMutableArray arrayWithCapacity:reports.size()]; | |
130 for (const auto* report : reports) { | |
131 RTCStatsReport* statsReport = | |
132 [[RTCStatsReport alloc] initWithStatsReport:*report]; | |
133 [stats addObject:statsReport]; | |
134 } | |
135 [_delegate peerConnection:_peerConnection didGetStats:stats]; | |
136 } | |
137 | |
138 private: | |
139 id<RTCStatsDelegate> _delegate; | |
140 RTCPeerConnection* _peerConnection; | |
141 }; | |
142 } | |
143 | |
144 @implementation RTCPeerConnection { | |
145 NSMutableArray* _localStreams; | |
146 std::unique_ptr<webrtc::RTCPeerConnectionObserver> _observer; | |
147 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection; | |
148 } | |
149 | |
150 - (BOOL)addICECandidate:(RTCICECandidate*)candidate { | |
151 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate( | |
152 candidate.candidate); | |
153 return self.peerConnection->AddIceCandidate(iceCandidate.get()); | |
154 } | |
155 | |
156 - (BOOL)addStream:(RTCMediaStream*)stream { | |
157 BOOL ret = self.peerConnection->AddStream(stream.mediaStream); | |
158 if (!ret) { | |
159 return NO; | |
160 } | |
161 [_localStreams addObject:stream]; | |
162 return YES; | |
163 } | |
164 | |
165 - (RTCDataChannel*)createDataChannelWithLabel:(NSString*)label | |
166 config:(RTCDataChannelInit*)config { | |
167 std::string labelString([label UTF8String]); | |
168 rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel = | |
169 self.peerConnection->CreateDataChannel(labelString, | |
170 config.dataChannelInit); | |
171 return [[RTCDataChannel alloc] initWithDataChannel:dataChannel]; | |
172 } | |
173 | |
174 - (void)createAnswerWithDelegate:(id<RTCSessionDescriptionDelegate>)delegate | |
175 constraints:(RTCMediaConstraints*)constraints { | |
176 rtc::scoped_refptr<webrtc::RTCCreateSessionDescriptionObserver> | |
177 observer(new rtc::RefCountedObject< | |
178 webrtc::RTCCreateSessionDescriptionObserver>(delegate, self)); | |
179 self.peerConnection->CreateAnswer(observer, constraints.constraints); | |
180 } | |
181 | |
182 - (void)createOfferWithDelegate:(id<RTCSessionDescriptionDelegate>)delegate | |
183 constraints:(RTCMediaConstraints*)constraints { | |
184 rtc::scoped_refptr<webrtc::RTCCreateSessionDescriptionObserver> | |
185 observer(new rtc::RefCountedObject< | |
186 webrtc::RTCCreateSessionDescriptionObserver>(delegate, self)); | |
187 self.peerConnection->CreateOffer(observer, constraints.constraints); | |
188 } | |
189 | |
190 - (void)removeStream:(RTCMediaStream*)stream { | |
191 self.peerConnection->RemoveStream(stream.mediaStream); | |
192 [_localStreams removeObject:stream]; | |
193 } | |
194 | |
195 - (void)setLocalDescriptionWithDelegate: | |
196 (id<RTCSessionDescriptionDelegate>)delegate | |
197 sessionDescription:(RTCSessionDescription*)sdp { | |
198 rtc::scoped_refptr<webrtc::RTCSetSessionDescriptionObserver> observer( | |
199 new rtc::RefCountedObject<webrtc::RTCSetSessionDescriptionObserver>( | |
200 delegate, self)); | |
201 self.peerConnection->SetLocalDescription(observer, sdp.sessionDescription); | |
202 } | |
203 | |
204 - (void)setRemoteDescriptionWithDelegate: | |
205 (id<RTCSessionDescriptionDelegate>)delegate | |
206 sessionDescription:(RTCSessionDescription*)sdp { | |
207 rtc::scoped_refptr<webrtc::RTCSetSessionDescriptionObserver> observer( | |
208 new rtc::RefCountedObject<webrtc::RTCSetSessionDescriptionObserver>( | |
209 delegate, self)); | |
210 self.peerConnection->SetRemoteDescription(observer, sdp.sessionDescription); | |
211 } | |
212 | |
213 - (BOOL)setConfiguration:(RTCConfiguration *)configuration { | |
214 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config( | |
215 [configuration createNativeConfiguration]); | |
216 if (!config) { | |
217 return NO; | |
218 } | |
219 return self.peerConnection->SetConfiguration(*config); | |
220 } | |
221 | |
222 - (RTCSessionDescription*)localDescription { | |
223 const webrtc::SessionDescriptionInterface* sdi = | |
224 self.peerConnection->local_description(); | |
225 return sdi ? [[RTCSessionDescription alloc] initWithSessionDescription:sdi] | |
226 : nil; | |
227 } | |
228 | |
229 - (NSArray*)localStreams { | |
230 return [_localStreams copy]; | |
231 } | |
232 | |
233 - (RTCSessionDescription*)remoteDescription { | |
234 const webrtc::SessionDescriptionInterface* sdi = | |
235 self.peerConnection->remote_description(); | |
236 return sdi ? [[RTCSessionDescription alloc] initWithSessionDescription:sdi] | |
237 : nil; | |
238 } | |
239 | |
240 - (RTCICEConnectionState)iceConnectionState { | |
241 return [RTCEnumConverter | |
242 convertIceConnectionStateToObjC:self.peerConnection | |
243 ->ice_connection_state()]; | |
244 } | |
245 | |
246 - (RTCICEGatheringState)iceGatheringState { | |
247 return [RTCEnumConverter | |
248 convertIceGatheringStateToObjC:self.peerConnection | |
249 ->ice_gathering_state()]; | |
250 } | |
251 | |
252 - (RTCSignalingState)signalingState { | |
253 return [RTCEnumConverter | |
254 convertSignalingStateToObjC:self.peerConnection->signaling_state()]; | |
255 } | |
256 | |
257 - (void)close { | |
258 self.peerConnection->Close(); | |
259 } | |
260 | |
261 - (BOOL)getStatsWithDelegate:(id<RTCStatsDelegate>)delegate | |
262 mediaStreamTrack:(RTCMediaStreamTrack*)mediaStreamTrack | |
263 statsOutputLevel:(RTCStatsOutputLevel)statsOutputLevel { | |
264 rtc::scoped_refptr<webrtc::RTCStatsObserver> observer( | |
265 new rtc::RefCountedObject<webrtc::RTCStatsObserver>(delegate, | |
266 self)); | |
267 webrtc::PeerConnectionInterface::StatsOutputLevel nativeOutputLevel = | |
268 [RTCEnumConverter convertStatsOutputLevelToNative:statsOutputLevel]; | |
269 return self.peerConnection->GetStats( | |
270 observer, mediaStreamTrack.mediaTrack, nativeOutputLevel); | |
271 } | |
272 | |
273 @end | |
274 | |
275 @implementation RTCPeerConnection (Internal) | |
276 | |
277 - (instancetype)initWithFactory:(webrtc::PeerConnectionFactoryInterface*)factory | |
278 iceServers:(const webrtc::PeerConnectionInterface::IceServers&)iceServers | |
279 constraints:(const webrtc::MediaConstraintsInterface*)constraints { | |
280 NSParameterAssert(factory != nullptr); | |
281 if (self = [super init]) { | |
282 webrtc::PeerConnectionInterface::RTCConfiguration config; | |
283 config.servers = iceServers; | |
284 _observer.reset(new webrtc::RTCPeerConnectionObserver(self)); | |
285 _peerConnection = factory->CreatePeerConnection( | |
286 config, constraints, nullptr, nullptr, _observer.get()); | |
287 _localStreams = [[NSMutableArray alloc] init]; | |
288 } | |
289 return self; | |
290 } | |
291 | |
292 - (instancetype)initWithFactory:(webrtc::PeerConnectionFactoryInterface *)factor
y | |
293 config:(const webrtc::PeerConnectionInterface::RTCConfi
guration &)config | |
294 constraints:(const webrtc::MediaConstraintsInterface *)const
raints | |
295 delegate:(id<RTCPeerConnectionDelegate>)delegate { | |
296 NSParameterAssert(factory); | |
297 if (self = [super init]) { | |
298 _observer.reset(new webrtc::RTCPeerConnectionObserver(self)); | |
299 _peerConnection = | |
300 factory->CreatePeerConnection(config, constraints, nullptr, nullptr, _ob
server.get()); | |
301 _localStreams = [[NSMutableArray alloc] init]; | |
302 _delegate = delegate; | |
303 } | |
304 return self; | |
305 } | |
306 | |
307 - (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)peerConnection { | |
308 return _peerConnection; | |
309 } | |
310 | |
311 @end | |
OLD | NEW |