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

Side by Side Diff: webrtc/examples/unityplugin/simple_peer_connection.cc

Issue 2987723002: Update native plugin dll for turn servers and video. (Closed)
Patch Set: misc change Created 3 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/examples/unityplugin/simple_peer_connection.h" 11 #include "webrtc/examples/unityplugin/simple_peer_connection.h"
12 12
13 #include <utility> 13 #include <utility>
14 14
15 #include "webrtc/api/test/fakeconstraints.h" 15 #include "webrtc/api/test/fakeconstraints.h"
16 #include "webrtc/media/engine/webrtcvideocapturerfactory.h" 16 #include "webrtc/media/engine/webrtcvideocapturerfactory.h"
17 #include "webrtc/modules/video_capture/video_capture_factory.h" 17 #include "webrtc/modules/video_capture/video_capture_factory.h"
18 #include "webrtc/rtc_base/json.h"
19
20 // Names used for a IceCandidate JSON object.
21 const char kCandidateSdpMidName[] = "sdpMid";
22 const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
23 const char kCandidateSdpName[] = "candidate";
24
25 // Names used for a SessionDescription JSON object.
26 const char kSessionDescriptionTypeName[] = "type";
27 const char kSessionDescriptionSdpName[] = "sdp";
28 18
29 // Names used for media stream labels. 19 // Names used for media stream labels.
30 const char kAudioLabel[] = "audio_label"; 20 const char kAudioLabel[] = "audio_label";
31 const char kVideoLabel[] = "video_label"; 21 const char kVideoLabel[] = "video_label";
32 const char kStreamLabel[] = "stream_label"; 22 const char kStreamLabel[] = "stream_label";
33 23
34 namespace { 24 namespace {
35 static int g_peer_count = 0; 25 static int g_peer_count = 0;
36 static std::unique_ptr<rtc::Thread> g_worker_thread; 26 static std::unique_ptr<rtc::Thread> g_worker_thread;
37 static std::unique_ptr<rtc::Thread> g_signaling_thread; 27 static std::unique_ptr<rtc::Thread> g_signaling_thread;
(...skipping 28 matching lines...) Expand all
66 LOG(INFO) << __FUNCTION__ << " " << error; 56 LOG(INFO) << __FUNCTION__ << " " << error;
67 } 57 }
68 58
69 protected: 59 protected:
70 DummySetSessionDescriptionObserver() {} 60 DummySetSessionDescriptionObserver() {}
71 ~DummySetSessionDescriptionObserver() {} 61 ~DummySetSessionDescriptionObserver() {}
72 }; 62 };
73 63
74 } // namespace 64 } // namespace
75 65
76 bool SimplePeerConnection::InitializePeerConnection(bool is_receiver) { 66 bool SimplePeerConnection::InitializePeerConnection(const char** turn_urls,
67 const int no_of_urls,
68 const char* username,
69 const char* credential,
70 bool is_receiver) {
77 RTC_DCHECK(peer_connection_.get() == nullptr); 71 RTC_DCHECK(peer_connection_.get() == nullptr);
78 72
79 if (g_peer_connection_factory == nullptr) { 73 if (g_peer_connection_factory == nullptr) {
80 g_worker_thread.reset(new rtc::Thread()); 74 g_worker_thread.reset(new rtc::Thread());
81 g_worker_thread->Start(); 75 g_worker_thread->Start();
82 g_signaling_thread.reset(new rtc::Thread()); 76 g_signaling_thread.reset(new rtc::Thread());
83 g_signaling_thread->Start(); 77 g_signaling_thread->Start();
84 78
85 g_peer_connection_factory = webrtc::CreatePeerConnectionFactory( 79 g_peer_connection_factory = webrtc::CreatePeerConnectionFactory(
86 g_worker_thread.get(), g_worker_thread.get(), g_signaling_thread.get(), 80 g_worker_thread.get(), g_worker_thread.get(), g_signaling_thread.get(),
87 nullptr, nullptr, nullptr); 81 nullptr, nullptr, nullptr);
88 } 82 }
89 if (!g_peer_connection_factory.get()) { 83 if (!g_peer_connection_factory.get()) {
90 DeletePeerConnection(); 84 DeletePeerConnection();
91 return false; 85 return false;
92 } 86 }
93 87
94 g_peer_count++; 88 g_peer_count++;
95 if (!CreatePeerConnection(is_receiver)) { 89 if (!CreatePeerConnection(turn_urls, no_of_urls, username, credential,
90 is_receiver)) {
96 DeletePeerConnection(); 91 DeletePeerConnection();
97 return false; 92 return false;
98 } 93 }
99 return peer_connection_.get() != nullptr; 94 return peer_connection_.get() != nullptr;
100 } 95 }
101 96
102 bool SimplePeerConnection::CreatePeerConnection(bool is_receiver) { 97 bool SimplePeerConnection::CreatePeerConnection(const char** turn_urls,
98 const int no_of_urls,
99 const char* username,
100 const char* credential,
101 bool is_receiver) {
103 RTC_DCHECK(g_peer_connection_factory.get() != nullptr); 102 RTC_DCHECK(g_peer_connection_factory.get() != nullptr);
104 RTC_DCHECK(peer_connection_.get() == nullptr); 103 RTC_DCHECK(peer_connection_.get() == nullptr);
105 104
106 webrtc::PeerConnectionInterface::RTCConfiguration config; 105 local_video_observer_.reset(new VideoObserver());
107 webrtc::PeerConnectionInterface::IceServer server; 106 remote_video_observer_.reset(new VideoObserver());
108 server.uri = GetPeerConnectionString(); 107
109 config.servers.push_back(server); 108 // Add the turn server.
109 if (turn_urls != nullptr) {
110 if (no_of_urls > 0) {
111 webrtc::PeerConnectionInterface::IceServer turn_server;
112 for (int i = 0; i < no_of_urls; i++) {
113 std::string url(turn_urls[i]);
114 if (url.length() > 0)
115 turn_server.urls.push_back(turn_urls[i]);
116 }
117
118 std::string user_name(username);
119 if (user_name.length() > 0)
120 turn_server.username = username;
121
122 std::string password(credential);
123 if (password.length() > 0)
124 turn_server.password = credential;
125
126 config_.servers.push_back(turn_server);
127 }
128 }
129
130 // Add the stun server.
131 webrtc::PeerConnectionInterface::IceServer stun_server;
132 stun_server.uri = GetPeerConnectionString();
133 config_.servers.push_back(stun_server);
110 134
111 webrtc::FakeConstraints constraints; 135 webrtc::FakeConstraints constraints;
112 constraints.SetAllowDtlsSctpDataChannels(); 136 constraints.SetAllowDtlsSctpDataChannels();
113 137
114 if (is_receiver) { 138 if (is_receiver) {
115 constraints.SetMandatoryReceiveAudio(true); 139 constraints.SetMandatoryReceiveAudio(true);
116 constraints.SetMandatoryReceiveVideo(true); 140 constraints.SetMandatoryReceiveVideo(true);
117 } 141 }
118 142
119 peer_connection_ = g_peer_connection_factory->CreatePeerConnection( 143 peer_connection_ = g_peer_connection_factory->CreatePeerConnection(
120 config, &constraints, nullptr, nullptr, this); 144 config_, &constraints, nullptr, nullptr, this);
121 145
122 return peer_connection_.get() != nullptr; 146 return peer_connection_.get() != nullptr;
123 } 147 }
124 148
125 void SimplePeerConnection::DeletePeerConnection() { 149 void SimplePeerConnection::DeletePeerConnection() {
126 g_peer_count--; 150 g_peer_count--;
127 151
128 CloseDataChannel(); 152 CloseDataChannel();
129 peer_connection_ = nullptr; 153 peer_connection_ = nullptr;
130 active_streams_.clear(); 154 active_streams_.clear();
(...skipping 22 matching lines...) Expand all
153 } 177 }
154 178
155 void SimplePeerConnection::OnSuccess( 179 void SimplePeerConnection::OnSuccess(
156 webrtc::SessionDescriptionInterface* desc) { 180 webrtc::SessionDescriptionInterface* desc) {
157 peer_connection_->SetLocalDescription( 181 peer_connection_->SetLocalDescription(
158 DummySetSessionDescriptionObserver::Create(), desc); 182 DummySetSessionDescriptionObserver::Create(), desc);
159 183
160 std::string sdp; 184 std::string sdp;
161 desc->ToString(&sdp); 185 desc->ToString(&sdp);
162 186
163 Json::StyledWriter writer;
164 Json::Value jmessage;
165 jmessage[kSessionDescriptionTypeName] = desc->type();
166 jmessage[kSessionDescriptionSdpName] = sdp;
167
168 if (OnLocalSdpReady) 187 if (OnLocalSdpReady)
169 OnLocalSdpReady(writer.write(jmessage).c_str()); 188 OnLocalSdpReady(desc->type().c_str(), sdp.c_str());
170 } 189 }
171 190
172 void SimplePeerConnection::OnFailure(const std::string& error) { 191 void SimplePeerConnection::OnFailure(const std::string& error) {
173 LOG(LERROR) << error; 192 LOG(LERROR) << error;
174 193
175 if (OnFailureMessage) 194 if (OnFailureMessage)
176 OnFailureMessage(error.c_str()); 195 OnFailureMessage(error.c_str());
177 } 196 }
178 197
179 void SimplePeerConnection::OnIceCandidate( 198 void SimplePeerConnection::OnIceCandidate(
180 const webrtc::IceCandidateInterface* candidate) { 199 const webrtc::IceCandidateInterface* candidate) {
181 LOG(INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index(); 200 LOG(INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index();
182 201
183 Json::StyledWriter writer;
184 Json::Value jmessage;
185
186 jmessage[kCandidateSdpMidName] = candidate->sdp_mid();
187 jmessage[kCandidateSdpMlineIndexName] = candidate->sdp_mline_index();
188 std::string sdp; 202 std::string sdp;
189 if (!candidate->ToString(&sdp)) { 203 if (!candidate->ToString(&sdp)) {
190 LOG(LS_ERROR) << "Failed to serialize candidate"; 204 LOG(LS_ERROR) << "Failed to serialize candidate";
191 return; 205 return;
192 } 206 }
193 jmessage[kCandidateSdpName] = sdp;
194 207
195 if (OnIceCandiateReady) 208 if (OnIceCandiateReady)
196 OnIceCandiateReady(writer.write(jmessage).c_str()); 209 OnIceCandiateReady(sdp.c_str(), candidate->sdp_mline_index(),
197 } 210 candidate->sdp_mid().c_str());
198 211 }
199 void SimplePeerConnection::RegisterOnVideoFramReady( 212
200 VIDEOFRAMEREADY_CALLBACK callback) { 213 void SimplePeerConnection::RegisterOnLocalI420FrameReady(
201 OnVideoFrameReady = callback; 214 I420FRAMEREADY_CALLBACK callback) {
215 if (local_video_observer_)
216 local_video_observer_->SetVideoCallback(callback);
217 }
218
219 void SimplePeerConnection::RegisterOnRemoteI420FrameReady(
220 I420FRAMEREADY_CALLBACK callback) {
221 if (remote_video_observer_)
222 remote_video_observer_->SetVideoCallback(callback);
202 } 223 }
203 224
204 void SimplePeerConnection::RegisterOnLocalDataChannelReady( 225 void SimplePeerConnection::RegisterOnLocalDataChannelReady(
205 LOCALDATACHANNELREADY_CALLBACK callback) { 226 LOCALDATACHANNELREADY_CALLBACK callback) {
206 OnLocalDataChannelReady = callback; 227 OnLocalDataChannelReady = callback;
207 } 228 }
208 229
209 void SimplePeerConnection::RegisterOnDataFromDataChannelReady( 230 void SimplePeerConnection::RegisterOnDataFromDataChannelReady(
210 DATAFROMEDATECHANNELREADY_CALLBACK callback) { 231 DATAFROMEDATECHANNELREADY_CALLBACK callback) {
211 OnDataFromDataChannelReady = callback; 232 OnDataFromDataChannelReady = callback;
(...skipping 11 matching lines...) Expand all
223 void SimplePeerConnection::RegisterOnLocalSdpReadytoSend( 244 void SimplePeerConnection::RegisterOnLocalSdpReadytoSend(
224 LOCALSDPREADYTOSEND_CALLBACK callback) { 245 LOCALSDPREADYTOSEND_CALLBACK callback) {
225 OnLocalSdpReady = callback; 246 OnLocalSdpReady = callback;
226 } 247 }
227 248
228 void SimplePeerConnection::RegisterOnIceCandiateReadytoSend( 249 void SimplePeerConnection::RegisterOnIceCandiateReadytoSend(
229 ICECANDIDATEREADYTOSEND_CALLBACK callback) { 250 ICECANDIDATEREADYTOSEND_CALLBACK callback) {
230 OnIceCandiateReady = callback; 251 OnIceCandiateReady = callback;
231 } 252 }
232 253
233 bool SimplePeerConnection::ReceivedSdp(const char* msg) { 254 bool SimplePeerConnection::SetRemoteDescription(const char* type,
255 const char* sdp) {
234 if (!peer_connection_) 256 if (!peer_connection_)
235 return false; 257 return false;
236 258
237 std::string message(msg); 259 std::string remote_desc(sdp);
238 260 std::string sdp_type(type);
239 Json::Reader reader;
240 Json::Value jmessage;
241 if (!reader.parse(message, jmessage)) {
242 LOG(WARNING) << "Received unknown message. " << message;
243 return false;
244 }
245 std::string type;
246 std::string json_object;
247
248 rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName, &type);
249 if (type.empty())
250 return false;
251
252 std::string sdp;
253 if (!rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName,
254 &sdp)) {
255 LOG(WARNING) << "Can't parse received session description message.";
256 return false;
257 }
258 webrtc::SdpParseError error; 261 webrtc::SdpParseError error;
259 webrtc::SessionDescriptionInterface* session_description( 262 webrtc::SessionDescriptionInterface* session_description(
260 webrtc::CreateSessionDescription(type, sdp, &error)); 263 webrtc::CreateSessionDescription(sdp_type, remote_desc, &error));
261 if (!session_description) { 264 if (!session_description) {
262 LOG(WARNING) << "Can't parse received session description message. " 265 LOG(WARNING) << "Can't parse received session description message. "
263 << "SdpParseError was: " << error.description; 266 << "SdpParseError was: " << error.description;
264 return false; 267 return false;
265 } 268 }
266 LOG(INFO) << " Received session description :" << message; 269 LOG(INFO) << " Received session description :" << remote_desc;
267 peer_connection_->SetRemoteDescription( 270 peer_connection_->SetRemoteDescription(
268 DummySetSessionDescriptionObserver::Create(), session_description); 271 DummySetSessionDescriptionObserver::Create(), session_description);
269 272
270 return true; 273 return true;
271 } 274 }
272 275
273 bool SimplePeerConnection::ReceivedIceCandidate(const char* ice_candidate) { 276 bool SimplePeerConnection::AddIceCandidate(const char* candidate,
277 const int sdp_mlineindex,
278 const char* sdp_mid) {
274 if (!peer_connection_) 279 if (!peer_connection_)
275 return false; 280 return false;
276 281
277 std::string message(ice_candidate);
278
279 Json::Reader reader;
280 Json::Value jmessage;
281 if (!reader.parse(message, jmessage)) {
282 LOG(WARNING) << "Received unknown message. " << message;
283 return false;
284 }
285 std::string type;
286 std::string json_object;
287
288 rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName, &type);
289 if (!type.empty())
290 return false;
291
292 std::string sdp_mid;
293 int sdp_mlineindex = 0;
294 std::string sdp;
295 if (!rtc::GetStringFromJsonObject(jmessage, kCandidateSdpMidName, &sdp_mid) ||
296 !rtc::GetIntFromJsonObject(jmessage, kCandidateSdpMlineIndexName,
297 &sdp_mlineindex) ||
298 !rtc::GetStringFromJsonObject(jmessage, kCandidateSdpName, &sdp)) {
299 LOG(WARNING) << "Can't parse received message.";
300 return false;
301 }
302 webrtc::SdpParseError error; 282 webrtc::SdpParseError error;
303 std::unique_ptr<webrtc::IceCandidateInterface> candidate( 283 std::unique_ptr<webrtc::IceCandidateInterface> ice_candidate(
304 webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, sdp, &error)); 284 webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, candidate, &error));
305 if (!candidate.get()) { 285 if (!ice_candidate.get()) {
306 LOG(WARNING) << "Can't parse received candidate message. " 286 LOG(WARNING) << "Can't parse received candidate message. "
307 << "SdpParseError was: " << error.description; 287 << "SdpParseError was: " << error.description;
308 return false; 288 return false;
309 } 289 }
310 if (!peer_connection_->AddIceCandidate(candidate.get())) { 290 if (!peer_connection_->AddIceCandidate(ice_candidate.get())) {
311 LOG(WARNING) << "Failed to apply the received candidate"; 291 LOG(WARNING) << "Failed to apply the received candidate";
312 return false; 292 return false;
313 } 293 }
314 LOG(INFO) << " Received candidate :" << message; 294 LOG(INFO) << " Received candidate :" << candidate;
315 return true; 295 return true;
316 } 296 }
317 297
318 void SimplePeerConnection::SetAudioControl(bool is_mute, bool is_record) { 298 void SimplePeerConnection::SetAudioControl(bool is_mute, bool is_record) {
319 is_mute_audio_ = is_mute; 299 is_mute_audio_ = is_mute;
320 is_record_audio_ = is_record; 300 is_record_audio_ = is_record;
321 301
322 SetAudioControl(); 302 SetAudioControl();
323 } 303 }
324 304
(...skipping 16 matching lines...) Expand all
341 track->set_enabled(false); 321 track->set_enabled(false);
342 else 322 else
343 track->set_enabled(true); 323 track->set_enabled(true);
344 } 324 }
345 } 325 }
346 326
347 void SimplePeerConnection::OnAddStream( 327 void SimplePeerConnection::OnAddStream(
348 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) { 328 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
349 LOG(INFO) << __FUNCTION__ << " " << stream->label(); 329 LOG(INFO) << __FUNCTION__ << " " << stream->label();
350 remote_stream_ = stream; 330 remote_stream_ = stream;
351 331 if (remote_video_observer_ && !remote_stream_->GetVideoTracks().empty()) {
332 remote_stream_->GetVideoTracks()[0]->AddOrUpdateSink(
333 remote_video_observer_.get(), rtc::VideoSinkWants());
334 }
352 SetAudioControl(); 335 SetAudioControl();
353 } 336 }
354 337
355 std::unique_ptr<cricket::VideoCapturer> 338 std::unique_ptr<cricket::VideoCapturer>
356 SimplePeerConnection::OpenVideoCaptureDevice() { 339 SimplePeerConnection::OpenVideoCaptureDevice() {
357 std::vector<std::string> device_names; 340 std::vector<std::string> device_names;
358 { 341 {
359 std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info( 342 std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(
360 webrtc::VideoCaptureFactory::CreateDeviceInfo()); 343 webrtc::VideoCaptureFactory::CreateDeviceInfo());
361 if (!info) { 344 if (!info) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 kAudioLabel, g_peer_connection_factory->CreateAudioSource(nullptr))); 378 kAudioLabel, g_peer_connection_factory->CreateAudioSource(nullptr)));
396 std::string id = audio_track->id(); 379 std::string id = audio_track->id();
397 stream->AddTrack(audio_track); 380 stream->AddTrack(audio_track);
398 381
399 if (!audio_only) { 382 if (!audio_only) {
400 std::unique_ptr<cricket::VideoCapturer> capture = OpenVideoCaptureDevice(); 383 std::unique_ptr<cricket::VideoCapturer> capture = OpenVideoCaptureDevice();
401 if (capture) { 384 if (capture) {
402 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track( 385 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
403 g_peer_connection_factory->CreateVideoTrack( 386 g_peer_connection_factory->CreateVideoTrack(
404 kVideoLabel, g_peer_connection_factory->CreateVideoSource( 387 kVideoLabel, g_peer_connection_factory->CreateVideoSource(
405 OpenVideoCaptureDevice(), nullptr))); 388 std::move(capture), nullptr)));
406 389
407 stream->AddTrack(video_track); 390 stream->AddTrack(video_track);
391 if (local_video_observer_ && !stream->GetVideoTracks().empty()) {
392 stream->GetVideoTracks()[0]->AddOrUpdateSink(
393 local_video_observer_.get(), rtc::VideoSinkWants());
394 }
408 } 395 }
409 } 396 }
410 397
411 if (!peer_connection_->AddStream(stream)) { 398 if (!peer_connection_->AddStream(stream)) {
412 LOG(LS_ERROR) << "Adding stream to PeerConnection failed"; 399 LOG(LS_ERROR) << "Adding stream to PeerConnection failed";
413 } 400 }
414 401
415 typedef std::pair<std::string, 402 typedef std::pair<std::string,
416 rtc::scoped_refptr<webrtc::MediaStreamInterface>> 403 rtc::scoped_refptr<webrtc::MediaStreamInterface>>
417 MediaStreamPair; 404 MediaStreamPair;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 492
506 for (const auto& param : params) { 493 for (const auto& param : params) {
507 uint32_t ssrc = param.ssrc.value_or(0); 494 uint32_t ssrc = param.ssrc.value_or(0);
508 if (ssrc > 0) 495 if (ssrc > 0)
509 ssrcs.push_back(ssrc); 496 ssrcs.push_back(ssrc);
510 } 497 }
511 } 498 }
512 499
513 return ssrcs; 500 return ssrcs;
514 } 501 }
OLDNEW
« no previous file with comments | « webrtc/examples/unityplugin/simple_peer_connection.h ('k') | webrtc/examples/unityplugin/unity_plugin_apis.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698