OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 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/pc/ortcfactory.h" | 11 #include "webrtc/pc/ortcfactory.h" |
12 | 12 |
13 #include <string> | 13 #include <string> |
14 #include <utility> // For std::move. | 14 #include <utility> // For std::move. |
15 | 15 |
| 16 #include "webrtc/api/proxy.h" |
| 17 #include "webrtc/api/mediastreamtrackproxy.h" |
| 18 #include "webrtc/api/videosourceproxy.h" |
16 #include "webrtc/base/bind.h" | 19 #include "webrtc/base/bind.h" |
17 #include "webrtc/base/asyncpacketsocket.h" | 20 #include "webrtc/base/asyncpacketsocket.h" |
| 21 #include "webrtc/base/logging.h" |
| 22 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" |
| 23 #include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h" |
18 #include "webrtc/p2p/base/basicpacketsocketfactory.h" | 24 #include "webrtc/p2p/base/basicpacketsocketfactory.h" |
19 #include "webrtc/p2p/base/udptransport.h" | 25 #include "webrtc/p2p/base/udptransport.h" |
| 26 #include "webrtc/pc/channelmanager.h" |
| 27 #include "webrtc/pc/localaudiosource.h" |
| 28 #include "webrtc/pc/audiotrack.h" |
| 29 #include "webrtc/pc/rtpreceivershim.h" |
| 30 #include "webrtc/pc/rtpsendershim.h" |
| 31 #include "webrtc/pc/rtptransportcontrollershim.h" |
| 32 #include "webrtc/pc/rtptransportshim.h" |
| 33 #include "webrtc/pc/videocapturertracksource.h" |
| 34 #include "webrtc/pc/videotrack.h" |
| 35 |
| 36 namespace { |
| 37 |
| 38 void ConvertFeedbackParam(const cricket::FeedbackParam& cricket_feedback, |
| 39 webrtc::RtpCodecCapability* codec) { |
| 40 if (cricket_feedback.id() == "ack") { |
| 41 RTC_DCHECK(cricket_feedback.param().empty()); |
| 42 codec->rtcp_feedback.emplace_back(webrtc::RtcpFeedbackType::ACK); |
| 43 } else if (cricket_feedback.id() == "ccm") { |
| 44 if (cricket_feedback.param() == "fir") { |
| 45 codec->rtcp_feedback.emplace_back(webrtc::RtcpFeedbackType::CCM, |
| 46 webrtc::RtcpFeedbackMessageType::FIR); |
| 47 } else { |
| 48 RTC_NOTREACHED(); |
| 49 } |
| 50 } else if (cricket_feedback.id() == "nack") { |
| 51 if (cricket_feedback.param().empty()) { |
| 52 codec->rtcp_feedback.emplace_back( |
| 53 webrtc::RtcpFeedbackType::NACK, |
| 54 webrtc::RtcpFeedbackMessageType::GENERIC_NACK); |
| 55 } else if (cricket_feedback.param() == "pli") { |
| 56 codec->rtcp_feedback.emplace_back(webrtc::RtcpFeedbackType::NACK, |
| 57 webrtc::RtcpFeedbackMessageType::PLI); |
| 58 } else { |
| 59 RTC_NOTREACHED(); |
| 60 } |
| 61 } else if (cricket_feedback.id() == "goog-remb") { |
| 62 RTC_DCHECK(cricket_feedback.param().empty()); |
| 63 codec->rtcp_feedback.emplace_back(webrtc::RtcpFeedbackType::REMB); |
| 64 } else if (cricket_feedback.id() == "transport-cc") { |
| 65 RTC_DCHECK(cricket_feedback.param().empty()); |
| 66 codec->rtcp_feedback.emplace_back(webrtc::RtcpFeedbackType::TRANSPORT_CC); |
| 67 } else { |
| 68 RTC_NOTREACHED(); |
| 69 } |
| 70 } |
| 71 |
| 72 template <typename C> |
| 73 void CodecSpecificConversion(const C& cricket_codec, |
| 74 webrtc::RtpCodecCapability* codec) {} |
| 75 |
| 76 template <> |
| 77 void CodecSpecificConversion<cricket::AudioCodec>( |
| 78 const cricket::AudioCodec& cricket_codec, |
| 79 webrtc::RtpCodecCapability* codec) { |
| 80 codec->num_channels = rtc::Optional<int>(cricket_codec.channels); |
| 81 } |
| 82 |
| 83 template <class C> |
| 84 webrtc::RtpCapabilities ConvertCapabilities( |
| 85 cricket::MediaType kind, |
| 86 const std::vector<C> cricket_codecs, |
| 87 const cricket::RtpHeaderExtensions& cricket_extensions) { |
| 88 webrtc::RtpCapabilities capabilities; |
| 89 bool have_red = false; |
| 90 bool have_ulpfec = false; |
| 91 bool have_flexfec = false; |
| 92 for (const C& cricket_codec : cricket_codecs) { |
| 93 if (cricket_codec.name == "red") { |
| 94 have_red = true; |
| 95 } else if (cricket_codec.name == "ulpfec") { |
| 96 have_ulpfec = true; |
| 97 } else if (cricket_codec.name == "flexfec") { |
| 98 have_flexfec = true; |
| 99 } |
| 100 webrtc::RtpCodecCapability codec; |
| 101 codec.name = cricket_codec.name; |
| 102 codec.kind = kind; |
| 103 codec.clock_rate = rtc::Optional<int>(cricket_codec.clockrate); |
| 104 codec.preferred_payload_type = rtc::Optional<int>(cricket_codec.id); |
| 105 for (const cricket::FeedbackParam& cricket_feedback : |
| 106 cricket_codec.feedback_params.params()) { |
| 107 ConvertFeedbackParam(cricket_feedback, &codec); |
| 108 } |
| 109 CodecSpecificConversion(cricket_codec, &codec); |
| 110 codec.parameters.insert(cricket_codec.params.begin(), |
| 111 cricket_codec.params.end()); |
| 112 capabilities.codecs.push_back(std::move(codec)); |
| 113 } |
| 114 for (const webrtc::RtpExtension& cricket_extension : cricket_extensions) { |
| 115 capabilities.header_extensions.emplace_back(cricket_extension.uri, |
| 116 cricket_extension.id); |
| 117 } |
| 118 if (have_red) { |
| 119 capabilities.fec.push_back(webrtc::FecMechanism::RED); |
| 120 } |
| 121 if (have_red && have_ulpfec) { |
| 122 capabilities.fec.push_back(webrtc::FecMechanism::RED_AND_ULPFEC); |
| 123 } |
| 124 if (have_flexfec) { |
| 125 capabilities.fec.push_back(webrtc::FecMechanism::FLEXFEC); |
| 126 } |
| 127 return capabilities; |
| 128 } |
| 129 |
| 130 } // namespace |
20 | 131 |
21 namespace webrtc { | 132 namespace webrtc { |
22 | 133 |
| 134 // Note that this proxy class uses the network thread as the "worker" thread. |
| 135 BEGIN_OWNED_PROXY_MAP(OrtcFactory) |
| 136 PROXY_SIGNALING_THREAD_DESTRUCTOR() |
| 137 PROXY_METHOD0(RTCErrorOr<std::unique_ptr<RtpTransportControllerInterface>>, |
| 138 CreateRtpTransportController) |
| 139 PROXY_METHOD4(RTCErrorOr<std::unique_ptr<RtpTransportInterface>>, |
| 140 CreateRtpTransport, |
| 141 const RtcpParameters&, |
| 142 PacketTransportInterface*, |
| 143 PacketTransportInterface*, |
| 144 RtpTransportControllerInterface*) |
| 145 PROXY_CONSTMETHOD1(RtpCapabilities, |
| 146 GetRtpSenderCapabilities, |
| 147 cricket::MediaType) |
| 148 PROXY_METHOD3(RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>>, |
| 149 CreateRtpSender, |
| 150 rtc::scoped_refptr<MediaStreamTrackInterface>, |
| 151 const RtpParameters&, |
| 152 RtpTransportInterface*) |
| 153 PROXY_METHOD3(RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>>, |
| 154 CreateRtpSender, |
| 155 cricket::MediaType, |
| 156 const RtpParameters&, |
| 157 RtpTransportInterface*) |
| 158 PROXY_CONSTMETHOD1(RtpCapabilities, |
| 159 GetRtpReceiverCapabilities, |
| 160 cricket::MediaType) |
| 161 PROXY_METHOD3(RTCErrorOr<std::unique_ptr<OrtcRtpReceiverInterface>>, |
| 162 CreateRtpReceiver, |
| 163 cricket::MediaType, |
| 164 const RtpParameters&, |
| 165 RtpTransportInterface*) |
| 166 PROXY_WORKER_METHOD3(RTCErrorOr<std::unique_ptr<UdpTransportInterface>>, |
| 167 CreateUdpTransport, |
| 168 int, |
| 169 uint16_t, |
| 170 uint16_t) |
| 171 PROXY_METHOD1(rtc::scoped_refptr<AudioSourceInterface>, |
| 172 CreateAudioSource, |
| 173 const cricket::AudioOptions&) |
| 174 PROXY_METHOD2(rtc::scoped_refptr<VideoTrackSourceInterface>, |
| 175 CreateVideoSource, |
| 176 std::unique_ptr<cricket::VideoCapturer>, |
| 177 const MediaConstraintsInterface*) |
| 178 PROXY_METHOD2(rtc::scoped_refptr<VideoTrackInterface>, |
| 179 CreateVideoTrack, |
| 180 const std::string&, |
| 181 VideoTrackSourceInterface*) |
| 182 PROXY_METHOD2(rtc::scoped_refptr<AudioTrackInterface>, |
| 183 CreateAudioTrack, |
| 184 const std::string&, |
| 185 AudioSourceInterface*) |
| 186 END_PROXY_MAP() |
| 187 |
23 // static | 188 // static |
24 std::unique_ptr<OrtcFactoryInterface> OrtcFactoryInterface::Create( | 189 RTCErrorOr<std::unique_ptr<OrtcFactoryInterface>> OrtcFactoryInterface::Create( |
25 rtc::Thread* network_thread, | 190 rtc::Thread* network_thread, |
26 rtc::Thread* signaling_thread, | 191 rtc::Thread* signaling_thread, |
27 rtc::NetworkManager* network_manager, | 192 rtc::NetworkManager* network_manager, |
28 rtc::PacketSocketFactory* socket_factory) { | 193 rtc::PacketSocketFactory* socket_factory, |
| 194 AudioDeviceModule* adm) { |
29 // Hop to signaling thread if needed. | 195 // Hop to signaling thread if needed. |
30 if (signaling_thread && !signaling_thread->IsCurrent()) { | 196 if (signaling_thread && !signaling_thread->IsCurrent()) { |
31 return signaling_thread->Invoke<std::unique_ptr<OrtcFactoryInterface>>( | 197 return signaling_thread |
32 RTC_FROM_HERE, | 198 ->Invoke<RTCErrorOr<std::unique_ptr<OrtcFactoryInterface>>>( |
33 rtc::Bind(&OrtcFactoryInterface::Create, network_thread, | 199 RTC_FROM_HERE, |
34 signaling_thread, network_manager, socket_factory)); | 200 rtc::Bind(&OrtcFactoryInterface::Create, network_thread, |
35 } | 201 signaling_thread, network_manager, socket_factory, adm)); |
36 OrtcFactory* new_factory = | 202 } |
37 new OrtcFactory(network_thread, signaling_thread, | 203 std::unique_ptr<OrtcFactory> new_factory(new OrtcFactory( |
38 network_manager, socket_factory); | 204 network_thread, signaling_thread, network_manager, socket_factory, adm)); |
| 205 RTCError err = new_factory->Initialize(); |
| 206 if (!err.ok()) { |
| 207 return err; |
| 208 } |
39 // Return a proxy so that any calls on the returned object (including | 209 // Return a proxy so that any calls on the returned object (including |
40 // destructor) happen on the signaling thread. | 210 // destructor) happen on the signaling thread. |
41 return OrtcFactoryProxy::Create(new_factory->signaling_thread(), | 211 return OrtcFactoryProxy::Create(new_factory->signaling_thread(), |
42 new_factory->network_thread(), new_factory); | 212 new_factory->network_thread(), |
| 213 new_factory.release()); |
43 } | 214 } |
44 | 215 |
45 OrtcFactory::OrtcFactory(rtc::Thread* network_thread, | 216 OrtcFactory::OrtcFactory(rtc::Thread* network_thread, |
46 rtc::Thread* signaling_thread, | 217 rtc::Thread* signaling_thread, |
47 rtc::NetworkManager* network_manager, | 218 rtc::NetworkManager* network_manager, |
48 rtc::PacketSocketFactory* socket_factory) | 219 rtc::PacketSocketFactory* socket_factory, |
| 220 AudioDeviceModule* adm) |
49 : network_thread_(network_thread), | 221 : network_thread_(network_thread), |
50 signaling_thread_(signaling_thread), | 222 signaling_thread_(signaling_thread), |
51 network_manager_(network_manager), | 223 network_manager_(network_manager), |
52 socket_factory_(socket_factory) { | 224 socket_factory_(socket_factory), |
| 225 adm_(adm), |
| 226 null_event_log_(RtcEventLog::CreateNull()), |
| 227 audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()) { |
53 if (!network_thread_) { | 228 if (!network_thread_) { |
54 owned_network_thread_ = rtc::Thread::CreateWithSocketServer(); | 229 owned_network_thread_ = rtc::Thread::CreateWithSocketServer(); |
55 owned_network_thread_->Start(); | 230 owned_network_thread_->Start(); |
56 network_thread_ = owned_network_thread_.get(); | 231 network_thread_ = owned_network_thread_.get(); |
57 } | 232 } |
58 | 233 |
59 // The worker thread is created internally because it's an implementation | 234 // The worker thread is created internally because it's an implementation |
60 // detail, and consumers of the API don't need to really know about it. | 235 // detail, and consumers of the API don't need to really know about it. |
61 owned_worker_thread_ = rtc::Thread::Create(); | 236 worker_thread_ = rtc::Thread::Create(); |
62 owned_worker_thread_->Start(); | 237 worker_thread_->Start(); |
63 | 238 |
64 if (signaling_thread_) { | 239 if (signaling_thread_) { |
65 RTC_DCHECK_RUN_ON(signaling_thread_); | 240 RTC_DCHECK_RUN_ON(signaling_thread_); |
66 } else { | 241 } else { |
67 signaling_thread_ = rtc::Thread::Current(); | 242 signaling_thread_ = rtc::Thread::Current(); |
68 if (!signaling_thread_) { | 243 if (!signaling_thread_) { |
69 // If this thread isn't already wrapped by an rtc::Thread, create a | 244 // If this thread isn't already wrapped by an rtc::Thread, create a |
70 // wrapper and own it in this class. | 245 // wrapper and own it in this class. |
71 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread(); | 246 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread(); |
72 wraps_signaling_thread_ = true; | 247 wraps_signaling_thread_ = true; |
(...skipping 10 matching lines...) Expand all Loading... |
83 } | 258 } |
84 } | 259 } |
85 | 260 |
86 OrtcFactory::~OrtcFactory() { | 261 OrtcFactory::~OrtcFactory() { |
87 RTC_DCHECK_RUN_ON(signaling_thread_); | 262 RTC_DCHECK_RUN_ON(signaling_thread_); |
88 if (wraps_signaling_thread_) { | 263 if (wraps_signaling_thread_) { |
89 rtc::ThreadManager::Instance()->UnwrapCurrentThread(); | 264 rtc::ThreadManager::Instance()->UnwrapCurrentThread(); |
90 } | 265 } |
91 } | 266 } |
92 | 267 |
93 std::unique_ptr<UdpTransportInterface> OrtcFactory::CreateUdpTransport( | 268 RTCErrorOr<std::unique_ptr<RtpTransportControllerInterface>> |
94 int family, | 269 OrtcFactory::CreateRtpTransportController() { |
95 uint16_t min_port, | 270 return RtpTransportControllerShim::CreateProxied( |
96 uint16_t max_port) { | 271 cricket::MediaConfig(), channel_manager_.get(), null_event_log_.get(), |
97 if (!network_thread_->IsCurrent()) { | 272 signaling_thread_, worker_thread_.get()); |
98 RTC_DCHECK_RUN_ON(signaling_thread_); | 273 } |
99 return network_thread_->Invoke<std::unique_ptr<UdpTransportInterface>>( | 274 |
100 RTC_FROM_HERE, rtc::Bind(&OrtcFactory::CreateUdpTransport, this, family, | 275 RTCErrorOr<std::unique_ptr<RtpTransportInterface>> |
101 min_port, max_port)); | 276 OrtcFactory::CreateRtpTransport( |
102 } | 277 const RtcpParameters& rtcp_parameters, |
| 278 PacketTransportInterface* rtp, |
| 279 PacketTransportInterface* rtcp, |
| 280 RtpTransportControllerInterface* transport_controller) { |
| 281 return RtpTransportShim::CreateProxied(rtcp_parameters, rtp, rtcp, |
| 282 transport_controller); |
| 283 } |
| 284 |
| 285 RtpCapabilities OrtcFactory::GetRtpSenderCapabilities( |
| 286 cricket::MediaType kind) const { |
| 287 switch (kind) { |
| 288 case cricket::MEDIA_TYPE_AUDIO: { |
| 289 cricket::AudioCodecs cricket_codecs; |
| 290 cricket::RtpHeaderExtensions cricket_extensions; |
| 291 channel_manager_->GetSupportedAudioSendCodecs(&cricket_codecs); |
| 292 channel_manager_->GetSupportedAudioRtpHeaderExtensions( |
| 293 &cricket_extensions); |
| 294 return ConvertCapabilities(kind, cricket_codecs, cricket_extensions); |
| 295 } |
| 296 case cricket::MEDIA_TYPE_VIDEO: { |
| 297 cricket::VideoCodecs cricket_codecs; |
| 298 cricket::RtpHeaderExtensions cricket_extensions; |
| 299 channel_manager_->GetSupportedVideoCodecs(&cricket_codecs); |
| 300 channel_manager_->GetSupportedVideoRtpHeaderExtensions( |
| 301 &cricket_extensions); |
| 302 return ConvertCapabilities(kind, cricket_codecs, cricket_extensions); |
| 303 } |
| 304 case cricket::MEDIA_TYPE_DATA: |
| 305 return RtpCapabilities(); |
| 306 } |
| 307 } |
| 308 |
| 309 RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>> |
| 310 OrtcFactory::CreateRtpSender( |
| 311 rtc::scoped_refptr<MediaStreamTrackInterface> track, |
| 312 const RtpParameters& rtp_parameters, |
| 313 RtpTransportInterface* transport) { |
| 314 if (!track) { |
| 315 return CreateAndLogError(RTCErrorType::INVALID_PARAMETER, |
| 316 "Cannot pass null track into CreateRtpSender."); |
| 317 } |
| 318 auto result = CreateRtpSender(cricket::MediaTypeFromString(track->kind()), |
| 319 rtp_parameters, transport); |
| 320 if (!result.ok()) { |
| 321 return result; |
| 322 } |
| 323 auto err = result.value()->SetTrack(track); |
| 324 if (!err.ok()) { |
| 325 return err; |
| 326 } |
| 327 return result; |
| 328 } |
| 329 |
| 330 RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>> |
| 331 OrtcFactory::CreateRtpSender(cricket::MediaType kind, |
| 332 const RtpParameters& rtp_parameters, |
| 333 RtpTransportInterface* transport) { |
| 334 if (kind == cricket::MEDIA_TYPE_DATA) { |
| 335 return CreateAndLogError(RTCErrorType::INVALID_PARAMETER, |
| 336 "Cannot create data RtpSender."); |
| 337 } |
| 338 if (!transport) { |
| 339 return CreateAndLogError( |
| 340 RTCErrorType::INVALID_PARAMETER, |
| 341 "Cannot pass null transport into CreateRtpSender."); |
| 342 } |
| 343 return RtpSenderShim::CreateProxied(kind, rtp_parameters, |
| 344 transport->GetInternal()); |
| 345 } |
| 346 |
| 347 RtpCapabilities OrtcFactory::GetRtpReceiverCapabilities( |
| 348 cricket::MediaType kind) const { |
| 349 switch (kind) { |
| 350 case cricket::MEDIA_TYPE_AUDIO: { |
| 351 cricket::AudioCodecs cricket_codecs; |
| 352 cricket::RtpHeaderExtensions cricket_extensions; |
| 353 channel_manager_->GetSupportedAudioReceiveCodecs(&cricket_codecs); |
| 354 channel_manager_->GetSupportedAudioRtpHeaderExtensions( |
| 355 &cricket_extensions); |
| 356 return ConvertCapabilities(kind, cricket_codecs, cricket_extensions); |
| 357 } |
| 358 case cricket::MEDIA_TYPE_VIDEO: { |
| 359 cricket::VideoCodecs cricket_codecs; |
| 360 cricket::RtpHeaderExtensions cricket_extensions; |
| 361 channel_manager_->GetSupportedVideoCodecs(&cricket_codecs); |
| 362 channel_manager_->GetSupportedVideoRtpHeaderExtensions( |
| 363 &cricket_extensions); |
| 364 return ConvertCapabilities(kind, cricket_codecs, cricket_extensions); |
| 365 } |
| 366 case cricket::MEDIA_TYPE_DATA: |
| 367 return RtpCapabilities(); |
| 368 } |
| 369 } |
| 370 |
| 371 RTCErrorOr<std::unique_ptr<OrtcRtpReceiverInterface>> |
| 372 OrtcFactory::CreateRtpReceiver(cricket::MediaType kind, |
| 373 const RtpParameters& rtp_parameters, |
| 374 RtpTransportInterface* transport) { |
| 375 if (kind == cricket::MEDIA_TYPE_DATA) { |
| 376 return CreateAndLogError(RTCErrorType::INVALID_PARAMETER, |
| 377 "Cannot create data RtpReceiver."); |
| 378 } |
| 379 if (!transport) { |
| 380 return CreateAndLogError( |
| 381 RTCErrorType::INVALID_PARAMETER, |
| 382 "Cannot pass null transport into CreateRtpReceiver."); |
| 383 } |
| 384 return RtpReceiverShim::CreateProxied(kind, rtp_parameters, |
| 385 transport->GetInternal()); |
| 386 } |
| 387 |
| 388 BEGIN_OWNED_PROXY_MAP(UdpTransport) |
| 389 PROXY_WORKER_THREAD_DESTRUCTOR() |
| 390 PROXY_WORKER_CONSTMETHOD0(rtc::SocketAddress, GetLocalAddress) |
| 391 PROXY_WORKER_METHOD1(bool, SetRemoteAddress, const rtc::SocketAddress&) |
| 392 PROXY_WORKER_CONSTMETHOD0(rtc::SocketAddress, GetRemoteAddress) |
| 393 protected: |
| 394 rtc::PacketTransportInternal* GetInternal() override { |
| 395 return internal(); |
| 396 } |
| 397 END_PROXY_MAP() |
| 398 |
| 399 RTCErrorOr<std::unique_ptr<UdpTransportInterface>> |
| 400 OrtcFactory::CreateUdpTransport(int family, |
| 401 uint16_t min_port, |
| 402 uint16_t max_port) { |
| 403 RTC_DCHECK_RUN_ON(network_thread_); |
103 std::unique_ptr<rtc::AsyncPacketSocket> socket( | 404 std::unique_ptr<rtc::AsyncPacketSocket> socket( |
104 socket_factory_->CreateUdpSocket( | 405 socket_factory_->CreateUdpSocket( |
105 rtc::SocketAddress(rtc::GetAnyIP(family), 0), min_port, max_port)); | 406 rtc::SocketAddress(rtc::GetAnyIP(family), 0), min_port, max_port)); |
106 if (!socket) { | 407 if (!socket) { |
107 LOG(LS_WARNING) << "Local socket allocation failure."; | 408 // Only log at warning level, because this method may be called with |
108 return nullptr; | 409 // specific port ranges to determine if a port is available, expecting the |
| 410 // possibility of an error. |
| 411 return CreateAndLogError(RTCErrorType::RESOURCE_EXHAUSTED, |
| 412 "Local socket allocation failure.", |
| 413 rtc::LS_WARNING); |
109 } | 414 } |
110 LOG(LS_INFO) << "Created UDP socket with address " | 415 LOG(LS_INFO) << "Created UDP socket with address " |
111 << socket->GetLocalAddress().ToSensitiveString() << "."; | 416 << socket->GetLocalAddress().ToSensitiveString() << "."; |
112 // Use proxy so that calls to the returned object are invoked on the network | 417 // Use proxy so that calls to the returned object are invoked on the network |
113 // thread. | 418 // thread. |
114 return UdpTransportProxy::Create( | 419 return UdpTransportProxyWithInternal<cricket::UdpTransport>::Create( |
115 signaling_thread_, network_thread_, | 420 signaling_thread_, network_thread_, |
116 new cricket::UdpTransport(std::string(), std::move(socket))); | 421 new cricket::UdpTransport(std::string(), std::move(socket))); |
117 } | 422 } |
118 | 423 |
| 424 rtc::scoped_refptr<AudioSourceInterface> OrtcFactory::CreateAudioSource( |
| 425 const cricket::AudioOptions& options) { |
| 426 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 427 return rtc::scoped_refptr<LocalAudioSource>( |
| 428 LocalAudioSource::Create(&options)); |
| 429 } |
| 430 |
| 431 rtc::scoped_refptr<VideoTrackSourceInterface> OrtcFactory::CreateVideoSource( |
| 432 std::unique_ptr<cricket::VideoCapturer> capturer, |
| 433 const MediaConstraintsInterface* constraints) { |
| 434 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 435 rtc::scoped_refptr<VideoTrackSourceInterface> source( |
| 436 VideoCapturerTrackSource::Create( |
| 437 worker_thread_.get(), std::move(capturer), constraints, false)); |
| 438 return VideoTrackSourceProxy::Create(signaling_thread_, worker_thread_.get(), |
| 439 source); |
| 440 } |
| 441 |
| 442 rtc::scoped_refptr<VideoTrackInterface> OrtcFactory::CreateVideoTrack( |
| 443 const std::string& id, |
| 444 VideoTrackSourceInterface* source) { |
| 445 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 446 rtc::scoped_refptr<VideoTrackInterface> track(VideoTrack::Create(id, source)); |
| 447 return VideoTrackProxy::Create(signaling_thread_, worker_thread_.get(), |
| 448 track); |
| 449 } |
| 450 |
| 451 rtc::scoped_refptr<AudioTrackInterface> OrtcFactory::CreateAudioTrack( |
| 452 const std::string& id, |
| 453 AudioSourceInterface* source) { |
| 454 RTC_DCHECK_RUN_ON(signaling_thread_); |
| 455 rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source)); |
| 456 return AudioTrackProxy::Create(signaling_thread_, track); |
| 457 } |
| 458 |
| 459 RTCError OrtcFactory::Initialize() { |
| 460 // TODO(deadbeef): Get rid of requirement to hop to worker thread here. |
| 461 std::unique_ptr<cricket::MediaEngineInterface> media_engine = |
| 462 worker_thread_->Invoke<std::unique_ptr<cricket::MediaEngineInterface>>( |
| 463 RTC_FROM_HERE, rtc::Bind(&OrtcFactory::CreateMediaEngine_w, this)); |
| 464 |
| 465 channel_manager_.reset(new cricket::ChannelManager( |
| 466 std::move(media_engine), worker_thread_.get(), network_thread_)); |
| 467 channel_manager_->SetVideoRtxEnabled(true); |
| 468 if (!channel_manager_->Init()) { |
| 469 return CreateAndLogError(RTCErrorType::INTERNAL_ERROR, |
| 470 "Failed to initialize ChannelManager."); |
| 471 } |
| 472 return RTCError(); |
| 473 } |
| 474 |
| 475 std::unique_ptr<cricket::MediaEngineInterface> |
| 476 OrtcFactory::CreateMediaEngine_w() { |
| 477 RTC_DCHECK_RUN_ON(worker_thread_.get()); |
| 478 // The nullptr arguments are optional factories that could be passed into the |
| 479 // OrtcFactory, but aren't yet. |
| 480 // Note that |adm_| may be null. |
| 481 return cricket::WebRtcMediaEngineFactory::Create(adm_, audio_decoder_factory_, |
| 482 nullptr, nullptr, nullptr); |
| 483 } |
| 484 |
119 } // namespace webrtc | 485 } // namespace webrtc |
OLD | NEW |