Simplify ChannelManager initialization.
* A ChannelManager instance is now created via ChannelManager::Create() * Initialization is performed inside Create(), RAII. * All member variables in CM are now either const or RTC_GUARDED_BY the worker thread. * Removed dead code (initialization and capturing states are gone). * ChannelManager now requires construction/destruction on worker thread. - one fewer threads that its aware of. * media_engine_ pointer removed from ConnectionContext. * Thread policy changes moved from ChannelManager to ConnectionContext. These changes will make a few other issues easier to fix, so tagging those bugs with this CL. Bug: webrtc:12601, webrtc:11988, webrtc:11992, webrtc:11994 Change-Id: I3284cf0a08c773e628af4124e8f52e9faddbe57a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/212617 Commit-Queue: Tommi <tommi@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33614}
This commit is contained in:
parent
97a387d7f3
commit
0b5ec183b5
@ -121,9 +121,9 @@ class MediaEngineInterface {
|
||||
public:
|
||||
virtual ~MediaEngineInterface() {}
|
||||
|
||||
// Initialization
|
||||
// Starts the engine.
|
||||
// Initialization. Needs to be called on the worker thread.
|
||||
virtual bool Init() = 0;
|
||||
|
||||
virtual VoiceEngineInterface& voice() = 0;
|
||||
virtual VideoEngineInterface& video() = 0;
|
||||
virtual const VoiceEngineInterface& voice() const = 0;
|
||||
@ -141,6 +141,8 @@ class CompositeMediaEngine : public MediaEngineInterface {
|
||||
CompositeMediaEngine(std::unique_ptr<VoiceEngineInterface> audio_engine,
|
||||
std::unique_ptr<VideoEngineInterface> video_engine);
|
||||
~CompositeMediaEngine() override;
|
||||
|
||||
// Always succeeds.
|
||||
bool Init() override;
|
||||
|
||||
VoiceEngineInterface& voice() override;
|
||||
@ -150,8 +152,8 @@ class CompositeMediaEngine : public MediaEngineInterface {
|
||||
|
||||
private:
|
||||
const std::unique_ptr<webrtc::WebRtcKeyValueConfig> trials_;
|
||||
std::unique_ptr<VoiceEngineInterface> voice_engine_;
|
||||
std::unique_ptr<VideoEngineInterface> video_engine_;
|
||||
const std::unique_ptr<VoiceEngineInterface> voice_engine_;
|
||||
const std::unique_ptr<VideoEngineInterface> video_engine_;
|
||||
};
|
||||
|
||||
enum DataChannelType {
|
||||
|
||||
@ -41,8 +41,7 @@ TEST(NullWebRtcVideoEngineTest, CheckInterface) {
|
||||
|
||||
CompositeMediaEngine engine(std::move(audio_engine),
|
||||
std::make_unique<NullWebRtcVideoEngine>());
|
||||
|
||||
EXPECT_TRUE(engine.Init());
|
||||
engine.Init();
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -340,6 +340,7 @@ rtc_library("connection_context") {
|
||||
"../rtc_base",
|
||||
"../rtc_base:checks",
|
||||
"../rtc_base:threading",
|
||||
"../rtc_base/task_utils:to_queued_task",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -25,45 +25,45 @@
|
||||
|
||||
namespace cricket {
|
||||
|
||||
// static
|
||||
std::unique_ptr<ChannelManager> ChannelManager::Create(
|
||||
std::unique_ptr<MediaEngineInterface> media_engine,
|
||||
std::unique_ptr<DataEngineInterface> data_engine,
|
||||
bool enable_rtx,
|
||||
rtc::Thread* worker_thread,
|
||||
rtc::Thread* network_thread) {
|
||||
RTC_DCHECK_RUN_ON(worker_thread);
|
||||
RTC_DCHECK(network_thread);
|
||||
RTC_DCHECK(worker_thread);
|
||||
RTC_DCHECK(data_engine);
|
||||
|
||||
if (media_engine)
|
||||
media_engine->Init();
|
||||
|
||||
return absl::WrapUnique(new ChannelManager(std::move(media_engine),
|
||||
std::move(data_engine), enable_rtx,
|
||||
worker_thread, network_thread));
|
||||
}
|
||||
|
||||
ChannelManager::ChannelManager(
|
||||
std::unique_ptr<MediaEngineInterface> media_engine,
|
||||
std::unique_ptr<DataEngineInterface> data_engine,
|
||||
bool enable_rtx,
|
||||
rtc::Thread* worker_thread,
|
||||
rtc::Thread* network_thread)
|
||||
: media_engine_(std::move(media_engine)),
|
||||
data_engine_(std::move(data_engine)),
|
||||
main_thread_(rtc::Thread::Current()),
|
||||
worker_thread_(worker_thread),
|
||||
network_thread_(network_thread) {
|
||||
network_thread_(network_thread),
|
||||
enable_rtx_(enable_rtx) {
|
||||
RTC_DCHECK(data_engine_);
|
||||
RTC_DCHECK(worker_thread_);
|
||||
RTC_DCHECK(network_thread_);
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
}
|
||||
|
||||
ChannelManager::~ChannelManager() {
|
||||
RTC_DCHECK_RUN_ON(main_thread_);
|
||||
if (initialized_) {
|
||||
Terminate();
|
||||
}
|
||||
// The media engine needs to be deleted on the worker thread for thread safe
|
||||
// destruction,
|
||||
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] { media_engine_.reset(); });
|
||||
}
|
||||
|
||||
bool ChannelManager::SetVideoRtxEnabled(bool enable) {
|
||||
RTC_DCHECK_RUN_ON(main_thread_);
|
||||
// To be safe, this call is only allowed before initialization. Apps like
|
||||
// Flute only have a singleton ChannelManager and we don't want this flag to
|
||||
// be toggled between calls or when there's concurrent calls. We expect apps
|
||||
// to enable this at startup and retain that setting for the lifetime of the
|
||||
// app.
|
||||
if (!initialized_) {
|
||||
enable_rtx_ = enable;
|
||||
return true;
|
||||
} else {
|
||||
RTC_LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
|
||||
return false;
|
||||
}
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
}
|
||||
|
||||
void ChannelManager::GetSupportedAudioSendCodecs(
|
||||
@ -121,35 +121,6 @@ void ChannelManager::GetSupportedDataCodecs(
|
||||
*codecs = data_engine_->data_codecs();
|
||||
}
|
||||
|
||||
bool ChannelManager::initialized() const {
|
||||
RTC_DCHECK_RUN_ON(main_thread_);
|
||||
return initialized_;
|
||||
}
|
||||
|
||||
bool ChannelManager::Init() {
|
||||
RTC_DCHECK_RUN_ON(main_thread_);
|
||||
RTC_DCHECK(!initialized_);
|
||||
if (initialized_) {
|
||||
return false;
|
||||
}
|
||||
RTC_DCHECK(network_thread_);
|
||||
RTC_DCHECK(worker_thread_);
|
||||
if (!network_thread_->IsCurrent()) {
|
||||
// Do not allow invoking calls to other threads on the network thread.
|
||||
network_thread_->Invoke<void>(
|
||||
RTC_FROM_HERE, [&] { network_thread_->DisallowBlockingCalls(); });
|
||||
}
|
||||
|
||||
if (media_engine_) {
|
||||
initialized_ = worker_thread_->Invoke<bool>(
|
||||
RTC_FROM_HERE, [&] { return media_engine_->Init(); });
|
||||
RTC_DCHECK(initialized_);
|
||||
} else {
|
||||
initialized_ = true;
|
||||
}
|
||||
return initialized_;
|
||||
}
|
||||
|
||||
RtpHeaderExtensions ChannelManager::GetDefaultEnabledAudioRtpHeaderExtensions()
|
||||
const {
|
||||
if (!media_engine_)
|
||||
@ -178,24 +149,9 @@ ChannelManager::GetSupportedVideoRtpHeaderExtensions() const {
|
||||
return media_engine_->video().GetRtpHeaderExtensions();
|
||||
}
|
||||
|
||||
void ChannelManager::Terminate() {
|
||||
RTC_DCHECK_RUN_ON(main_thread_);
|
||||
RTC_DCHECK(initialized_);
|
||||
if (!initialized_) {
|
||||
return;
|
||||
}
|
||||
// Need to destroy the channels on the worker thread.
|
||||
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
|
||||
video_channels_.clear();
|
||||
voice_channels_.clear();
|
||||
data_channels_.clear();
|
||||
});
|
||||
initialized_ = false;
|
||||
}
|
||||
|
||||
VoiceChannel* ChannelManager::CreateVoiceChannel(
|
||||
webrtc::Call* call,
|
||||
const cricket::MediaConfig& media_config,
|
||||
const MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
@ -249,6 +205,7 @@ void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
auto it = absl::c_find_if(voice_channels_,
|
||||
[&](const std::unique_ptr<VoiceChannel>& p) {
|
||||
return p.get() == voice_channel;
|
||||
@ -263,7 +220,7 @@ void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
|
||||
|
||||
VideoChannel* ChannelManager::CreateVideoChannel(
|
||||
webrtc::Call* call,
|
||||
const cricket::MediaConfig& media_config,
|
||||
const MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
@ -319,6 +276,7 @@ void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
|
||||
[&] { DestroyVideoChannel(video_channel); });
|
||||
return;
|
||||
}
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
|
||||
auto it = absl::c_find_if(video_channels_,
|
||||
[&](const std::unique_ptr<VideoChannel>& p) {
|
||||
@ -333,7 +291,7 @@ void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
|
||||
}
|
||||
|
||||
RtpDataChannel* ChannelManager::CreateRtpDataChannel(
|
||||
const cricket::MediaConfig& media_config,
|
||||
const MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
@ -348,6 +306,8 @@ RtpDataChannel* ChannelManager::CreateRtpDataChannel(
|
||||
});
|
||||
}
|
||||
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
|
||||
// This is ok to alloc from a thread other than the worker thread.
|
||||
DataMediaChannel* media_channel = data_engine_->CreateChannel(media_config);
|
||||
if (!media_channel) {
|
||||
@ -378,6 +338,7 @@ void ChannelManager::DestroyRtpDataChannel(RtpDataChannel* data_channel) {
|
||||
RTC_FROM_HERE, [&] { return DestroyRtpDataChannel(data_channel); });
|
||||
return;
|
||||
}
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
|
||||
auto it = absl::c_find_if(data_channels_,
|
||||
[&](const std::unique_ptr<RtpDataChannel>& p) {
|
||||
@ -391,6 +352,12 @@ void ChannelManager::DestroyRtpDataChannel(RtpDataChannel* data_channel) {
|
||||
data_channels_.erase(it);
|
||||
}
|
||||
|
||||
bool ChannelManager::has_channels() const {
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
return (!voice_channels_.empty() || !video_channels_.empty() ||
|
||||
!data_channels_.empty());
|
||||
}
|
||||
|
||||
bool ChannelManager::StartAecDump(webrtc::FileWrapper file,
|
||||
int64_t max_size_bytes) {
|
||||
return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
|
||||
|
||||
@ -45,11 +45,17 @@ namespace cricket {
|
||||
// using device manager.
|
||||
class ChannelManager final {
|
||||
public:
|
||||
// Construct a ChannelManager with the specified media engine and data engine.
|
||||
ChannelManager(std::unique_ptr<MediaEngineInterface> media_engine,
|
||||
// Returns an initialized instance of ChannelManager.
|
||||
// If media_engine is non-nullptr, then the returned ChannelManager instance
|
||||
// will own that reference and media engine initialization
|
||||
static std::unique_ptr<ChannelManager> Create(
|
||||
std::unique_ptr<MediaEngineInterface> media_engine,
|
||||
std::unique_ptr<DataEngineInterface> data_engine,
|
||||
bool enable_rtx,
|
||||
rtc::Thread* worker_thread,
|
||||
rtc::Thread* network_thread);
|
||||
|
||||
ChannelManager() = delete;
|
||||
~ChannelManager();
|
||||
|
||||
rtc::Thread* worker_thread() const { return worker_thread_; }
|
||||
@ -70,20 +76,13 @@ class ChannelManager final {
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
GetSupportedVideoRtpHeaderExtensions() const;
|
||||
|
||||
// Indicates whether the media engine is started.
|
||||
bool initialized() const;
|
||||
// Starts up the media engine.
|
||||
bool Init();
|
||||
// Shuts down the media engine.
|
||||
void Terminate();
|
||||
|
||||
// The operations below all occur on the worker thread.
|
||||
// ChannelManager retains ownership of the created channels, so clients should
|
||||
// call the appropriate Destroy*Channel method when done.
|
||||
|
||||
// Creates a voice channel, to be associated with the specified session.
|
||||
VoiceChannel* CreateVoiceChannel(webrtc::Call* call,
|
||||
const cricket::MediaConfig& media_config,
|
||||
const MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
@ -99,7 +98,7 @@ class ChannelManager final {
|
||||
// Version of the above that takes PacketTransportInternal.
|
||||
VideoChannel* CreateVideoChannel(
|
||||
webrtc::Call* call,
|
||||
const cricket::MediaConfig& media_config,
|
||||
const MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
@ -112,7 +111,7 @@ class ChannelManager final {
|
||||
void DestroyVideoChannel(VideoChannel* video_channel);
|
||||
|
||||
RtpDataChannel* CreateRtpDataChannel(
|
||||
const cricket::MediaConfig& media_config,
|
||||
const MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
@ -123,19 +122,7 @@ class ChannelManager final {
|
||||
void DestroyRtpDataChannel(RtpDataChannel* data_channel);
|
||||
|
||||
// Indicates whether any channels exist.
|
||||
bool has_channels() const {
|
||||
return (!voice_channels_.empty() || !video_channels_.empty() ||
|
||||
!data_channels_.empty());
|
||||
}
|
||||
|
||||
// RTX will be enabled/disabled in engines that support it. The supporting
|
||||
// engines will start offering an RTX codec. Must be called before Init().
|
||||
bool SetVideoRtxEnabled(bool enable);
|
||||
|
||||
// Starts/stops the local microphone and enables polling of the input level.
|
||||
bool capturing() const { return capturing_; }
|
||||
|
||||
// The operations below occur on the main thread.
|
||||
bool has_channels() const;
|
||||
|
||||
// Starts AEC dump using existing file, with a specified maximum file size in
|
||||
// bytes. When the limit is reached, logging will stop and the file will be
|
||||
@ -146,20 +133,26 @@ class ChannelManager final {
|
||||
void StopAecDump();
|
||||
|
||||
private:
|
||||
std::unique_ptr<MediaEngineInterface> media_engine_; // Nullable.
|
||||
std::unique_ptr<DataEngineInterface> data_engine_; // Non-null.
|
||||
bool initialized_ RTC_GUARDED_BY(main_thread_) = false;
|
||||
rtc::Thread* const main_thread_;
|
||||
ChannelManager(std::unique_ptr<MediaEngineInterface> media_engine,
|
||||
std::unique_ptr<DataEngineInterface> data_engine,
|
||||
bool enable_rtx,
|
||||
rtc::Thread* worker_thread,
|
||||
rtc::Thread* network_thread);
|
||||
|
||||
const std::unique_ptr<MediaEngineInterface> media_engine_; // Nullable.
|
||||
const std::unique_ptr<DataEngineInterface> data_engine_; // Non-null.
|
||||
rtc::Thread* const worker_thread_;
|
||||
rtc::Thread* const network_thread_;
|
||||
|
||||
// Vector contents are non-null.
|
||||
std::vector<std::unique_ptr<VoiceChannel>> voice_channels_;
|
||||
std::vector<std::unique_ptr<VideoChannel>> video_channels_;
|
||||
std::vector<std::unique_ptr<RtpDataChannel>> data_channels_;
|
||||
std::vector<std::unique_ptr<VoiceChannel>> voice_channels_
|
||||
RTC_GUARDED_BY(worker_thread_);
|
||||
std::vector<std::unique_ptr<VideoChannel>> video_channels_
|
||||
RTC_GUARDED_BY(worker_thread_);
|
||||
std::vector<std::unique_ptr<RtpDataChannel>> data_channels_
|
||||
RTC_GUARDED_BY(worker_thread_);
|
||||
|
||||
bool enable_rtx_ = false;
|
||||
bool capturing_ = false;
|
||||
const bool enable_rtx_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -26,11 +26,9 @@
|
||||
#include "rtc_base/thread.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace cricket {
|
||||
namespace {
|
||||
const bool kDefaultSrtpRequired = true;
|
||||
}
|
||||
|
||||
namespace cricket {
|
||||
|
||||
static const AudioCodec kAudioCodecs[] = {
|
||||
AudioCodec(97, "voice", 1, 2, 3),
|
||||
@ -43,31 +41,34 @@ static const VideoCodec kVideoCodecs[] = {
|
||||
VideoCodec(96, "rtx"),
|
||||
};
|
||||
|
||||
std::unique_ptr<MediaEngineInterface> CreateFakeMediaEngine() {
|
||||
auto fme = std::make_unique<FakeMediaEngine>();
|
||||
fme->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs));
|
||||
fme->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs));
|
||||
return fme;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class ChannelManagerTest : public ::testing::Test {
|
||||
protected:
|
||||
ChannelManagerTest()
|
||||
: network_(rtc::Thread::CreateWithSocketServer()),
|
||||
worker_(rtc::Thread::Create()),
|
||||
worker_(rtc::Thread::Current()),
|
||||
video_bitrate_allocator_factory_(
|
||||
webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
|
||||
fme_(new cricket::FakeMediaEngine()),
|
||||
fdme_(new cricket::FakeDataEngine()),
|
||||
cm_(new cricket::ChannelManager(
|
||||
std::unique_ptr<MediaEngineInterface>(fme_),
|
||||
std::unique_ptr<DataEngineInterface>(fdme_),
|
||||
worker_.get(),
|
||||
cm_(cricket::ChannelManager::Create(CreateFakeMediaEngine(),
|
||||
std::make_unique<FakeDataEngine>(),
|
||||
false,
|
||||
worker_,
|
||||
network_.get())),
|
||||
fake_call_() {
|
||||
fme_->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs));
|
||||
fme_->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs));
|
||||
network_->SetName("Network", this);
|
||||
worker_->SetName("Worker", this);
|
||||
network_->Start();
|
||||
worker_->Start();
|
||||
}
|
||||
|
||||
void TestCreateDestroyChannels(webrtc::RtpTransportInternal* rtp_transport) {
|
||||
worker_->Invoke<void>(RTC_FROM_HERE, [this, rtp_transport]() {
|
||||
RTC_DCHECK_RUN_ON(worker_);
|
||||
cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
|
||||
&fake_call_, cricket::MediaConfig(), rtp_transport,
|
||||
rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
|
||||
@ -87,42 +88,17 @@ class ChannelManagerTest : public ::testing::Test {
|
||||
cm_->DestroyVideoChannel(video_channel);
|
||||
cm_->DestroyVoiceChannel(voice_channel);
|
||||
cm_->DestroyRtpDataChannel(rtp_data_channel);
|
||||
});
|
||||
cm_->Terminate();
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::Thread> network_;
|
||||
std::unique_ptr<rtc::Thread> worker_;
|
||||
rtc::Thread* const worker_;
|
||||
std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
|
||||
video_bitrate_allocator_factory_;
|
||||
// |fme_| and |fdme_| are actually owned by |cm_|.
|
||||
cricket::FakeMediaEngine* fme_;
|
||||
cricket::FakeDataEngine* fdme_;
|
||||
std::unique_ptr<cricket::ChannelManager> cm_;
|
||||
cricket::FakeCall fake_call_;
|
||||
rtc::UniqueRandomIdGenerator ssrc_generator_;
|
||||
};
|
||||
|
||||
// Test that we startup/shutdown properly.
|
||||
TEST_F(ChannelManagerTest, StartupShutdown) {
|
||||
EXPECT_FALSE(cm_->initialized());
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
EXPECT_TRUE(cm_->initialized());
|
||||
cm_->Terminate();
|
||||
EXPECT_FALSE(cm_->initialized());
|
||||
}
|
||||
|
||||
// Test that we startup/shutdown properly with a worker thread.
|
||||
TEST_F(ChannelManagerTest, StartupShutdownOnThread) {
|
||||
EXPECT_FALSE(cm_->initialized());
|
||||
EXPECT_EQ(network_.get(), cm_->network_thread());
|
||||
EXPECT_EQ(worker_.get(), cm_->worker_thread());
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
EXPECT_TRUE(cm_->initialized());
|
||||
cm_->Terminate();
|
||||
EXPECT_FALSE(cm_->initialized());
|
||||
}
|
||||
|
||||
TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
|
||||
std::vector<VideoCodec> send_codecs;
|
||||
std::vector<VideoCodec> recv_codecs;
|
||||
@ -135,35 +111,25 @@ TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
|
||||
EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec));
|
||||
|
||||
// Enable and check.
|
||||
EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
|
||||
cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(),
|
||||
std::make_unique<FakeDataEngine>(),
|
||||
true, worker_, network_.get());
|
||||
cm_->GetSupportedVideoSendCodecs(&send_codecs);
|
||||
EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec));
|
||||
cm_->GetSupportedVideoSendCodecs(&recv_codecs);
|
||||
EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec));
|
||||
|
||||
// Disable and check.
|
||||
EXPECT_TRUE(cm_->SetVideoRtxEnabled(false));
|
||||
cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(),
|
||||
std::make_unique<FakeDataEngine>(),
|
||||
false, worker_, network_.get());
|
||||
cm_->GetSupportedVideoSendCodecs(&send_codecs);
|
||||
EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec));
|
||||
cm_->GetSupportedVideoSendCodecs(&recv_codecs);
|
||||
EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec));
|
||||
|
||||
// Cannot toggle rtx after initialization.
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
EXPECT_FALSE(cm_->SetVideoRtxEnabled(true));
|
||||
EXPECT_FALSE(cm_->SetVideoRtxEnabled(false));
|
||||
|
||||
// Can set again after terminate.
|
||||
cm_->Terminate();
|
||||
EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
|
||||
cm_->GetSupportedVideoSendCodecs(&send_codecs);
|
||||
EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec));
|
||||
cm_->GetSupportedVideoSendCodecs(&recv_codecs);
|
||||
EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec));
|
||||
}
|
||||
|
||||
TEST_F(ChannelManagerTest, CreateDestroyChannels) {
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
auto rtp_dtls_transport = std::make_unique<FakeDtlsTransport>(
|
||||
"fake_dtls_transport", cricket::ICE_CANDIDATE_COMPONENT_RTP,
|
||||
network_.get());
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "media/base/rtp_data_engine.h"
|
||||
#include "rtc_base/helpers.h"
|
||||
#include "rtc_base/ref_counted_object.h"
|
||||
#include "rtc_base/task_utils/to_queued_task.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -75,11 +76,7 @@ std::unique_ptr<SctpTransportFactoryInterface> MaybeCreateSctpFactory(
|
||||
// Static
|
||||
rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
|
||||
PeerConnectionFactoryDependencies* dependencies) {
|
||||
auto context = new rtc::RefCountedObject<ConnectionContext>(dependencies);
|
||||
if (!context->channel_manager_->Init()) {
|
||||
return nullptr;
|
||||
}
|
||||
return context;
|
||||
return new rtc::RefCountedObject<ConnectionContext>(dependencies);
|
||||
}
|
||||
|
||||
ConnectionContext::ConnectionContext(
|
||||
@ -97,7 +94,6 @@ ConnectionContext::ConnectionContext(
|
||||
network_monitor_factory_(
|
||||
std::move(dependencies->network_monitor_factory)),
|
||||
call_factory_(std::move(dependencies->call_factory)),
|
||||
media_engine_(std::move(dependencies->media_engine)),
|
||||
sctp_factory_(
|
||||
MaybeCreateSctpFactory(std::move(dependencies->sctp_factory),
|
||||
network_thread())),
|
||||
@ -107,7 +103,14 @@ ConnectionContext::ConnectionContext(
|
||||
signaling_thread_->AllowInvokesToThread(worker_thread_);
|
||||
signaling_thread_->AllowInvokesToThread(network_thread_);
|
||||
worker_thread_->AllowInvokesToThread(network_thread_);
|
||||
if (network_thread_->IsCurrent()) {
|
||||
network_thread_->DisallowAllInvokes();
|
||||
} else {
|
||||
network_thread_->PostTask(ToQueuedTask([thread = network_thread_] {
|
||||
thread->DisallowBlockingCalls();
|
||||
thread->DisallowAllInvokes();
|
||||
}));
|
||||
}
|
||||
|
||||
RTC_DCHECK_RUN_ON(signaling_thread_);
|
||||
rtc::InitRandom(rtc::Time32());
|
||||
@ -120,11 +123,13 @@ ConnectionContext::ConnectionContext(
|
||||
default_socket_factory_ =
|
||||
std::make_unique<rtc::BasicPacketSocketFactory>(network_thread());
|
||||
|
||||
channel_manager_ = std::make_unique<cricket::ChannelManager>(
|
||||
std::move(media_engine_), std::make_unique<cricket::RtpDataEngine>(),
|
||||
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
|
||||
channel_manager_ = cricket::ChannelManager::Create(
|
||||
std::move(dependencies->media_engine),
|
||||
std::make_unique<cricket::RtpDataEngine>(), /*enable_rtx=*/true,
|
||||
worker_thread(), network_thread());
|
||||
});
|
||||
|
||||
channel_manager_->SetVideoRtxEnabled(true);
|
||||
// Set warning levels on the threads, to give warnings when response
|
||||
// may be slower than is expected of the thread.
|
||||
// Since some of the threads may be the same, start with the least
|
||||
@ -137,7 +142,8 @@ ConnectionContext::ConnectionContext(
|
||||
|
||||
ConnectionContext::~ConnectionContext() {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread_);
|
||||
channel_manager_.reset(nullptr);
|
||||
worker_thread_->Invoke<void>(RTC_FROM_HERE,
|
||||
[&]() { channel_manager_.reset(nullptr); });
|
||||
|
||||
// Make sure |worker_thread()| and |signaling_thread()| outlive
|
||||
// |default_socket_factory_| and |default_network_manager_|.
|
||||
|
||||
@ -120,8 +120,6 @@ class ConnectionContext : public rtc::RefCountInterface {
|
||||
|
||||
std::unique_ptr<rtc::BasicPacketSocketFactory> default_socket_factory_
|
||||
RTC_GUARDED_BY(signaling_thread_);
|
||||
std::unique_ptr<cricket::MediaEngineInterface> media_engine_
|
||||
RTC_GUARDED_BY(signaling_thread_);
|
||||
std::unique_ptr<SctpTransportFactoryInterface> const sctp_factory_;
|
||||
// Accessed both on signaling thread and worker thread.
|
||||
std::unique_ptr<WebRtcKeyValueConfig> const trials_;
|
||||
|
||||
@ -108,24 +108,25 @@ class RtpSenderReceiverTest
|
||||
// Create fake media engine/etc. so we can create channels to use to
|
||||
// test RtpSenders/RtpReceivers.
|
||||
media_engine_(new cricket::FakeMediaEngine()),
|
||||
channel_manager_(absl::WrapUnique(media_engine_),
|
||||
std::make_unique<cricket::RtpDataEngine>(),
|
||||
worker_thread_,
|
||||
network_thread_),
|
||||
fake_call_(),
|
||||
local_stream_(MediaStream::Create(kStreamId1)) {
|
||||
// Create channels to be used by the RtpSenders and RtpReceivers.
|
||||
channel_manager_.Init();
|
||||
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
|
||||
channel_manager_ = cricket::ChannelManager::Create(
|
||||
absl::WrapUnique(media_engine_),
|
||||
std::make_unique<cricket::RtpDataEngine>(), false, worker_thread_,
|
||||
network_thread_);
|
||||
});
|
||||
|
||||
bool srtp_required = true;
|
||||
rtp_dtls_transport_ = std::make_unique<cricket::FakeDtlsTransport>(
|
||||
"fake_dtls_transport", cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
rtp_transport_ = CreateDtlsSrtpTransport();
|
||||
|
||||
voice_channel_ = channel_manager_.CreateVoiceChannel(
|
||||
voice_channel_ = channel_manager_->CreateVoiceChannel(
|
||||
&fake_call_, cricket::MediaConfig(), rtp_transport_.get(),
|
||||
rtc::Thread::Current(), cricket::CN_AUDIO, srtp_required,
|
||||
webrtc::CryptoOptions(), &ssrc_generator_, cricket::AudioOptions());
|
||||
video_channel_ = channel_manager_.CreateVideoChannel(
|
||||
video_channel_ = channel_manager_->CreateVideoChannel(
|
||||
&fake_call_, cricket::MediaConfig(), rtp_transport_.get(),
|
||||
rtc::Thread::Current(), cricket::CN_VIDEO, srtp_required,
|
||||
webrtc::CryptoOptions(), &ssrc_generator_, cricket::VideoOptions(),
|
||||
@ -161,6 +162,18 @@ class RtpSenderReceiverTest
|
||||
cricket::StreamParams::CreateLegacy(kVideoSsrc2));
|
||||
}
|
||||
|
||||
~RtpSenderReceiverTest() {
|
||||
audio_rtp_sender_ = nullptr;
|
||||
video_rtp_sender_ = nullptr;
|
||||
audio_rtp_receiver_ = nullptr;
|
||||
video_rtp_receiver_ = nullptr;
|
||||
local_stream_ = nullptr;
|
||||
video_track_ = nullptr;
|
||||
audio_track_ = nullptr;
|
||||
worker_thread_->Invoke<void>(RTC_FROM_HERE,
|
||||
[&]() { channel_manager_.reset(); });
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::RtpTransportInternal> CreateDtlsSrtpTransport() {
|
||||
auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
|
||||
/*rtcp_mux_required=*/true);
|
||||
@ -497,7 +510,7 @@ class RtpSenderReceiverTest
|
||||
video_bitrate_allocator_factory_;
|
||||
// |media_engine_| is actually owned by |channel_manager_|.
|
||||
cricket::FakeMediaEngine* media_engine_;
|
||||
cricket::ChannelManager channel_manager_;
|
||||
std::unique_ptr<cricket::ChannelManager> channel_manager_;
|
||||
cricket::FakeCall fake_call_;
|
||||
cricket::VoiceChannel* voice_channel_;
|
||||
cricket::VideoChannel* video_channel_;
|
||||
|
||||
@ -82,21 +82,23 @@ TEST(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
|
||||
class RtpTransceiverUnifiedPlanTest : public ::testing::Test {
|
||||
public:
|
||||
RtpTransceiverUnifiedPlanTest()
|
||||
: channel_manager_(std::make_unique<cricket::FakeMediaEngine>(),
|
||||
: channel_manager_(cricket::ChannelManager::Create(
|
||||
std::make_unique<cricket::FakeMediaEngine>(),
|
||||
std::make_unique<cricket::FakeDataEngine>(),
|
||||
false,
|
||||
rtc::Thread::Current(),
|
||||
rtc::Thread::Current()),
|
||||
rtc::Thread::Current())),
|
||||
transceiver_(RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
|
||||
rtc::Thread::Current(),
|
||||
new rtc::RefCountedObject<MockRtpSenderInternal>()),
|
||||
RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
|
||||
rtc::Thread::Current(),
|
||||
new rtc::RefCountedObject<MockRtpReceiverInternal>()),
|
||||
&channel_manager_,
|
||||
channel_manager_.GetSupportedAudioRtpHeaderExtensions(),
|
||||
channel_manager_.get(),
|
||||
channel_manager_->GetSupportedAudioRtpHeaderExtensions(),
|
||||
/* on_negotiation_needed= */ [] {}) {}
|
||||
|
||||
cricket::ChannelManager channel_manager_;
|
||||
std::unique_ptr<cricket::ChannelManager> channel_manager_;
|
||||
RtpTransceiver transceiver_;
|
||||
};
|
||||
|
||||
@ -117,10 +119,12 @@ TEST_F(RtpTransceiverUnifiedPlanTest, StopSetsDirection) {
|
||||
class RtpTransceiverTestForHeaderExtensions : public ::testing::Test {
|
||||
public:
|
||||
RtpTransceiverTestForHeaderExtensions()
|
||||
: channel_manager_(std::make_unique<cricket::FakeMediaEngine>(),
|
||||
: channel_manager_(cricket::ChannelManager::Create(
|
||||
std::make_unique<cricket::FakeMediaEngine>(),
|
||||
std::make_unique<cricket::FakeDataEngine>(),
|
||||
false,
|
||||
rtc::Thread::Current(),
|
||||
rtc::Thread::Current()),
|
||||
rtc::Thread::Current())),
|
||||
extensions_(
|
||||
{RtpHeaderExtensionCapability("uri1",
|
||||
1,
|
||||
@ -140,11 +144,11 @@ class RtpTransceiverTestForHeaderExtensions : public ::testing::Test {
|
||||
RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
|
||||
rtc::Thread::Current(),
|
||||
new rtc::RefCountedObject<MockRtpReceiverInternal>()),
|
||||
&channel_manager_,
|
||||
channel_manager_.get(),
|
||||
extensions_,
|
||||
/* on_negotiation_needed= */ [] {}) {}
|
||||
|
||||
cricket::ChannelManager channel_manager_;
|
||||
std::unique_ptr<cricket::ChannelManager> channel_manager_;
|
||||
std::vector<RtpHeaderExtensionCapability> extensions_;
|
||||
RtpTransceiver transceiver_;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user