Merge SendTask implementation for SingleThreadedTaskQueueForTesting and TaskQueueForTest

That allows to use SingleThreadedTaskQueueForTesting via TaskQueueBase interface
but still have access to test-only SendTask function.

Bug: webrtc:10933
Change-Id: I3cc397e55ea2f1ed9e5d885d6a2ccda412beb826
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156002
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29480}
This commit is contained in:
Danil Chapovalov 2019-10-15 10:04:57 +02:00 committed by Commit Bot
parent 35214fcfe2
commit eb90e6ffe3
18 changed files with 773 additions and 668 deletions

View file

@ -552,7 +552,8 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
update.packet_loss_ratio = 0; update.packet_loss_ratio = 0;
update.round_trip_time = TimeDelta::ms(50); update.round_trip_time = TimeDelta::ms(50);
update.bwe_period = TimeDelta::ms(6000); update.bwe_period = TimeDelta::ms(6000);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) { TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
@ -565,7 +566,8 @@ TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
Eq(DataRate::bps(helper.config().max_bitrate_bps - 5000))))); Eq(DataRate::bps(helper.config().max_bitrate_bps - 5000)))));
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::bps(helper.config().max_bitrate_bps - 5000); update.target_bitrate = DataRate::bps(helper.config().max_bitrate_bps - 5000);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) { TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
@ -580,7 +582,8 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
Eq(DataRate::kbps(6))))); Eq(DataRate::kbps(6)))));
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(1); update.target_bitrate = DataRate::kbps(1);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) { TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
@ -595,7 +598,8 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
Eq(DataRate::kbps(64))))); Eq(DataRate::kbps(64)))));
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(128); update.target_bitrate = DataRate::kbps(128);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
TEST(AudioSendStreamTest, SSBweWithOverhead) { TEST(AudioSendStreamTest, SSBweWithOverhead) {
@ -614,7 +618,8 @@ TEST(AudioSendStreamTest, SSBweWithOverhead) {
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = bitrate; update.target_bitrate = bitrate;
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) { TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
@ -633,7 +638,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(1); update.target_bitrate = DataRate::kbps(1);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) { TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
@ -652,7 +658,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(128); update.target_bitrate = DataRate::kbps(128);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) { TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
@ -667,7 +674,8 @@ TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
update.packet_loss_ratio = 0; update.packet_loss_ratio = 0;
update.round_trip_time = TimeDelta::ms(50); update.round_trip_time = TimeDelta::ms(50);
update.bwe_period = TimeDelta::ms(5000); update.bwe_period = TimeDelta::ms(5000);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
} }
// Test that AudioSendStream doesn't recreate the encoder unnecessarily. // Test that AudioSendStream doesn't recreate the encoder unnecessarily.

View file

@ -374,7 +374,8 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
TEST(AudioMixer, ConstructFromOtherThread) { TEST(AudioMixer, ConstructFromOtherThread) {
TaskQueueForTest init_queue("init"); TaskQueueForTest init_queue("init");
rtc::scoped_refptr<AudioMixer> mixer; rtc::scoped_refptr<AudioMixer> mixer;
init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); }); init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); },
RTC_FROM_HERE);
MockMixerAudioSource participant; MockMixerAudioSource participant;
EXPECT_CALL(participant, PreferredSampleRate()) EXPECT_CALL(participant, PreferredSampleRate())
@ -384,7 +385,8 @@ TEST(AudioMixer, ConstructFromOtherThread) {
TaskQueueForTest participant_queue("participant"); TaskQueueForTest participant_queue("participant");
participant_queue.SendTask( participant_queue.SendTask(
[&mixer, &participant]() { mixer->AddSource(&participant); }); [&mixer, &participant]() { mixer->AddSource(&participant); },
RTC_FROM_HERE);
EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
.Times(Exactly(1)); .Times(Exactly(1));

View file

@ -447,7 +447,7 @@ void VideoCodecTestFixtureImpl::ProcessAllFrames(
} }
// Wait until we know that the last frame has been sent for encode. // Wait until we know that the last frame has been sent for encode.
task_queue->SendTask([] {}); task_queue->SendTask([] {}, RTC_FROM_HERE);
// Give the VideoProcessor pipeline some time to process the last frame, // Give the VideoProcessor pipeline some time to process the last frame,
// and then release the codecs. // and then release the codecs.
@ -686,22 +686,26 @@ void VideoCodecTestFixtureImpl::SetUpAndInitObjects(
cpu_process_time_.reset(new CpuProcessTime(config_)); cpu_process_time_.reset(new CpuProcessTime(config_));
task_queue->SendTask([this]() { task_queue->SendTask(
[this]() {
CreateEncoderAndDecoder(); CreateEncoderAndDecoder();
processor_ = std::make_unique<VideoProcessor>( processor_ = std::make_unique<VideoProcessor>(
encoder_.get(), &decoders_, source_frame_reader_.get(), config_, encoder_.get(), &decoders_, source_frame_reader_.get(), config_,
&stats_, &encoded_frame_writers_, &stats_, &encoded_frame_writers_,
decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_); decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_);
}); },
RTC_FROM_HERE);
} }
void VideoCodecTestFixtureImpl::ReleaseAndCloseObjects( void VideoCodecTestFixtureImpl::ReleaseAndCloseObjects(
TaskQueueForTest* task_queue) { TaskQueueForTest* task_queue) {
task_queue->SendTask([this]() { task_queue->SendTask(
[this]() {
processor_.reset(); processor_.reset();
// The VideoProcessor must be destroyed before the codecs. // The VideoProcessor must be destroyed before the codecs.
DestroyEncoderAndDecoder(); DestroyEncoderAndDecoder();
}); },
RTC_FROM_HERE);
source_frame_reader_->Close(); source_frame_reader_->Close();
@ -724,10 +728,12 @@ void VideoCodecTestFixtureImpl::PrintSettings(
RTC_LOG(LS_INFO) << "==> Codec names"; RTC_LOG(LS_INFO) << "==> Codec names";
std::string encoder_name; std::string encoder_name;
std::string decoder_name; std::string decoder_name;
task_queue->SendTask([this, &encoder_name, &decoder_name] { task_queue->SendTask(
[this, &encoder_name, &decoder_name] {
encoder_name = encoder_->GetEncoderInfo().implementation_name; encoder_name = encoder_->GetEncoderInfo().implementation_name;
decoder_name = decoders_.at(0)->ImplementationName(); decoder_name = decoders_.at(0)->ImplementationName();
}); },
RTC_FROM_HERE);
RTC_LOG(LS_INFO) << "enc_impl_name: " << encoder_name; RTC_LOG(LS_INFO) << "enc_impl_name: " << encoder_name;
RTC_LOG(LS_INFO) << "dec_impl_name: " << decoder_name; RTC_LOG(LS_INFO) << "dec_impl_name: " << decoder_name;
} }

View file

@ -54,15 +54,17 @@ class VideoProcessorTest : public ::testing::Test {
ExpectInit(); ExpectInit();
EXPECT_CALL(frame_reader_mock_, FrameLength()) EXPECT_CALL(frame_reader_mock_, FrameLength())
.WillRepeatedly(Return(kFrameSize)); .WillRepeatedly(Return(kFrameSize));
q_.SendTask([this] { q_.SendTask(
[this] {
video_processor_ = std::make_unique<VideoProcessor>( video_processor_ = std::make_unique<VideoProcessor>(
&encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_, &encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_,
&encoded_frame_writers_, /*decoded_frame_writers=*/nullptr); &encoded_frame_writers_, /*decoded_frame_writers=*/nullptr);
}); },
RTC_FROM_HERE);
} }
~VideoProcessorTest() { ~VideoProcessorTest() {
q_.SendTask([this] { video_processor_.reset(); }); q_.SendTask([this] { video_processor_.reset(); }, RTC_FROM_HERE);
} }
void ExpectInit() { void ExpectInit() {
@ -104,7 +106,8 @@ TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
static_cast<double>(kFramerateFps)))) static_cast<double>(kFramerateFps))))
.Times(1); .Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); }); q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); },
RTC_FROM_HERE);
EXPECT_CALL(frame_reader_mock_, ReadFrame()) EXPECT_CALL(frame_reader_mock_, ReadFrame())
.WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight))); .WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight)));
@ -112,13 +115,13 @@ TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
encoder_mock_, encoder_mock_,
Encode(Property(&VideoFrame::timestamp, 1 * 90000 / kFramerateFps), _)) Encode(Property(&VideoFrame::timestamp, 1 * 90000 / kFramerateFps), _))
.Times(1); .Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); }); q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
EXPECT_CALL( EXPECT_CALL(
encoder_mock_, encoder_mock_,
Encode(Property(&VideoFrame::timestamp, 2 * 90000 / kFramerateFps), _)) Encode(Property(&VideoFrame::timestamp, 2 * 90000 / kFramerateFps), _))
.Times(1); .Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); }); q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
ExpectRelease(); ExpectRelease();
} }
@ -133,14 +136,15 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
static_cast<double>(kStartFramerateFps)))) static_cast<double>(kStartFramerateFps))))
.Times(1); .Times(1);
q_.SendTask( q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); }); [=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); },
RTC_FROM_HERE);
EXPECT_CALL(frame_reader_mock_, ReadFrame()) EXPECT_CALL(frame_reader_mock_, ReadFrame())
.WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight))); .WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight)));
EXPECT_CALL(encoder_mock_, EXPECT_CALL(encoder_mock_,
Encode(Property(&VideoFrame::timestamp, kStartTimestamp), _)) Encode(Property(&VideoFrame::timestamp, kStartTimestamp), _))
.Times(1); .Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); }); q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
const int kNewFramerateFps = 13; const int kNewFramerateFps = 13;
EXPECT_CALL( EXPECT_CALL(
@ -149,14 +153,15 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
static_cast<double>(kNewFramerateFps)))) static_cast<double>(kNewFramerateFps))))
.Times(1); .Times(1);
q_.SendTask( q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); }); [=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); },
RTC_FROM_HERE);
EXPECT_CALL(encoder_mock_, EXPECT_CALL(encoder_mock_,
Encode(Property(&VideoFrame::timestamp, Encode(Property(&VideoFrame::timestamp,
kStartTimestamp + 90000 / kNewFramerateFps), kStartTimestamp + 90000 / kNewFramerateFps),
_)) _))
.Times(1); .Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); }); q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
ExpectRelease(); ExpectRelease();
} }
@ -175,7 +180,8 @@ TEST_F(VideoProcessorTest, SetRates) {
Field(&VideoEncoder::RateControlParameters::framerate_fps, Field(&VideoEncoder::RateControlParameters::framerate_fps,
static_cast<double>(kFramerateFps))))) static_cast<double>(kFramerateFps)))))
.Times(1); .Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); }); q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); },
RTC_FROM_HERE);
const uint32_t kNewBitrateKbps = 456; const uint32_t kNewBitrateKbps = 456;
const int kNewFramerateFps = 34; const int kNewFramerateFps = 34;
@ -190,7 +196,8 @@ TEST_F(VideoProcessorTest, SetRates) {
static_cast<double>(kNewFramerateFps))))) static_cast<double>(kNewFramerateFps)))))
.Times(1); .Times(1);
q_.SendTask( q_.SendTask(
[=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); }); [=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); },
RTC_FROM_HERE);
ExpectRelease(); ExpectRelease();
} }

