diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc index d787a8adbd..a49c0ee3c5 100644 --- a/audio/audio_send_stream_unittest.cc +++ b/audio/audio_send_stream_unittest.cc @@ -552,7 +552,8 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { update.packet_loss_ratio = 0; update.round_trip_time = TimeDelta::ms(50); 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) { @@ -565,7 +566,8 @@ TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) { Eq(DataRate::bps(helper.config().max_bitrate_bps - 5000))))); BitrateAllocationUpdate update; 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) { @@ -580,7 +582,8 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) { Eq(DataRate::kbps(6))))); BitrateAllocationUpdate update; 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) { @@ -595,7 +598,8 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) { Eq(DataRate::kbps(64))))); BitrateAllocationUpdate update; 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) { @@ -614,7 +618,8 @@ TEST(AudioSendStreamTest, SSBweWithOverhead) { &BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); BitrateAllocationUpdate update; update.target_bitrate = bitrate; - helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }); + helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); }, + RTC_FROM_HERE); } TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) { @@ -633,7 +638,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) { &BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); BitrateAllocationUpdate update; 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) { @@ -652,7 +658,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) { &BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); BitrateAllocationUpdate update; 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) { @@ -667,7 +674,8 @@ TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) { update.packet_loss_ratio = 0; update.round_trip_time = TimeDelta::ms(50); 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. diff --git a/modules/audio_mixer/audio_mixer_impl_unittest.cc b/modules/audio_mixer/audio_mixer_impl_unittest.cc index cfb3319d01..f899dd618a 100644 --- a/modules/audio_mixer/audio_mixer_impl_unittest.cc +++ b/modules/audio_mixer/audio_mixer_impl_unittest.cc @@ -374,7 +374,8 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) { TEST(AudioMixer, ConstructFromOtherThread) { TaskQueueForTest init_queue("init"); rtc::scoped_refptr mixer; - init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); }); + init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); }, + RTC_FROM_HERE); MockMixerAudioSource participant; EXPECT_CALL(participant, PreferredSampleRate()) @@ -384,7 +385,8 @@ TEST(AudioMixer, ConstructFromOtherThread) { TaskQueueForTest participant_queue("participant"); participant_queue.SendTask( - [&mixer, &participant]() { mixer->AddSource(&participant); }); + [&mixer, &participant]() { mixer->AddSource(&participant); }, + RTC_FROM_HERE); EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) .Times(Exactly(1)); diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc index 63a6b6dc32..a424baba2e 100644 --- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc +++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc @@ -447,7 +447,7 @@ void VideoCodecTestFixtureImpl::ProcessAllFrames( } // 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, // and then release the codecs. @@ -686,22 +686,26 @@ void VideoCodecTestFixtureImpl::SetUpAndInitObjects( cpu_process_time_.reset(new CpuProcessTime(config_)); - task_queue->SendTask([this]() { - CreateEncoderAndDecoder(); - processor_ = std::make_unique( - encoder_.get(), &decoders_, source_frame_reader_.get(), config_, - &stats_, &encoded_frame_writers_, - decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_); - }); + task_queue->SendTask( + [this]() { + CreateEncoderAndDecoder(); + processor_ = std::make_unique( + encoder_.get(), &decoders_, source_frame_reader_.get(), config_, + &stats_, &encoded_frame_writers_, + decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_); + }, + RTC_FROM_HERE); } void VideoCodecTestFixtureImpl::ReleaseAndCloseObjects( TaskQueueForTest* task_queue) { - task_queue->SendTask([this]() { - processor_.reset(); - // The VideoProcessor must be destroyed before the codecs. - DestroyEncoderAndDecoder(); - }); + task_queue->SendTask( + [this]() { + processor_.reset(); + // The VideoProcessor must be destroyed before the codecs. + DestroyEncoderAndDecoder(); + }, + RTC_FROM_HERE); source_frame_reader_->Close(); @@ -724,10 +728,12 @@ void VideoCodecTestFixtureImpl::PrintSettings( RTC_LOG(LS_INFO) << "==> Codec names"; std::string encoder_name; std::string decoder_name; - task_queue->SendTask([this, &encoder_name, &decoder_name] { - encoder_name = encoder_->GetEncoderInfo().implementation_name; - decoder_name = decoders_.at(0)->ImplementationName(); - }); + task_queue->SendTask( + [this, &encoder_name, &decoder_name] { + encoder_name = encoder_->GetEncoderInfo().implementation_name; + decoder_name = decoders_.at(0)->ImplementationName(); + }, + RTC_FROM_HERE); RTC_LOG(LS_INFO) << "enc_impl_name: " << encoder_name; RTC_LOG(LS_INFO) << "dec_impl_name: " << decoder_name; } diff --git a/modules/video_coding/codecs/test/videoprocessor_unittest.cc b/modules/video_coding/codecs/test/videoprocessor_unittest.cc index 49f68f2cf5..2d9404293b 100644 --- a/modules/video_coding/codecs/test/videoprocessor_unittest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_unittest.cc @@ -54,15 +54,17 @@ class VideoProcessorTest : public ::testing::Test { ExpectInit(); EXPECT_CALL(frame_reader_mock_, FrameLength()) .WillRepeatedly(Return(kFrameSize)); - q_.SendTask([this] { - video_processor_ = std::make_unique( - &encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_, - &encoded_frame_writers_, /*decoded_frame_writers=*/nullptr); - }); + q_.SendTask( + [this] { + video_processor_ = std::make_unique( + &encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_, + &encoded_frame_writers_, /*decoded_frame_writers=*/nullptr); + }, + RTC_FROM_HERE); } ~VideoProcessorTest() { - q_.SendTask([this] { video_processor_.reset(); }); + q_.SendTask([this] { video_processor_.reset(); }, RTC_FROM_HERE); } void ExpectInit() { @@ -104,7 +106,8 @@ TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) { SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps, static_cast(kFramerateFps)))) .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()) .WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight))); @@ -112,13 +115,13 @@ TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) { encoder_mock_, Encode(Property(&VideoFrame::timestamp, 1 * 90000 / kFramerateFps), _)) .Times(1); - q_.SendTask([this] { video_processor_->ProcessFrame(); }); + q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE); EXPECT_CALL( encoder_mock_, Encode(Property(&VideoFrame::timestamp, 2 * 90000 / kFramerateFps), _)) .Times(1); - q_.SendTask([this] { video_processor_->ProcessFrame(); }); + q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE); ExpectRelease(); } @@ -133,14 +136,15 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) { static_cast(kStartFramerateFps)))) .Times(1); q_.SendTask( - [=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); }); + [=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); }, + RTC_FROM_HERE); EXPECT_CALL(frame_reader_mock_, ReadFrame()) .WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight))); EXPECT_CALL(encoder_mock_, Encode(Property(&VideoFrame::timestamp, kStartTimestamp), _)) .Times(1); - q_.SendTask([this] { video_processor_->ProcessFrame(); }); + q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE); const int kNewFramerateFps = 13; EXPECT_CALL( @@ -149,14 +153,15 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) { static_cast(kNewFramerateFps)))) .Times(1); q_.SendTask( - [=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); }); + [=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); }, + RTC_FROM_HERE); EXPECT_CALL(encoder_mock_, Encode(Property(&VideoFrame::timestamp, kStartTimestamp + 90000 / kNewFramerateFps), _)) .Times(1); - q_.SendTask([this] { video_processor_->ProcessFrame(); }); + q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE); ExpectRelease(); } @@ -175,7 +180,8 @@ TEST_F(VideoProcessorTest, SetRates) { Field(&VideoEncoder::RateControlParameters::framerate_fps, static_cast(kFramerateFps))))) .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 int kNewFramerateFps = 34; @@ -190,7 +196,8 @@ TEST_F(VideoProcessorTest, SetRates) { static_cast(kNewFramerateFps))))) .Times(1); q_.SendTask( - [=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); }); + [=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); }, + RTC_FROM_HERE); ExpectRelease(); } diff --git a/modules/video_coding/utility/quality_scaler_unittest.cc b/modules/video_coding/utility/quality_scaler_unittest.cc index 012ef729c1..939865da35 100644 --- a/modules/video_coding/utility/quality_scaler_unittest.cc +++ b/modules/video_coding/utility/quality_scaler_unittest.cc @@ -71,15 +71,17 @@ class QualityScalerTest : public ::testing::Test, : scoped_field_trial_(GetParam()), task_queue_("QualityScalerTestQueue"), observer_(new MockAdaptationObserver()) { - task_queue_.SendTask([this] { - qs_ = std::unique_ptr(new QualityScalerUnderTest( - &task_queue_, observer_.get(), - VideoEncoder::QpThresholds(kLowQp, kHighQp))); - }); + task_queue_.SendTask( + [this] { + qs_ = std::unique_ptr(new QualityScalerUnderTest( + &task_queue_, observer_.get(), + VideoEncoder::QpThresholds(kLowQp, kHighQp))); + }, + RTC_FROM_HERE); } ~QualityScalerTest() { - task_queue_.SendTask([this] { qs_ = nullptr; }); + task_queue_.SendTask([this] { qs_ = nullptr; }, RTC_FROM_HERE); } void TriggerScale(ScaleDirection scale_direction) { @@ -118,46 +120,52 @@ INSTANTIATE_TEST_SUITE_P( "")); 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_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); } 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_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); } 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_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); } TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) { - task_queue_.SendTask([this] { - for (int i = 0; i < kFramerate * 5; ++i) { - qs_->ReportDroppedFrameByMediaOpt(); - qs_->ReportDroppedFrameByMediaOpt(); - qs_->ReportQp(kHighQp, 0); - } - }); + task_queue_.SendTask( + [this] { + for (int i = 0; i < kFramerate * 5; ++i) { + qs_->ReportDroppedFrameByMediaOpt(); + qs_->ReportDroppedFrameByMediaOpt(); + qs_->ReportQp(kHighQp, 0); + } + }, + RTC_FROM_HERE); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); } TEST_P(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) { - task_queue_.SendTask([this] { - for (int i = 0; i < kFramerate * 5; ++i) { - qs_->ReportDroppedFrameByMediaOpt(); - qs_->ReportQp(kHighQp, 0); - } - }); + task_queue_.SendTask( + [this] { + for (int i = 0; i < kFramerate * 5; ++i) { + qs_->ReportDroppedFrameByMediaOpt(); + qs_->ReportQp(kHighQp, 0); + } + }, + RTC_FROM_HERE); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); @@ -165,84 +173,98 @@ TEST_P(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) { TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsIfFieldTrialEnabled) { const bool kDownScaleExpected = !GetParam().empty(); - task_queue_.SendTask([this] { - for (int i = 0; i < kFramerate * 5; ++i) { - qs_->ReportDroppedFrameByMediaOpt(); - qs_->ReportDroppedFrameByEncoder(); - qs_->ReportQp(kHighQp, 0); - } - }); + task_queue_.SendTask( + [this] { + for (int i = 0; i < kFramerate * 5; ++i) { + qs_->ReportDroppedFrameByMediaOpt(); + qs_->ReportDroppedFrameByEncoder(); + qs_->ReportQp(kHighQp, 0); + } + }, + RTC_FROM_HERE); EXPECT_EQ(kDownScaleExpected, observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(kDownScaleExpected ? 1 : 0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); } 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_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); } 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_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_up_events_); } 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_EQ(1, observer_->adapt_down_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_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_up_events_); } TEST_P(QualityScalerTest, DoesNotScaleUntilEnoughFramesObserved) { - task_queue_.SendTask([this] { - // Not enough frames to make a decision. - for (int i = 0; i < kMinFramesNeededToScale - 1; ++i) { - qs_->ReportQp(kLowQp, 0); - } - }); + task_queue_.SendTask( + [this] { + // Not enough frames to make a decision. + for (int i = 0; i < kMinFramesNeededToScale - 1; ++i) { + qs_->ReportQp(kLowQp, 0); + } + }, + RTC_FROM_HERE); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); - task_queue_.SendTask([this] { - // Send 1 more. Enough frames observed, should result in an adapt request. - qs_->ReportQp(kLowQp, 0); - }); + task_queue_.SendTask( + [this] { + // Send 1 more. Enough frames observed, should result in an adapt + // request. + qs_->ReportQp(kLowQp, 0); + }, + RTC_FROM_HERE); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_up_events_); // Samples should be cleared after an adapt request. - task_queue_.SendTask([this] { - // Not enough frames to make a decision. - qs_->ReportQp(kLowQp, 0); - }); + task_queue_.SendTask( + [this] { + // Not enough frames to make a decision. + qs_->ReportQp(kLowQp, 0); + }, + RTC_FROM_HERE); EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(0, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_up_events_); } TEST_P(QualityScalerTest, ScalesDownAndBackUpWithMinFramesNeeded) { - task_queue_.SendTask([this] { - for (int i = 0; i < kMinFramesNeededToScale; ++i) { - qs_->ReportQp(kHighQp + 1, 0); - } - }); + task_queue_.SendTask( + [this] { + for (int i = 0; i < kMinFramesNeededToScale; ++i) { + qs_->ReportQp(kHighQp + 1, 0); + } + }, + RTC_FROM_HERE); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(0, observer_->adapt_up_events_); // Samples cleared. - task_queue_.SendTask([this] { - for (int i = 0; i < kMinFramesNeededToScale; ++i) { - qs_->ReportQp(kLowQp, 0); - } - }); + task_queue_.SendTask( + [this] { + for (int i = 0; i < kMinFramesNeededToScale; ++i) { + qs_->ReportQp(kLowQp, 0); + } + }, + RTC_FROM_HERE); EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs)); EXPECT_EQ(1, observer_->adapt_down_events_); EXPECT_EQ(1, observer_->adapt_up_events_); diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index 564989ab36..896076bdc9 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -1077,8 +1077,10 @@ rtc_source_set("task_queue_for_test") { deps = [ ":checks", ":macromagic", + ":rtc_base_approved", ":rtc_event", ":rtc_task_queue", + "../api/task_queue", "../api/task_queue:default_task_queue_factory", "task_utils:to_queued_task", "//third_party/abseil-cpp/absl/strings", diff --git a/rtc_base/synchronization/sequence_checker_unittest.cc b/rtc_base/synchronization/sequence_checker_unittest.cc index 00b847ca1b..1e62e9759b 100644 --- a/rtc_base/synchronization/sequence_checker_unittest.cc +++ b/rtc_base/synchronization/sequence_checker_unittest.cc @@ -84,16 +84,20 @@ TEST(SequenceCheckerTest, DetachFromThreadAndUseOnTaskQueue) { SequenceChecker sequence_checker; sequence_checker.Detach(); TaskQueueForTest queue; - queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); }); + queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); }, + RTC_FROM_HERE); } TEST(SequenceCheckerTest, DetachFromTaskQueueAndUseOnThread) { TaskQueueForTest queue; - queue.SendTask([] { - SequenceChecker sequence_checker; - sequence_checker.Detach(); - RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); }); - }); + queue.SendTask( + [] { + SequenceChecker sequence_checker; + sequence_checker.Detach(); + RunOnDifferentThread( + [&] { EXPECT_TRUE(sequence_checker.IsCurrent()); }); + }, + RTC_FROM_HERE); } TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) { @@ -106,7 +110,8 @@ TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) { SequenceChecker sequence_checker; TaskQueueForTest queue; 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) { @@ -114,13 +119,15 @@ TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) { sequence_checker.Detach(); 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 // another task queue. TaskQueueForTest queue2; 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 { @@ -147,7 +154,7 @@ TEST(SequenceCheckerTest, TestAnnotations) { void TestAnnotationsOnWrongQueue() { TestAnnotations annotations; TaskQueueForTest queue; - queue.SendTask([&] { annotations.ModifyTestVar(); }); + queue.SendTask([&] { annotations.ModifyTestVar(); }, RTC_FROM_HERE); } #if RTC_DCHECK_IS_ON diff --git a/rtc_base/task_queue_for_test.h b/rtc_base/task_queue_for_test.h index be91c50480..40fc9c8a7e 100644 --- a/rtc_base/task_queue_for_test.h +++ b/rtc_base/task_queue_for_test.h @@ -14,14 +14,27 @@ #include #include "absl/strings/string_view.h" +#include "api/task_queue/task_queue_base.h" #include "rtc_base/checks.h" #include "rtc_base/event.h" +#include "rtc_base/location.h" #include "rtc_base/task_queue.h" #include "rtc_base/task_utils/to_queued_task.h" #include "rtc_base/thread_annotations.h" namespace webrtc { +template +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(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 { public: 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|.). template void SendTask(Closure* task) { - RTC_DCHECK(!IsCurrent()); + RTC_CHECK(!IsCurrent()); rtc::Event event; PostTask(ToQueuedTask( [&task] { RTC_CHECK_EQ(false, static_cast(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 task executes on the task queue. template - void SendTask(Closure&& task) { - RTC_DCHECK(!IsCurrent()); - rtc::Event event; - PostTask( - ToQueuedTask(std::forward(task), [&event] { event.Set(); })); - event.Wait(rtc::Event::kForever); + void SendTask(Closure&& task, rtc::Location loc) { + ::webrtc::SendTask(Get(), std::forward(task), loc); } }; diff --git a/rtc_base/weak_ptr_unittest.cc b/rtc_base/weak_ptr_unittest.cc index 9e22312c28..0757a1d096 100644 --- a/rtc_base/weak_ptr_unittest.cc +++ b/rtc_base/weak_ptr_unittest.cc @@ -204,7 +204,7 @@ template std::unique_ptr NewObjectCreatedOnTaskQueue() { std::unique_ptr obj; webrtc::TaskQueueForTest queue("NewObjectCreatedOnTaskQueue"); - queue.SendTask([&] { obj = std::make_unique(); }); + queue.SendTask([&] { obj = std::make_unique(); }, RTC_FROM_HERE); return obj; } @@ -226,11 +226,13 @@ TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) { // Create weak ptr on main thread WeakPtr weak_ptr = target->factory.GetWeakPtr(); webrtc::TaskQueueForTest queue("queue"); - queue.SendTask([&] { - // Dereference and invalide weak_ptr on another thread. - EXPECT_EQ(weak_ptr.get(), target.get()); - target.reset(); - }); + queue.SendTask( + [&] { + // Dereference and invalide weak_ptr on another thread. + EXPECT_EQ(weak_ptr.get(), target.get()); + target.reset(); + }, + RTC_FROM_HERE); } } // namespace rtc diff --git a/test/BUILD.gn b/test/BUILD.gn index ff13621c1e..00b78d43e7 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -631,6 +631,7 @@ rtc_source_set("single_threaded_task_queue") { "../rtc_base:checks", "../rtc_base:deprecation", "../rtc_base:rtc_base_approved", + "../rtc_base:task_queue_for_test", "../rtc_base/task_utils:to_queued_task", ] } diff --git a/test/network/network_emulation_manager.cc b/test/network/network_emulation_manager.cc index b0caac33f4..ead8fe5d55 100644 --- a/test/network/network_emulation_manager.cc +++ b/test/network/network_emulation_manager.cc @@ -138,16 +138,18 @@ EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute( void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) { RTC_CHECK(route->active) << "Route already cleared"; - task_queue_.SendTask([route]() { - // Remove receiver from intermediate nodes. - for (auto* node : route->via_nodes) { - node->router()->RemoveReceiver(route->to->GetPeerLocalAddress()); - } - // Remove destination endpoint from source endpoint's router. - route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress()); + task_queue_.SendTask( + [route]() { + // Remove receiver from intermediate nodes. + for (auto* node : route->via_nodes) { + node->router()->RemoveReceiver(route->to->GetPeerLocalAddress()); + } + // Remove destination endpoint from source endpoint's router. + route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress()); - route->active = false; - }); + route->active = false; + }, + RTC_FROM_HERE); } TrafficRoute* NetworkEmulationManagerImpl::CreateTrafficRoute( diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc index aa656c878e..d94d979601 100644 --- a/test/pc/e2e/peer_connection_quality_test.cc +++ b/test/pc/e2e/peer_connection_quality_test.cc @@ -379,12 +379,14 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { RTC_LOG(INFO) << "Test is done, initiating disconnect sequence."; - task_queue_->SendTask([&stats_poller, this]() { - RTC_DCHECK_RUN_ON(task_queue_.get()); - stats_polling_task_.Stop(); - // Get final end-of-call stats. - stats_poller.PollStatsAndNotifyObservers(); - }); + task_queue_->SendTask( + [&stats_poller, this]() { + RTC_DCHECK_RUN_ON(task_queue_.get()); + stats_polling_task_.Stop(); + // Get final end-of-call stats. + stats_poller.PollStatsAndNotifyObservers(); + }, + RTC_FROM_HERE); // We need to detach AEC dumping from peers, because dump uses |task_queue_| // 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 // call related objects after these objects will be destroyed during call tear // down. - task_queue_->SendTask([this]() { - rtc::CritScope crit(&lock_); - for (auto& handle : repeating_task_handles_) { - handle.Stop(); - } - }); + task_queue_->SendTask( + [this]() { + rtc::CritScope crit(&lock_); + for (auto& handle : repeating_task_handles_) { + handle.Stop(); + } + }, + RTC_FROM_HERE); // Tear down the call. signaling_thread->Invoke( RTC_FROM_HERE, diff --git a/test/scenario/call_client.cc b/test/scenario/call_client.cc index 9293d0111d..cb29ff6d45 100644 --- a/test/scenario/call_client.cc +++ b/test/scenario/call_client.cc @@ -320,7 +320,7 @@ void CallClient::AddExtensions(std::vector extensions) { void CallClient::SendTask(std::function task) { time_controller_->InvokeWithControlledYield( - [&] { task_queue_.SendTask(std::move(task)); }); + [&] { task_queue_.SendTask(std::move(task), RTC_FROM_HERE); }); } CallClientPair::~CallClientPair() = default; diff --git a/test/scenario/video_frame_matcher.cc b/test/scenario/video_frame_matcher.cc index 2f95b29c0c..cf682c36a9 100644 --- a/test/scenario/video_frame_matcher.cc +++ b/test/scenario/video_frame_matcher.cc @@ -29,7 +29,7 @@ VideoFrameMatcher::VideoFrameMatcher( task_queue_("VideoAnalyzer") {} VideoFrameMatcher::~VideoFrameMatcher() { - task_queue_.SendTask([this] { Finalize(); }); + task_queue_.SendTask([this] { Finalize(); }, RTC_FROM_HERE); } void VideoFrameMatcher::RegisterLayer(int layer_id) { diff --git a/test/single_threaded_task_queue.cc b/test/single_threaded_task_queue.cc index 9fbb24ac88..c3aac1c7ba 100644 --- a/test/single_threaded_task_queue.cc +++ b/test/single_threaded_task_queue.cc @@ -67,19 +67,6 @@ DEPRECATED_SingleThreadedTaskQueueForTesting::PostDelayed( 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) { rtc::CritScope lock(&cs_); for (auto it = tasks_.begin(); it != tasks_.end(); it++) { diff --git a/test/single_threaded_task_queue.h b/test/single_threaded_task_queue.h index 52316c66e9..433d9ea315 100644 --- a/test/single_threaded_task_queue.h +++ b/test/single_threaded_task_queue.h @@ -13,12 +13,14 @@ #include #include #include +#include #include "api/task_queue/task_queue_base.h" #include "rtc_base/critical_section.h" #include "rtc_base/deprecation.h" #include "rtc_base/event.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/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 // 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 + void SendTask(Closure&& task) { + ::webrtc::SendTask(this, std::forward(task), RTC_FROM_HERE); + } // Given an identifier to the task, attempts to eject it from the queue. // Returns true if the task was found and cancelled. Failure possible diff --git a/video/overuse_frame_detector_unittest.cc b/video/overuse_frame_detector_unittest.cc index fac56b9d1d..7d8217ccf9 100644 --- a/video/overuse_frame_detector_unittest.cc +++ b/video/overuse_frame_detector_unittest.cc @@ -431,9 +431,11 @@ TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) { TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) { TaskQueueForTest queue("OveruseFrameDetectorTestQueue"); - queue.SendTask([&] { - overuse_detector_->StartCheckForOveruse(&queue, options_, observer_); - }); + queue.SendTask( + [&] { + overuse_detector_->StartCheckForOveruse(&queue, options_, observer_); + }, + RTC_FROM_HERE); rtc::Event event; // Expect NormalUsage(). When called, stop the |overuse_detector_| and then @@ -910,9 +912,11 @@ TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) { TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) { TaskQueueForTest queue("OveruseFrameDetectorTestQueue"); - queue.SendTask([&] { - overuse_detector_->StartCheckForOveruse(&queue, options_, observer_); - }); + queue.SendTask( + [&] { + overuse_detector_->StartCheckForOveruse(&queue, options_, observer_); + }, + RTC_FROM_HERE); rtc::Event event; // Expect NormalUsage(). When called, stop the |overuse_detector_| and then diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc index 5c19a18b9e..fdf0024105 100644 --- a/video/video_send_stream_impl_unittest.cc +++ b/video/video_send_stream_impl_unittest.cc @@ -153,67 +153,72 @@ class VideoSendStreamImplTest : public ::testing::Test { }; TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) { - test_queue_.SendTask([this] { - const bool kSuspend = false; - config_.suspend_below_min_bitrate = kSuspend; - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); - EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) - .WillOnce(Invoke( - [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + test_queue_.SendTask( + [this] { + const bool kSuspend = false; + config_.suspend_below_min_bitrate = kSuspend; + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kRealtimeVideo); + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) + .WillOnce(Invoke([&](BitrateAllocatorObserver*, + MediaStreamAllocationConfig config) { EXPECT_EQ(config.min_bitrate_bps, 0u); EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps); EXPECT_EQ(config.pad_up_bitrate_bps, 0u); EXPECT_EQ(config.enforce_min_bitrate, !kSuspend); EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority); })); - vss_impl->Start(); - EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); - vss_impl->Stop(); - }); + vss_impl->Start(); + EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())) + .Times(1); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { - test_queue_.SendTask([this] { - const bool kSuspend = false; - config_.suspend_below_min_bitrate = kSuspend; - config_.rtp.extensions.emplace_back( - RtpExtension::kTransportSequenceNumberUri, 1); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); - vss_impl->Start(); + test_queue_.SendTask( + [this] { + const bool kSuspend = false; + config_.suspend_below_min_bitrate = kSuspend; + config_.rtp.extensions.emplace_back( + RtpExtension::kTransportSequenceNumberUri, 1); + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kRealtimeVideo); + vss_impl->Start(); - // QVGA + VGA configuration matching defaults in media/engine/simulcast.cc. - VideoStream qvga_stream; - qvga_stream.width = 320; - qvga_stream.height = 180; - qvga_stream.max_framerate = 30; - qvga_stream.min_bitrate_bps = 30000; - qvga_stream.target_bitrate_bps = 150000; - qvga_stream.max_bitrate_bps = 200000; - qvga_stream.max_qp = 56; - qvga_stream.bitrate_priority = 1; + // QVGA + VGA configuration matching defaults in + // media/engine/simulcast.cc. + VideoStream qvga_stream; + qvga_stream.width = 320; + qvga_stream.height = 180; + qvga_stream.max_framerate = 30; + qvga_stream.min_bitrate_bps = 30000; + qvga_stream.target_bitrate_bps = 150000; + qvga_stream.max_bitrate_bps = 200000; + qvga_stream.max_qp = 56; + qvga_stream.bitrate_priority = 1; - VideoStream vga_stream; - vga_stream.width = 640; - vga_stream.height = 360; - vga_stream.max_framerate = 30; - vga_stream.min_bitrate_bps = 150000; - vga_stream.target_bitrate_bps = 500000; - vga_stream.max_bitrate_bps = 700000; - vga_stream.max_qp = 56; - vga_stream.bitrate_priority = 1; + VideoStream vga_stream; + vga_stream.width = 640; + vga_stream.height = 360; + vga_stream.max_framerate = 30; + vga_stream.min_bitrate_bps = 150000; + vga_stream.target_bitrate_bps = 500000; + vga_stream.max_bitrate_bps = 700000; + vga_stream.max_qp = 56; + vga_stream.bitrate_priority = 1; - int min_transmit_bitrate_bps = 30000; + int min_transmit_bitrate_bps = 30000; - config_.rtp.ssrcs.emplace_back(1); - config_.rtp.ssrcs.emplace_back(2); + config_.rtp.ssrcs.emplace_back(1); + config_.rtp.ssrcs.emplace_back(2); - EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) - .WillRepeatedly(Invoke( - [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) + .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*, + MediaStreamAllocationConfig config) { EXPECT_EQ(config.min_bitrate_bps, static_cast(min_transmit_bitrate_bps)); EXPECT_EQ(config.max_bitrate_bps, @@ -227,60 +232,62 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { EXPECT_EQ(config.enforce_min_bitrate, !kSuspend); })); - static_cast(vss_impl.get()) - ->OnEncoderConfigurationChanged( - std::vector{qvga_stream, vga_stream}, - VideoEncoderConfig::ContentType::kRealtimeVideo, - min_transmit_bitrate_bps); - vss_impl->Stop(); - }); + static_cast(vss_impl.get()) + ->OnEncoderConfigurationChanged( + std::vector{qvga_stream, vga_stream}, + VideoEncoderConfig::ContentType::kRealtimeVideo, + min_transmit_bitrate_bps); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { - test_queue_.SendTask([this] { - const bool kSuspend = false; - config_.suspend_below_min_bitrate = kSuspend; - config_.rtp.extensions.emplace_back( - RtpExtension::kTransportSequenceNumberUri, 1); - config_.periodic_alr_bandwidth_probing = true; - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->Start(); + test_queue_.SendTask( + [this] { + const bool kSuspend = false; + config_.suspend_below_min_bitrate = kSuspend; + config_.rtp.extensions.emplace_back( + RtpExtension::kTransportSequenceNumberUri, 1); + config_.periodic_alr_bandwidth_probing = true; + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kScreen); + vss_impl->Start(); - // Simulcast screenshare. - VideoStream low_stream; - low_stream.width = 1920; - low_stream.height = 1080; - low_stream.max_framerate = 5; - low_stream.min_bitrate_bps = 30000; - low_stream.target_bitrate_bps = 200000; - low_stream.max_bitrate_bps = 1000000; - low_stream.num_temporal_layers = 2; - low_stream.max_qp = 56; - low_stream.bitrate_priority = 1; + // Simulcast screenshare. + VideoStream low_stream; + low_stream.width = 1920; + low_stream.height = 1080; + low_stream.max_framerate = 5; + low_stream.min_bitrate_bps = 30000; + low_stream.target_bitrate_bps = 200000; + low_stream.max_bitrate_bps = 1000000; + low_stream.num_temporal_layers = 2; + low_stream.max_qp = 56; + low_stream.bitrate_priority = 1; - VideoStream high_stream; - high_stream.width = 1920; - high_stream.height = 1080; - high_stream.max_framerate = 30; - high_stream.min_bitrate_bps = 60000; - high_stream.target_bitrate_bps = 1250000; - high_stream.max_bitrate_bps = 1250000; - high_stream.num_temporal_layers = 2; - high_stream.max_qp = 56; - high_stream.bitrate_priority = 1; + VideoStream high_stream; + high_stream.width = 1920; + high_stream.height = 1080; + high_stream.max_framerate = 30; + high_stream.min_bitrate_bps = 60000; + high_stream.target_bitrate_bps = 1250000; + high_stream.max_bitrate_bps = 1250000; + high_stream.num_temporal_layers = 2; + high_stream.max_qp = 56; + high_stream.bitrate_priority = 1; - // With ALR probing, this will be the padding target instead of - // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps. - int min_transmit_bitrate_bps = 400000; + // With ALR probing, this will be the padding target instead of + // low_stream.target_bitrate_bps + high_stream.min_bitrate_bps. + int min_transmit_bitrate_bps = 400000; - config_.rtp.ssrcs.emplace_back(1); - config_.rtp.ssrcs.emplace_back(2); + config_.rtp.ssrcs.emplace_back(1); + config_.rtp.ssrcs.emplace_back(2); - EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) - .WillRepeatedly(Invoke( - [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) + .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*, + MediaStreamAllocationConfig config) { EXPECT_EQ(config.min_bitrate_bps, static_cast(low_stream.min_bitrate_bps)); EXPECT_EQ(config.max_bitrate_bps, @@ -293,12 +300,14 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { EXPECT_EQ(config.enforce_min_bitrate, !kSuspend); })); - static_cast(vss_impl.get()) - ->OnEncoderConfigurationChanged( - std::vector{low_stream, high_stream}, - VideoEncoderConfig::ContentType::kScreen, min_transmit_bitrate_bps); - vss_impl->Stop(); - }); + static_cast(vss_impl.get()) + ->OnEncoderConfigurationChanged( + std::vector{low_stream, high_stream}, + VideoEncoderConfig::ContentType::kScreen, + min_transmit_bitrate_bps); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, @@ -306,39 +315,40 @@ TEST_F(VideoSendStreamImplTest, test::ScopedFieldTrials hysteresis_experiment( "WebRTC-VideoRateControl/video_hysteresis:1.25/"); - test_queue_.SendTask([this] { - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); - vss_impl->Start(); + test_queue_.SendTask( + [this] { + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kRealtimeVideo); + vss_impl->Start(); - // 2-layer video simulcast. - VideoStream low_stream; - low_stream.width = 320; - low_stream.height = 240; - low_stream.max_framerate = 30; - low_stream.min_bitrate_bps = 30000; - low_stream.target_bitrate_bps = 100000; - low_stream.max_bitrate_bps = 200000; - low_stream.max_qp = 56; - low_stream.bitrate_priority = 1; + // 2-layer video simulcast. + VideoStream low_stream; + low_stream.width = 320; + low_stream.height = 240; + low_stream.max_framerate = 30; + low_stream.min_bitrate_bps = 30000; + low_stream.target_bitrate_bps = 100000; + low_stream.max_bitrate_bps = 200000; + low_stream.max_qp = 56; + low_stream.bitrate_priority = 1; - VideoStream high_stream; - high_stream.width = 640; - high_stream.height = 480; - high_stream.max_framerate = 30; - high_stream.min_bitrate_bps = 150000; - high_stream.target_bitrate_bps = 500000; - high_stream.max_bitrate_bps = 750000; - high_stream.max_qp = 56; - high_stream.bitrate_priority = 1; + VideoStream high_stream; + high_stream.width = 640; + high_stream.height = 480; + high_stream.max_framerate = 30; + high_stream.min_bitrate_bps = 150000; + high_stream.target_bitrate_bps = 500000; + high_stream.max_bitrate_bps = 750000; + high_stream.max_qp = 56; + high_stream.bitrate_priority = 1; - config_.rtp.ssrcs.emplace_back(1); - config_.rtp.ssrcs.emplace_back(2); + config_.rtp.ssrcs.emplace_back(1); + config_.rtp.ssrcs.emplace_back(2); - EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) - .WillRepeatedly(Invoke( - [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) + .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*, + MediaStreamAllocationConfig config) { EXPECT_EQ(config.min_bitrate_bps, static_cast(low_stream.min_bitrate_bps)); EXPECT_EQ(config.max_bitrate_bps, @@ -352,460 +362,485 @@ TEST_F(VideoSendStreamImplTest, } })); - static_cast(vss_impl.get()) - ->OnEncoderConfigurationChanged( - std::vector{low_stream, high_stream}, - VideoEncoderConfig::ContentType::kRealtimeVideo, - /*min_transmit_bitrate_bps=*/0); - vss_impl->Stop(); - }); + static_cast(vss_impl.get()) + ->OnEncoderConfigurationChanged( + std::vector{low_stream, high_stream}, + VideoEncoderConfig::ContentType::kRealtimeVideo, + /*min_transmit_bitrate_bps=*/0); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) { test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString()); - test_queue_.SendTask([this] { - constexpr int kId = 1; - config_.rtp.extensions.emplace_back( - RtpExtension::kTransportSequenceNumberUri, kId); - EXPECT_CALL(transport_controller_, - SetPacingFactor(kAlrProbingExperimentPaceMultiplier)) - .Times(1); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->Start(); - vss_impl->Stop(); - }); + test_queue_.SendTask( + [this] { + constexpr int kId = 1; + config_.rtp.extensions.emplace_back( + RtpExtension::kTransportSequenceNumberUri, kId); + EXPECT_CALL(transport_controller_, + SetPacingFactor(kAlrProbingExperimentPaceMultiplier)) + .Times(1); + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kScreen); + vss_impl->Start(); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) { test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString()); - test_queue_.SendTask([this] { - EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->Start(); - vss_impl->Stop(); - }); + test_queue_.SendTask( + [this] { + EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kScreen); + vss_impl->Start(); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) { - test_queue_.SendTask([this] { - EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->Start(); - VideoBitrateAllocationObserver* const observer = - static_cast(vss_impl.get()); + test_queue_.SendTask( + [this] { + EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kScreen); + vss_impl->Start(); + VideoBitrateAllocationObserver* const observer = + static_cast(vss_impl.get()); - // Populate a test instance of video bitrate allocation. - VideoBitrateAllocation alloc; - alloc.SetBitrate(0, 0, 10000); - alloc.SetBitrate(0, 1, 20000); - alloc.SetBitrate(1, 0, 30000); - alloc.SetBitrate(1, 1, 40000); + // Populate a test instance of video bitrate allocation. + VideoBitrateAllocation alloc; + alloc.SetBitrate(0, 0, 10000); + alloc.SetBitrate(0, 1, 20000); + alloc.SetBitrate(1, 0, 30000); + alloc.SetBitrate(1, 1, 40000); - // Encoder starts out paused, don't forward allocation. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0); - observer->OnBitrateAllocationUpdated(alloc); + // Encoder starts out paused, don't forward allocation. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(0); + observer->OnBitrateAllocationUpdated(alloc); - // Unpause encoder, allocation should be passed through. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1); - observer->OnBitrateAllocationUpdated(alloc); + // Unpause encoder, allocation should be passed through. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(alloc); - // Pause encoder again, and block allocations. - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(0)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(0)); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0); - observer->OnBitrateAllocationUpdated(alloc); + // Pause encoder again, and block allocations. + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(0)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(0)); + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(0); + observer->OnBitrateAllocationUpdated(alloc); - vss_impl->Stop(); - }); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) { - test_queue_.SendTask([this] { - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->Start(); - // Unpause encoder, to allows allocations to be passed through. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - VideoBitrateAllocationObserver* const observer = - static_cast(vss_impl.get()); + test_queue_.SendTask( + [this] { + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kScreen); + vss_impl->Start(); + // Unpause encoder, to allows allocations to be passed through. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); + VideoBitrateAllocationObserver* const observer = + static_cast(vss_impl.get()); - // Populate a test instance of video bitrate allocation. - VideoBitrateAllocation alloc; - alloc.SetBitrate(0, 0, 10000); - alloc.SetBitrate(0, 1, 20000); - alloc.SetBitrate(1, 0, 30000); - alloc.SetBitrate(1, 1, 40000); + // Populate a test instance of video bitrate allocation. + VideoBitrateAllocation alloc; + alloc.SetBitrate(0, 0, 10000); + alloc.SetBitrate(0, 1, 20000); + alloc.SetBitrate(1, 0, 30000); + alloc.SetBitrate(1, 1, 40000); - // Initial value. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1); - observer->OnBitrateAllocationUpdated(alloc); + // Initial value. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(alloc); - VideoBitrateAllocation updated_alloc = alloc; - // Needs 10% increase in bitrate to trigger immediate forward. - const uint32_t base_layer_min_update_bitrate_bps = - alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10; + VideoBitrateAllocation updated_alloc = alloc; + // Needs 10% increase in bitrate to trigger immediate forward. + const uint32_t base_layer_min_update_bitrate_bps = + alloc.GetBitrate(0, 0) + alloc.get_sum_bps() / 10; - // Too small increase, don't forward. - updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0); - observer->OnBitrateAllocationUpdated(updated_alloc); + // Too small increase, don't forward. + updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1); + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(_)).Times(0); + observer->OnBitrateAllocationUpdated(updated_alloc); - // Large enough increase, do forward. - updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc)) - .Times(1); - observer->OnBitrateAllocationUpdated(updated_alloc); + // Large enough increase, do forward. + updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps); + EXPECT_CALL(rtp_video_sender_, + OnBitrateAllocationUpdated(updated_alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(updated_alloc); - // This is now a decrease compared to last forward allocation, forward - // immediately. - updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc)) - .Times(1); - observer->OnBitrateAllocationUpdated(updated_alloc); + // This is now a decrease compared to last forward allocation, forward + // immediately. + updated_alloc.SetBitrate(0, 0, base_layer_min_update_bitrate_bps - 1); + EXPECT_CALL(rtp_video_sender_, + OnBitrateAllocationUpdated(updated_alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(updated_alloc); - vss_impl->Stop(); - }); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) { - test_queue_.SendTask([this] { - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->Start(); - // Unpause encoder, to allows allocations to be passed through. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - VideoBitrateAllocationObserver* const observer = - static_cast(vss_impl.get()); + test_queue_.SendTask( + [this] { + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kScreen); + vss_impl->Start(); + // Unpause encoder, to allows allocations to be passed through. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); + VideoBitrateAllocationObserver* const observer = + static_cast(vss_impl.get()); - // Populate a test instance of video bitrate allocation. - VideoBitrateAllocation alloc; - alloc.SetBitrate(0, 0, 10000); - alloc.SetBitrate(0, 1, 20000); - alloc.SetBitrate(1, 0, 30000); - alloc.SetBitrate(1, 1, 40000); + // Populate a test instance of video bitrate allocation. + VideoBitrateAllocation alloc; + alloc.SetBitrate(0, 0, 10000); + alloc.SetBitrate(0, 1, 20000); + alloc.SetBitrate(1, 0, 30000); + alloc.SetBitrate(1, 1, 40000); - // Initial value. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1); - observer->OnBitrateAllocationUpdated(alloc); + // Initial value. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(alloc); - // Move some bitrate from one layer to a new one, but keep sum the same. - // Since layout has changed, immediately trigger forward. - VideoBitrateAllocation updated_alloc = alloc; - updated_alloc.SetBitrate(2, 0, 10000); - updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000); - EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps()); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(updated_alloc)) - .Times(1); - observer->OnBitrateAllocationUpdated(updated_alloc); + // Move some bitrate from one layer to a new one, but keep sum the same. + // Since layout has changed, immediately trigger forward. + VideoBitrateAllocation updated_alloc = alloc; + updated_alloc.SetBitrate(2, 0, 10000); + updated_alloc.SetBitrate(1, 1, alloc.GetBitrate(1, 1) - 10000); + EXPECT_EQ(alloc.get_sum_bps(), updated_alloc.get_sum_bps()); + EXPECT_CALL(rtp_video_sender_, + OnBitrateAllocationUpdated(updated_alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(updated_alloc); - vss_impl->Stop(); - }); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) { - test_queue_.SendTask([this] { - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->Start(); - const uint32_t kBitrateBps = 100000; - // Unpause encoder, to allows allocations to be passed through. - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillRepeatedly(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - VideoBitrateAllocationObserver* const observer = - static_cast(vss_impl.get()); + test_queue_.SendTask( + [this] { + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kScreen); + vss_impl->Start(); + const uint32_t kBitrateBps = 100000; + // Unpause encoder, to allows allocations to be passed through. + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillRepeatedly(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); + VideoBitrateAllocationObserver* const observer = + static_cast(vss_impl.get()); - // Populate a test instance of video bitrate allocation. - VideoBitrateAllocation alloc; - alloc.SetBitrate(0, 0, 10000); - alloc.SetBitrate(0, 1, 20000); - alloc.SetBitrate(1, 0, 30000); - alloc.SetBitrate(1, 1, 40000); + // Populate a test instance of video bitrate allocation. + VideoBitrateAllocation alloc; + alloc.SetBitrate(0, 0, 10000); + alloc.SetBitrate(0, 1, 20000); + alloc.SetBitrate(1, 0, 30000); + alloc.SetBitrate(1, 1, 40000); - EncodedImage encoded_image; - CodecSpecificInfo codec_specific; - EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _)) - .WillRepeatedly(Return( - EncodedImageCallback::Result(EncodedImageCallback::Result::OK))); + EncodedImage encoded_image; + CodecSpecificInfo codec_specific; + EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _)) + .WillRepeatedly(Return(EncodedImageCallback::Result( + EncodedImageCallback::Result::OK))); - // Max time we will throttle similar video bitrate allocations. - static constexpr int64_t kMaxVbaThrottleTimeMs = 500; + // Max time we will throttle similar video bitrate allocations. + static constexpr int64_t kMaxVbaThrottleTimeMs = 500; - { - // Initial value. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) - .Times(1); - observer->OnBitrateAllocationUpdated(alloc); - } + { + // Initial value. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(alloc); + } - { - // Sending same allocation again, this one should be throttled. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) - .Times(0); - observer->OnBitrateAllocationUpdated(alloc); - } + { + // Sending same allocation again, this one should be throttled. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(0); + observer->OnBitrateAllocationUpdated(alloc); + } - clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000); + clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000); - { - // Sending similar allocation again after timeout, should forward. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) - .Times(1); - observer->OnBitrateAllocationUpdated(alloc); - } + { + // Sending similar allocation again after timeout, should forward. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(1); + observer->OnBitrateAllocationUpdated(alloc); + } - { - // Sending similar allocation again without timeout, throttle. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) - .Times(0); - observer->OnBitrateAllocationUpdated(alloc); - } + { + // Sending similar allocation again without timeout, throttle. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(0); + observer->OnBitrateAllocationUpdated(alloc); + } - { - // Send encoded image, should be a noop. - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) - .Times(0); - static_cast(vss_impl.get()) - ->OnEncodedImage(encoded_image, &codec_specific, nullptr); - } + { + // Send encoded image, should be a noop. + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(0); + static_cast(vss_impl.get()) + ->OnEncodedImage(encoded_image, &codec_specific, nullptr); + } - { - // Advance time and send encoded image, this should wake up and send - // cached bitrate allocation. - clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) - .Times(1); - static_cast(vss_impl.get()) - ->OnEncodedImage(encoded_image, &codec_specific, nullptr); - } + { + // Advance time and send encoded image, this should wake up and send + // cached bitrate allocation. + clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000); + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(1); + static_cast(vss_impl.get()) + ->OnEncodedImage(encoded_image, &codec_specific, nullptr); + } - { - // Advance time and send encoded image, there should be no cached - // allocation to send. - clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000); - EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) - .Times(0); - static_cast(vss_impl.get()) - ->OnEncodedImage(encoded_image, &codec_specific, nullptr); - } + { + // Advance time and send encoded image, there should be no cached + // allocation to send. + clock_.AdvanceTimeMicroseconds(kMaxVbaThrottleTimeMs * 1000); + EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)) + .Times(0); + static_cast(vss_impl.get()) + ->OnEncodedImage(encoded_image, &codec_specific, nullptr); + } - vss_impl->Stop(); - }); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { - test_queue_.SendTask([this] { - const bool kSuspend = false; - config_.suspend_below_min_bitrate = kSuspend; - config_.rtp.extensions.emplace_back( - RtpExtension::kTransportSequenceNumberUri, 1); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); - vss_impl->Start(); + test_queue_.SendTask( + [this] { + const bool kSuspend = false; + config_.suspend_below_min_bitrate = kSuspend; + config_.rtp.extensions.emplace_back( + RtpExtension::kTransportSequenceNumberUri, 1); + auto vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kRealtimeVideo); + vss_impl->Start(); - VideoStream qvga_stream; - qvga_stream.width = 320; - qvga_stream.height = 180; - qvga_stream.max_framerate = 30; - qvga_stream.min_bitrate_bps = 30000; - qvga_stream.target_bitrate_bps = 150000; - qvga_stream.max_bitrate_bps = 200000; - qvga_stream.max_qp = 56; - qvga_stream.bitrate_priority = 1; + VideoStream qvga_stream; + qvga_stream.width = 320; + qvga_stream.height = 180; + qvga_stream.max_framerate = 30; + qvga_stream.min_bitrate_bps = 30000; + qvga_stream.target_bitrate_bps = 150000; + qvga_stream.max_bitrate_bps = 200000; + qvga_stream.max_qp = 56; + qvga_stream.bitrate_priority = 1; - int min_transmit_bitrate_bps = 30000; + int min_transmit_bitrate_bps = 30000; - config_.rtp.ssrcs.emplace_back(1); + config_.rtp.ssrcs.emplace_back(1); - static_cast(vss_impl.get()) - ->OnEncoderConfigurationChanged( - std::vector{qvga_stream}, - VideoEncoderConfig::ContentType::kRealtimeVideo, - min_transmit_bitrate_bps); + static_cast(vss_impl.get()) + ->OnEncoderConfigurationChanged( + std::vector{qvga_stream}, + VideoEncoderConfig::ContentType::kRealtimeVideo, + min_transmit_bitrate_bps); - const DataRate network_constrained_rate = - DataRate::bps(qvga_stream.target_bitrate_bps); - BitrateAllocationUpdate update; - update.target_bitrate = network_constrained_rate; - update.stable_target_bitrate = network_constrained_rate; - update.round_trip_time = TimeDelta::ms(1); - EXPECT_CALL(rtp_video_sender_, - OnBitrateUpdated(network_constrained_rate.bps(), _, - update.round_trip_time.ms(), _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(network_constrained_rate.bps())); - EXPECT_CALL( - video_stream_encoder_, - OnBitrateUpdated(network_constrained_rate, network_constrained_rate, - network_constrained_rate, 0, _)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); + const DataRate network_constrained_rate = + DataRate::bps(qvga_stream.target_bitrate_bps); + BitrateAllocationUpdate update; + update.target_bitrate = network_constrained_rate; + update.stable_target_bitrate = network_constrained_rate; + update.round_trip_time = TimeDelta::ms(1); + EXPECT_CALL(rtp_video_sender_, + OnBitrateUpdated(network_constrained_rate.bps(), _, + update.round_trip_time.ms(), _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(network_constrained_rate.bps())); + EXPECT_CALL( + video_stream_encoder_, + OnBitrateUpdated(network_constrained_rate, network_constrained_rate, + network_constrained_rate, 0, _)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); - // Test allocation where the link allocation is larger than the target, - // meaning we have some headroom on the link. - const DataRate qvga_max_bitrate = - DataRate::bps(qvga_stream.max_bitrate_bps); - const DataRate headroom = DataRate::bps(50000); - const DataRate rate_with_headroom = qvga_max_bitrate + headroom; - EXPECT_CALL(rtp_video_sender_, - OnBitrateUpdated(rate_with_headroom.bps(), _, - update.round_trip_time.ms(), _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(rate_with_headroom.bps())); - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - rate_with_headroom, 0, _)); - update.target_bitrate = rate_with_headroom; - update.stable_target_bitrate = rate_with_headroom; - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); + // Test allocation where the link allocation is larger than the target, + // meaning we have some headroom on the link. + const DataRate qvga_max_bitrate = + DataRate::bps(qvga_stream.max_bitrate_bps); + const DataRate headroom = DataRate::bps(50000); + const DataRate rate_with_headroom = qvga_max_bitrate + headroom; + EXPECT_CALL(rtp_video_sender_, + OnBitrateUpdated(rate_with_headroom.bps(), _, + update.round_trip_time.ms(), _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(rate_with_headroom.bps())); + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, + rate_with_headroom, 0, _)); + update.target_bitrate = rate_with_headroom; + update.stable_target_bitrate = rate_with_headroom; + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); - // Add protection bitrate to the mix, this should be subtracted from the - // headroom. - const uint32_t protection_bitrate_bps = 10000; - EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) - .WillOnce(Return(protection_bitrate_bps)); + // Add protection bitrate to the mix, this should be subtracted from the + // headroom. + const uint32_t protection_bitrate_bps = 10000; + EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) + .WillOnce(Return(protection_bitrate_bps)); - EXPECT_CALL(rtp_video_sender_, - OnBitrateUpdated(rate_with_headroom.bps(), _, - update.round_trip_time.ms(), _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(rate_with_headroom.bps())); - const DataRate headroom_minus_protection = - rate_with_headroom - DataRate::bps(protection_bitrate_bps); - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - headroom_minus_protection, 0, _)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); + EXPECT_CALL(rtp_video_sender_, + OnBitrateUpdated(rate_with_headroom.bps(), _, + update.round_trip_time.ms(), _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(rate_with_headroom.bps())); + const DataRate headroom_minus_protection = + rate_with_headroom - DataRate::bps(protection_bitrate_bps); + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, + headroom_minus_protection, 0, _)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); - // Protection bitrate exceeds head room, link allocation should be capped to - // target bitrate. - EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) - .WillOnce(Return(headroom.bps() + 1000)); - EXPECT_CALL(rtp_video_sender_, - OnBitrateUpdated(rate_with_headroom.bps(), _, - update.round_trip_time.ms(), _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(rate_with_headroom.bps())); - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - qvga_max_bitrate, 0, _)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); + // Protection bitrate exceeds head room, link allocation should be + // capped to target bitrate. + EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) + .WillOnce(Return(headroom.bps() + 1000)); + EXPECT_CALL(rtp_video_sender_, + OnBitrateUpdated(rate_with_headroom.bps(), _, + update.round_trip_time.ms(), _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(rate_with_headroom.bps())); + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, + qvga_max_bitrate, 0, _)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); - // Set rates to zero on stop. - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), - DataRate::Zero(), 0, 0)); - vss_impl->Stop(); - }); + // Set rates to zero on stop. + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), + DataRate::Zero(), 0, 0)); + vss_impl->Stop(); + }, + RTC_FROM_HERE); } TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { int padding_bitrate = 0; std::unique_ptr vss_impl; - test_queue_.SendTask([&] { - vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); + test_queue_.SendTask( + [&] { + vss_impl = CreateVideoSendStreamImpl( + kDefaultInitialBitrateBps, kDefaultBitratePriority, + VideoEncoderConfig::ContentType::kRealtimeVideo); - // Capture padding bitrate for testing. - EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) - .WillRepeatedly(Invoke( - [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + // Capture padding bitrate for testing. + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) + .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*, + MediaStreamAllocationConfig config) { padding_bitrate = config.pad_up_bitrate_bps; })); - // If observer is removed, no padding will be sent. - EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())) - .WillRepeatedly( - Invoke([&](BitrateAllocatorObserver*) { padding_bitrate = 0; })); + // If observer is removed, no padding will be sent. + EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())) + .WillRepeatedly(Invoke( + [&](BitrateAllocatorObserver*) { padding_bitrate = 0; })); - EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _)) - .WillRepeatedly(Return( - EncodedImageCallback::Result(EncodedImageCallback::Result::OK))); - const bool kSuspend = false; - config_.suspend_below_min_bitrate = kSuspend; - config_.rtp.extensions.emplace_back( - RtpExtension::kTransportSequenceNumberUri, 1); - VideoStream qvga_stream; - qvga_stream.width = 320; - qvga_stream.height = 180; - qvga_stream.max_framerate = 30; - qvga_stream.min_bitrate_bps = 30000; - qvga_stream.target_bitrate_bps = 150000; - qvga_stream.max_bitrate_bps = 200000; - qvga_stream.max_qp = 56; - qvga_stream.bitrate_priority = 1; + EXPECT_CALL(rtp_video_sender_, OnEncodedImage(_, _, _)) + .WillRepeatedly(Return(EncodedImageCallback::Result( + EncodedImageCallback::Result::OK))); + const bool kSuspend = false; + config_.suspend_below_min_bitrate = kSuspend; + config_.rtp.extensions.emplace_back( + RtpExtension::kTransportSequenceNumberUri, 1); + VideoStream qvga_stream; + qvga_stream.width = 320; + qvga_stream.height = 180; + qvga_stream.max_framerate = 30; + qvga_stream.min_bitrate_bps = 30000; + qvga_stream.target_bitrate_bps = 150000; + qvga_stream.max_bitrate_bps = 200000; + qvga_stream.max_qp = 56; + qvga_stream.bitrate_priority = 1; - int min_transmit_bitrate_bps = 30000; + int min_transmit_bitrate_bps = 30000; - config_.rtp.ssrcs.emplace_back(1); + config_.rtp.ssrcs.emplace_back(1); - vss_impl->Start(); + vss_impl->Start(); - // Starts without padding. - EXPECT_EQ(0, padding_bitrate); + // Starts without padding. + EXPECT_EQ(0, padding_bitrate); - // Reconfigure e.g. due to a fake frame. - static_cast(vss_impl.get()) - ->OnEncoderConfigurationChanged( - std::vector{qvga_stream}, - VideoEncoderConfig::ContentType::kRealtimeVideo, - min_transmit_bitrate_bps); - // Still no padding because no actual frames were passed, only - // reconfiguration happened. - EXPECT_EQ(0, padding_bitrate); + // Reconfigure e.g. due to a fake frame. + static_cast(vss_impl.get()) + ->OnEncoderConfigurationChanged( + std::vector{qvga_stream}, + VideoEncoderConfig::ContentType::kRealtimeVideo, + min_transmit_bitrate_bps); + // Still no padding because no actual frames were passed, only + // reconfiguration happened. + EXPECT_EQ(0, padding_bitrate); - // Unpause encoder. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); + // Unpause encoder. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - // A frame is encoded. - EncodedImage encoded_image; - CodecSpecificInfo codec_specific; - static_cast(vss_impl.get()) - ->OnEncodedImage(encoded_image, &codec_specific, nullptr); - // Only after actual frame is encoded are we enabling the padding. - EXPECT_GT(padding_bitrate, 0); - }); + // A frame is encoded. + EncodedImage encoded_image; + CodecSpecificInfo codec_specific; + static_cast(vss_impl.get()) + ->OnEncodedImage(encoded_image, &codec_specific, nullptr); + // Only after actual frame is encoded are we enabling the padding. + EXPECT_GT(padding_bitrate, 0); + }, + RTC_FROM_HERE); rtc::Event done; test_queue_.PostDelayedTask(