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 ateDescriptor.h" | |
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICEOption s.h" | |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConne ction00HandlerClient.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 scriptionDescriptor.h" | |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" | |
24 | |
25 PeerConnectionHandlerJsep::PeerConnectionHandlerJsep( | |
26 WebKit::WebPeerConnection00HandlerClient* 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::WebSessionDescriptionDescriptor PeerConnectionHandlerJsep::createOffer( | |
46 const WebKit::WebMediaHints& hints) { | |
47 WebKit::WebSessionDescriptionDescriptor 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 LOG(ERROR) << "Failed to create native offer"; | |
54 return offer; | |
55 } | |
56 | |
57 offer = CreateWebKitSessionDescription(native_offer); | |
58 delete native_offer; | |
59 return offer; | |
60 } | |
61 | |
62 WebKit::WebSessionDescriptionDescriptor PeerConnectionHandlerJsep::createAnswer( | |
63 const WebKit::WebString& offer, | |
64 const WebKit::WebMediaHints& hints) { | |
65 WebKit::WebSessionDescriptionDescriptor answer; | |
66 | |
67 webrtc::MediaHints native_hints(hints.audio(), hints.video()); | |
68 webrtc::SessionDescriptionInterface* native_offer = | |
69 dependency_factory_->CreateSessionDescription(UTF16ToUTF8(offer)); | |
70 if (!native_offer) { | |
71 LOG(ERROR) << "Failed to create native offer"; | |
72 return answer; | |
73 } | |
74 | |
75 webrtc::SessionDescriptionInterface* native_answer = | |
76 native_peer_connection_->CreateAnswer(native_hints, native_offer); | |
77 delete native_offer; | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
scoped_ptr?
Henrik Grunell
2012/03/27 07:22:05
Agree. Done throughout the file.
| |
78 if (!native_answer) { | |
79 LOG(ERROR) << "Failed to create native answer"; | |
80 return answer; | |
81 } | |
82 | |
83 answer = CreateWebKitSessionDescription(native_answer); | |
84 delete native_answer; | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
scoped_ptr?
Henrik Grunell
2012/03/27 07:22:05
Done.
| |
85 return answer; | |
86 } | |
87 | |
88 bool PeerConnectionHandlerJsep::setLocalDescription( | |
89 Action action, | |
90 const WebKit::WebSessionDescriptionDescriptor& description) { | |
91 webrtc::PeerConnectionInterface::Action native_action; | |
92 if (!GetNativeAction(action, &native_action)) | |
93 return false; | |
94 | |
95 webrtc::SessionDescriptionInterface* native_desc = | |
96 CreateNativeSessionDescription(description); | |
97 if (!native_desc) | |
98 return false; | |
99 | |
100 return native_peer_connection_->SetLocalDescription(native_action, | |
101 native_desc); | |
102 } | |
103 | |
104 bool PeerConnectionHandlerJsep::setRemoteDescription( | |
105 Action action, | |
106 const WebKit::WebSessionDescriptionDescriptor& description) { | |
107 webrtc::PeerConnectionInterface::Action native_action; | |
108 if (!GetNativeAction(action, &native_action)) | |
109 return false; | |
110 | |
111 webrtc::SessionDescriptionInterface* native_desc = | |
112 CreateNativeSessionDescription(description); | |
113 if (!native_desc) | |
114 return false; | |
115 | |
116 return native_peer_connection_->SetRemoteDescription(native_action, | |
117 native_desc); | |
118 } | |
119 | |
120 WebKit::WebSessionDescriptionDescriptor | |
121 PeerConnectionHandlerJsep::localDescription() { | |
122 const webrtc::SessionDescriptionInterface* native_desc = | |
123 native_peer_connection_->local_description(); | |
124 WebKit::WebSessionDescriptionDescriptor description = | |
125 CreateWebKitSessionDescription(native_desc); | |
126 return description; | |
127 } | |
128 | |
129 WebKit::WebSessionDescriptionDescriptor | |
130 PeerConnectionHandlerJsep::remoteDescription() { | |
131 const webrtc::SessionDescriptionInterface* native_desc = | |
132 native_peer_connection_->remote_description(); | |
133 WebKit::WebSessionDescriptionDescriptor description = | |
134 CreateWebKitSessionDescription(native_desc); | |
135 return description; | |
136 } | |
137 | |
138 bool PeerConnectionHandlerJsep::startIce(const WebKit::WebICEOptions& options) { | |
139 webrtc::PeerConnectionInterface::IceOptions native_options; | |
140 switch (options.candidateTypeToUse()) { | |
141 case WebKit::WebICEOptions::CandidateTypeAll: | |
142 native_options = webrtc::PeerConnectionInterface::kUseAll; | |
143 break; | |
144 case WebKit::WebICEOptions::CandidateTypeNoRelay: | |
145 native_options = webrtc::PeerConnectionInterface::kNoRelay; | |
146 break; | |
147 case WebKit::WebICEOptions::CandidateTypeOnlyRelay: | |
148 native_options = webrtc::PeerConnectionInterface::kOnlyRelay; | |
149 break; | |
150 default: | |
151 NOTREACHED(); | |
152 return false; | |
153 } | |
154 native_peer_connection_->StartIce(native_options); | |
155 return true; | |
156 } | |
157 | |
158 bool PeerConnectionHandlerJsep::processIceMessage( | |
159 const WebKit::WebICECandidateDescriptor& candidate) { | |
160 webrtc::IceCandidateInterface* native_candidate = | |
161 dependency_factory_->CreateIceCandidate( | |
162 UTF16ToUTF8(candidate.label()), | |
163 UTF16ToUTF8(candidate.candidateLine())); | |
164 if (!native_candidate) { | |
165 LOG(ERROR) << "Could not create native ICE candidate"; | |
166 return false; | |
167 } | |
168 | |
169 bool return_value = | |
170 native_peer_connection_->ProcessIceMessage(native_candidate); | |
171 delete native_candidate; | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
scoped_ptr?
Henrik Grunell
2012/03/27 07:22:05
Done.
| |
172 if (!return_value) | |
173 LOG(ERROR) << "Error processing ICE message"; | |
174 return return_value; | |
175 } | |
176 | |
177 void PeerConnectionHandlerJsep::addStream( | |
178 const WebKit::WebMediaStreamDescriptor& stream) { | |
179 AddStream(stream); | |
180 native_peer_connection_->CommitStreamChanges(); | |
181 } | |
182 | |
183 void PeerConnectionHandlerJsep::removeStream( | |
184 const WebKit::WebMediaStreamDescriptor& stream) { | |
185 RemoveStream(stream); | |
186 native_peer_connection_->CommitStreamChanges(); | |
187 } | |
188 | |
189 void PeerConnectionHandlerJsep::stop() { | |
190 // TODO(ronghuawu): There's an issue with signaling messages being sent during | |
191 // close. We need to investigate further. Not calling Close() on native | |
192 // PeerConnection is OK for now. | |
193 native_peer_connection_ = NULL; | |
194 media_stream_impl_->ClosePeerConnection(this); | |
195 } | |
196 | |
197 void PeerConnectionHandlerJsep::OnError() { | |
198 // TODO(grunell): Implement. | |
199 NOTIMPLEMENTED(); | |
200 } | |
201 | |
202 void PeerConnectionHandlerJsep::OnMessage(const std::string& msg) { | |
203 // TODO(grunell): Implement. | |
204 NOTIMPLEMENTED(); | |
205 } | |
206 | |
207 void PeerConnectionHandlerJsep::OnSignalingMessage(const std::string& msg) { | |
208 // Not used by JSEP PeerConnection. | |
209 NOTREACHED(); | |
210 } | |
211 | |
212 void PeerConnectionHandlerJsep::OnStateChange(StateType state_changed) { | |
213 switch (state_changed) { | |
214 case kReadyState: | |
215 WebKit::WebPeerConnection00HandlerClient::ReadyState ready_state; | |
216 switch (native_peer_connection_->ready_state()) { | |
217 case webrtc::PeerConnectionInterface::kNew: | |
218 ready_state = WebKit::WebPeerConnection00HandlerClient::ReadyStateNew; | |
219 break; | |
220 case webrtc::PeerConnectionInterface::kNegotiating: | |
221 ready_state = | |
222 WebKit::WebPeerConnection00HandlerClient::ReadyStateNegotiating; | |
223 break; | |
224 case webrtc::PeerConnectionInterface::kActive: | |
225 ready_state = | |
226 WebKit::WebPeerConnection00HandlerClient::ReadyStateActive; | |
227 break; | |
228 case webrtc::PeerConnectionInterface::kClosing: | |
229 // Not used by JSEP. | |
230 NOTREACHED(); | |
231 return; | |
232 case webrtc::PeerConnectionInterface::kClosed: | |
233 ready_state = | |
234 WebKit::WebPeerConnection00HandlerClient::ReadyStateClosed; | |
235 break; | |
236 default: | |
237 NOTREACHED(); | |
238 return; | |
239 } | |
240 client_->didChangeReadyState(ready_state); | |
241 break; | |
242 case kIceState: | |
243 // TODO(grunell): Implement when available in native PeerConnection. | |
244 NOTIMPLEMENTED(); | |
245 break; | |
246 case kSdpState: | |
247 // Not used by JSEP. | |
248 NOTREACHED(); | |
249 return; | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
just use break; here and below?
Henrik Grunell
2012/03/27 07:22:05
Sounds good. Done.
| |
250 default: | |
251 NOTREACHED(); | |
252 return; | |
253 } | |
254 } | |
255 | |
256 void PeerConnectionHandlerJsep::OnAddStream( | |
257 webrtc::MediaStreamInterface* stream) { | |
258 if (!stream) | |
259 return; | |
260 | |
261 DCHECK(remote_streams_.find(stream) == remote_streams_.end()); | |
262 WebKit::WebMediaStreamDescriptor descriptor = | |
263 CreateWebKitStreamDescriptor(stream); | |
264 remote_streams_.insert( | |
265 std::pair<webrtc::MediaStreamInterface*, | |
266 WebKit::WebMediaStreamDescriptor>(stream, descriptor)); | |
267 client_->didAddRemoteStream(descriptor); | |
268 } | |
269 | |
270 void PeerConnectionHandlerJsep::OnRemoveStream( | |
271 webrtc::MediaStreamInterface* stream) { | |
272 if (!stream) | |
273 return; | |
274 | |
275 RemoteStreamMap::iterator it = remote_streams_.find(stream); | |
276 if (it == remote_streams_.end()) { | |
277 NOTREACHED() << "Stream not found"; | |
278 return; | |
279 } | |
280 WebKit::WebMediaStreamDescriptor descriptor = it->second; | |
281 DCHECK(!descriptor.isNull()); | |
282 remote_streams_.erase(it); | |
283 client_->didRemoveRemoteStream(descriptor); | |
284 } | |
285 | |
286 void PeerConnectionHandlerJsep::OnIceCandidate( | |
287 const webrtc::IceCandidateInterface* candidate) { | |
288 WebKit::WebICECandidateDescriptor web_candidate; | |
289 | |
290 std::string label = candidate->label(); | |
291 std::string sdp; | |
292 if (!candidate->ToString(&sdp)) { | |
293 LOG(ERROR) << "Could not get SDP string"; | |
294 return; | |
295 } | |
296 | |
297 web_candidate.initialize(UTF8ToUTF16(label), UTF8ToUTF16(sdp)); | |
298 | |
299 // moreToFollow parameter isn't supported in native PeerConnection, so we | |
300 // always use true here, and then false in OnIceComplete(). | |
301 client_->didGenerateICECandidate(web_candidate, true); | |
302 } | |
303 | |
304 void PeerConnectionHandlerJsep::OnIceComplete() { | |
305 // moreToFollow parameter isn't supported in native PeerConnection, so we | |
306 // send an empty WebIseCandidate with moreToFollow=false. | |
307 WebKit::WebICECandidateDescriptor web_candidate; | |
308 client_->didGenerateICECandidate(web_candidate, false); | |
309 } | |
310 | |
311 webrtc::SessionDescriptionInterface* | |
312 PeerConnectionHandlerJsep::CreateNativeSessionDescription( | |
313 const WebKit::WebSessionDescriptionDescriptor& description) { | |
314 std::string initial_sdp = UTF16ToUTF8(description.initialSDP()); | |
315 webrtc::SessionDescriptionInterface* native_desc = | |
316 dependency_factory_->CreateSessionDescription(initial_sdp); | |
317 if (!native_desc) { | |
318 LOG(ERROR) << "Failed to create native session description"; | |
319 return NULL; | |
320 } | |
321 | |
322 for (size_t i = 0; i < description.numberOfAddedCandidates(); ++i) { | |
323 WebKit::WebICECandidateDescriptor candidate = description.candidate(i); | |
324 webrtc::IceCandidateInterface* native_candidate = | |
325 dependency_factory_->CreateIceCandidate( | |
326 UTF16ToUTF8(candidate.label()), | |
327 UTF16ToUTF8(candidate.candidateLine())); | |
328 if (!native_desc->AddCandidate(native_candidate)) | |
329 LOG(ERROR) << "Failed to add candidate to native session description"; | |
330 delete native_candidate; | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
scoped_ptr
Henrik Grunell
2012/03/27 07:22:05
Done.
| |
331 } | |
332 | |
333 return native_desc; | |
334 } | |
335 | |
336 WebKit::WebSessionDescriptionDescriptor | |
337 PeerConnectionHandlerJsep::CreateWebKitSessionDescription( | |
338 const webrtc::SessionDescriptionInterface* native_desc) { | |
339 WebKit::WebSessionDescriptionDescriptor description; | |
340 if (!native_desc) { | |
341 VLOG(1) << "Native session description is null"; | |
342 return description; | |
343 } | |
344 | |
345 std::string sdp; | |
346 if (!native_desc->ToString(&sdp)) { | |
347 LOG(ERROR) << "Failed to get SDP string of native session description"; | |
348 return description; | |
349 } | |
350 | |
351 description.initialize(UTF8ToUTF16(sdp)); | |
352 return description; | |
353 } | |
354 | |
355 bool PeerConnectionHandlerJsep::GetNativeAction( | |
356 const Action action, | |
357 webrtc::PeerConnectionInterface::Action* native_action) { | |
358 switch (action) { | |
359 case ActionSDPOffer: | |
360 *native_action = webrtc::PeerConnectionInterface::kOffer; | |
361 break; | |
362 case ActionSDPPRanswer: | |
363 VLOG(1) << "Action PRANSWER not supported yet"; | |
364 return false; | |
365 case ActionSDPAnswer: | |
366 *native_action = webrtc::PeerConnectionInterface::kAnswer; | |
367 break; | |
368 default: | |
369 NOTREACHED(); | |
370 return false; | |
371 } | |
372 return true; | |
373 } | |
OLD | NEW |