Make MediaChannel classes aware of the network thread.

This CL mostly adds plumbing to get awareness of the network thread
to the media channel classes. Currently this pointer is only used
to DCHECK that `SetInterface` for the `NetworkInterface` pointer, is
called on the network thread. Follow up changes will establish that
most of the methods are called on the network thread and the mutex
in the MediaChannel base class, can be removed.

Most of the changes in the CL are in channel_unittest.cc. They're mostly
around updating the tests to incorporate the network thread in ways
that reflect how the classes are used in production. Another change is
to use accessor methods for the media channel instances instead of
caching potentially dangling pointers.

Bug: webrtc:11993
Change-Id: I8e2ed1bc23724e238554dbce386789d69660f7e4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217682
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33951}
This commit is contained in:
Tommi 2021-05-06 22:03:19 +02:00 committed by WebRTC LUCI CQ
parent ad5037b4a8
commit c9625f09de
11 changed files with 295 additions and 217 deletions

View File

@ -18,6 +18,7 @@
#include "rtc_base/checks.h"
namespace cricket {
using webrtc::TaskQueueBase;
FakeVoiceMediaChannel::DtmfInfo::DtmfInfo(uint32_t ssrc,
int event_code,
@ -49,8 +50,11 @@ AudioSource* FakeVoiceMediaChannel::VoiceChannelAudioSink::source() const {
}
FakeVoiceMediaChannel::FakeVoiceMediaChannel(FakeVoiceEngine* engine,
const AudioOptions& options)
: engine_(engine), max_bps_(-1) {
const AudioOptions& options,
TaskQueueBase* network_thread)
: RtpHelper<VoiceMediaChannel>(network_thread),
engine_(engine),
max_bps_(-1) {
output_scalings_[0] = 1.0; // For default channel.
SetOptions(options);
}
@ -253,8 +257,11 @@ bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info,
}
FakeVideoMediaChannel::FakeVideoMediaChannel(FakeVideoEngine* engine,
const VideoOptions& options)
: engine_(engine), max_bps_(-1) {
const VideoOptions& options,
TaskQueueBase* network_thread)
: RtpHelper<VideoMediaChannel>(network_thread),
engine_(engine),
max_bps_(-1) {
SetOptions(options);
}
FakeVideoMediaChannel::~FakeVideoMediaChannel() {
@ -440,7 +447,8 @@ VoiceMediaChannel* FakeVoiceEngine::CreateMediaChannel(
return nullptr;
}
FakeVoiceMediaChannel* ch = new FakeVoiceMediaChannel(this, options);
FakeVoiceMediaChannel* ch =
new FakeVoiceMediaChannel(this, options, call->network_thread());
channels_.push_back(ch);
return ch;
}
@ -506,7 +514,8 @@ VideoMediaChannel* FakeVideoEngine::CreateMediaChannel(
return nullptr;
}
FakeVideoMediaChannel* ch = new FakeVideoMediaChannel(this, options);
FakeVideoMediaChannel* ch =
new FakeVideoMediaChannel(this, options, call->network_thread());
channels_.emplace_back(ch);
return ch;
}

View File

@ -42,8 +42,9 @@ class FakeVoiceEngine;
template <class Base>
class RtpHelper : public Base {
public:
RtpHelper()
: sending_(false),
explicit RtpHelper(webrtc::TaskQueueBase* network_thread)
: Base(network_thread),
sending_(false),
playout_(false),
fail_set_send_codecs_(false),
fail_set_recv_codecs_(false),
@ -314,8 +315,9 @@ class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> {
int event_code;
int duration;
};
explicit FakeVoiceMediaChannel(FakeVoiceEngine* engine,
const AudioOptions& options);
FakeVoiceMediaChannel(FakeVoiceEngine* engine,
const AudioOptions& options,
webrtc::TaskQueueBase* network_thread);
~FakeVoiceMediaChannel();
const std::vector<AudioCodec>& recv_codecs() const;
const std::vector<AudioCodec>& send_codecs() const;
@ -406,7 +408,9 @@ bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info,
class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> {
public:
FakeVideoMediaChannel(FakeVideoEngine* engine, const VideoOptions& options);
FakeVideoMediaChannel(FakeVideoEngine* engine,
const VideoOptions& options,
webrtc::TaskQueueBase* network_thread);
~FakeVideoMediaChannel();

View File

@ -11,20 +11,31 @@
#include "media/base/media_channel.h"
namespace cricket {
using webrtc::FrameDecryptorInterface;
using webrtc::FrameEncryptorInterface;
using webrtc::FrameTransformerInterface;
using webrtc::MutexLock;
using webrtc::TaskQueueBase;
using webrtc::VideoTrackInterface;
VideoOptions::VideoOptions()
: content_hint(webrtc::VideoTrackInterface::ContentHint::kNone) {}
: content_hint(VideoTrackInterface::ContentHint::kNone) {}
VideoOptions::~VideoOptions() = default;
MediaChannel::MediaChannel(const MediaConfig& config)
: enable_dscp_(config.enable_dscp) {}
MediaChannel::MediaChannel(const MediaConfig& config,
TaskQueueBase* network_thread)
: enable_dscp_(config.enable_dscp), network_thread_(network_thread) {}
MediaChannel::MediaChannel() : enable_dscp_(false) {}
MediaChannel::MediaChannel(TaskQueueBase* network_thread)
: enable_dscp_(false), network_thread_(network_thread) {}
MediaChannel::~MediaChannel() {}
MediaChannel::~MediaChannel() {
RTC_DCHECK(!network_interface_);
}
void MediaChannel::SetInterface(NetworkInterface* iface) {
webrtc::MutexLock lock(&network_interface_mutex_);
RTC_DCHECK_RUN_ON(network_thread_);
MutexLock lock(&network_interface_mutex_);
network_interface_ = iface;
UpdateDscp();
}
@ -35,13 +46,13 @@ int MediaChannel::GetRtpSendTimeExtnId() const {
void MediaChannel::SetFrameEncryptor(
uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor) {
rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
// Placeholder should be pure virtual once internal supports it.
}
void MediaChannel::SetFrameDecryptor(
uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor) {
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
// Placeholder should be pure virtual once internal supports it.
}
@ -61,7 +72,7 @@ int MediaChannel::SetOption(NetworkInterface::SocketType type,
rtc::Socket::Option opt,
int option)
RTC_LOCKS_EXCLUDED(network_interface_mutex_) {
webrtc::MutexLock lock(&network_interface_mutex_);
MutexLock lock(&network_interface_mutex_);
return SetOptionLocked(type, opt, option);
}
@ -79,11 +90,11 @@ bool MediaChannel::ExtmapAllowMixed() const {
void MediaChannel::SetEncoderToPacketizerFrameTransformer(
uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {}
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {}
void MediaChannel::SetDepacketizerToDecoderFrameTransformer(
uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {}
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {}
int MediaChannel::SetOptionLocked(NetworkInterface::SocketType type,
rtc::Socket::Option opt,
@ -100,12 +111,12 @@ bool MediaChannel::DscpEnabled() const {
// This is the DSCP value used for both RTP and RTCP channels if DSCP is
// enabled. It can be changed at any time via |SetPreferredDscp|.
rtc::DiffServCodePoint MediaChannel::PreferredDscp() const {
webrtc::MutexLock lock(&network_interface_mutex_);
MutexLock lock(&network_interface_mutex_);
return preferred_dscp_;
}
int MediaChannel::SetPreferredDscp(rtc::DiffServCodePoint preferred_dscp) {
webrtc::MutexLock lock(&network_interface_mutex_);
MutexLock lock(&network_interface_mutex_);
if (preferred_dscp == preferred_dscp_) {
return 0;
}
@ -128,7 +139,7 @@ int MediaChannel::UpdateDscp() {
bool MediaChannel::DoSendPacket(rtc::CopyOnWriteBuffer* packet,
bool rtcp,
const rtc::PacketOptions& options) {
webrtc::MutexLock lock(&network_interface_mutex_);
MutexLock lock(&network_interface_mutex_);
if (!network_interface_)
return false;

View File

@ -168,8 +168,9 @@ class MediaChannel {
virtual ~NetworkInterface() {}
};
explicit MediaChannel(const MediaConfig& config);
MediaChannel();
MediaChannel(const MediaConfig& config,
webrtc::TaskQueueBase* network_thread);
explicit MediaChannel(webrtc::TaskQueueBase* network_thread);
virtual ~MediaChannel();
virtual cricket::MediaType media_type() const = 0;
@ -296,6 +297,8 @@ class MediaChannel {
RTC_LOCKS_EXCLUDED(network_interface_mutex_);
const bool enable_dscp_;
webrtc::TaskQueueBase* const network_thread_;
// |network_interface_| can be accessed from the worker_thread and
// from any MediaEngine threads. This critical section is to protect accessing
// of network_interface_ object.
@ -761,9 +764,11 @@ struct AudioRecvParameters : RtpParameters<AudioCodec> {};
class VoiceMediaChannel : public MediaChannel, public Delayable {
public:
VoiceMediaChannel() {}
explicit VoiceMediaChannel(const MediaConfig& config)
: MediaChannel(config) {}
explicit VoiceMediaChannel(webrtc::TaskQueueBase* network_thread)
: MediaChannel(network_thread) {}
VoiceMediaChannel(const MediaConfig& config,
webrtc::TaskQueueBase* network_thread)
: MediaChannel(config, network_thread) {}
~VoiceMediaChannel() override {}
cricket::MediaType media_type() const override;
@ -831,9 +836,11 @@ struct VideoRecvParameters : RtpParameters<VideoCodec> {};
class VideoMediaChannel : public MediaChannel, public Delayable {
public:
VideoMediaChannel() {}
explicit VideoMediaChannel(const MediaConfig& config)
: MediaChannel(config) {}
explicit VideoMediaChannel(webrtc::TaskQueueBase* network_thread)
: MediaChannel(network_thread) {}
VideoMediaChannel(const MediaConfig& config,
webrtc::TaskQueueBase* network_thread)
: MediaChannel(config, network_thread) {}
~VideoMediaChannel() override {}
cricket::MediaType media_type() const override;

View File

@ -702,7 +702,7 @@ WebRtcVideoChannel::WebRtcVideoChannel(
webrtc::VideoEncoderFactory* encoder_factory,
webrtc::VideoDecoderFactory* decoder_factory,
webrtc::VideoBitrateAllocatorFactory* bitrate_allocator_factory)
: VideoMediaChannel(config),
: VideoMediaChannel(config, call->network_thread()),
worker_thread_(call->worker_thread()),
call_(call),
unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
@ -1869,7 +1869,7 @@ void WebRtcVideoChannel::OnNetworkRouteChanged(
}
void WebRtcVideoChannel::SetInterface(NetworkInterface* iface) {
RTC_DCHECK_RUN_ON(&thread_checker_);
RTC_DCHECK_RUN_ON(&network_thread_checker_);
MediaChannel::SetInterface(iface);
// Set the RTP recv/send buffer to a bigger size.

View File

@ -1381,7 +1381,7 @@ WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(
const AudioOptions& options,
const webrtc::CryptoOptions& crypto_options,
webrtc::Call* call)
: VoiceMediaChannel(config),
: VoiceMediaChannel(config, call->network_thread()),
worker_thread_(call->worker_thread()),
engine_(engine),
call_(call),

View File

@ -888,6 +888,8 @@ if (rtc_include_tests && !build_with_chromium) {
"../rtc_base:rtc_base_approved",
"../rtc_base:rtc_base_tests_utils",
"../rtc_base:threading",
"../rtc_base/task_utils:pending_task_safety_flag",
"../rtc_base/task_utils:to_queued_task",
"../rtc_base/third_party/sigslot",
"../system_wrappers:metrics",
"../test:field_trial",

View File

@ -208,22 +208,22 @@ void BaseChannel::DisconnectFromRtpTransport() {
void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
RTC_DCHECK_RUN_ON(worker_thread());
network_thread_->Invoke<void>(
RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
// Both RTP and RTCP channels should be set, we can call SetInterface on
// the media channel and it can set network options.
media_channel_->SetInterface(this);
network_thread_->Invoke<void>(RTC_FROM_HERE, [this, rtp_transport] {
SetRtpTransport(rtp_transport);
// Both RTP and RTCP channels should be set, we can call SetInterface on
// the media channel and it can set network options.
media_channel_->SetInterface(this);
});
}
void BaseChannel::Deinit() {
RTC_DCHECK_RUN_ON(worker_thread());
media_channel_->SetInterface(/*iface=*/nullptr);
// Packets arrive on the network thread, processing packets calls virtual
// functions, so need to stop this process in Deinit that is called in
// derived classes destructor.
network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
RTC_DCHECK_RUN_ON(network_thread());
media_channel_->SetInterface(/*iface=*/nullptr);
FlushRtcpMessages_n();
if (rtp_transport_) {

View File

@ -35,6 +35,8 @@
#include "rtc_base/checks.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/task_utils/pending_task_safety_flag.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "test/gmock.h"
#include "test/gtest.h"
@ -119,19 +121,30 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
network_thread_keeper_->SetName("Network", nullptr);
network_thread_ = network_thread_keeper_.get();
}
RTC_DCHECK(network_thread_);
}
~ChannelTest() {
if (network_thread_) {
network_thread_->Invoke<void>(
RTC_FROM_HERE, [this]() { network_thread_safety_->SetNotAlive(); });
}
}
void CreateChannels(int flags1, int flags2) {
CreateChannels(std::make_unique<typename T::MediaChannel>(
nullptr, typename T::Options()),
nullptr, typename T::Options(), network_thread_),
std::make_unique<typename T::MediaChannel>(
nullptr, typename T::Options()),
nullptr, typename T::Options(), network_thread_),
flags1, flags2);
}
void CreateChannels(std::unique_ptr<typename T::MediaChannel> ch1,
std::unique_ptr<typename T::MediaChannel> ch2,
int flags1,
int flags2) {
RTC_DCHECK(!channel1_);
RTC_DCHECK(!channel2_);
// Network thread is started in CreateChannels, to allow the test to
// configure a fake clock before any threads are spawned and attempt to
// access the time.
@ -143,8 +156,6 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
// channels.
RTC_DCHECK_EQ(flags1 & RAW_PACKET_TRANSPORT, flags2 & RAW_PACKET_TRANSPORT);
rtc::Thread* worker_thread = rtc::Thread::Current();
media_channel1_ = ch1.get();
media_channel2_ = ch2.get();
rtc::PacketTransportInternal* rtp1 = nullptr;
rtc::PacketTransportInternal* rtcp1 = nullptr;
rtc::PacketTransportInternal* rtp2 = nullptr;
@ -399,43 +410,59 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
fake_rtp_packet_transport2_.reset();
fake_rtcp_packet_transport2_.reset();
if (network_thread_keeper_) {
RTC_DCHECK_EQ(network_thread_, network_thread_keeper_.get());
network_thread_ = nullptr;
network_thread_keeper_.reset();
}
return true;
}
void SendRtp(typename T::MediaChannel* media_channel, rtc::Buffer data) {
network_thread_->PostTask(webrtc::ToQueuedTask(
network_thread_safety_, [media_channel, data = std::move(data)]() {
media_channel->SendRtp(data.data(), data.size(),
rtc::PacketOptions());
}));
}
void SendRtp1() {
media_channel1_->SendRtp(rtp_packet_.data(), rtp_packet_.size(),
rtc::PacketOptions());
SendRtp1(rtc::Buffer(rtp_packet_.data(), rtp_packet_.size()));
}
void SendRtp1(rtc::Buffer data) {
SendRtp(media_channel1(), std::move(data));
}
void SendRtp2() {
media_channel2_->SendRtp(rtp_packet_.data(), rtp_packet_.size(),
rtc::PacketOptions());
SendRtp2(rtc::Buffer(rtp_packet_.data(), rtp_packet_.size()));
}
void SendRtp2(rtc::Buffer data) {
SendRtp(media_channel2(), std::move(data));
}
// Methods to send custom data.
void SendCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) {
rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
media_channel1_->SendRtp(data.data(), data.size(), rtc::PacketOptions());
SendRtp1(CreateRtpData(ssrc, sequence_number, pl_type));
}
void SendCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) {
rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
media_channel2_->SendRtp(data.data(), data.size(), rtc::PacketOptions());
SendRtp2(CreateRtpData(ssrc, sequence_number, pl_type));
}
bool CheckRtp1() {
return media_channel1_->CheckRtp(rtp_packet_.data(), rtp_packet_.size());
return media_channel1()->CheckRtp(rtp_packet_.data(), rtp_packet_.size());
}
bool CheckRtp2() {
return media_channel2_->CheckRtp(rtp_packet_.data(), rtp_packet_.size());
return media_channel2()->CheckRtp(rtp_packet_.data(), rtp_packet_.size());
}
// Methods to check custom data.
bool CheckCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) {
rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
return media_channel1_->CheckRtp(data.data(), data.size());
return media_channel1()->CheckRtp(data.data(), data.size());
}
bool CheckCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) {
rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
return media_channel2_->CheckRtp(data.data(), data.size());
return media_channel2()->CheckRtp(data.data(), data.size());
}
rtc::Buffer CreateRtpData(uint32_t ssrc, int sequence_number, int pl_type) {
rtc::Buffer data(rtp_packet_.data(), rtp_packet_.size());
@ -448,8 +475,8 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
return data;
}
bool CheckNoRtp1() { return media_channel1_->CheckNoRtp(); }
bool CheckNoRtp2() { return media_channel2_->CheckNoRtp(); }
bool CheckNoRtp1() { return media_channel1()->CheckNoRtp(); }
bool CheckNoRtp2() { return media_channel2()->CheckNoRtp(); }
void CreateContent(int flags,
const cricket::AudioCodec& audio_codec,
@ -529,13 +556,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
void TestInit() {
CreateChannels(0, 0);
EXPECT_FALSE(IsSrtpActive(channel1_));
EXPECT_FALSE(media_channel1_->sending());
EXPECT_FALSE(media_channel1()->sending());
if (verify_playout_) {
EXPECT_FALSE(media_channel1_->playout());
EXPECT_FALSE(media_channel1()->playout());
}
EXPECT_TRUE(media_channel1_->codecs().empty());
EXPECT_TRUE(media_channel1_->recv_streams().empty());
EXPECT_TRUE(media_channel1_->rtp_packets().empty());
EXPECT_TRUE(media_channel1()->codecs().empty());
EXPECT_TRUE(media_channel1()->recv_streams().empty());
EXPECT_TRUE(media_channel1()->rtp_packets().empty());
}
// Test that SetLocalContent and SetRemoteContent properly configure
@ -545,11 +572,11 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
typename T::Content content;
CreateContent(0, kPcmuCodec, kH264Codec, &content);
EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, NULL));
EXPECT_EQ(0U, media_channel1_->codecs().size());
EXPECT_EQ(0U, media_channel1()->codecs().size());
EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, NULL));
ASSERT_EQ(1U, media_channel1_->codecs().size());
ASSERT_EQ(1U, media_channel1()->codecs().size());
EXPECT_TRUE(
CodecMatches(content.codecs()[0], media_channel1_->codecs()[0]));
CodecMatches(content.codecs()[0], media_channel1()->codecs()[0]));
}
// Test that SetLocalContent and SetRemoteContent properly configure
@ -566,7 +593,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, NULL));
content.set_extmap_allow_mixed_enum(answer_enum);
EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, NULL));
EXPECT_EQ(answer, media_channel1_->ExtmapAllowMixed());
EXPECT_EQ(answer, media_channel1()->ExtmapAllowMixed());
}
void TestSetContentsExtmapAllowMixedCallee(bool offer, bool answer) {
// For a callee, SetRemoteContent() is called first with an offer and next
@ -580,7 +607,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kOffer, NULL));
content.set_extmap_allow_mixed_enum(answer_enum);
EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kAnswer, NULL));
EXPECT_EQ(answer, media_channel1_->ExtmapAllowMixed());
EXPECT_EQ(answer, media_channel1()->ExtmapAllowMixed());
}
// Test that SetLocalContent and SetRemoteContent properly deals
@ -590,11 +617,11 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
typename T::Content content;
EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, NULL));
CreateContent(0, kPcmuCodec, kH264Codec, &content);
EXPECT_EQ(0U, media_channel1_->codecs().size());
EXPECT_EQ(0U, media_channel1()->codecs().size());
EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, NULL));
ASSERT_EQ(1U, media_channel1_->codecs().size());
ASSERT_EQ(1U, media_channel1()->codecs().size());
EXPECT_TRUE(
CodecMatches(content.codecs()[0], media_channel1_->codecs()[0]));
CodecMatches(content.codecs()[0], media_channel1()->codecs()[0]));
}
// Test that SetLocalContent and SetRemoteContent properly set RTCP
@ -636,20 +663,20 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
content1.AddStream(stream1);
EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, NULL));
channel1_->Enable(true);
EXPECT_EQ(1u, media_channel1_->send_streams().size());
EXPECT_EQ(1u, media_channel1()->send_streams().size());
EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, NULL));
EXPECT_EQ(1u, media_channel2_->recv_streams().size());
EXPECT_EQ(1u, media_channel2()->recv_streams().size());
ConnectFakeTransports();
// Channel 2 do not send anything.
typename T::Content content2;
CreateContent(0, kPcmuCodec, kH264Codec, &content2);
EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, NULL));
EXPECT_EQ(0u, media_channel1_->recv_streams().size());
EXPECT_EQ(0u, media_channel1()->recv_streams().size());
EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, NULL));
channel2_->Enable(true);
EXPECT_EQ(0u, media_channel2_->send_streams().size());
EXPECT_EQ(0u, media_channel2()->send_streams().size());
SendCustomRtp1(kSsrc1, 0);
WaitForThreads();
@ -660,21 +687,21 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
CreateContent(0, kPcmuCodec, kH264Codec, &content3);
content3.AddStream(stream2);
EXPECT_TRUE(channel2_->SetLocalContent(&content3, SdpType::kOffer, NULL));
ASSERT_EQ(1u, media_channel2_->send_streams().size());
EXPECT_EQ(stream2, media_channel2_->send_streams()[0]);
ASSERT_EQ(1u, media_channel2()->send_streams().size());
EXPECT_EQ(stream2, media_channel2()->send_streams()[0]);
EXPECT_TRUE(channel1_->SetRemoteContent(&content3, SdpType::kOffer, NULL));
ASSERT_EQ(1u, media_channel1_->recv_streams().size());
EXPECT_EQ(stream2, media_channel1_->recv_streams()[0]);
ASSERT_EQ(1u, media_channel1()->recv_streams().size());
EXPECT_EQ(stream2, media_channel1()->recv_streams()[0]);
// Channel 1 replies but stop sending stream1.
typename T::Content content4;
CreateContent(0, kPcmuCodec, kH264Codec, &content4);
EXPECT_TRUE(channel1_->SetLocalContent(&content4, SdpType::kAnswer, NULL));
EXPECT_EQ(0u, media_channel1_->send_streams().size());
EXPECT_EQ(0u, media_channel1()->send_streams().size());
EXPECT_TRUE(channel2_->SetRemoteContent(&content4, SdpType::kAnswer, NULL));
EXPECT_EQ(0u, media_channel2_->recv_streams().size());
EXPECT_EQ(0u, media_channel2()->recv_streams().size());
SendCustomRtp2(kSsrc2, 0);
WaitForThreads();
@ -685,58 +712,58 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
void TestPlayoutAndSendingStates() {
CreateChannels(0, 0);
if (verify_playout_) {
EXPECT_FALSE(media_channel1_->playout());
EXPECT_FALSE(media_channel1()->playout());
}
EXPECT_FALSE(media_channel1_->sending());
EXPECT_FALSE(media_channel1()->sending());
if (verify_playout_) {
EXPECT_FALSE(media_channel2_->playout());
EXPECT_FALSE(media_channel2()->playout());
}
EXPECT_FALSE(media_channel2_->sending());
EXPECT_FALSE(media_channel2()->sending());
channel1_->Enable(true);
FlushCurrentThread();
if (verify_playout_) {
EXPECT_FALSE(media_channel1_->playout());
EXPECT_FALSE(media_channel1()->playout());
}
EXPECT_FALSE(media_channel1_->sending());
EXPECT_FALSE(media_channel1()->sending());
EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_,
SdpType::kOffer, NULL));
if (verify_playout_) {
EXPECT_TRUE(media_channel1_->playout());
EXPECT_TRUE(media_channel1()->playout());
}
EXPECT_FALSE(media_channel1_->sending());
EXPECT_FALSE(media_channel1()->sending());
EXPECT_TRUE(channel2_->SetRemoteContent(&local_media_content1_,
SdpType::kOffer, NULL));
if (verify_playout_) {
EXPECT_FALSE(media_channel2_->playout());
EXPECT_FALSE(media_channel2()->playout());
}
EXPECT_FALSE(media_channel2_->sending());
EXPECT_FALSE(media_channel2()->sending());
EXPECT_TRUE(channel2_->SetLocalContent(&local_media_content2_,
SdpType::kAnswer, NULL));
if (verify_playout_) {
EXPECT_FALSE(media_channel2_->playout());
EXPECT_FALSE(media_channel2()->playout());
}
EXPECT_FALSE(media_channel2_->sending());
EXPECT_FALSE(media_channel2()->sending());
ConnectFakeTransports();
if (verify_playout_) {
EXPECT_TRUE(media_channel1_->playout());
EXPECT_TRUE(media_channel1()->playout());
}
EXPECT_FALSE(media_channel1_->sending());
EXPECT_FALSE(media_channel1()->sending());
if (verify_playout_) {
EXPECT_FALSE(media_channel2_->playout());
EXPECT_FALSE(media_channel2()->playout());
}
EXPECT_FALSE(media_channel2_->sending());
EXPECT_FALSE(media_channel2()->sending());
channel2_->Enable(true);
FlushCurrentThread();
if (verify_playout_) {
EXPECT_TRUE(media_channel2_->playout());
EXPECT_TRUE(media_channel2()->playout());
}
EXPECT_TRUE(media_channel2_->sending());
EXPECT_TRUE(media_channel2()->sending());
EXPECT_TRUE(channel1_->SetRemoteContent(&local_media_content2_,
SdpType::kAnswer, NULL));
if (verify_playout_) {
EXPECT_TRUE(media_channel1_->playout());
EXPECT_TRUE(media_channel1()->playout());
}
EXPECT_TRUE(media_channel1_->sending());
EXPECT_TRUE(media_channel1()->sending());
}
// Test that changing the MediaContentDirection in the local and remote
@ -754,13 +781,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
channel2_->Enable(true);
FlushCurrentThread();
if (verify_playout_) {
EXPECT_FALSE(media_channel1_->playout());
EXPECT_FALSE(media_channel1()->playout());
}
EXPECT_FALSE(media_channel1_->sending());
EXPECT_FALSE(media_channel1()->sending());
if (verify_playout_) {
EXPECT_FALSE(media_channel2_->playout());
EXPECT_FALSE(media_channel2()->playout());
}
EXPECT_FALSE(media_channel2_->sending());
EXPECT_FALSE(media_channel2()->sending());
EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, NULL));
EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, NULL));
@ -771,13 +798,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
ConnectFakeTransports();
if (verify_playout_) {
EXPECT_TRUE(media_channel1_->playout());
EXPECT_TRUE(media_channel1()->playout());
}
EXPECT_FALSE(media_channel1_->sending()); // remote InActive
EXPECT_FALSE(media_channel1()->sending()); // remote InActive
if (verify_playout_) {
EXPECT_FALSE(media_channel2_->playout()); // local InActive
EXPECT_FALSE(media_channel2()->playout()); // local InActive
}
EXPECT_FALSE(media_channel2_->sending()); // local InActive
EXPECT_FALSE(media_channel2()->sending()); // local InActive
// Update |content2| to be RecvOnly.
content2.set_direction(RtpTransceiverDirection::kRecvOnly);
@ -787,13 +814,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
channel1_->SetRemoteContent(&content2, SdpType::kPrAnswer, NULL));
if (verify_playout_) {
EXPECT_TRUE(media_channel1_->playout());
EXPECT_TRUE(media_channel1()->playout());
}
EXPECT_TRUE(media_channel1_->sending());
EXPECT_TRUE(media_channel1()->sending());
if (verify_playout_) {
EXPECT_TRUE(media_channel2_->playout()); // local RecvOnly
EXPECT_TRUE(media_channel2()->playout()); // local RecvOnly
}
EXPECT_FALSE(media_channel2_->sending()); // local RecvOnly
EXPECT_FALSE(media_channel2()->sending()); // local RecvOnly
// Update |content2| to be SendRecv.
content2.set_direction(RtpTransceiverDirection::kSendRecv);
@ -801,13 +828,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, NULL));
if (verify_playout_) {
EXPECT_TRUE(media_channel1_->playout());
EXPECT_TRUE(media_channel1()->playout());
}
EXPECT_TRUE(media_channel1_->sending());
EXPECT_TRUE(media_channel1()->sending());
if (verify_playout_) {
EXPECT_TRUE(media_channel2_->playout());
EXPECT_TRUE(media_channel2()->playout());
}
EXPECT_TRUE(media_channel2_->sending());
EXPECT_TRUE(media_channel2()->sending());
}
// Tests that when the transport channel signals a candidate pair change
@ -876,18 +903,18 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
EXPECT_FALSE(IsSrtpActive(channel1_));
EXPECT_TRUE(SendInitiate());
if (verify_playout_) {
EXPECT_TRUE(media_channel1_->playout());
EXPECT_TRUE(media_channel1()->playout());
}
EXPECT_FALSE(media_channel1_->sending());
EXPECT_FALSE(media_channel1()->sending());
EXPECT_TRUE(SendAccept());
EXPECT_FALSE(IsSrtpActive(channel1_));
EXPECT_TRUE(media_channel1_->sending());
EXPECT_EQ(1U, media_channel1_->codecs().size());
EXPECT_TRUE(media_channel1()->sending());
EXPECT_EQ(1U, media_channel1()->codecs().size());
if (verify_playout_) {
EXPECT_TRUE(media_channel2_->playout());
EXPECT_TRUE(media_channel2()->playout());
}
EXPECT_TRUE(media_channel2_->sending());
EXPECT_EQ(1U, media_channel2_->codecs().size());
EXPECT_TRUE(media_channel2()->sending());
EXPECT_EQ(1U, media_channel2()->codecs().size());
}
// Test that we don't crash if packets are sent during call teardown
@ -897,16 +924,17 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
void TestCallTeardownRtcpMux() {
class LastWordMediaChannel : public T::MediaChannel {
public:
LastWordMediaChannel() : T::MediaChannel(NULL, typename T::Options()) {}
explicit LastWordMediaChannel(rtc::Thread* network_thread)
: T::MediaChannel(NULL, typename T::Options(), network_thread) {}
~LastWordMediaChannel() {
T::MediaChannel::SendRtp(kPcmuFrame, sizeof(kPcmuFrame),
rtc::PacketOptions());
T::MediaChannel::SendRtcp(kRtcpReport, sizeof(kRtcpReport));
}
};
CreateChannels(std::make_unique<LastWordMediaChannel>(),
std::make_unique<LastWordMediaChannel>(), RTCP_MUX,
RTCP_MUX);
CreateChannels(std::make_unique<LastWordMediaChannel>(network_thread_),
std::make_unique<LastWordMediaChannel>(network_thread_),
RTCP_MUX, RTCP_MUX);
EXPECT_TRUE(SendInitiate());
EXPECT_TRUE(SendAccept());
EXPECT_TRUE(Terminate());
@ -1035,7 +1063,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
fake_rtp_dtls_transport1_->SetWritable(true);
});
EXPECT_TRUE(media_channel1_->sending());
EXPECT_TRUE(media_channel1()->sending());
SendRtp1();
SendRtp2();
WaitForThreads();
@ -1049,7 +1077,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
bool asymmetric = true;
fake_rtp_dtls_transport1_->SetDestination(nullptr, asymmetric);
});
EXPECT_TRUE(media_channel1_->sending());
EXPECT_TRUE(media_channel1()->sending());
// Should fail also.
SendRtp1();
@ -1065,7 +1093,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
fake_rtp_dtls_transport1_->SetDestination(fake_rtp_dtls_transport2_.get(),
asymmetric);
});
EXPECT_TRUE(media_channel1_->sending());
EXPECT_TRUE(media_channel1()->sending());
SendRtp1();
SendRtp2();
WaitForThreads();
@ -1118,17 +1146,17 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
std::unique_ptr<typename T::Content> content(
CreateMediaContentWithStream(1));
media_channel1_->set_fail_set_recv_codecs(true);
media_channel1()->set_fail_set_recv_codecs(true);
EXPECT_FALSE(
channel1_->SetLocalContent(content.get(), SdpType::kOffer, &err));
EXPECT_FALSE(
channel1_->SetLocalContent(content.get(), SdpType::kAnswer, &err));
media_channel1_->set_fail_set_send_codecs(true);
media_channel1()->set_fail_set_send_codecs(true);
EXPECT_FALSE(
channel1_->SetRemoteContent(content.get(), SdpType::kOffer, &err));
media_channel1_->set_fail_set_send_codecs(true);
media_channel1()->set_fail_set_send_codecs(true);
EXPECT_FALSE(
channel1_->SetRemoteContent(content.get(), SdpType::kAnswer, &err));
}
@ -1141,14 +1169,14 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
CreateMediaContentWithStream(1));
EXPECT_TRUE(
channel1_->SetLocalContent(content1.get(), SdpType::kOffer, &err));
EXPECT_TRUE(media_channel1_->HasSendStream(1));
EXPECT_TRUE(media_channel1()->HasSendStream(1));
std::unique_ptr<typename T::Content> content2(
CreateMediaContentWithStream(2));
EXPECT_TRUE(
channel1_->SetLocalContent(content2.get(), SdpType::kOffer, &err));
EXPECT_FALSE(media_channel1_->HasSendStream(1));
EXPECT_TRUE(media_channel1_->HasSendStream(2));
EXPECT_FALSE(media_channel1()->HasSendStream(1));
EXPECT_TRUE(media_channel1()->HasSendStream(2));
}
void TestReceiveTwoOffers() {
@ -1159,14 +1187,14 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
CreateMediaContentWithStream(1));
EXPECT_TRUE(
channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, &err));
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
EXPECT_TRUE(media_channel1()->HasRecvStream(1));
std::unique_ptr<typename T::Content> content2(
CreateMediaContentWithStream(2));
EXPECT_TRUE(
channel1_->SetRemoteContent(content2.get(), SdpType::kOffer, &err));
EXPECT_FALSE(media_channel1_->HasRecvStream(1));
EXPECT_TRUE(media_channel1_->HasRecvStream(2));
EXPECT_FALSE(media_channel1()->HasRecvStream(1));
EXPECT_TRUE(media_channel1()->HasRecvStream(2));
}
void TestSendPrAnswer() {
@ -1178,24 +1206,24 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
CreateMediaContentWithStream(1));
EXPECT_TRUE(
channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, &err));
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
EXPECT_TRUE(media_channel1()->HasRecvStream(1));
// Send PR answer
std::unique_ptr<typename T::Content> content2(
CreateMediaContentWithStream(2));
EXPECT_TRUE(
channel1_->SetLocalContent(content2.get(), SdpType::kPrAnswer, &err));
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
EXPECT_TRUE(media_channel1_->HasSendStream(2));
EXPECT_TRUE(media_channel1()->HasRecvStream(1));
EXPECT_TRUE(media_channel1()->HasSendStream(2));
// Send answer
std::unique_ptr<typename T::Content> content3(
CreateMediaContentWithStream(3));
EXPECT_TRUE(
channel1_->SetLocalContent(content3.get(), SdpType::kAnswer, &err));
EXPECT_TRUE(media_channel1_->HasRecvStream(1));
EXPECT_FALSE(media_channel1_->HasSendStream(2));
EXPECT_TRUE(media_channel1_->HasSendStream(3));
EXPECT_TRUE(media_channel1()->HasRecvStream(1));
EXPECT_FALSE(media_channel1()->HasSendStream(2));
EXPECT_TRUE(media_channel1()->HasSendStream(3));
}
void TestReceivePrAnswer() {
@ -1207,39 +1235,39 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
CreateMediaContentWithStream(1));
EXPECT_TRUE(
channel1_->SetLocalContent(content1.get(), SdpType::kOffer, &err));
EXPECT_TRUE(media_channel1_->HasSendStream(1));
EXPECT_TRUE(media_channel1()->HasSendStream(1));
// Receive PR answer
std::unique_ptr<typename T::Content> content2(
CreateMediaContentWithStream(2));
EXPECT_TRUE(
channel1_->SetRemoteContent(content2.get(), SdpType::kPrAnswer, &err));
EXPECT_TRUE(media_channel1_->HasSendStream(1));
EXPECT_TRUE(media_channel1_->HasRecvStream(2));
EXPECT_TRUE(media_channel1()->HasSendStream(1));
EXPECT_TRUE(media_channel1()->HasRecvStream(2));
// Receive answer
std::unique_ptr<typename T::Content> content3(
CreateMediaContentWithStream(3));
EXPECT_TRUE(
channel1_->SetRemoteContent(content3.get(), SdpType::kAnswer, &err));
EXPECT_TRUE(media_channel1_->HasSendStream(1));
EXPECT_FALSE(media_channel1_->HasRecvStream(2));
EXPECT_TRUE(media_channel1_->HasRecvStream(3));
EXPECT_TRUE(media_channel1()->HasSendStream(1));
EXPECT_FALSE(media_channel1()->HasRecvStream(2));
EXPECT_TRUE(media_channel1()->HasRecvStream(3));
}
void TestOnTransportReadyToSend() {
CreateChannels(0, 0);
EXPECT_FALSE(media_channel1_->ready_to_send());
EXPECT_FALSE(media_channel1()->ready_to_send());
network_thread_->PostTask(
RTC_FROM_HERE, [this] { channel1_->OnTransportReadyToSend(true); });
WaitForThreads();
EXPECT_TRUE(media_channel1_->ready_to_send());
EXPECT_TRUE(media_channel1()->ready_to_send());
network_thread_->PostTask(
RTC_FROM_HERE, [this] { channel1_->OnTransportReadyToSend(false); });
WaitForThreads();
EXPECT_FALSE(media_channel1_->ready_to_send());
EXPECT_FALSE(media_channel1()->ready_to_send());
}
bool SetRemoteContentWithBitrateLimit(int remote_limit) {
@ -1267,8 +1295,8 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
CreateChannels(0, 0);
EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_,
SdpType::kOffer, NULL));
EXPECT_EQ(media_channel1_->max_bps(), -1);
VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1),
EXPECT_EQ(media_channel1()->max_bps(), -1);
VerifyMaxBitrate(media_channel1()->GetRtpSendParameters(kSsrc1),
absl::nullopt);
}
@ -1285,17 +1313,16 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
CreateChannels(DTLS, DTLS);
channel1_->SetOption(cricket::BaseChannel::ST_RTP,
rtc::Socket::Option::OPT_SNDBUF, kSndBufSize);
channel2_->SetOption(cricket::BaseChannel::ST_RTP,
rtc::Socket::Option::OPT_RCVBUF, kRcvBufSize);
new_rtp_transport_ = CreateDtlsSrtpTransport(
fake_rtp_dtls_transport2_.get(), fake_rtcp_dtls_transport2_.get());
bool rcv_success, send_success;
int rcv_buf, send_buf;
network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
channel1_->SetOption(cricket::BaseChannel::ST_RTP,
rtc::Socket::Option::OPT_SNDBUF, kSndBufSize);
channel2_->SetOption(cricket::BaseChannel::ST_RTP,
rtc::Socket::Option::OPT_RCVBUF, kRcvBufSize);
channel1_->SetRtpTransport(new_rtp_transport_.get());
send_success = fake_rtp_dtls_transport2_->GetOption(
rtc::Socket::Option::OPT_SNDBUF, &send_buf);
@ -1388,9 +1415,24 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
// Worker thread = current Thread process received messages.
ProcessThreadQueue(rtc::Thread::Current());
}
typename T::MediaChannel* media_channel1() {
RTC_DCHECK(channel1_);
RTC_DCHECK(channel1_->media_channel());
return static_cast<typename T::MediaChannel*>(channel1_->media_channel());
}
typename T::MediaChannel* media_channel2() {
RTC_DCHECK(channel2_);
RTC_DCHECK(channel2_->media_channel());
return static_cast<typename T::MediaChannel*>(channel2_->media_channel());
}
// TODO(pbos): Remove playout from all media channels and let renderers mute
// themselves.
const bool verify_playout_;
rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> network_thread_safety_ =
webrtc::PendingTaskSafetyFlag::CreateDetached();
std::unique_ptr<rtc::Thread> network_thread_keeper_;
rtc::Thread* network_thread_;
std::unique_ptr<cricket::FakeDtlsTransport> fake_rtp_dtls_transport1_;
@ -1405,9 +1447,6 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
std::unique_ptr<webrtc::RtpTransportInternal> rtp_transport2_;
std::unique_ptr<webrtc::RtpTransportInternal> new_rtp_transport_;
cricket::FakeMediaEngine media_engine_;
// The media channels are owned by the voice channel objects below.
typename T::MediaChannel* media_channel1_ = nullptr;
typename T::MediaChannel* media_channel2_ = nullptr;
std::unique_ptr<typename T::Channel> channel1_;
std::unique_ptr<typename T::Channel> channel2_;
typename T::Content local_media_content1_;
@ -1567,8 +1606,8 @@ class VideoChannelDoubleThreadTest : public ChannelTest<VideoTraits> {
TEST_F(VoiceChannelSingleThreadTest, TestInit) {
Base::TestInit();
EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
EXPECT_TRUE(media_channel1_->dtmf_info_queue().empty());
EXPECT_FALSE(media_channel1()->IsStreamMuted(0));
EXPECT_TRUE(media_channel1()->dtmf_info_queue().empty());
}
TEST_F(VoiceChannelSingleThreadTest, TestDeinit) {
@ -1708,8 +1747,8 @@ TEST_F(VoiceChannelSingleThreadTest, SocketOptionsMergedOnSetTransport) {
// VoiceChannelDoubleThreadTest
TEST_F(VoiceChannelDoubleThreadTest, TestInit) {
Base::TestInit();
EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
EXPECT_TRUE(media_channel1_->dtmf_info_queue().empty());
EXPECT_FALSE(media_channel1()->IsStreamMuted(0));
EXPECT_TRUE(media_channel1()->dtmf_info_queue().empty());
}
TEST_F(VoiceChannelDoubleThreadTest, TestDeinit) {
@ -1999,12 +2038,12 @@ TEST_F(VideoChannelSingleThreadTest, TestSetLocalOfferWithPacketization) {
CreateChannels(0, 0);
EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, NULL));
EXPECT_THAT(media_channel1_->send_codecs(), testing::IsEmpty());
ASSERT_THAT(media_channel1_->recv_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1_->recv_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1_->recv_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1_->recv_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1_->recv_codecs()[1].packetization,
EXPECT_THAT(media_channel1()->send_codecs(), testing::IsEmpty());
ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1()->recv_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1()->recv_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization,
cricket::kPacketizationParamRaw);
}
@ -2018,12 +2057,12 @@ TEST_F(VideoChannelSingleThreadTest, TestSetRemoteOfferWithPacketization) {
CreateChannels(0, 0);
EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kOffer, NULL));
EXPECT_THAT(media_channel1_->recv_codecs(), testing::IsEmpty());
ASSERT_THAT(media_channel1_->send_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1_->send_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1_->send_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1_->send_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1_->send_codecs()[1].packetization,
EXPECT_THAT(media_channel1()->recv_codecs(), testing::IsEmpty());
ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1()->send_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1()->send_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1()->send_codecs()[1].packetization,
cricket::kPacketizationParamRaw);
}
@ -2038,17 +2077,17 @@ TEST_F(VideoChannelSingleThreadTest, TestSetAnswerWithPacketization) {
EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, NULL));
EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kAnswer, NULL));
ASSERT_THAT(media_channel1_->recv_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1_->recv_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1_->recv_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1_->recv_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1_->recv_codecs()[1].packetization,
ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1()->recv_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1()->recv_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization,
cricket::kPacketizationParamRaw);
EXPECT_THAT(media_channel1_->send_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1_->send_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1_->send_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1_->send_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1_->send_codecs()[1].packetization,
EXPECT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2));
EXPECT_TRUE(media_channel1()->send_codecs()[0].Matches(kVp8Codec));
EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
EXPECT_TRUE(media_channel1()->send_codecs()[1].Matches(vp9_codec));
EXPECT_EQ(media_channel1()->send_codecs()[1].packetization,
cricket::kPacketizationParamRaw);
}
@ -2066,10 +2105,10 @@ TEST_F(VideoChannelSingleThreadTest, TestSetLocalAnswerWithoutPacketization) {
EXPECT_TRUE(
channel1_->SetRemoteContent(&remote_video, SdpType::kOffer, NULL));
EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, NULL));
ASSERT_THAT(media_channel1_->recv_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1_->recv_codecs()[0].packetization, absl::nullopt);
ASSERT_THAT(media_channel1_->send_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1_->send_codecs()[0].packetization, absl::nullopt);
ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
}
TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) {
@ -2086,10 +2125,10 @@ TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) {
EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kOffer, NULL));
EXPECT_TRUE(
channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, NULL));
ASSERT_THAT(media_channel1_->recv_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1_->recv_codecs()[0].packetization, absl::nullopt);
ASSERT_THAT(media_channel1_->send_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1_->send_codecs()[0].packetization, absl::nullopt);
ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt);
ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
}
TEST_F(VideoChannelSingleThreadTest,
@ -2108,10 +2147,10 @@ TEST_F(VideoChannelSingleThreadTest,
EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kOffer, NULL));
EXPECT_FALSE(
channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, NULL));
ASSERT_THAT(media_channel1_->recv_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1_->recv_codecs()[0].packetization,
ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization,
cricket::kPacketizationParamRaw);
EXPECT_THAT(media_channel1_->send_codecs(), testing::IsEmpty());
EXPECT_THAT(media_channel1()->send_codecs(), testing::IsEmpty());
}
TEST_F(VideoChannelSingleThreadTest,
@ -2130,9 +2169,9 @@ TEST_F(VideoChannelSingleThreadTest,
channel1_->SetRemoteContent(&remote_video, SdpType::kOffer, NULL));
EXPECT_FALSE(
channel1_->SetLocalContent(&local_video, SdpType::kAnswer, NULL));
EXPECT_THAT(media_channel1_->recv_codecs(), testing::IsEmpty());
ASSERT_THAT(media_channel1_->send_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1_->send_codecs()[0].packetization, absl::nullopt);
EXPECT_THAT(media_channel1()->recv_codecs(), testing::IsEmpty());
ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1));
EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt);
}
// VideoChannelDoubleThreadTest

View File

@ -28,8 +28,10 @@ namespace webrtc {
// Fake VoiceMediaChannel where the result of GetStats can be configured.
class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel {
public:
FakeVoiceMediaChannelForStats()
: cricket::FakeVoiceMediaChannel(nullptr, cricket::AudioOptions()) {}
explicit FakeVoiceMediaChannelForStats(TaskQueueBase* network_thread)
: cricket::FakeVoiceMediaChannel(nullptr,
cricket::AudioOptions(),
network_thread) {}
void SetStats(const cricket::VoiceMediaInfo& voice_info) {
stats_ = voice_info;
@ -52,8 +54,10 @@ class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel {
// Fake VideoMediaChannel where the result of GetStats can be configured.
class FakeVideoMediaChannelForStats : public cricket::FakeVideoMediaChannel {
public:
FakeVideoMediaChannelForStats()
: cricket::FakeVideoMediaChannel(nullptr, cricket::VideoOptions()) {}
explicit FakeVideoMediaChannelForStats(TaskQueueBase* network_thread)
: cricket::FakeVideoMediaChannel(nullptr,
cricket::VideoOptions(),
network_thread) {}
void SetStats(const cricket::VideoMediaInfo& video_info) {
stats_ = video_info;
@ -196,7 +200,7 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
const std::string& transport_name) {
RTC_DCHECK(!voice_channel_);
auto voice_media_channel =
std::make_unique<FakeVoiceMediaChannelForStats>();
std::make_unique<FakeVoiceMediaChannelForStats>(network_thread_);
auto* voice_media_channel_ptr = voice_media_channel.get();
voice_channel_ = std::make_unique<VoiceChannelForTesting>(
worker_thread_, network_thread_, signaling_thread_,
@ -213,7 +217,7 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
const std::string& transport_name) {
RTC_DCHECK(!video_channel_);
auto video_media_channel =
std::make_unique<FakeVideoMediaChannelForStats>();
std::make_unique<FakeVideoMediaChannelForStats>(network_thread_);
auto video_media_channel_ptr = video_media_channel.get();
video_channel_ = std::make_unique<VideoChannelForTesting>(
worker_thread_, network_thread_, signaling_thread_,

View File

@ -29,9 +29,11 @@ class VideoRtpReceiverTest : public testing::Test {
protected:
class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
public:
MockVideoMediaChannel(cricket::FakeVideoEngine* engine,
const cricket::VideoOptions& options)
: FakeVideoMediaChannel(engine, options) {}
MockVideoMediaChannel(
cricket::FakeVideoEngine* engine,
const cricket::VideoOptions& options,
TaskQueueBase* network_thread = rtc::Thread::Current())
: FakeVideoMediaChannel(engine, options, network_thread) {}
MOCK_METHOD(void,
SetRecordableEncodedFrameCallback,
(uint32_t, std::function<void(const RecordableEncodedFrame&)>),