OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 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 |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include "webrtc/ortc/ortcfactory.h" |
| 12 |
| 13 #include <vector> |
| 14 #include <utility> // For std::move. |
| 15 |
| 16 #include "webrtc/api/proxy.h" |
| 17 #include "webrtc/api/mediastreamtrackproxy.h" |
| 18 #include "webrtc/api/rtcerror.h" |
| 19 #include "webrtc/api/videosourceproxy.h" |
| 20 #include "webrtc/base/asyncpacketsocket.h" |
| 21 #include "webrtc/base/bind.h" |
| 22 #include "webrtc/base/checks.h" |
| 23 #include "webrtc/base/logging.h" |
| 24 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" |
| 25 #include "webrtc/media/base/mediaconstants.h" |
| 26 #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h" |
| 27 #include "webrtc/ortc/ortcrtpreceiveradapter.h" |
| 28 #include "webrtc/ortc/ortcrtpsenderadapter.h" |
| 29 #include "webrtc/ortc/rtpparametersconversion.h" |
| 30 #include "webrtc/ortc/rtptransportadapter.h" |
| 31 #include "webrtc/ortc/rtptransportcontrolleradapter.h" |
| 32 #include "webrtc/p2p/base/basicpacketsocketfactory.h" |
| 33 #include "webrtc/p2p/base/udptransport.h" |
| 34 #include "webrtc/pc/channelmanager.h" |
| 35 #include "webrtc/pc/localaudiosource.h" |
| 36 #include "webrtc/pc/audiotrack.h" |
| 37 #include "webrtc/pc/videocapturertracksource.h" |
| 38 #include "webrtc/pc/videotrack.h" |
| 39 |
| 40 namespace { |
| 41 |
| 42 // Asserts that all of the built-in capabilities can be converted to |
| 43 // RtpCapabilities. If they can't, something's wrong (for example, maybe a new |
| 44 // feedback mechanism is supported, but an enum value wasn't added to |
| 45 // rtpparameters.h). |
| 46 template <typename C> |
| 47 webrtc::RtpCapabilities ToRtpCapabilitiesWithAsserts( |
| 48 const std::vector<C>& cricket_codecs, |
| 49 const cricket::RtpHeaderExtensions& cricket_extensions) { |
| 50 webrtc::RtpCapabilities capabilities = |
| 51 webrtc::ToRtpCapabilities(cricket_codecs, cricket_extensions); |
| 52 RTC_DCHECK_EQ(capabilities.codecs.size(), cricket_codecs.size()); |
| 53 for (size_t i = 0; i < capabilities.codecs.size(); ++i) { |
| 54 RTC_DCHECK_EQ(capabilities.codecs[i].rtcp_feedback.size(), |
| 55 cricket_codecs[i].feedback_params.params().size()); |
| 56 } |
| 57 RTC_DCHECK_EQ(capabilities.header_extensions.size(), |
| 58 cricket_extensions.size()); |
| 59 return capabilities; |
| 60 } |
| 61 |
| 62 } // namespace |
| 63 |
| 64 namespace webrtc { |
| 65 |
| 66 // Note that this proxy class uses the network thread as the "worker" thread. |
| 67 BEGIN_OWNED_PROXY_MAP(OrtcFactory) |
| 68 PROXY_SIGNALING_THREAD_DESTRUCTOR() |
| 69 PROXY_METHOD0(RTCErrorOr<std::unique_ptr<RtpTransportControllerInterface>>, |
| 70 CreateRtpTransportController) |
| 71 PROXY_METHOD4(RTCErrorOr<std::unique_ptr<RtpTransportInterface>>, |
| 72 CreateRtpTransport, |
| 73 const RtcpParameters&, |
| 74 PacketTransportInterface*, |
| 75 PacketTransportInterface*, |
| 76 RtpTransportControllerInterface*) |
| 77 PROXY_CONSTMETHOD1(RtpCapabilities, |
| 78 GetRtpSenderCapabilities, |
| 79 cricket::MediaType) |
| 80 PROXY_METHOD2(RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>>, |
| 81 CreateRtpSender, |
| 82 rtc::scoped_refptr<MediaStreamTrackInterface>, |
| 83 RtpTransportInterface*) |
| 84 PROXY_METHOD2(RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>>, |
| 85 CreateRtpSender, |
| 86 cricket::MediaType, |
| 87 RtpTransportInterface*) |
| 88 PROXY_CONSTMETHOD1(RtpCapabilities, |
| 89 GetRtpReceiverCapabilities, |
| 90 cricket::MediaType) |
| 91 PROXY_METHOD2(RTCErrorOr<std::unique_ptr<OrtcRtpReceiverInterface>>, |
| 92 CreateRtpReceiver, |
| 93 cricket::MediaType, |
| 94 RtpTransportInterface*) |
| 95 PROXY_WORKER_METHOD3(RTCErrorOr<std::unique_ptr<UdpTransportInterface>>, |
| 96 CreateUdpTransport, |
| 97 int, |
| 98 uint16_t, |
| 99 uint16_t) |
| 100 PROXY_METHOD1(rtc::scoped_refptr<AudioSourceInterface>, |
| 101 CreateAudioSource, |
| 102 const cricket::AudioOptions&) |
| 103 PROXY_METHOD2(rtc::scoped_refptr<VideoTrackSourceInterface>, |
| 104 CreateVideoSource, |
| 105 std::unique_ptr<cricket::VideoCapturer>, |
| 106 const MediaConstraintsInterface*) |
| 107 PROXY_METHOD2(rtc::scoped_refptr<VideoTrackInterface>, |
| 108 CreateVideoTrack, |
| 109 const std::string&, |
| 110 VideoTrackSourceInterface*) |
| 111 PROXY_METHOD2(rtc::scoped_refptr<AudioTrackInterface>, |
| 112 CreateAudioTrack, |
| 113 const std::string&, |
| 114 AudioSourceInterface*) |
| 115 END_PROXY_MAP() |
| 116 |
| 117 // static |
| 118 RTCErrorOr<std::unique_ptr<OrtcFactoryInterface>> OrtcFactory::Create( |
| 119 rtc::Thread* network_thread, |
| 120 rtc::Thread* signaling_thread, |
| 121 rtc::NetworkManager* network_manager, |
| 122 rtc::PacketSocketFactory* socket_factory, |
| 123 AudioDeviceModule* adm, |
| 124 std::unique_ptr<cricket::MediaEngineInterface> media_engine) { |
| 125 // Hop to signaling thread if needed. |
| 126 if (signaling_thread && !signaling_thread->IsCurrent()) { |
| 127 return signaling_thread |
| 128 ->Invoke<RTCErrorOr<std::unique_ptr<OrtcFactoryInterface>>>( |
| 129 RTC_FROM_HERE, |
| 130 rtc::Bind(&OrtcFactoryInterface::Create, network_thread, |
| 131 signaling_thread, network_manager, socket_factory, adm)); |
| 132 } |
| 133 std::unique_ptr<OrtcFactory> new_factory(new OrtcFactory( |
| 134 network_thread, signaling_thread, network_manager, socket_factory, adm)); |
| 135 RTCError err = new_factory->Initialize(std::move(media_engine)); |
| 136 if (!err.ok()) { |
| 137 return err; |
| 138 } |
| 139 // Return a proxy so that any calls on the returned object (including |
| 140 // destructor) happen on the signaling thread. |
| 141 return OrtcFactoryProxy::Create(new_factory->signaling_thread(), |
| 142 new_factory->network_thread(), |
| 143 new_factory.release()); |
| 144 } |
| 145 |
| 146 RTCErrorOr<std::unique_ptr<OrtcFactoryInterface>> OrtcFactoryInterface::Create( |
| 147 rtc::Thread* network_thread, |
| 148 rtc::Thread* signaling_thread, |
| 149 rtc::NetworkManager* network_manager, |
| 150 rtc::PacketSocketFactory* socket_factory, |
| 151 AudioDeviceModule* adm) { |
| 152 return OrtcFactory::Create(network_thread, signaling_thread, network_manager, |
| 153 socket_factory, adm, nullptr); |
| 154 } |
| 155 |
| 156 OrtcFactory::OrtcFactory(rtc::Thread* network_thread, |
| 157 rtc::Thread* signaling_thread, |
| 158 rtc::NetworkManager* network_manager, |
| 159 rtc::PacketSocketFactory* socket_factory, |
| 160 AudioDeviceModule* adm) |
| 161 : network_thread_(network_thread), |
| 162 signaling_thread_(signaling_thread), |
| 163 network_manager_(network_manager), |
| 164 socket_factory_(socket_factory), |
| 165 adm_(adm), |
| 166 null_event_log_(RtcEventLog::CreateNull()), |
| 167 audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()) { |
| 168 if (!network_thread_) { |
| 169 owned_network_thread_ = rtc::Thread::CreateWithSocketServer(); |
| 170 owned_network_thread_->Start(); |
| 171 network_thread_ = owned_network_thread_.get(); |
| 172 } |
| 173 |
| 174 // The worker thread is created internally because it's an implementation |
| 175 // detail, and consumers of the API don't need to really know about it. |
| 176 worker_thread_ = rtc::Thread::Create(); |
| 177 worker_thread_->Start(); |
| 178 |
| 179 if (signaling_thread_) { |
| 180 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 181 } else { |
| 182 signaling_thread_ = rtc::Thread::Current(); |
| 183 if (!signaling_thread_) { |
| 184 // If this thread isn't already wrapped by an rtc::Thread, create a |
| 185 // wrapper and own it in this class. |
| 186 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread(); |
| 187 wraps_signaling_thread_ = true; |
| 188 } |
| 189 } |
| 190 if (!network_manager_) { |
| 191 owned_network_manager_.reset(new rtc::BasicNetworkManager()); |
| 192 network_manager_ = owned_network_manager_.get(); |
| 193 } |
| 194 if (!socket_factory_) { |
| 195 owned_socket_factory_.reset( |
| 196 new rtc::BasicPacketSocketFactory(network_thread_)); |
| 197 socket_factory_ = owned_socket_factory_.get(); |
| 198 } |
| 199 } |
| 200 |
| 201 OrtcFactory::~OrtcFactory() { |
| 202 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 203 if (wraps_signaling_thread_) { |
| 204 rtc::ThreadManager::Instance()->UnwrapCurrentThread(); |
| 205 } |
| 206 } |
| 207 |
| 208 RTCErrorOr<std::unique_ptr<RtpTransportControllerInterface>> |
| 209 OrtcFactory::CreateRtpTransportController() { |
| 210 return RtpTransportControllerAdapter::CreateProxied( |
| 211 cricket::MediaConfig(), channel_manager_.get(), null_event_log_.get(), |
| 212 signaling_thread_, worker_thread_.get()); |
| 213 } |
| 214 |
| 215 RTCErrorOr<std::unique_ptr<RtpTransportInterface>> |
| 216 OrtcFactory::CreateRtpTransport( |
| 217 const RtcpParameters& rtcp_parameters, |
| 218 PacketTransportInterface* rtp, |
| 219 PacketTransportInterface* rtcp, |
| 220 RtpTransportControllerInterface* transport_controller) { |
| 221 if (transport_controller) { |
| 222 return RtpTransportAdapter::CreateProxied(rtcp_parameters, rtp, rtcp, |
| 223 transport_controller); |
| 224 } else { |
| 225 // If |transport_controller| is null, create one automatically, which the |
| 226 // returned RtpTransport will own. |
| 227 auto result = CreateRtpTransportController(); |
| 228 if (!result.ok()) { |
| 229 return result.MoveError(); |
| 230 } |
| 231 return RtpTransportAdapter::CreateProxied(rtcp_parameters, rtp, rtcp, |
| 232 result.MoveValue()); |
| 233 } |
| 234 } |
| 235 |
| 236 RtpCapabilities OrtcFactory::GetRtpSenderCapabilities( |
| 237 cricket::MediaType kind) const { |
| 238 switch (kind) { |
| 239 case cricket::MEDIA_TYPE_AUDIO: { |
| 240 cricket::AudioCodecs cricket_codecs; |
| 241 cricket::RtpHeaderExtensions cricket_extensions; |
| 242 channel_manager_->GetSupportedAudioSendCodecs(&cricket_codecs); |
| 243 channel_manager_->GetSupportedAudioRtpHeaderExtensions( |
| 244 &cricket_extensions); |
| 245 return ToRtpCapabilitiesWithAsserts(cricket_codecs, cricket_extensions); |
| 246 } |
| 247 case cricket::MEDIA_TYPE_VIDEO: { |
| 248 cricket::VideoCodecs cricket_codecs; |
| 249 cricket::RtpHeaderExtensions cricket_extensions; |
| 250 channel_manager_->GetSupportedVideoCodecs(&cricket_codecs); |
| 251 channel_manager_->GetSupportedVideoRtpHeaderExtensions( |
| 252 &cricket_extensions); |
| 253 return ToRtpCapabilitiesWithAsserts(cricket_codecs, cricket_extensions); |
| 254 } |
| 255 case cricket::MEDIA_TYPE_DATA: |
| 256 return RtpCapabilities(); |
| 257 } |
| 258 } |
| 259 |
| 260 RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>> |
| 261 OrtcFactory::CreateRtpSender( |
| 262 rtc::scoped_refptr<MediaStreamTrackInterface> track, |
| 263 RtpTransportInterface* transport) { |
| 264 if (!track) { |
| 265 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, |
| 266 "Cannot pass null track into CreateRtpSender."); |
| 267 } |
| 268 auto result = |
| 269 CreateRtpSender(cricket::MediaTypeFromString(track->kind()), transport); |
| 270 if (!result.ok()) { |
| 271 return result; |
| 272 } |
| 273 auto err = result.value()->SetTrack(track); |
| 274 if (!err.ok()) { |
| 275 return err; |
| 276 } |
| 277 return result; |
| 278 } |
| 279 |
| 280 RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>> |
| 281 OrtcFactory::CreateRtpSender(cricket::MediaType kind, |
| 282 RtpTransportInterface* transport) { |
| 283 if (kind == cricket::MEDIA_TYPE_DATA) { |
| 284 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, |
| 285 "Cannot create data RtpSender."); |
| 286 } |
| 287 if (!transport) { |
| 288 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, |
| 289 "Cannot pass null transport into CreateRtpSender."); |
| 290 } |
| 291 return transport->GetInternal() |
| 292 ->rtp_transport_controller() |
| 293 ->CreateProxiedRtpSender(kind, transport); |
| 294 } |
| 295 |
| 296 RtpCapabilities OrtcFactory::GetRtpReceiverCapabilities( |
| 297 cricket::MediaType kind) const { |
| 298 switch (kind) { |
| 299 case cricket::MEDIA_TYPE_AUDIO: { |
| 300 cricket::AudioCodecs cricket_codecs; |
| 301 cricket::RtpHeaderExtensions cricket_extensions; |
| 302 channel_manager_->GetSupportedAudioReceiveCodecs(&cricket_codecs); |
| 303 channel_manager_->GetSupportedAudioRtpHeaderExtensions( |
| 304 &cricket_extensions); |
| 305 return ToRtpCapabilitiesWithAsserts(cricket_codecs, cricket_extensions); |
| 306 } |
| 307 case cricket::MEDIA_TYPE_VIDEO: { |
| 308 cricket::VideoCodecs cricket_codecs; |
| 309 cricket::RtpHeaderExtensions cricket_extensions; |
| 310 channel_manager_->GetSupportedVideoCodecs(&cricket_codecs); |
| 311 channel_manager_->GetSupportedVideoRtpHeaderExtensions( |
| 312 &cricket_extensions); |
| 313 return ToRtpCapabilitiesWithAsserts(cricket_codecs, cricket_extensions); |
| 314 } |
| 315 case cricket::MEDIA_TYPE_DATA: |
| 316 return RtpCapabilities(); |
| 317 } |
| 318 } |
| 319 |
| 320 RTCErrorOr<std::unique_ptr<OrtcRtpReceiverInterface>> |
| 321 OrtcFactory::CreateRtpReceiver(cricket::MediaType kind, |
| 322 RtpTransportInterface* transport) { |
| 323 if (kind == cricket::MEDIA_TYPE_DATA) { |
| 324 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, |
| 325 "Cannot create data RtpReceiver."); |
| 326 } |
| 327 if (!transport) { |
| 328 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, |
| 329 "Cannot pass null transport into CreateRtpReceiver."); |
| 330 } |
| 331 return transport->GetInternal() |
| 332 ->rtp_transport_controller() |
| 333 ->CreateProxiedRtpReceiver(kind, transport); |
| 334 } |
| 335 |
| 336 BEGIN_OWNED_PROXY_MAP(UdpTransport) |
| 337 PROXY_WORKER_THREAD_DESTRUCTOR() |
| 338 PROXY_WORKER_CONSTMETHOD0(rtc::SocketAddress, GetLocalAddress) |
| 339 PROXY_WORKER_METHOD1(bool, SetRemoteAddress, const rtc::SocketAddress&) |
| 340 PROXY_WORKER_CONSTMETHOD0(rtc::SocketAddress, GetRemoteAddress) |
| 341 protected: |
| 342 rtc::PacketTransportInternal* GetInternal() override { |
| 343 return internal(); |
| 344 } |
| 345 END_PROXY_MAP() |
| 346 |
| 347 RTCErrorOr<std::unique_ptr<UdpTransportInterface>> |
| 348 OrtcFactory::CreateUdpTransport(int family, |
| 349 uint16_t min_port, |
| 350 uint16_t max_port) { |
| 351 RTC_DCHECK_RUN_ON(network_thread_); |
| 352 std::unique_ptr<rtc::AsyncPacketSocket> socket( |
| 353 socket_factory_->CreateUdpSocket( |
| 354 rtc::SocketAddress(rtc::GetAnyIP(family), 0), min_port, max_port)); |
| 355 if (!socket) { |
| 356 // Only log at warning level, because this method may be called with |
| 357 // specific port ranges to determine if a port is available, expecting the |
| 358 // possibility of an error. |
| 359 LOG_AND_RETURN_ERROR_EX(RTCErrorType::RESOURCE_EXHAUSTED, |
| 360 "Local socket allocation failure.", LS_WARNING); |
| 361 } |
| 362 LOG(LS_INFO) << "Created UDP socket with address " |
| 363 << socket->GetLocalAddress().ToSensitiveString() << "."; |
| 364 // Use proxy so that calls to the returned object are invoked on the network |
| 365 // thread. |
| 366 return UdpTransportProxyWithInternal<cricket::UdpTransport>::Create( |
| 367 signaling_thread_, network_thread_, |
| 368 new cricket::UdpTransport(std::string(), std::move(socket))); |
| 369 } |
| 370 |
| 371 rtc::scoped_refptr<AudioSourceInterface> OrtcFactory::CreateAudioSource( |
| 372 const cricket::AudioOptions& options) { |
| 373 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 374 return rtc::scoped_refptr<LocalAudioSource>( |
| 375 LocalAudioSource::Create(&options)); |
| 376 } |
| 377 |
| 378 rtc::scoped_refptr<VideoTrackSourceInterface> OrtcFactory::CreateVideoSource( |
| 379 std::unique_ptr<cricket::VideoCapturer> capturer, |
| 380 const MediaConstraintsInterface* constraints) { |
| 381 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 382 rtc::scoped_refptr<VideoTrackSourceInterface> source( |
| 383 VideoCapturerTrackSource::Create( |
| 384 worker_thread_.get(), std::move(capturer), constraints, false)); |
| 385 return VideoTrackSourceProxy::Create(signaling_thread_, worker_thread_.get(), |
| 386 source); |
| 387 } |
| 388 |
| 389 rtc::scoped_refptr<VideoTrackInterface> OrtcFactory::CreateVideoTrack( |
| 390 const std::string& id, |
| 391 VideoTrackSourceInterface* source) { |
| 392 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 393 rtc::scoped_refptr<VideoTrackInterface> track(VideoTrack::Create(id, source)); |
| 394 return VideoTrackProxy::Create(signaling_thread_, worker_thread_.get(), |
| 395 track); |
| 396 } |
| 397 |
| 398 rtc::scoped_refptr<AudioTrackInterface> OrtcFactory::CreateAudioTrack( |
| 399 const std::string& id, |
| 400 AudioSourceInterface* source) { |
| 401 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 402 rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source)); |
| 403 return AudioTrackProxy::Create(signaling_thread_, track); |
| 404 } |
| 405 |
| 406 RTCError OrtcFactory::Initialize( |
| 407 std::unique_ptr<cricket::MediaEngineInterface> media_engine) { |
| 408 // TODO(deadbeef): Get rid of requirement to hop to worker thread here. |
| 409 if (!media_engine) { |
| 410 media_engine = |
| 411 worker_thread_->Invoke<std::unique_ptr<cricket::MediaEngineInterface>>( |
| 412 RTC_FROM_HERE, rtc::Bind(&OrtcFactory::CreateMediaEngine_w, this)); |
| 413 } |
| 414 |
| 415 channel_manager_.reset(new cricket::ChannelManager( |
| 416 std::move(media_engine), worker_thread_.get(), network_thread_)); |
| 417 channel_manager_->SetVideoRtxEnabled(true); |
| 418 if (!channel_manager_->Init()) { |
| 419 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, |
| 420 "Failed to initialize ChannelManager."); |
| 421 } |
| 422 return RTCError::OK(); |
| 423 } |
| 424 |
| 425 std::unique_ptr<cricket::MediaEngineInterface> |
| 426 OrtcFactory::CreateMediaEngine_w() { |
| 427 RTC_DCHECK_RUN_ON(worker_thread_.get()); |
| 428 // The nullptr arguments are optional factories that could be passed into the |
| 429 // OrtcFactory, but aren't yet. |
| 430 // Note that |adm_| may be null. |
| 431 return std::unique_ptr<cricket::MediaEngineInterface>( |
| 432 cricket::WebRtcMediaEngineFactory::Create(adm_, audio_decoder_factory_, |
| 433 nullptr, nullptr, nullptr)); |
| 434 } |
| 435 |
| 436 } // namespace webrtc |
OLD | NEW |