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/peer_connection_handler_jsep.h" | |
6 | |
7 #include <utility> | |
8 #include <vector> | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/logging.h" | |
12 #include "base/string_number_conversions.h" | |
13 #include "base/utf_string_conversions.h" | |
14 #include "content/renderer/media/media_stream_dependency_factory.h" | |
15 #include "content/renderer/media/media_stream_impl.h" | |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebIceCandid ate.h" | |
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebIceOption s.h" | |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebJSEPPeerC onnectionHandlerClient.h" | |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaHint s.h" | |
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre amDescriptor.h" | |
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre amSource.h" | |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSessionDe scription.h" | |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" | |
24 | |
25 PeerConnectionHandlerJsep::PeerConnectionHandlerJsep( | |
26 WebKit::WebJSEPPeerConnectionHandlerClient* client, | |
27 MediaStreamImpl* msi, | |
28 MediaStreamDependencyFactory* dependency_factory) | |
29 : PeerConnectionHandlerBase(msi, dependency_factory), | |
30 client_(client) { | |
31 } | |
32 | |
33 PeerConnectionHandlerJsep::~PeerConnectionHandlerJsep() { | |
34 } | |
35 | |
36 void PeerConnectionHandlerJsep::initialize( | |
37 const WebKit::WebString& server_configuration, | |
38 const WebKit::WebString& username) { | |
39 native_peer_connection_ = dependency_factory_->CreatePeerConnection( | |
40 UTF16ToUTF8(server_configuration), | |
41 this); | |
42 CHECK(native_peer_connection_); | |
43 } | |
44 | |
45 WebKit::WebSessionDescription PeerConnectionHandlerJsep::createOffer( | |
46 const WebKit::WebMediaHints& hints) { | |
47 WebKit::WebSessionDescription offer; | |
48 | |
49 webrtc::MediaHints native_hints(hints.audio(), hints.video()); | |
50 webrtc::SessionDescriptionInterface* native_offer = | |
51 native_peer_connection_->CreateOffer(native_hints); | |
52 if (!native_offer) | |
53 return offer; | |
54 | |
55 offer = CreateWebKitSessionDescription(native_offer); | |
56 delete native_offer; | |
57 return offer; | |
58 } | |
59 | |
60 WebKit::WebSessionDescription PeerConnectionHandlerJsep::createAnswer( | |
61 const WebKit::WebString& offer, | |
62 const WebKit::WebMediaHints& hints) { | |
63 WebKit::WebSessionDescription answer; | |
64 | |
65 webrtc::MediaHints native_hints(hints.audio(), hints.video()); | |
66 webrtc::SessionDescriptionInterface* native_offer = | |
67 webrtc::CreateSessionDescription(UTF16ToUTF8(offer)); | |
68 if (!native_offer) | |
69 return answer; | |
70 | |
71 webrtc::SessionDescriptionInterface* native_answer = | |
72 native_peer_connection_->CreateAnswer(native_hints, native_offer); | |
73 delete native_offer; | |
74 if (!native_answer) | |
75 return answer; | |
76 | |
77 answer = CreateWebKitSessionDescription(native_answer); | |
78 delete native_answer; | |
79 return answer; | |
80 } | |
81 | |
82 bool PeerConnectionHandlerJsep::setLocalDescription( | |
83 Action action, | |
84 const WebKit::WebSessionDescription& description) { | |
85 webrtc::PeerConnectionInterface::Action native_action; | |
86 if (!GetNativeAction(action, &native_action)) | |
87 return false; | |
88 | |
89 webrtc::SessionDescriptionInterface* native_desc = | |
90 CreateNativeSessionDescription(description); | |
91 if (!native_desc) | |
92 return false; | |
93 | |
94 return native_peer_connection_->SetLocalDescription(native_action, | |
95 native_desc); | |
96 } | |
97 | |
98 bool PeerConnectionHandlerJsep::setRemoteDescription( | |
99 Action action, | |
100 const WebKit::WebSessionDescription& description) { | |
101 webrtc::PeerConnectionInterface::Action native_action; | |
102 if (!GetNativeAction(action, &native_action)) | |
103 return false; | |
104 | |
105 webrtc::SessionDescriptionInterface* native_desc = | |
106 CreateNativeSessionDescription(description); | |
107 if (!native_desc) | |
108 return false; | |
109 | |
110 return native_peer_connection_->SetRemoteDescription(native_action, | |
111 native_desc); | |
112 } | |
113 | |
114 WebKit::WebSessionDescription PeerConnectionHandlerJsep::localDescription() { | |
115 const webrtc::SessionDescriptionInterface* native_desc = | |
116 native_peer_connection_->local_description(); | |
117 WebKit::WebSessionDescription description = | |
118 CreateWebKitSessionDescription(native_desc); | |
119 delete native_desc; | |
120 return description; | |
121 } | |
122 | |
123 WebKit::WebSessionDescription PeerConnectionHandlerJsep::remoteDescription() { | |
124 const webrtc::SessionDescriptionInterface* native_desc = | |
125 native_peer_connection_->remote_description(); | |
126 WebKit::WebSessionDescription description = | |
127 CreateWebKitSessionDescription(native_desc); | |
128 delete native_desc; | |
129 return description; | |
130 } | |
131 | |
132 bool PeerConnectionHandlerJsep::startIce(const WebKit::WebIceOptions& options) { | |
133 webrtc::PeerConnectionInterface::IceOptions native_options; | |
134 switch (options.useCandidates()) { | |
135 case WebKit::WebIceOptions::ALL: | |
136 native_options = webrtc::PeerConnectionInterface::kUseAll; | |
137 break; | |
138 case WebKit::WebIceOptions::NO_RELAY: | |
139 native_options = webrtc::PeerConnectionInterface::kNoRelay; | |
140 break; | |
141 case WebKit::WebIceOptions::ONLY_RELAY: | |
142 native_options = webrtc::PeerConnectionInterface::kOnlyRelay; | |
143 break; | |
144 default: | |
145 NOTREACHED(); | |
146 return false; | |
147 } | |
148 native_peer_connection_->StartIce(native_options); | |
149 return true; | |
150 } | |
151 | |
152 bool PeerConnectionHandlerJsep::processIceMessage( | |
153 const WebKit::WebIceCandidate& candidate) { | |
154 webrtc::IceCandidateInterface* native_candidate = | |
155 webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()), | |
156 UTF16ToUTF8(candidate.candidateLine())); | |
157 if (!native_candidate) | |
158 return false; | |
159 | |
160 bool return_value = | |
161 native_peer_connection_->ProcessIceMessage(native_candidate); | |
162 delete native_candidate; | |
163 return return_value; | |
164 } | |
165 | |
166 void PeerConnectionHandlerJsep::addStream( | |
167 const WebKit::WebMediaStreamDescriptor& stream) { | |
168 AddStream(stream); | |
169 native_peer_connection_->CommitStreamChanges(); | |
170 } | |
171 | |
172 void PeerConnectionHandlerJsep::removeStream( | |
173 const WebKit::WebMediaStreamDescriptor& stream) { | |
174 RemoveStream(stream); | |
175 native_peer_connection_->CommitStreamChanges(); | |
176 } | |
177 | |
178 void PeerConnectionHandlerJsep::stop() { | |
179 // TODO(ronghuawu): There's an issue with signaling messages being sent during | |
180 // close. We need to investigate further. Not calling Close() on native | |
181 // PeerConnection is OK for now. | |
182 native_peer_connection_ = NULL; | |
183 media_stream_impl_->ClosePeerConnection(); | |
184 } | |
185 | |
186 void PeerConnectionHandlerJsep::OnError() { | |
187 // TODO(grunell): Implement. | |
188 NOTIMPLEMENTED(); | |
189 } | |
190 | |
191 void PeerConnectionHandlerJsep::OnMessage(const std::string& msg) { | |
192 // TODO(grunell): Implement. | |
193 NOTIMPLEMENTED(); | |
194 } | |
195 | |
196 void PeerConnectionHandlerJsep::OnSignalingMessage(const std::string& msg) { | |
197 // Not used by JSEP PeerConnection. | |
198 NOTREACHED(); | |
199 } | |
200 | |
201 void PeerConnectionHandlerJsep::OnStateChange(StateType state_changed) { | |
202 switch (state_changed) { | |
203 case kReadyState: | |
204 WebKit::WebJSEPPeerConnectionHandlerClient::ReadyState ready_state; | |
205 switch (native_peer_connection_->ready_state()) { | |
206 case webrtc::PeerConnectionInterface::kNew: | |
207 ready_state = WebKit::WebJSEPPeerConnectionHandlerClient::NEW; | |
208 break; | |
209 case webrtc::PeerConnectionInterface::kNegotiating: | |
210 ready_state = WebKit::WebJSEPPeerConnectionHandlerClient::NEGOTIATING; | |
211 break; | |
212 case webrtc::PeerConnectionInterface::kActive: | |
213 ready_state = WebKit::WebJSEPPeerConnectionHandlerClient::ACTIVE; | |
214 break; | |
215 case webrtc::PeerConnectionInterface::kClosing: | |
216 // Not used by JSEP. | |
217 NOTREACHED(); | |
218 return; | |
219 case webrtc::PeerConnectionInterface::kClosed: | |
220 ready_state = WebKit::WebJSEPPeerConnectionHandlerClient::CLOSED; | |
221 break; | |
222 default: | |
223 NOTREACHED(); | |
224 return; | |
225 } | |
226 client_->didChangeReadyState(ready_state); | |
227 break; | |
228 case kIceState: | |
229 // TODO(grunell): Implement when available in native PeerConnection. | |
230 NOTIMPLEMENTED(); | |
231 break; | |
232 case kSdpState: | |
233 // Not used by JSEP. | |
234 NOTREACHED(); | |
235 return; | |
236 default: | |
237 NOTREACHED(); | |
238 return; | |
239 } | |
240 } | |
241 | |
242 void PeerConnectionHandlerJsep::OnAddStream( | |
243 webrtc::MediaStreamInterface* stream) { | |
244 if (!stream) | |
245 return; | |
246 | |
247 if (!message_loop_proxy_->BelongsToCurrentThread()) { | |
248 message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | |
249 &PeerConnectionHandlerJsep::OnAddStreamCallback, | |
250 base::Unretained(this), | |
tommi (sloooow) - chröme
2012/03/15 12:31:52
is there no chance that the PeerConnectionHandlerJ
Henrik Grunell
2012/03/23 12:50:45
Actually, we are guaranteed to be called on the co
| |
251 stream)); | |
252 } else { | |
253 OnAddStreamCallback(stream); | |
254 } | |
255 } | |
256 | |
257 void PeerConnectionHandlerJsep::OnRemoveStream( | |
258 webrtc::MediaStreamInterface* stream) { | |
259 if (!stream) | |
260 return; | |
261 | |
262 if (!message_loop_proxy_->BelongsToCurrentThread()) { | |
263 message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | |
264 &PeerConnectionHandlerJsep::OnRemoveStreamCallback, | |
265 base::Unretained(this), | |
266 stream)); | |
267 } else { | |
268 OnRemoveStreamCallback(stream); | |
269 } | |
270 } | |
271 | |
272 void PeerConnectionHandlerJsep::OnIceCandidate( | |
273 const webrtc::IceCandidateInterface* candidate) { | |
274 WebKit::WebIceCandidate web_candidate; | |
275 | |
276 std::string label = candidate->label(); | |
277 std::string sdp; | |
278 if (!candidate->ToString(&sdp)) { | |
279 LOG(ERROR) << "Could not get SDP string"; | |
280 return; | |
281 } | |
282 | |
283 web_candidate.initialize(UTF8ToUTF16(label), UTF8ToUTF16(sdp)); | |
284 | |
285 // moreToFollow parameter isn't supported in native PeerConnection, so we | |
286 // always use true here, and then false in OnIceComplete(). | |
287 client_->didGenerateIceCandidate(web_candidate, true); | |
288 } | |
289 | |
290 void PeerConnectionHandlerJsep::OnIceComplete() { | |
291 // moreToFollow parameter isn't supported in native PeerConnection, so we | |
292 // send an empty WebIseCandidate with moreToFollow=false. | |
293 WebKit::WebIceCandidate web_candidate; | |
294 client_->didGenerateIceCandidate(web_candidate, false); | |
295 } | |
296 | |
297 webrtc::SessionDescriptionInterface* | |
298 PeerConnectionHandlerJsep::CreateNativeSessionDescription( | |
299 const WebKit::WebSessionDescription& description) { | |
300 std::string initial_sdp = UTF16ToUTF8(description.initialSdp()); | |
301 webrtc::SessionDescriptionInterface* native_desc = | |
302 webrtc::CreateSessionDescription(initial_sdp); | |
303 if (!native_desc) | |
304 return NULL; | |
305 | |
306 for (size_t i = 0; i < description.numberOfAddedCandidates(); ++i) { | |
307 WebKit::WebIceCandidate candidate = description.candidate(i); | |
308 webrtc::IceCandidateInterface* native_candidate = | |
309 webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()), | |
310 UTF16ToUTF8(candidate.candidateLine())); | |
311 native_desc->AddCandidate(native_candidate); | |
312 } | |
313 | |
314 return native_desc; | |
315 } | |
316 | |
317 WebKit::WebSessionDescription | |
318 PeerConnectionHandlerJsep::CreateWebKitSessionDescription( | |
319 const webrtc::SessionDescriptionInterface* native_desc) { | |
320 WebKit::WebSessionDescription description; | |
321 if (!native_desc) | |
322 return description; | |
323 | |
324 std::string sdp; | |
325 if (!native_desc->ToString(&sdp)) | |
326 return description; | |
327 | |
328 description.initialize(UTF8ToUTF16(sdp)); | |
329 return description; | |
330 } | |
331 | |
332 bool PeerConnectionHandlerJsep::GetNativeAction( | |
333 const Action action, | |
334 webrtc::PeerConnectionInterface::Action* native_action) { | |
335 switch (action) { | |
336 case SDP_OFFER: | |
337 *native_action = webrtc::PeerConnectionInterface::kOffer; | |
338 break; | |
339 case SDP_PRANSWER: | |
340 DVLOG(1) << "Action PRANSWER not supported yet"; | |
341 return false; | |
342 case SDP_ANSWER: | |
343 *native_action = webrtc::PeerConnectionInterface::kAnswer; | |
344 break; | |
345 default: | |
346 NOTREACHED(); | |
347 return false; | |
348 } | |
349 return true; | |
350 } | |
351 | |
352 void PeerConnectionHandlerJsep::OnAddStreamCallback( | |
353 webrtc::MediaStreamInterface* stream) { | |
354 DCHECK(remote_streams_.find(stream) == remote_streams_.end()); | |
355 WebKit::WebMediaStreamDescriptor descriptor = | |
356 CreateWebKitStreamDescriptor(stream); | |
357 remote_streams_.insert( | |
358 std::pair<webrtc::MediaStreamInterface*, | |
359 WebKit::WebMediaStreamDescriptor>(stream, descriptor)); | |
360 client_->didAddRemoteStream(descriptor); | |
361 } | |
362 | |
363 void PeerConnectionHandlerJsep::OnRemoveStreamCallback( | |
364 webrtc::MediaStreamInterface* stream) { | |
365 RemoteStreamMap::iterator it = remote_streams_.find(stream); | |
366 if (it == remote_streams_.end()) { | |
367 NOTREACHED() << "Stream not found"; | |
368 return; | |
369 } | |
370 WebKit::WebMediaStreamDescriptor descriptor = it->second; | |
371 DCHECK(!descriptor.isNull()); | |
372 remote_streams_.erase(it); | |
373 client_->didRemoveRemoteStream(descriptor); | |
374 } | |
OLD | NEW |