Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(271)

Side by Side Diff: content/renderer/media/rtc_peer_connection_handler.cc

Issue 10703095: New PeerConnection handler in Chrome to support latest PeerConnection draft (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed broken unittes. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/WebRTCICECandidate. h"
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectio nHandlerClient.h"
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescri ption.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();
tommi (sloooow) - chröme 2012/09/13 12:20:14 nit: you can remove this since you have a default
perkj_chrome 2012/09/13 13:41:34 Done.
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::WebRTCSessionDescription
73 CreateWebKitSessionDescription(
tommi (sloooow) - chröme 2012/09/13 12:20:14 shouldn't this have zero indent like in other plac
perkj_chrome 2012/09/13 13:41:34 Done.
74 const webrtc::SessionDescriptionInterface* native_desc) {
75 WebKit::WebRTCSessionDescription 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*/) {
tommi (sloooow) - chröme 2012/09/13 12:20:14 remove /* */
perkj_chrome 2012/09/13 13:41:34 Done.
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::WebRTCSessionDescription& description) {
215 webrtc::SessionDescriptionInterface* native_desc =
216 CreateNativeSessionDescription(description);
217 if (!native_desc) {
218 const char kReason[] = "Failed to parse SessionDescription.";
219 LOG(ERROR) << kReason;
220 WebKit::WebString reason(kReason);
221 request.requestFailed(reason);
222 return;
223 }
224 talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request(
225 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
226 native_peer_connection_->SetLocalDescription(set_request.get(), native_desc);
227 }
228
229 void RTCPeerConnectionHandler::setRemoteDescription(
230 const WebKit::WebRTCVoidRequest& request,
231 const WebKit::WebRTCSessionDescription& description) {
232 webrtc::SessionDescriptionInterface* native_desc =
233 CreateNativeSessionDescription(description);
234 if (!native_desc) {
235 const char kReason[] = "Failed to parse SessionDescription.";
236 LOG(ERROR) << kReason;
237 WebKit::WebString reason(kReason);
238 request.requestFailed(reason);
239 return;
240 }
241 talk_base::scoped_refptr<SetSessionDescriptionRequest> set_request(
tommi (sloooow) - chröme 2012/09/13 12:20:14 can you use Chrome's scoped_refptr instead? (same
perkj_chrome 2012/09/13 13:41:34 Done.
242 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
243 native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc);
tommi (sloooow) - chröme 2012/09/13 12:20:14 ...and then you don't need the .get() calls
perkj_chrome 2012/09/13 13:41:34 Done.
244 }
245
246 WebKit::WebRTCSessionDescription
247 RTCPeerConnectionHandler::localDescription() {
248 const webrtc::SessionDescriptionInterface* native_desc =
249 native_peer_connection_->local_description();
250 WebKit::WebRTCSessionDescription description =
251 CreateWebKitSessionDescription(native_desc);
252 return description;
253 }
254
255 WebKit::WebRTCSessionDescription
256 RTCPeerConnectionHandler::remoteDescription() {
257 const webrtc::SessionDescriptionInterface* native_desc =
258 native_peer_connection_->remote_description();
259 WebKit::WebRTCSessionDescription description =
260 CreateWebKitSessionDescription(native_desc);
261 return description;
262 }
263
264 bool RTCPeerConnectionHandler::updateICE(
265 const WebKit::WebRTCConfiguration& server_configuration,
266 const WebKit::WebMediaConstraints& options) {
267 webrtc::JsepInterface::IceServers servers;
268 GetNativeIceServers(server_configuration, &servers);
269 RTCMediaConstraints constraints(options);
270 return native_peer_connection_->UpdateIce(servers,
271 &constraints);
272 }
273
274 bool RTCPeerConnectionHandler::addICECandidate(
275 const WebKit::WebRTCICECandidate& candidate) {
276 scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
277 dependency_factory_->CreateIceCandidate(
278 UTF16ToUTF8(candidate.sdpMid()),
279 candidate.sdpMLineIndex(),
280 UTF16ToUTF8(candidate.candidate())));
281 if (!native_candidate.get()) {
282 LOG(ERROR) << "Could not create native ICE candidate.";
283 return false;
284 }
285
286 bool return_value =
287 native_peer_connection_->AddIceCandidate(native_candidate.get());
288 if (!return_value)
289 LOG(ERROR) << "Error processing ICE candidate.";
tommi (sloooow) - chröme 2012/09/13 12:20:14 use LOG_IF
perkj_chrome 2012/09/13 13:41:34 Done.
290 return return_value;
291 }
292
293 bool RTCPeerConnectionHandler::addStream(
294 const WebKit::WebMediaStreamDescriptor& stream,
295 const WebKit::WebMediaConstraints& options) {
296 RTCMediaConstraints constraints(options);
297 return AddStream(stream, &constraints);
298 }
299
300 void RTCPeerConnectionHandler::removeStream(
301 const WebKit::WebMediaStreamDescriptor& stream) {
302 RemoveStream(stream);
303 }
304
305 void RTCPeerConnectionHandler::stop() {
306 DVLOG(1) << "RTCPeerConnectionHandler::stop";
307 native_peer_connection_ = NULL;
308 }
309
310 void RTCPeerConnectionHandler::OnError() {
311 // TODO(perkj): Implement.
312 NOTIMPLEMENTED();
313 }
314
315 void RTCPeerConnectionHandler::OnStateChange(StateType state_changed) {
316 switch (state_changed) {
317 case kReadyState: {
318 WebKit::WebRTCPeerConnectionHandlerClient::ReadyState ready_state =
319 GetWebKitReadyState(native_peer_connection_->ready_state());
320 client_->didChangeReadyState(ready_state);
321 break;
322 }
323 case kIceState: {
324 WebKit::WebRTCPeerConnectionHandlerClient::ICEState ice_state =
325 GetWebKitIceState(native_peer_connection_->ice_state());
326 client_->didChangeICEState(ice_state);
327 break;
328 }
329 default:
330 NOTREACHED();
331 break;
332 }
333 }
334
335 void RTCPeerConnectionHandler::OnAddStream(
336 webrtc::MediaStreamInterface* stream) {
337 if (!stream) {
338 LOG(ERROR) << "OnAddStream: stream is null";
tommi (sloooow) - chröme 2012/09/13 12:20:14 should there just be a DCHECK at the top of the fu
perkj_chrome 2012/09/13 13:41:34 Done.
339 return;
340 }
341
342 DCHECK(remote_streams_.find(stream) == remote_streams_.end());
343 WebKit::WebMediaStreamDescriptor descriptor =
344 CreateWebKitStreamDescriptor(stream);
345 remote_streams_.insert(
346 std::pair<webrtc::MediaStreamInterface*,
347 WebKit::WebMediaStreamDescriptor>(stream, descriptor));
348 client_->didAddRemoteStream(descriptor);
349 }
350
351 void RTCPeerConnectionHandler::OnRemoveStream(
352 webrtc::MediaStreamInterface* stream) {
353 if (!stream) {
354 LOG(ERROR) << "OnRemoveStream: stream is null";
tommi (sloooow) - chröme 2012/09/13 12:20:14 DCHECK? same for similar cases throughout
perkj_chrome 2012/09/13 13:41:34 Done.
355 return;
356 }
357
358 RemoteStreamMap::iterator it = remote_streams_.find(stream);
359 if (it == remote_streams_.end()) {
360 NOTREACHED() << "Stream not found";
361 return;
362 }
363 WebKit::WebMediaStreamDescriptor descriptor = it->second;
364 DCHECK(!descriptor.isNull());
365 remote_streams_.erase(it);
366 client_->didRemoveRemoteStream(descriptor);
367 }
368
369 void RTCPeerConnectionHandler::OnIceCandidate(
370 const webrtc::IceCandidateInterface* candidate) {
371 std::string sdp;
372 if (!candidate->ToString(&sdp)) {
373 LOG(ERROR) << "OnIceCandidate: Could not get SDP string.";
374 return;
375 }
376 WebKit::WebRTCICECandidate web_candidate;
377 web_candidate.initialize(UTF8ToUTF16(sdp),
378 UTF8ToUTF16(candidate->sdp_mid()),
379 candidate->sdp_mline_index());
380 client_->didGenerateICECandidate(web_candidate);
381 }
382
383 void RTCPeerConnectionHandler::OnIceComplete() {
384 // Generates a NULL ice candidate object.
385 WebKit::WebRTCICECandidate web_candidate;
386 client_->didGenerateICECandidate(web_candidate);
387 }
388
389 void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
390 client_->negotiationNeeded();
391 }
392
393 webrtc::SessionDescriptionInterface*
394 RTCPeerConnectionHandler::CreateNativeSessionDescription(
395 const WebKit::WebRTCSessionDescription& description) {
396 std::string sdp = UTF16ToUTF8(description.sdp());
397 std::string type = UTF16ToUTF8(description.type());
398 webrtc::SessionDescriptionInterface* native_desc =
399 dependency_factory_->CreateSessionDescription(type, sdp);
400 if (!native_desc) {
tommi (sloooow) - chröme 2012/09/13 12:20:14 remove this if+return and just do this instead: L
perkj_chrome 2012/09/13 13:41:34 Done.
401 LOG(ERROR) << "Failed to create native session description. Type: "
402 << type << " SDP: " << sdp;
403 return NULL;
404 }
405
406 return native_desc;
407 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698