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

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 code review comments by Ronghua. Created 8 years, 4 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/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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698