| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |