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

Side by Side Diff: webrtc/ortc/ortcfactory.cc

Issue 2675173003: Adding "adapter" ORTC objects on top of ChannelManager/BaseChannel/etc. (Closed)
Patch Set: More sender/receiver tests. Created 3 years, 10 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
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698