| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/protocol/webrtc_transport.h" | 5 #include "remoting/protocol/webrtc_transport.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 | 139 |
| 140 class WebrtcTransport::PeerConnectionWrapper | 140 class WebrtcTransport::PeerConnectionWrapper |
| 141 : public webrtc::PeerConnectionObserver { | 141 : public webrtc::PeerConnectionObserver { |
| 142 public: | 142 public: |
| 143 PeerConnectionWrapper( | 143 PeerConnectionWrapper( |
| 144 rtc::Thread* worker_thread, | 144 rtc::Thread* worker_thread, |
| 145 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory, | 145 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory, |
| 146 std::unique_ptr<cricket::PortAllocator> port_allocator, | 146 std::unique_ptr<cricket::PortAllocator> port_allocator, |
| 147 base::WeakPtr<WebrtcTransport> transport) | 147 base::WeakPtr<WebrtcTransport> transport) |
| 148 : transport_(transport) { | 148 : transport_(transport) { |
| 149 scoped_refptr<WebrtcAudioModule> audio_module = | 149 audio_module_ = new rtc::RefCountedObject<WebrtcAudioModule>(); |
| 150 new rtc::RefCountedObject<WebrtcAudioModule>(); | |
| 151 | 150 |
| 152 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( | 151 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( |
| 153 worker_thread, rtc::Thread::Current(), audio_module.get(), | 152 worker_thread, rtc::Thread::Current(), audio_module_.get(), |
| 154 encoder_factory.release(), nullptr); | 153 encoder_factory.release(), nullptr); |
| 155 | 154 |
| 156 webrtc::FakeConstraints constraints; | 155 webrtc::FakeConstraints constraints; |
| 157 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | 156 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
| 158 webrtc::MediaConstraintsInterface::kValueTrue); | 157 webrtc::MediaConstraintsInterface::kValueTrue); |
| 159 peer_connection_ = peer_connection_factory_->CreatePeerConnection( | 158 peer_connection_ = peer_connection_factory_->CreatePeerConnection( |
| 160 webrtc::PeerConnectionInterface::RTCConfiguration(), &constraints, | 159 webrtc::PeerConnectionInterface::RTCConfiguration(), &constraints, |
| 161 std::move(port_allocator), nullptr, this); | 160 std::move(port_allocator), nullptr, this); |
| 162 } | 161 } |
| 163 virtual ~PeerConnectionWrapper() { peer_connection_->Close(); } | 162 virtual ~PeerConnectionWrapper() { peer_connection_->Close(); } |
| 164 | 163 |
| 164 WebrtcAudioModule* audio_module() { |
| 165 return audio_module_.get(); |
| 166 } |
| 167 |
| 165 webrtc::PeerConnectionInterface* peer_connection() { | 168 webrtc::PeerConnectionInterface* peer_connection() { |
| 166 return peer_connection_.get(); | 169 return peer_connection_.get(); |
| 167 } | 170 } |
| 168 | 171 |
| 169 webrtc::PeerConnectionFactoryInterface* peer_connection_factory() { | 172 webrtc::PeerConnectionFactoryInterface* peer_connection_factory() { |
| 170 return peer_connection_factory_.get(); | 173 return peer_connection_factory_.get(); |
| 171 } | 174 } |
| 172 | 175 |
| 173 // webrtc::PeerConnectionObserver interface. | 176 // webrtc::PeerConnectionObserver interface. |
| 174 void OnSignalingChange( | 177 void OnSignalingChange( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 | 221 |
| 219 base::WeakPtr<WebrtcTransport> transport_; | 222 base::WeakPtr<WebrtcTransport> transport_; |
| 220 | 223 |
| 221 DISALLOW_COPY_AND_ASSIGN(PeerConnectionWrapper); | 224 DISALLOW_COPY_AND_ASSIGN(PeerConnectionWrapper); |
| 222 }; | 225 }; |
| 223 | 226 |
| 224 WebrtcTransport::WebrtcTransport( | 227 WebrtcTransport::WebrtcTransport( |
| 225 rtc::Thread* worker_thread, | 228 rtc::Thread* worker_thread, |
| 226 scoped_refptr<TransportContext> transport_context, | 229 scoped_refptr<TransportContext> transport_context, |
| 227 EventHandler* event_handler) | 230 EventHandler* event_handler) |
| 228 : worker_thread_(worker_thread), | 231 : transport_context_(transport_context), |
| 229 transport_context_(transport_context), | |
| 230 event_handler_(event_handler), | 232 event_handler_(event_handler), |
| 231 handshake_hmac_(crypto::HMAC::SHA256), | 233 handshake_hmac_(crypto::HMAC::SHA256), |
| 232 weak_factory_(this) { | 234 weak_factory_(this) { |
| 233 transport_context_->set_relay_mode(TransportContext::RelayMode::TURN); | 235 transport_context_->set_relay_mode(TransportContext::RelayMode::TURN); |
| 236 |
| 237 video_encoder_factory_ = new WebrtcDummyVideoEncoderFactory(); |
| 238 std::unique_ptr<cricket::PortAllocator> port_allocator = |
| 239 transport_context_->port_allocator_factory()->CreatePortAllocator( |
| 240 transport_context_); |
| 241 |
| 242 // Takes ownership of video_encoder_factory_. |
| 243 peer_connection_wrapper_.reset(new PeerConnectionWrapper( |
| 244 worker_thread, base::WrapUnique(video_encoder_factory_), |
| 245 std::move(port_allocator), weak_factory_.GetWeakPtr())); |
| 234 } | 246 } |
| 235 | 247 |
| 236 WebrtcTransport::~WebrtcTransport() { | 248 WebrtcTransport::~WebrtcTransport() { |
| 237 Close(OK); | 249 Close(OK); |
| 238 } | 250 } |
| 239 | 251 |
| 240 webrtc::PeerConnectionInterface* WebrtcTransport::peer_connection() { | 252 webrtc::PeerConnectionInterface* WebrtcTransport::peer_connection() { |
| 241 return peer_connection_wrapper_ ? peer_connection_wrapper_->peer_connection() | 253 return peer_connection_wrapper_ ? peer_connection_wrapper_->peer_connection() |
| 242 : nullptr; | 254 : nullptr; |
| 243 } | 255 } |
| 244 | 256 |
| 245 webrtc::PeerConnectionFactoryInterface* | 257 webrtc::PeerConnectionFactoryInterface* |
| 246 WebrtcTransport::peer_connection_factory() { | 258 WebrtcTransport::peer_connection_factory() { |
| 247 return peer_connection_wrapper_ | 259 return peer_connection_wrapper_ |
| 248 ? peer_connection_wrapper_->peer_connection_factory() | 260 ? peer_connection_wrapper_->peer_connection_factory() |
| 249 : nullptr; | 261 : nullptr; |
| 250 } | 262 } |
| 251 | 263 |
| 264 WebrtcAudioModule* WebrtcTransport::audio_module() { |
| 265 return peer_connection_wrapper_ |
| 266 ? peer_connection_wrapper_->audio_module() |
| 267 : nullptr; |
| 268 } |
| 269 |
| 252 std::unique_ptr<MessagePipe> WebrtcTransport::CreateOutgoingChannel( | 270 std::unique_ptr<MessagePipe> WebrtcTransport::CreateOutgoingChannel( |
| 253 const std::string& name) { | 271 const std::string& name) { |
| 254 webrtc::DataChannelInit config; | 272 webrtc::DataChannelInit config; |
| 255 config.reliable = true; | 273 config.reliable = true; |
| 256 return base::MakeUnique<WebrtcDataStreamAdapter>( | 274 return base::MakeUnique<WebrtcDataStreamAdapter>( |
| 257 peer_connection()->CreateDataChannel(name, &config)); | 275 peer_connection()->CreateDataChannel(name, &config)); |
| 258 } | 276 } |
| 259 | 277 |
| 260 void WebrtcTransport::Start( | 278 void WebrtcTransport::Start( |
| 261 Authenticator* authenticator, | 279 Authenticator* authenticator, |
| 262 SendTransportInfoCallback send_transport_info_callback) { | 280 SendTransportInfoCallback send_transport_info_callback) { |
| 263 DCHECK(thread_checker_.CalledOnValidThread()); | 281 DCHECK(thread_checker_.CalledOnValidThread()); |
| 264 DCHECK(send_transport_info_callback_.is_null()); | 282 DCHECK(send_transport_info_callback_.is_null()); |
| 265 | 283 |
| 266 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | 284 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| 267 | 285 |
| 268 // TODO(sergeyu): Investigate if it's possible to avoid Send(). | 286 // TODO(sergeyu): Investigate if it's possible to avoid Send(). |
| 269 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 287 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| 270 | 288 |
| 271 send_transport_info_callback_ = std::move(send_transport_info_callback); | 289 send_transport_info_callback_ = std::move(send_transport_info_callback); |
| 272 | 290 |
| 273 if (!handshake_hmac_.Init(authenticator->GetAuthKey())) { | 291 if (!handshake_hmac_.Init(authenticator->GetAuthKey())) { |
| 274 LOG(FATAL) << "HMAC::Init() failed."; | 292 LOG(FATAL) << "HMAC::Init() failed."; |
| 275 } | 293 } |
| 276 | 294 |
| 277 video_encoder_factory_ = new WebrtcDummyVideoEncoderFactory(); | |
| 278 std::unique_ptr<cricket::PortAllocator> port_allocator = | |
| 279 transport_context_->port_allocator_factory()->CreatePortAllocator( | |
| 280 transport_context_); | |
| 281 | |
| 282 // Takes ownership of video_encoder_factory_. | |
| 283 peer_connection_wrapper_.reset(new PeerConnectionWrapper( | |
| 284 worker_thread_, base::WrapUnique(video_encoder_factory_), | |
| 285 std::move(port_allocator), weak_factory_.GetWeakPtr())); | |
| 286 | |
| 287 event_handler_->OnWebrtcTransportConnecting(); | 295 event_handler_->OnWebrtcTransportConnecting(); |
| 288 | 296 |
| 289 if (transport_context_->role() == TransportRole::SERVER) | 297 if (transport_context_->role() == TransportRole::SERVER) |
| 290 RequestNegotiation(); | 298 RequestNegotiation(); |
| 291 } | 299 } |
| 292 | 300 |
| 293 bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { | 301 bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { |
| 294 DCHECK(thread_checker_.CalledOnValidThread()); | 302 DCHECK(thread_checker_.CalledOnValidThread()); |
| 295 | 303 |
| 296 if (transport_info->Name() != QName(kTransportNamespace, "transport")) | 304 if (transport_info->Name() != QName(kTransportNamespace, "transport")) |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 } | 435 } |
| 428 | 436 |
| 429 std::string description_sdp; | 437 std::string description_sdp; |
| 430 if (!description->ToString(&description_sdp)) { | 438 if (!description->ToString(&description_sdp)) { |
| 431 LOG(ERROR) << "Failed to serialize description."; | 439 LOG(ERROR) << "Failed to serialize description."; |
| 432 Close(CHANNEL_CONNECTION_ERROR); | 440 Close(CHANNEL_CONNECTION_ERROR); |
| 433 return; | 441 return; |
| 434 } | 442 } |
| 435 description_sdp = NormalizeSessionDescription(description_sdp); | 443 description_sdp = NormalizeSessionDescription(description_sdp); |
| 436 | 444 |
| 445 // Update SDP format to use stereo for opus codec. |
| 446 std::string opus_line = "a=rtpmap:111 opus/48000/2\n"; |
| 447 std::string opus_line_with_bitrate = |
| 448 opus_line + "a=fmtp:111 stereo=1; x-google-min-bitrate=160\n"; |
| 449 base::ReplaceSubstringsAfterOffset(&description_sdp, 0, opus_line, |
| 450 opus_line_with_bitrate); |
| 451 |
| 437 // Format and send the session description to the peer. | 452 // Format and send the session description to the peer. |
| 438 std::unique_ptr<XmlElement> transport_info( | 453 std::unique_ptr<XmlElement> transport_info( |
| 439 new XmlElement(QName(kTransportNamespace, "transport"), true)); | 454 new XmlElement(QName(kTransportNamespace, "transport"), true)); |
| 440 XmlElement* offer_tag = | 455 XmlElement* offer_tag = |
| 441 new XmlElement(QName(kTransportNamespace, "session-description")); | 456 new XmlElement(QName(kTransportNamespace, "session-description")); |
| 442 transport_info->AddElement(offer_tag); | 457 transport_info->AddElement(offer_tag); |
| 443 offer_tag->SetAttr(QName(std::string(), "type"), description->type()); | 458 offer_tag->SetAttr(QName(std::string(), "type"), description->type()); |
| 444 offer_tag->SetBodyText(description_sdp); | 459 offer_tag->SetBodyText(description_sdp); |
| 445 | 460 |
| 446 std::string digest; | 461 std::string digest; |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 // the stack and so it must be destroyed later. | 678 // the stack and so it must be destroyed later. |
| 664 base::ThreadTaskRunnerHandle::Get()->DeleteSoon( | 679 base::ThreadTaskRunnerHandle::Get()->DeleteSoon( |
| 665 FROM_HERE, peer_connection_wrapper_.release()); | 680 FROM_HERE, peer_connection_wrapper_.release()); |
| 666 | 681 |
| 667 if (error != OK) | 682 if (error != OK) |
| 668 event_handler_->OnWebrtcTransportError(error); | 683 event_handler_->OnWebrtcTransportError(error); |
| 669 } | 684 } |
| 670 | 685 |
| 671 } // namespace protocol | 686 } // namespace protocol |
| 672 } // namespace remoting | 687 } // namespace remoting |
| OLD | NEW |