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

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: Readd the UMA histogram for Deprecated PeerConnection to not screw up the stats. 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 }
49
50 static WebKit::WebRTCPeerConnectionHandlerClient::ReadyState
51 GetWebKitReadyState(webrtc::PeerConnectionInterface::ReadyState ready_state) {
52 switch (ready_state) {
53 case webrtc::PeerConnectionInterface::kNew:
54 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateNew;
55 case webrtc::PeerConnectionInterface::kOpening:
56 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateOpening;
57 case webrtc::PeerConnectionInterface::kActive:
58 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateActive;
59 case webrtc::PeerConnectionInterface::kClosing:
60 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosing;
61 case webrtc::PeerConnectionInterface::kClosed:
62 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed;
63 default:
64 NOTREACHED();
65 return WebKit::WebRTCPeerConnectionHandlerClient::ReadyStateClosed;
66 }
67 }
68
69 static WebKit::WebRTCSessionDescription
70 CreateWebKitSessionDescription(
71 const webrtc::SessionDescriptionInterface* native_desc) {
72 WebKit::WebRTCSessionDescription description;
73 if (!native_desc) {
74 LOG(ERROR) << "Native session description is null.";
75 return description;
76 }
77
78 std::string sdp;
79 if (!native_desc->ToString(&sdp)) {
80 LOG(ERROR) << "Failed to get SDP string of native session description.";
81 return description;
82 }
83
84 description.initialize(UTF8ToUTF16(native_desc->type()), UTF8ToUTF16(sdp));
85 return description;
86 }
87
88 // Converter functions from WebKit types to libjingle types.
89
90 static void GetNativeIceServers(
91 const WebKit::WebRTCConfiguration& server_configuration,
92 webrtc::JsepInterface::IceServers* servers) {
93 if (server_configuration.isNull() || !servers)
94 return;
95 for (size_t i = 0; i < server_configuration.numberOfServers(); ++i) {
96 webrtc::JsepInterface::IceServer server;
97 const WebKit::WebRTCICEServer& webkit_server =
98 server_configuration.server(i);
99 server.password = UTF16ToUTF8(webkit_server.credential());
100 server.uri = webkit_server.uri().spec();
101 servers->push_back(server);
102 }
103 }
104
105 // Class mapping responses from calls to libjingle CreateOffer/Answer and
106 // the WebKit::WebRTCSessionDescriptionRequest.
107 class CreateSessionDescriptionRequest
108 : public webrtc::CreateSessionDescriptionObserver {
109 public:
110 explicit CreateSessionDescriptionRequest(
111 const WebKit::WebRTCSessionDescriptionRequest& request)
112 : webkit_request_(request) {}
113
114 virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE {
115 webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc));
116 }
117 virtual void OnFailure(const std::string& error) OVERRIDE {
118 webkit_request_.requestFailed(UTF8ToUTF16(error));
119 }
120
121 protected:
122 virtual ~CreateSessionDescriptionRequest() {}
123
124 private:
125 WebKit::WebRTCSessionDescriptionRequest webkit_request_;
126 };
127
128 // Class mapping responses from calls to libjingle
129 // SetLocalDescription/SetRemoteDescription and a WebKit::WebRTCVoidRequest.
130 class SetSessionDescriptionRequest
131 : public webrtc::SetSessionDescriptionObserver {
132 public:
133 explicit SetSessionDescriptionRequest(
134 const WebKit::WebRTCVoidRequest& request)
135 : webkit_request_(request) {}
136
137 virtual void OnSuccess() OVERRIDE {
138 webkit_request_.requestSucceeded();
139 }
140 virtual void OnFailure(const std::string& error) OVERRIDE {
141 webkit_request_.requestFailed(UTF8ToUTF16(error));
142 }
143
144 protected:
145 virtual ~SetSessionDescriptionRequest() {}
146
147 private:
148 WebKit::WebRTCVoidRequest webkit_request_;
149 };
150
151 // TODO(perkj): Implement MediaConstraints when WebKit have done so.
152 class RTCMediaConstraints : public webrtc::MediaConstraintsInterface {
153 public:
154 explicit RTCMediaConstraints(
155 const WebKit::WebMediaConstraints& constraints) {
156 }
157 ~RTCMediaConstraints() {}
158 };
159
160 RTCPeerConnectionHandler::RTCPeerConnectionHandler(
161 WebKit::WebRTCPeerConnectionHandlerClient* client,
162 MediaStreamDependencyFactory* dependency_factory)
163 : PeerConnectionHandlerBase(dependency_factory),
164 client_(client) {
165 }
166
167 RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
168 }
169
170 bool RTCPeerConnectionHandler::initialize(
171 const WebKit::WebRTCConfiguration& server_configuration,
172 const WebKit::WebMediaConstraints& options ) {
173 webrtc::JsepInterface::IceServers servers;
174 GetNativeIceServers(server_configuration, &servers);
175
176 RTCMediaConstraints constraints(options);
177 native_peer_connection_ =
178 dependency_factory_->CreatePeerConnection(
179 servers, &constraints, this);
180 if (!native_peer_connection_) {
181 LOG(ERROR) << "Failed to initialize native PeerConnection.";
182 return false;
183 }
184 return true;
185 }
186
187 void RTCPeerConnectionHandler::createOffer(
188 const WebKit::WebRTCSessionDescriptionRequest& request,
189 const WebKit::WebMediaConstraints& options) {
190 scoped_refptr<CreateSessionDescriptionRequest> description_request(
191 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
192 request));
193 RTCMediaConstraints constraints(options);
194 native_peer_connection_->CreateOffer(description_request, &constraints);
195 }
196
197 void RTCPeerConnectionHandler::createAnswer(
198 const WebKit::WebRTCSessionDescriptionRequest& request,
199 const WebKit::WebMediaConstraints& options) {
200 scoped_refptr<CreateSessionDescriptionRequest> description_request(
201 new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
202 request));
203 RTCMediaConstraints constraints(options);
204 native_peer_connection_->CreateAnswer(description_request, &constraints);
205 }
206
207 void RTCPeerConnectionHandler::setLocalDescription(
208 const WebKit::WebRTCVoidRequest& request,
209 const WebKit::WebRTCSessionDescription& description) {
210 webrtc::SessionDescriptionInterface* native_desc =
211 CreateNativeSessionDescription(description);
212 if (!native_desc) {
213 const char kReason[] = "Failed to parse SessionDescription.";
214 LOG(ERROR) << kReason;
215 WebKit::WebString reason(kReason);
216 request.requestFailed(reason);
217 return;
218 }
219 scoped_refptr<SetSessionDescriptionRequest> set_request(
220 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
221 native_peer_connection_->SetLocalDescription(set_request, native_desc);
222 }
223
224 void RTCPeerConnectionHandler::setRemoteDescription(
225 const WebKit::WebRTCVoidRequest& request,
226 const WebKit::WebRTCSessionDescription& description) {
227 webrtc::SessionDescriptionInterface* native_desc =
228 CreateNativeSessionDescription(description);
229 if (!native_desc) {
230 const char kReason[] = "Failed to parse SessionDescription.";
231 LOG(ERROR) << kReason;
232 WebKit::WebString reason(kReason);
233 request.requestFailed(reason);
234 return;
235 }
236 scoped_refptr<SetSessionDescriptionRequest> set_request(
237 new talk_base::RefCountedObject<SetSessionDescriptionRequest>(request));
238 native_peer_connection_->SetRemoteDescription(set_request, native_desc);
239 }
240
241 WebKit::WebRTCSessionDescription
242 RTCPeerConnectionHandler::localDescription() {
243 const webrtc::SessionDescriptionInterface* native_desc =
244 native_peer_connection_->local_description();
245 WebKit::WebRTCSessionDescription description =
246 CreateWebKitSessionDescription(native_desc);
247 return description;
248 }
249
250 WebKit::WebRTCSessionDescription
251 RTCPeerConnectionHandler::remoteDescription() {
252 const webrtc::SessionDescriptionInterface* native_desc =
253 native_peer_connection_->remote_description();
254 WebKit::WebRTCSessionDescription description =
255 CreateWebKitSessionDescription(native_desc);
256 return description;
257 }
258
259 bool RTCPeerConnectionHandler::updateICE(
260 const WebKit::WebRTCConfiguration& server_configuration,
261 const WebKit::WebMediaConstraints& options) {
262 webrtc::JsepInterface::IceServers servers;
263 GetNativeIceServers(server_configuration, &servers);
264 RTCMediaConstraints constraints(options);
265 return native_peer_connection_->UpdateIce(servers,
266 &constraints);
267 }
268
269 bool RTCPeerConnectionHandler::addICECandidate(
270 const WebKit::WebRTCICECandidate& candidate) {
271 scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
272 dependency_factory_->CreateIceCandidate(
273 UTF16ToUTF8(candidate.sdpMid()),
274 candidate.sdpMLineIndex(),
275 UTF16ToUTF8(candidate.candidate())));
276 if (!native_candidate.get()) {
277 LOG(ERROR) << "Could not create native ICE candidate.";
278 return false;
279 }
280
281 bool return_value =
282 native_peer_connection_->AddIceCandidate(native_candidate.get());
283 LOG_IF(ERROR, !return_value) << "Error processing ICE candidate.";
284 return return_value;
285 }
286
287 bool RTCPeerConnectionHandler::addStream(
288 const WebKit::WebMediaStreamDescriptor& stream,
289 const WebKit::WebMediaConstraints& options) {
290 RTCMediaConstraints constraints(options);
291 return AddStream(stream, &constraints);
292 }
293
294 void RTCPeerConnectionHandler::removeStream(
295 const WebKit::WebMediaStreamDescriptor& stream) {
296 RemoveStream(stream);
297 }
298
299 void RTCPeerConnectionHandler::stop() {
300 DVLOG(1) << "RTCPeerConnectionHandler::stop";
301 native_peer_connection_ = NULL;
302 }
303
304 void RTCPeerConnectionHandler::OnError() {
305 // TODO(perkj): Implement.
306 NOTIMPLEMENTED();
307 }
308
309 void RTCPeerConnectionHandler::OnStateChange(StateType state_changed) {
310 switch (state_changed) {
311 case kReadyState: {
312 WebKit::WebRTCPeerConnectionHandlerClient::ReadyState ready_state =
313 GetWebKitReadyState(native_peer_connection_->ready_state());
314 client_->didChangeReadyState(ready_state);
315 break;
316 }
317 case kIceState: {
318 WebKit::WebRTCPeerConnectionHandlerClient::ICEState ice_state =
319 GetWebKitIceState(native_peer_connection_->ice_state());
320 client_->didChangeICEState(ice_state);
321 break;
322 }
323 default:
324 NOTREACHED();
325 break;
326 }
327 }
328
329 void RTCPeerConnectionHandler::OnAddStream(
330 webrtc::MediaStreamInterface* stream) {
331 DCHECK(stream);
332 DCHECK(remote_streams_.find(stream) == remote_streams_.end());
333 WebKit::WebMediaStreamDescriptor descriptor =
334 CreateWebKitStreamDescriptor(stream);
335 remote_streams_.insert(
336 std::pair<webrtc::MediaStreamInterface*,
337 WebKit::WebMediaStreamDescriptor>(stream, descriptor));
338 client_->didAddRemoteStream(descriptor);
339 }
340
341 void RTCPeerConnectionHandler::OnRemoveStream(
342 webrtc::MediaStreamInterface* stream) {
343 DCHECK(stream);
344 RemoteStreamMap::iterator it = remote_streams_.find(stream);
345 if (it == remote_streams_.end()) {
346 NOTREACHED() << "Stream not found";
347 return;
348 }
349 WebKit::WebMediaStreamDescriptor descriptor = it->second;
350 DCHECK(!descriptor.isNull());
351 remote_streams_.erase(it);
352 client_->didRemoveRemoteStream(descriptor);
353 }
354
355 void RTCPeerConnectionHandler::OnIceCandidate(
356 const webrtc::IceCandidateInterface* candidate) {
357 DCHECK(candidate);
358 std::string sdp;
359 if (!candidate->ToString(&sdp)) {
360 NOTREACHED() << "OnIceCandidate: Could not get SDP string.";
361 return;
362 }
363 WebKit::WebRTCICECandidate web_candidate;
364 web_candidate.initialize(UTF8ToUTF16(sdp),
365 UTF8ToUTF16(candidate->sdp_mid()),
366 candidate->sdp_mline_index());
367 client_->didGenerateICECandidate(web_candidate);
368 }
369
370 void RTCPeerConnectionHandler::OnIceComplete() {
371 // Generates a NULL ice candidate object.
372 WebKit::WebRTCICECandidate web_candidate;
373 client_->didGenerateICECandidate(web_candidate);
374 }
375
376 void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
377 client_->negotiationNeeded();
378 }
379
380 webrtc::SessionDescriptionInterface*
381 RTCPeerConnectionHandler::CreateNativeSessionDescription(
382 const WebKit::WebRTCSessionDescription& description) {
383 std::string sdp = UTF16ToUTF8(description.sdp());
384 std::string type = UTF16ToUTF8(description.type());
385 webrtc::SessionDescriptionInterface* native_desc =
386 dependency_factory_->CreateSessionDescription(type, sdp);
387
388 LOG_IF(ERROR, !native_desc) << "Failed to create native session description."
389 << " Type: " << type << " SDP: " << sdp;
390
391 return native_desc;
392 }
OLDNEW
« no previous file with comments | « content/renderer/media/rtc_peer_connection_handler.h ('k') | content/renderer/media/rtc_peer_connection_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698