View file

@ -71,15 +71,17 @@ class QualityScalerTest : public ::testing::Test,
: scoped_field_trial_(GetParam()), : scoped_field_trial_(GetParam()),
task_queue_("QualityScalerTestQueue"), task_queue_("QualityScalerTestQueue"),
observer_(new MockAdaptationObserver()) { observer_(new MockAdaptationObserver()) {
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
qs_ = std::unique_ptr<QualityScaler>(new QualityScalerUnderTest( qs_ = std::unique_ptr<QualityScaler>(new QualityScalerUnderTest(
&task_queue_, observer_.get(), &task_queue_, observer_.get(),
VideoEncoder::QpThresholds(kLowQp, kHighQp))); VideoEncoder::QpThresholds(kLowQp, kHighQp)));
}); },
RTC_FROM_HERE);
} }
~QualityScalerTest() { ~QualityScalerTest() {
task_queue_.SendTask([this] { qs_ = nullptr; }); task_queue_.SendTask([this] { qs_ = nullptr; }, RTC_FROM_HERE);
} }
void TriggerScale(ScaleDirection scale_direction) { void TriggerScale(ScaleDirection scale_direction) {
@ -118,46 +120,52 @@ INSTANTIATE_TEST_SUITE_P(
"")); ""));
TEST_P(QualityScalerTest, DownscalesAfterContinuousFramedrop) { TEST_P(QualityScalerTest, DownscalesAfterContinuousFramedrop) {
task_queue_.SendTask([this] { TriggerScale(kScaleDown); }); task_queue_.SendTask([this] { TriggerScale(kScaleDown); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, KeepsScaleAtHighQp) { TEST_P(QualityScalerTest, KeepsScaleAtHighQp) {
task_queue_.SendTask([this] { TriggerScale(kKeepScaleAtHighQp); }); task_queue_.SendTask([this] { TriggerScale(kKeepScaleAtHighQp); },
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, DownscalesAboveHighQp) { TEST_P(QualityScalerTest, DownscalesAboveHighQp) {
task_queue_.SendTask([this] { TriggerScale(kScaleDownAboveHighQp); }); task_queue_.SendTask([this] { TriggerScale(kScaleDownAboveHighQp); },
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) { TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) {
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
for (int i = 0; i < kFramerate * 5; ++i) { for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt(); qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportDroppedFrameByMediaOpt(); qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportQp(kHighQp, 0); qs_->ReportQp(kHighQp, 0);
} }
}); },
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) { TEST_P(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) {
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
for (int i = 0; i < kFramerate * 5; ++i) { for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt(); qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportQp(kHighQp, 0); qs_->ReportQp(kHighQp, 0);
} }
}); },
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
@ -165,84 +173,98 @@ TEST_P(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) {
TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsIfFieldTrialEnabled) { TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsIfFieldTrialEnabled) {
const bool kDownScaleExpected = !GetParam().empty(); const bool kDownScaleExpected = !GetParam().empty();
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
for (int i = 0; i < kFramerate * 5; ++i) { for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt(); qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportDroppedFrameByEncoder(); qs_->ReportDroppedFrameByEncoder();
qs_->ReportQp(kHighQp, 0); qs_->ReportQp(kHighQp, 0);
} }
}); },
RTC_FROM_HERE);
EXPECT_EQ(kDownScaleExpected, observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(kDownScaleExpected, observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(kDownScaleExpected ? 1 : 0, observer_->adapt_down_events_); EXPECT_EQ(kDownScaleExpected ? 1 : 0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, KeepsScaleOnNormalQp) { TEST_P(QualityScalerTest, KeepsScaleOnNormalQp) {
task_queue_.SendTask([this] { TriggerScale(kKeepScaleAboveLowQp); }); task_queue_.SendTask([this] { TriggerScale(kKeepScaleAboveLowQp); },
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, UpscalesAfterLowQp) { TEST_P(QualityScalerTest, UpscalesAfterLowQp) {
task_queue_.SendTask([this] { TriggerScale(kScaleUp); }); task_queue_.SendTask([this] { TriggerScale(kScaleUp); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_); EXPECT_EQ(1, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, ScalesDownAndBackUp) { TEST_P(QualityScalerTest, ScalesDownAndBackUp) {
task_queue_.SendTask([this] { TriggerScale(kScaleDown); }); task_queue_.SendTask([this] { TriggerScale(kScaleDown); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
task_queue_.SendTask([this] { TriggerScale(kScaleUp); }); task_queue_.SendTask([this] { TriggerScale(kScaleUp); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_); EXPECT_EQ(1, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, DoesNotScaleUntilEnoughFramesObserved) { TEST_P(QualityScalerTest, DoesNotScaleUntilEnoughFramesObserved) {
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
// Not enough frames to make a decision. // Not enough frames to make a decision.
for (int i = 0; i < kMinFramesNeededToScale - 1; ++i) { for (int i = 0; i < kMinFramesNeededToScale - 1; ++i) {
qs_->ReportQp(kLowQp, 0); qs_->ReportQp(kLowQp, 0);
} }
}); },
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
task_queue_.SendTask([this] { task_queue_.SendTask(
// Send 1 more. Enough frames observed, should result in an adapt request. [this] {
// Send 1 more. Enough frames observed, should result in an adapt
// request.
qs_->ReportQp(kLowQp, 0); qs_->ReportQp(kLowQp, 0);
}); },
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_); EXPECT_EQ(1, observer_->adapt_up_events_);
// Samples should be cleared after an adapt request. // Samples should be cleared after an adapt request.
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
// Not enough frames to make a decision. // Not enough frames to make a decision.
qs_->ReportQp(kLowQp, 0); qs_->ReportQp(kLowQp, 0);
}); },
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_); EXPECT_EQ(1, observer_->adapt_up_events_);
} }
TEST_P(QualityScalerTest, ScalesDownAndBackUpWithMinFramesNeeded) { TEST_P(QualityScalerTest, ScalesDownAndBackUpWithMinFramesNeeded) {
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
for (int i = 0; i < kMinFramesNeededToScale; ++i) { for (int i = 0; i < kMinFramesNeededToScale; ++i) {
qs_->ReportQp(kHighQp + 1, 0); qs_->ReportQp(kHighQp + 1, 0);
} }
}); },
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_); EXPECT_EQ(0, observer_->adapt_up_events_);
// Samples cleared. // Samples cleared.
task_queue_.SendTask([this] { task_queue_.SendTask(
[this] {
for (int i = 0; i < kMinFramesNeededToScale; ++i) { for (int i = 0; i < kMinFramesNeededToScale; ++i) {
qs_->ReportQp(kLowQp, 0); qs_->ReportQp(kLowQp, 0);
} }
}); },
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_); EXPECT_EQ(1, observer_->adapt_up_events_);

View file

@ -1077,8 +1077,10 @@ rtc_source_set("task_queue_for_test") {
deps = [ deps = [
":checks", ":checks",
":macromagic", ":macromagic",
":rtc_base_approved",
":rtc_event", ":rtc_event",
":rtc_task_queue", ":rtc_task_queue",
"../api/task_queue",
"../api/task_queue:default_task_queue_factory", "../api/task_queue:default_task_queue_factory",
"task_utils:to_queued_task", "task_utils:to_queued_task",
"//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/strings",

View file

@ -84,16 +84,20 @@ TEST(SequenceCheckerTest, DetachFromThreadAndUseOnTaskQueue) {
SequenceChecker sequence_checker; SequenceChecker sequence_checker;
sequence_checker.Detach(); sequence_checker.Detach();
TaskQueueForTest queue; TaskQueueForTest queue;
queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); }); queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); },
RTC_FROM_HERE);
} }
TEST(SequenceCheckerTest, DetachFromTaskQueueAndUseOnThread) { TEST(SequenceCheckerTest, DetachFromTaskQueueAndUseOnThread) {
TaskQueueForTest queue; TaskQueueForTest queue;
queue.SendTask([] { queue.SendTask(
[] {
SequenceChecker sequence_checker; SequenceChecker sequence_checker;
sequence_checker.Detach(); sequence_checker.Detach();
RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); }); RunOnDifferentThread(
}); [&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
},
RTC_FROM_HERE);
} }
TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) { TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) {
@ -106,7 +110,8 @@ TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) {
SequenceChecker sequence_checker; SequenceChecker sequence_checker;
TaskQueueForTest queue; TaskQueueForTest queue;
queue.SendTask( queue.SendTask(
[&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); }); [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); },
RTC_FROM_HERE);
} }
TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) { TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) {
@ -114,13 +119,15 @@ TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) {
sequence_checker.Detach(); sequence_checker.Detach();
TaskQueueForTest queue1; TaskQueueForTest queue1;
queue1.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); }); queue1.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); },
RTC_FROM_HERE);
// IsCurrent should return false in debug builds after moving to // IsCurrent should return false in debug builds after moving to
// another task queue. // another task queue.
TaskQueueForTest queue2; TaskQueueForTest queue2;
queue2.SendTask( queue2.SendTask(
[&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); }); [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); },
RTC_FROM_HERE);
} }
class TestAnnotations { class TestAnnotations {
@ -147,7 +154,7 @@ TEST(SequenceCheckerTest, TestAnnotations) {
void TestAnnotationsOnWrongQueue() { void TestAnnotationsOnWrongQueue() {
TestAnnotations annotations; TestAnnotations annotations;
TaskQueueForTest queue; TaskQueueForTest queue;
queue.SendTask([&] { annotations.ModifyTestVar(); }); queue.SendTask([&] { annotations.ModifyTestVar(); }, RTC_FROM_HERE);
} }
#if RTC_DCHECK_IS_ON #if RTC_DCHECK_IS_ON

View file

@ -14,14 +14,27 @@
#include <utility> #include <utility>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/task_queue/task_queue_base.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/location.h"
#include "rtc_base/task_queue.h" #include "rtc_base/task_queue.h"
#include "rtc_base/task_utils/to_queued_task.h" #include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_annotations.h"
namespace webrtc { namespace webrtc {
template <typename Closure>
void SendTask(TaskQueueBase* task_queue, Closure&& task, rtc::Location loc) {
RTC_CHECK(!task_queue->IsCurrent())
<< "Called SendTask to a queue from the same queue at " << loc.ToString();
rtc::Event event;
task_queue->PostTask(
ToQueuedTask(std::forward<Closure>(task), [&event] { event.Set(); }));
RTC_CHECK(event.Wait(/*give_up_after_ms=*/120'000, /*warn_after_ms=*/10'000))
<< "Waited too long at " << loc.ToString();
}
class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue { class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue {
public: public:
using rtc::TaskQueue::TaskQueue; using rtc::TaskQueue::TaskQueue;
@ -38,7 +51,7 @@ class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue {
// task queue (i.e. the Run() method always returns |false|.). // task queue (i.e. the Run() method always returns |false|.).
template <class Closure> template <class Closure>
void SendTask(Closure* task) { void SendTask(Closure* task) {
RTC_DCHECK(!IsCurrent()); RTC_CHECK(!IsCurrent());
rtc::Event event; rtc::Event event;
PostTask(ToQueuedTask( PostTask(ToQueuedTask(
[&task] { RTC_CHECK_EQ(false, static_cast<QueuedTask*>(task)->Run()); }, [&task] { RTC_CHECK_EQ(false, static_cast<QueuedTask*>(task)->Run()); },
@ -49,12 +62,8 @@ class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue {
// A convenience, test-only method that blocks the current thread while // A convenience, test-only method that blocks the current thread while
// a task executes on the task queue. // a task executes on the task queue.
template <class Closure> template <class Closure>
void SendTask(Closure&& task) { void SendTask(Closure&& task, rtc::Location loc) {
RTC_DCHECK(!IsCurrent()); ::webrtc::SendTask(Get(), std::forward<Closure>(task), loc);
rtc::Event event;
PostTask(
ToQueuedTask(std::forward<Closure>(task), [&event] { event.Set(); }));
event.Wait(rtc::Event::kForever);
} }
}; };

View file

@ -204,7 +204,7 @@ template <class T>
std::unique_ptr<T> NewObjectCreatedOnTaskQueue() { std::unique_ptr<T> NewObjectCreatedOnTaskQueue() {
std::unique_ptr<T> obj; std::unique_ptr<T> obj;
webrtc::TaskQueueForTest queue("NewObjectCreatedOnTaskQueue"); webrtc::TaskQueueForTest queue("NewObjectCreatedOnTaskQueue");
queue.SendTask([&] { obj = std::make_unique<T>(); }); queue.SendTask([&] { obj = std::make_unique<T>(); }, RTC_FROM_HERE);
return obj; return obj;
} }
@ -226,11 +226,13 @@ TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) {
// Create weak ptr on main thread // Create weak ptr on main thread
WeakPtr<Target> weak_ptr = target->factory.GetWeakPtr(); WeakPtr<Target> weak_ptr = target->factory.GetWeakPtr();
webrtc::TaskQueueForTest queue("queue"); webrtc::TaskQueueForTest queue("queue");
queue.SendTask([&] { queue.SendTask(
[&] {
// Dereference and invalide weak_ptr on another thread. // Dereference and invalide weak_ptr on another thread.
EXPECT_EQ(weak_ptr.get(), target.get()); EXPECT_EQ(weak_ptr.get(), target.get());
target.reset(); target.reset();
}); },
RTC_FROM_HERE);
} }
} // namespace rtc } // namespace rtc

View file

@ -631,6 +631,7 @@ rtc_source_set("single_threaded_task_queue") {
"../rtc_base:checks", "../rtc_base:checks",
"../rtc_base:deprecation", "../rtc_base:deprecation",
"../rtc_base:rtc_base_approved", "../rtc_base:rtc_base_approved",
"../rtc_base:task_queue_for_test",
"../rtc_base/task_utils:to_queued_task", "../rtc_base/task_utils:to_queued_task",
] ]
} }

View file

@ -138,7 +138,8 @@ EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) { void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) {
RTC_CHECK(route->active) << "Route already cleared"; RTC_CHECK(route->active) << "Route already cleared";
task_queue_.SendTask([route]() { task_queue_.SendTask(
[route]() {
// Remove receiver from intermediate nodes. // Remove receiver from intermediate nodes.
for (auto* node : route->via_nodes) { for (auto* node : route->via_nodes) {
node->router()->RemoveReceiver(route->to->GetPeerLocalAddress()); node->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
@ -147,7 +148,8 @@ void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) {
route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress()); route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
route->active = false; route->active = false;
}); },
RTC_FROM_HERE);
} }
TrafficRoute* NetworkEmulationManagerImpl::CreateTrafficRoute( TrafficRoute* NetworkEmulationManagerImpl::CreateTrafficRoute(

View file

@ -379,12 +379,14 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
RTC_LOG(INFO) << "Test is done, initiating disconnect sequence."; RTC_LOG(INFO) << "Test is done, initiating disconnect sequence.";
task_queue_->SendTask([&stats_poller, this]() { task_queue_->SendTask(
[&stats_poller, this]() {
RTC_DCHECK_RUN_ON(task_queue_.get()); RTC_DCHECK_RUN_ON(task_queue_.get());
stats_polling_task_.Stop(); stats_polling_task_.Stop();
// Get final end-of-call stats. // Get final end-of-call stats.
stats_poller.PollStatsAndNotifyObservers(); stats_poller.PollStatsAndNotifyObservers();
}); },
RTC_FROM_HERE);
// We need to detach AEC dumping from peers, because dump uses |task_queue_| // We need to detach AEC dumping from peers, because dump uses |task_queue_|
// inside. // inside.
@ -393,12 +395,14 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
// Stop all client started tasks on task queue to prevent their access to any // Stop all client started tasks on task queue to prevent their access to any
// call related objects after these objects will be destroyed during call tear // call related objects after these objects will be destroyed during call tear
// down. // down.
task_queue_->SendTask([this]() { task_queue_->SendTask(
[this]() {
rtc::CritScope crit(&lock_); rtc::CritScope crit(&lock_);
for (auto& handle : repeating_task_handles_) { for (auto& handle : repeating_task_handles_) {
handle.Stop(); handle.Stop();
} }
}); },
RTC_FROM_HERE);
// Tear down the call. // Tear down the call.
signaling_thread->Invoke<void>( signaling_thread->Invoke<void>(
RTC_FROM_HERE, RTC_FROM_HERE,

View file

@ -320,7 +320,7 @@ void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
void CallClient::SendTask(std::function<void()> task) { void CallClient::SendTask(std::function<void()> task) {
time_controller_->InvokeWithControlledYield( time_controller_->InvokeWithControlledYield(
[&] { task_queue_.SendTask(std::move(task)); }); [&] { task_queue_.SendTask(std::move(task), RTC_FROM_HERE); });
} }
CallClientPair::~CallClientPair() = default; CallClientPair::~CallClientPair() = default;

View file

@ -29,7 +29,7 @@ VideoFrameMatcher::VideoFrameMatcher(
task_queue_("VideoAnalyzer") {} task_queue_("VideoAnalyzer") {}
VideoFrameMatcher::~VideoFrameMatcher() { VideoFrameMatcher::~VideoFrameMatcher() {
task_queue_.SendTask([this] { Finalize(); }); task_queue_.SendTask([this] { Finalize(); }, RTC_FROM_HERE);
} }
void VideoFrameMatcher::RegisterLayer(int layer_id) { void VideoFrameMatcher::RegisterLayer(int layer_id) {

View file

@ -67,19 +67,6 @@ DEPRECATED_SingleThreadedTaskQueueForTesting::PostDelayed(
return id; return id;
} }
void DEPRECATED_SingleThreadedTaskQueueForTesting::SendTask(Task task) {
RTC_DCHECK(!IsCurrent());
rtc::Event done;
if (PostTask([&task, &done]() {
task();
done.Set();
}) == kInvalidTaskId) {
return;
}
// Give up after 30 seconds, warn after 10.
RTC_CHECK(done.Wait(30000, 10000));
}
bool DEPRECATED_SingleThreadedTaskQueueForTesting::CancelTask(TaskId task_id) { bool DEPRECATED_SingleThreadedTaskQueueForTesting::CancelTask(TaskId task_id) {
rtc::CritScope lock(&cs_); rtc::CritScope lock(&cs_);
for (auto it = tasks_.begin(); it != tasks_.end(); it++) { for (auto it = tasks_.begin(); it != tasks_.end(); it++) {

View file

@ -13,12 +13,14 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <utility>
#include "api/task_queue/task_queue_base.h" #include "api/task_queue/task_queue_base.h"
#include "rtc_base/critical_section.h" #include "rtc_base/critical_section.h"
#include "rtc_base/deprecation.h" #include "rtc_base/deprecation.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/platform_thread.h" #include "rtc_base/platform_thread.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/task_utils/to_queued_task.h" #include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/thread_checker.h" #include "rtc_base/thread_checker.h"
@ -61,7 +63,12 @@ class DEPRECATED_SingleThreadedTaskQueueForTesting : public TaskQueueBase {
// Send one task to the queue. The function does not return until the task // Send one task to the queue. The function does not return until the task
// has finished executing. No support for canceling the task. // has finished executing. No support for canceling the task.
void SendTask(Task task); // TODO(bugs.webrtc.org/10933): Remove this function in favor of free SendTask
// to reduce direct mentioning of the SingleThreadedTaskQueueForTesting class.
template <typename Closure>
void SendTask(Closure&& task) {
::webrtc::SendTask(this, std::forward<Closure>(task), RTC_FROM_HERE);
}
// Given an identifier to the task, attempts to eject it from the queue. // Given an identifier to the task, attempts to eject it from the queue.
// Returns true if the task was found and cancelled. Failure possible // Returns true if the task was found and cancelled. Failure possible

View file

@ -431,9 +431,11 @@ TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) { TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
TaskQueueForTest queue("OveruseFrameDetectorTestQueue"); TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
queue.SendTask([&] { queue.SendTask(
[&] {
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_); overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
}); },
RTC_FROM_HERE);
rtc::Event event; rtc::Event event;
// Expect NormalUsage(). When called, stop the |overuse_detector_| and then // Expect NormalUsage(). When called, stop the |overuse_detector_| and then
@ -910,9 +912,11 @@ TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) { TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
TaskQueueForTest queue("OveruseFrameDetectorTestQueue"); TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
queue.SendTask([&] { queue.SendTask(
[&] {
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_); overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
}); },
RTC_FROM_HERE);
rtc::Event event; rtc::Event event;
// Expect NormalUsage(). When called, stop the |overuse_detector_| and then // Expect NormalUsage(). When called, stop the |overuse_detector_| and then

View file

@ -153,15 +153,16 @@ class VideoSendStreamImplTest : public ::testing::Test {
}; };
TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) { TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
const bool kSuspend = false; const bool kSuspend = false;
config_.suspend_below_min_bitrate = kSuspend; config_.suspend_below_min_bitrate = kSuspend;
auto vss_impl = CreateVideoSendStreamImpl( auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kRealtimeVideo); VideoEncoderConfig::ContentType::kRealtimeVideo);
EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
.WillOnce(Invoke( .WillOnce(Invoke([&](BitrateAllocatorObserver*,
[&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { MediaStreamAllocationConfig config) {
EXPECT_EQ(config.min_bitrate_bps, 0u); EXPECT_EQ(config.min_bitrate_bps, 0u);
EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps); EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps);
EXPECT_EQ(config.pad_up_bitrate_bps, 0u); EXPECT_EQ(config.pad_up_bitrate_bps, 0u);
@ -169,13 +170,16 @@ TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) {
EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority); EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority);
})); }));
vss_impl->Start(); vss_impl->Start();
EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
.Times(1);
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
const bool kSuspend = false; const bool kSuspend = false;
config_.suspend_below_min_bitrate = kSuspend; config_.suspend_below_min_bitrate = kSuspend;
config_.rtp.extensions.emplace_back( config_.rtp.extensions.emplace_back(
@ -185,7 +189,8 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
VideoEncoderConfig::ContentType::kRealtimeVideo); VideoEncoderConfig::ContentType::kRealtimeVideo);
vss_impl->Start(); vss_impl->Start();
// QVGA + VGA configuration matching defaults in media/engine/simulcast.cc. // QVGA + VGA configuration matching defaults in
// media/engine/simulcast.cc.
VideoStream qvga_stream; VideoStream qvga_stream;
qvga_stream.width = 320; qvga_stream.width = 320;
qvga_stream.height = 180; qvga_stream.height = 180;
@ -212,8 +217,8 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
config_.rtp.ssrcs.emplace_back(2); config_.rtp.ssrcs.emplace_back(2);
EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
.WillRepeatedly(Invoke( .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
[&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { MediaStreamAllocationConfig config) {
EXPECT_EQ(config.min_bitrate_bps, EXPECT_EQ(config.min_bitrate_bps,
static_cast<uint32_t>(min_transmit_bitrate_bps)); static_cast<uint32_t>(min_transmit_bitrate_bps));
EXPECT_EQ(config.max_bitrate_bps, EXPECT_EQ(config.max_bitrate_bps,
@ -233,11 +238,13 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) {
VideoEncoderConfig::ContentType::kRealtimeVideo, VideoEncoderConfig::ContentType::kRealtimeVideo,
min_transmit_bitrate_bps); min_transmit_bitrate_bps);
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
const bool kSuspend = false; const bool kSuspend = false;
config_.suspend_below_min_bitrate = kSuspend; config_.suspend_below_min_bitrate = kSuspend;
config_.rtp.extensions.emplace_back( config_.rtp.extensions.emplace_back(
@ -279,8 +286,8 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
config_.rtp.ssrcs.emplace_back(2); config_.rtp.ssrcs.emplace_back(2);
EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
.WillRepeatedly(Invoke( .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
[&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { MediaStreamAllocationConfig config) {
EXPECT_EQ(config.min_bitrate_bps, EXPECT_EQ(config.min_bitrate_bps,
static_cast<uint32_t>(low_stream.min_bitrate_bps)); static_cast<uint32_t>(low_stream.min_bitrate_bps));
EXPECT_EQ(config.max_bitrate_bps, EXPECT_EQ(config.max_bitrate_bps,
@ -296,9 +303,11 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) {
static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get()) static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
->OnEncoderConfigurationChanged( ->OnEncoderConfigurationChanged(
std::vector<VideoStream>{low_stream, high_stream}, std::vector<VideoStream>{low_stream, high_stream},
VideoEncoderConfig::ContentType::kScreen, min_transmit_bitrate_bps); VideoEncoderConfig::ContentType::kScreen,
min_transmit_bitrate_bps);
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, TEST_F(VideoSendStreamImplTest,
@ -306,7 +315,8 @@ TEST_F(VideoSendStreamImplTest,
test::ScopedFieldTrials hysteresis_experiment( test::ScopedFieldTrials hysteresis_experiment(
"WebRTC-VideoRateControl/video_hysteresis:1.25/"); "WebRTC-VideoRateControl/video_hysteresis:1.25/");
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
auto vss_impl = CreateVideoSendStreamImpl( auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kRealtimeVideo); VideoEncoderConfig::ContentType::kRealtimeVideo);
@ -337,8 +347,8 @@ TEST_F(VideoSendStreamImplTest,
config_.rtp.ssrcs.emplace_back(2); config_.rtp.ssrcs.emplace_back(2);
EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
.WillRepeatedly(Invoke( .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
[&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { MediaStreamAllocationConfig config) {
EXPECT_EQ(config.min_bitrate_bps, EXPECT_EQ(config.min_bitrate_bps,
static_cast<uint32_t>(low_stream.min_bitrate_bps)); static_cast<uint32_t>(low_stream.min_bitrate_bps));
EXPECT_EQ(config.max_bitrate_bps, EXPECT_EQ(config.max_bitrate_bps,
@ -358,13 +368,15 @@ TEST_F(VideoSendStreamImplTest,
VideoEncoderConfig::ContentType::kRealtimeVideo, VideoEncoderConfig::ContentType::kRealtimeVideo,
/*min_transmit_bitrate_bps=*/0); /*min_transmit_bitrate_bps=*/0);
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) { TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString()); test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
constexpr int kId = 1; constexpr int kId = 1;
config_.rtp.extensions.emplace_back( config_.rtp.extensions.emplace_back(
RtpExtension::kTransportSequenceNumberUri, kId); RtpExtension::kTransportSequenceNumberUri, kId);
@ -376,23 +388,27 @@ TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) {
VideoEncoderConfig::ContentType::kScreen); VideoEncoderConfig::ContentType::kScreen);
vss_impl->Start(); vss_impl->Start();
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) { TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) {
test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString()); test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
auto vss_impl = CreateVideoSendStreamImpl( auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kScreen); VideoEncoderConfig::ContentType::kScreen);
vss_impl->Start(); vss_impl->Start();
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) { TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0);
auto vss_impl = CreateVideoSendStreamImpl( auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
@ -409,7 +425,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
alloc.SetBitrate(1, 1, 40000); alloc.SetBitrate(1, 1, 40000);
// Encoder starts out paused, don't forward allocation. // Encoder starts out paused, don't forward allocation.
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0); EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(0);
observer->OnBitrateAllocationUpdated(alloc); observer->OnBitrateAllocationUpdated(alloc);
// Unpause encoder, allocation should be passed through. // Unpause encoder, allocation should be passed through.
@ -419,7 +436,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
.WillOnce(Return(kBitrateBps)); .WillOnce(Return(kBitrateBps));
static_cast<BitrateAllocatorObserver*>(vss_impl.get()) static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(CreateAllocation(kBitrateBps)); ->OnBitrateUpdated(CreateAllocation(kBitrateBps));
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1); EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(alloc); observer->OnBitrateAllocationUpdated(alloc);
// Pause encoder again, and block allocations. // Pause encoder again, and block allocations.
@ -428,15 +446,18 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) {
.WillOnce(Return(0)); .WillOnce(Return(0));
static_cast<BitrateAllocatorObserver*>(vss_impl.get()) static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(CreateAllocation(0)); ->OnBitrateUpdated(CreateAllocation(0));
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0); EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(0);
observer->OnBitrateAllocationUpdated(alloc); observer->OnBitrateAllocationUpdated(alloc);
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) { TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
auto vss_impl = CreateVideoSendStreamImpl( auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kScreen); VideoEncoderConfig::ContentType::kScreen);
@ -459,7 +480,8 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
alloc.SetBitrate(1, 1, 40000); alloc.SetBitrate(1, 1, 40000);
// Initial value. // Initial value.
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1); EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(alloc); observer->OnBitrateAllocationUpdated(alloc);
VideoBitrateAllocation updated_alloc = alloc; VideoBitrateAllocation updated_alloc = alloc;
@ -474,23 +496,27 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) {
// Large enough increase, do forward. // Large enough increase, do forward.
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps); updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc)) EXPECT_CALL(rtp_video_sender_,
OnBitrateAllocationUpdated(updated_alloc))
.Times(1); .Times(1);
observer->OnBitrateAllocationUpdated(updated_alloc); observer->OnBitrateAllocationUpdated(updated_alloc);
// This is now a decrease compared to last forward allocation, forward // This is now a decrease compared to last forward allocation, forward
// immediately. // immediately.
updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1); updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1);
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc)) EXPECT_CALL(rtp_video_sender_,
OnBitrateAllocationUpdated(updated_alloc))
.Times(1); .Times(1);
observer->OnBitrateAllocationUpdated(updated_alloc); observer->OnBitrateAllocationUpdated(updated_alloc);
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) { TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
auto vss_impl = CreateVideoSendStreamImpl( auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kScreen); VideoEncoderConfig::ContentType::kScreen);
@ -513,7 +539,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
alloc.SetBitrate(1, 1, 40000); alloc.SetBitrate(1, 1, 40000);
// Initial value. // Initial value.
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1); EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc))
.Times(1);
observer->OnBitrateAllocationUpdated(alloc); observer->OnBitrateAllocationUpdated(alloc);
// Move some bitrate from one layer to a new one, but keep sum the same. // Move some bitrate from one layer to a new one, but keep sum the same.
@ -522,16 +549,19 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) {
updated_alloc.SetBitrate(2, 0, 10000); updated_alloc.SetBitrate(2, 0, 10000);
updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000); updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000);
EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps()); EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps());
EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc)) EXPECT_CALL(rtp_video_sender_,
OnBitrateAllocationUpdated(updated_alloc))
.Times(1); .Times(1);
observer->OnBitrateAllocationUpdated(updated_alloc); observer->OnBitrateAllocationUpdated(updated_alloc);
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) { TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
auto vss_impl = CreateVideoSendStreamImpl( auto vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kScreen); VideoEncoderConfig::ContentType::kScreen);
@ -556,8 +586,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
EncodedImage encoded_image; EncodedImage encoded_image;
CodecSpecificInfo codec_specific; CodecSpecificInfo codec_specific;
EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _)) EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
.WillRepeatedly(Return( .WillRepeatedly(Return(EncodedImageCallback::Result(
EncodedImageCallback::Result(EncodedImageCallback::Result::OK))); EncodedImageCallback::Result::OK)));
// Max time we will throttle similar video bitrate allocations. // Max time we will throttle similar video bitrate allocations.
static constexpr int64_t kMaxVbaThrottleTimeMs = 500; static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
@ -621,11 +651,13 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) {
} }
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
test_queue_.SendTask([this] { test_queue_.SendTask(
[this] {
const bool kSuspend = false; const bool kSuspend = false;
config_.suspend_below_min_bitrate = kSuspend; config_.suspend_below_min_bitrate = kSuspend;
config_.rtp.extensions.emplace_back( config_.rtp.extensions.emplace_back(
@ -711,8 +743,8 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
static_cast<BitrateAllocatorObserver*>(vss_impl.get()) static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(update); ->OnBitrateUpdated(update);
// Protection bitrate exceeds head room, link allocation should be capped to // Protection bitrate exceeds head room, link allocation should be
// target bitrate. // capped to target bitrate.
EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps())
.WillOnce(Return(headroom.bps() + 1000)); .WillOnce(Return(headroom.bps() + 1000));
EXPECT_CALL(rtp_video_sender_, EXPECT_CALL(rtp_video_sender_,
@ -731,32 +763,34 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(),
DataRate::Zero(), 0, 0)); DataRate::Zero(), 0, 0));
vss_impl->Stop(); vss_impl->Stop();
}); },
RTC_FROM_HERE);
} }
TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
int padding_bitrate = 0; int padding_bitrate = 0;
std::unique_ptr<VideoSendStreamImpl> vss_impl; std::unique_ptr<VideoSendStreamImpl> vss_impl;
test_queue_.SendTask([&] { test_queue_.SendTask(
[&] {
vss_impl = CreateVideoSendStreamImpl( vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority, kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kRealtimeVideo); VideoEncoderConfig::ContentType::kRealtimeVideo);
// Capture padding bitrate for testing. // Capture padding bitrate for testing.
EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _))
.WillRepeatedly(Invoke( .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*,
[&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { MediaStreamAllocationConfig config) {
padding_bitrate = config.pad_up_bitrate_bps; padding_bitrate = config.pad_up_bitrate_bps;
})); }));
// If observer is removed, no padding will be sent. // If observer is removed, no padding will be sent.
EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())) EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
.WillRepeatedly( .WillRepeatedly(Invoke(
Invoke([&](BitrateAllocatorObserver*) { padding_bitrate = 0; })); [&](BitrateAllocatorObserver*) { padding_bitrate = 0; }));
EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _)) EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _))
.WillRepeatedly(Return( .WillRepeatedly(Return(EncodedImageCallback::Result(
EncodedImageCallback::Result(EncodedImageCallback::Result::OK))); EncodedImageCallback::Result::OK)));
const bool kSuspend = false; const bool kSuspend = false;
config_.suspend_below_min_bitrate = kSuspend; config_.suspend_below_min_bitrate = kSuspend;
config_.rtp.extensions.emplace_back( config_.rtp.extensions.emplace_back(
@ -805,7 +839,8 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
->OnEncodedImage(encoded_image, &codec_specific, nullptr); ->OnEncodedImage(encoded_image, &codec_specific, nullptr);
// Only after actual frame is encoded are we enabling the padding. // Only after actual frame is encoded are we enabling the padding.
EXPECT_GT(padding_bitrate, 0); EXPECT_GT(padding_bitrate, 0);
}); },
RTC_FROM_HERE);
rtc::Event done; rtc::Event done;
test_queue_.PostDelayedTask( test_queue_.PostDelayedTask(