OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/renderer/media/rtc_peer_connection_handler.h" | |
6 | |
7 #include <string> | |
8 #include <utility> | |
9 | |
10 #include "base/logging.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/utf_string_conversions.h" | |
13 #include "content/renderer/media/media_stream_dependency_factory.h" | |
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints .h" | |
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCConfiguration .h" | |
16 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCICECandidateD escriptor.h" | |
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectio nHandlerClient.h" | |
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescri ptionDescriptor.h" | |
19 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescri ptionRequest.h" | |
20 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCVoidRequest.h " | |
21 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" | |
22 | |
23 // Converter functions from libjingle types to WebKit types. | |
24 | |
25 static WebKit::WebRTCPeerConnectionHandlerClient::ICEState | |
26 GetWebKitIceState(webrtc::PeerConnectionInterface::IceState ice_state) { | |
27 switch (ice_state) { | |
28 case webrtc::PeerConnectionInterface::kIceNew: | |
29 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateNew; | |
30 case webrtc::PeerConnectionInterface::kIceGathering: | |
31 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateGathering; | |
32 case webrtc::PeerConnectionInterface::kIceWaiting: | |
33 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateWaiting; | |
34 case webrtc::PeerConnectionInterface::kIceChecking: | |
35 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateChecking; | |
36 case webrtc::PeerConnectionInterface::kIceConnected: | |
37 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateConnected; | |
38 case webrtc::PeerConnectionInterface::kIceCompleted: | |
39 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateCompleted; | |
40 case webrtc::PeerConnectionInterface::kIceFailed: | |
41 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateFailed; | |
42 case webrtc::PeerConnectionInterface::kIceClosed: | |
43 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateClosed; | |
44 default: | |
45 NOTREACHED(); | |
46 return WebKit::WebRTCPeerConnectionHandlerClient::ICEStateClosed; | |
47 } | |
48 NOTREACHED(); | |
49 } | |
50 | |
51 static WebKit::WebRTCPeerConnectionHandlerClient::ReadyState | |
52 GetWebKitReadyState( | |
53 webrtc::PeerConnectionInterface::ReadyState ready_state) { | |
54 switch (ready_state) { | |
55 case webrtc::PeerConnectionInterface::kNew: | |
56 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateNew; | |
57 case webrtc::PeerConnectionInterface::kOpening: | |
58 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateOpening; | |
59 case webrtc::PeerConnectionInterface::kActive: | |
60 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateActive; | |
61 case webrtc::PeerConnectionInterface::kClosing: | |
62 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosing; | |
63 case webrtc::PeerConnectionInterface::kClosed: | |
64 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed; | |
65 default: | |
66 NOTREACHED(); | |
67 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed; | |
68 } | |
69 NOTREACHED(); | |
70 } | |
71 | |
72 static WebKit::WebRTCSessionDescriptionDescriptor | |
73 CreateWebKitSessionDescription( | |
74 const webrtc::SessionDescriptionInterface* native_desc) { | |
75 WebKit::WebRTCSessionDescriptionDescriptor description; | |
76 if (!native_desc) { | |
77 LOG(ERROR) << "Native session description is null."; | |
78 return description; | |
79 } | |
80 | |
81 std::string sdp; | |
82 if (!native_desc->ToString(&sdp)) { | |
83 LOG(ERROR) << "Failed to get SDP string of native session description."; | |
84 return description; | |
85 } | |
86 | |
87 description.initialize(UTF8ToUTF16(native_desc->type()), UTF8ToUTF16(sdp)); | |
88 return description; | |
89 } | |
90 | |
91 // Converter functions from WebKit types to libjingle types. | |
92 | |
93 static void GetNativeIceServers( | |
94 const WebKit::WebRTCConfiguration& server_configuration, | |
95 webrtc::JsepInterface::IceServers* servers) { | |
96 if (server_configuration.isNull() || !servers) | |
97 return; | |
98 for (size_t i = 0; i < server_configuration.numberOfServers(); ++i) { | |
99 webrtc::JsepInterface::IceServer server; | |
100 const WebKit::WebRTCICEServer& webkit_server = | |
101 server_configuration.server(i); | |
102 server.password = UTF16ToUTF8(webkit_server.credential()); | |
103 server.uri = webkit_server.uri().spec(); | |
104 servers->push_back(server); | |
105 } | |
106 } | |
107 | |
108 // Class mapping responses from calls to libjingle CreateOffer/Answer and | |
109 // the WebKit::WebRTCSessionDescriptionRequest. | |
110 class CreateSessionDescriptionRequest | |
111 : public webrtc::CreateSessionDescriptionObserver { | |
112 public: | |
113 explicit CreateSessionDescriptionRequest( | |
114 const WebKit::WebRTCSessionDescriptionRequest& request) | |
115 : webkit_request_(request) {} | |
116 | |
117 virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE { | |
118 webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc)); | |
119 } | |
120 virtual void OnFailure(const std::string& error) OVERRIDE { | |
121 webkit_request_.requestFailed(UTF8ToUTF16(error)); | |
122 } | |
123 | |
124 protected: | |
125 virtual ~CreateSessionDescriptionRequest() {} | |
126 | |
127 private: | |
128 WebKit::WebRTCSessionDescriptionRequest webkit_request_; | |
129 }; | |
130 | |
131 // Class mapping responses from calls to libjingle | |
132 // SetLocalDescription/SetRemoteDescription and a WebKit::WebRTCVoidRequest. | |
133 class SetSessionDescriptionRequest | |
134 : public webrtc::SetSessionDescriptionObserver { | |
135 public: | |
136 explicit SetSessionDescriptionRequest( | |
137 const WebKit::WebRTCVoidRequest& request) | |
138 : webkit_request_(request) {} | |
139 | |
140 virtual void OnSuccess() OVERRIDE { | |
141 webkit_request_.requestSucceeded(); | |
142 } | |
143 virtual void OnFailure(const std::string& error) OVERRIDE { | |
144 webkit_request_.requestFailed(UTF8ToUTF16(error)); | |
145 } | |
146 | |
147 protected: | |
148 virtual ~SetSessionDescriptionRequest() {} | |
149 | |
150 private: | |
151 WebKit::WebRTCVoidRequest webkit_request_; | |
152 }; | |
153 | |
154 // TODO(perkj): Implement MediaConstraints when WebKit have done so. | |
155 class RTCMediaConstraints : public webrtc::MediaConstraintsInterface { | |
156 public: | |
157 explicit RTCMediaConstraints( | |
158 const WebKit::WebMediaConstraints& /*constraints*/) { | |
159 } | |
160 ~RTCMediaConstraints() {} | |
161 }; | |
162 | |
163 RTCPeerConnectionHandler::RTCPeerConnectionHandler( | |
164 WebKit::WebRTCPeerConnectionHandlerClient* client, | |
165 MediaStreamDependencyFactory* dependency_factory) | |
166 : PeerConnectionHandlerBase(dependency_factory), | |
167 client_(client) { | |
168 } | |
169 | |
170 RTCPeerConnectionHandler::~RTCPeerConnectionHandler() { | |
171 } | |
172 | |
173 bool RTCPeerConnectionHandler::initialize( | |
174 const WebKit::WebRTCConfiguration& server_configuration, | |
175 const WebKit::WebMediaConstraints& options ) { | |
176 webrtc::JsepInterface::IceServers servers; | |
177 GetNativeIceServers(server_configuration, &servers); | |
178 | |
179 RTCMediaConstraints constraints(options); | |
180 native_peer_connection_ = | |
181 dependency_factory_->CreatePeerConnection( | |
182 servers, &constraints, this); | |
183 if (!native_peer_connection_) { | |
184 LOG(ERROR) << "Failed to initialize native PeerConnection."; | |
185 return false; | |
186 } | |
187 return true; | |
188 } | |
189 | |
190 void RTCPeerConnectionHandler::createOffer( | |
191 const WebKit::WebRTCSessionDescriptionRequest& request, | |
192 const WebKit::WebMediaConstraints& options) { | |
193 talk_base::scoped_refptr<CreateSessionDescriptionRequest> description_request( | |
194 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>( | |
195 request)); | |
196 RTCMediaConstraints constraints(options); | |
197 native_peer_connection_->CreateOffer( | |
198 description_request.get(), &constraints); | |
199 } | |
200 | |
201 void RTCPeerConnectionHandler::createAnswer( | |
202 const WebKit::WebRTCSessionDescriptionRequest& request, | |
203 const WebKit::WebMediaConstraints& options) { | |
204 talk_base::scoped_refptr<CreateSessionDescriptionRequest> description_request( | |
205 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>( | |
206 request)); | |
207 RTCMediaConstraints constraints(options); | |
208 native_peer_connection_->CreateAnswer(description_request.get(), | |
209 &constraints); | |
210 } | |
211 | |
212 void RTCPeerConnectionHandler::setLocalDescription( | |
213 const WebKit::WebRTCVoidRequest& request, | |
214 const WebKit::WebRTCSessionDescriptionDescriptor& description) { | |
215 webrtc::SessionDescriptionInterface* native_desc = | |
216 CreateNativeSessionDescription(description); | |
217 if (!native_desc) { | |
218 LOG(ERROR) << "Failed to parse SessionDescription."; | |
Ronghua Wu (Left Chromium)
2012/08/15 00:57:32
Can you just LOG the |reason|, so that you don't n
perkj_chrome
2012/08/15 09:12:30
Done.
| |
219 WebKit::WebString reason("Failed to parse SessionDescription."); | |
220 request.requestFailed(reason); | |
221 return; | |
222 } | |
223 talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request( | |
224 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request)); | |
225 native_peer_connection_->SetLocalDescription(set_request.get(), native_desc); | |
226 } | |
227 | |
228 void RTCPeerConnectionHandler::setRemoteDescription( | |
229 const WebKit::WebRTCVoidRequest& request, | |
230 const WebKit::WebRTCSessionDescriptionDescriptor& description) { | |
231 webrtc::SessionDescriptionInterface* native_desc = | |
232 CreateNativeSessionDescription(description); | |
233 if (!native_desc) { | |
234 LOG(ERROR) << "Failed to parse SessionDescription."; | |
235 WebKit::WebString reason("Failed to parse SessionDescription."); | |
236 request.requestFailed(reason); | |
237 return; | |
238 } | |
239 talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request( | |
240 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request)); | |
241 native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc); | |
242 } | |
243 | |
244 WebKit::WebRTCSessionDescriptionDescriptor | |
245 RTCPeerConnectionHandler::localDescription() { | |
246 const webrtc::SessionDescriptionInterface* native_desc = | |
247 native_peer_connection_->local_description(); | |
248 WebKit::WebRTCSessionDescriptionDescriptor description = | |
249 CreateWebKitSessionDescription(native_desc); | |
250 return description; | |
251 } | |
252 | |
253 WebKit::WebRTCSessionDescriptionDescriptor | |
254 RTCPeerConnectionHandler::remoteDescription() { | |
255 const webrtc::SessionDescriptionInterface* native_desc = | |
256 native_peer_connection_->remote_description(); | |
257 WebKit::WebRTCSessionDescriptionDescriptor description = | |
258 CreateWebKitSessionDescription(native_desc); | |
259 return description; | |
260 } | |
261 | |
262 bool RTCPeerConnectionHandler::updateICE( | |
263 const WebKit::WebRTCConfiguration& server_configuration, | |
264 const WebKit::WebMediaConstraints& options) { | |
265 webrtc::JsepInterface::IceServers servers; | |
266 GetNativeIceServers(server_configuration, &servers); | |
267 RTCMediaConstraints constraints(options); | |
268 return native_peer_connection_->UpdateIce(servers, | |
269 &constraints); | |
270 } | |
271 | |
272 bool RTCPeerConnectionHandler::addICECandidate( | |
273 const WebKit::WebRTCICECandidateDescriptor& candidate) { | |
274 scoped_ptr<webrtc::IceCandidateInterface> native_candidate( | |
275 dependency_factory_->CreateIceCandidate( | |
276 UTF16ToUTF8(candidate.sdpMid()), | |
277 candidate.sdpMLineIndex(), | |
278 UTF16ToUTF8(candidate.candidate()))); | |
279 if (!native_candidate.get()) { | |
280 LOG(ERROR) << "Could not create native ICE candidate."; | |
281 return false; | |
282 } | |
283 | |
284 bool return_value = | |
285 native_peer_connection_->AddIceCandidate(native_candidate.get()); | |
286 if (!return_value) | |
287 LOG(ERROR) << "Error processing ICE candidate."; | |
288 return return_value; | |
289 } | |
290 | |
291 bool RTCPeerConnectionHandler::addStream( | |
292 const WebKit::WebMediaStreamDescriptor& stream, | |
293 const WebKit::WebMediaConstraints& options) { | |
294 RTCMediaConstraints constraints(options); | |
295 return AddStream(stream, &constraints); | |
296 } | |
297 | |
298 void RTCPeerConnectionHandler::removeStream( | |
299 const WebKit::WebMediaStreamDescriptor& stream) { | |
300 RemoveStream(stream); | |
301 } | |
302 | |
303 void RTCPeerConnectionHandler::stop() { | |
304 DVLOG(1) << "RTCPeerConnectionHandler::stop"; | |
305 native_peer_connection_ = NULL; | |
306 } | |
307 | |
308 void RTCPeerConnectionHandler::OnError() { | |
309 // TODO(perkj): Implement. | |
310 NOTIMPLEMENTED(); | |
311 } | |
312 | |
313 void RTCPeerConnectionHandler::OnStateChange(StateType state_changed) { | |
314 switch (state_changed) { | |
315 case kReadyState: { | |
316 WebKit::WebRTCPeerConnectionHandlerClient::ReadyState ready_state = | |
317 GetWebKitReadyState(native_peer_connection_->ready_state()); | |
318 client_->didChangeReadyState(ready_state); | |
319 break; | |
320 } | |
321 case kIceState: { | |
322 WebKit::WebRTCPeerConnectionHandlerClient::ICEState ice_state = | |
323 GetWebKitIceState(native_peer_connection_->ice_state()); | |
324 client_->didChangeICEState(ice_state); | |
325 break; | |
326 } | |
327 default: | |
328 NOTREACHED(); | |
329 break; | |
330 } | |
331 } | |
332 | |
333 void RTCPeerConnectionHandler::OnAddStream( | |
334 webrtc::MediaStreamInterface* stream) { | |
335 if (!stream) { | |
336 LOG(ERROR) << "OnAddStream: stream is null"; | |
337 return; | |
338 } | |
339 | |
340 DCHECK(remote_streams_.find(stream) == remote_streams_.end()); | |
341 WebKit::WebMediaStreamDescriptor descriptor = | |
342 CreateWebKitStreamDescriptor(stream); | |
343 remote_streams_.insert( | |
344 std::pair<webrtc::MediaStreamInterface*, | |
345 WebKit::WebMediaStreamDescriptor>(stream, descriptor)); | |
346 client_->didAddRemoteStream(descriptor); | |
347 } | |
348 | |
349 void RTCPeerConnectionHandler::OnRemoveStream( | |
350 webrtc::MediaStreamInterface* stream) { | |
351 if (!stream) { | |
352 LOG(ERROR) << "OnRemoveStream: stream is null"; | |
353 return; | |
354 } | |
355 | |
356 RemoteStreamMap::iterator it = remote_streams_.find(stream); | |
357 if (it == remote_streams_.end()) { | |
358 NOTREACHED() << "Stream not found"; | |
359 return; | |
360 } | |
361 WebKit::WebMediaStreamDescriptor descriptor = it->second; | |
362 DCHECK(!descriptor.isNull()); | |
363 remote_streams_.erase(it); | |
364 client_->didRemoveRemoteStream(descriptor); | |
365 } | |
366 | |
367 void RTCPeerConnectionHandler::OnIceCandidate( | |
368 const webrtc::IceCandidateInterface* candidate) { | |
369 std::string sdp; | |
370 if (!candidate->ToString(&sdp)) { | |
371 LOG(ERROR) << "OnIceCandidate: Could not get SDP string."; | |
372 return; | |
373 } | |
374 WebKit::WebRTCICECandidateDescriptor web_candidate; | |
375 web_candidate.initialize(UTF8ToUTF16(sdp), | |
376 UTF8ToUTF16(candidate->sdp_mid()), | |
377 candidate->sdp_mline_index()); | |
378 client_->didGenerateICECandidate(web_candidate); | |
379 } | |
380 | |
381 void RTCPeerConnectionHandler::OnIceComplete() { | |
382 // Generates a NULL ice candidate object. | |
383 WebKit::WebRTCICECandidateDescriptor web_candidate; | |
384 client_->didGenerateICECandidate(web_candidate); | |
385 } | |
386 | |
387 void RTCPeerConnectionHandler::OnRenegotiationNeeded() { | |
388 client_->doRenegotiate(); | |
389 } | |
390 | |
391 webrtc::SessionDescriptionInterface* | |
392 RTCPeerConnectionHandler::CreateNativeSessionDescription( | |
393 const WebKit::WebRTCSessionDescriptionDescriptor& description) { | |
394 std::string sdp = UTF16ToUTF8(description.sdp()); | |
395 std::string type = UTF16ToUTF8(description.type()); | |
396 webrtc::SessionDescriptionInterface* native_desc = | |
397 dependency_factory_->CreateSessionDescription(type, sdp); | |
398 if (!native_desc) { | |
399 LOG(ERROR) << "Failed to create native session description. Type: " | |
400 << type << " SDP: " << sdp; | |
401 return NULL; | |
402 } | |
403 | |
404 return native_desc; | |
405 } | |
OLD | NEW |