mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-15 23:01:21 +01:00

This CL removes direct access to SendSideCongestionController (SSCC) via the RtpTransportControllerSend interface and replaces all usages with calls on RtpTransportControllerSend which will in turn calls SSCC. This prepares for later refactor of RtpTransportControllerSend. Bug: webrtc:8415 Change-Id: I68363a3ab0203b95579f747402a1e7f58a5eeeb5 Reviewed-on: https://webrtc-review.googlesource.com/53860 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22044}
494 lines
19 KiB
C++
494 lines
19 KiB
C++
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
|
#include "modules/bitrate_controller/include/bitrate_controller.h"
|
|
#include "modules/congestion_controller/congestion_controller_unittests_helper.h"
|
|
#include "modules/congestion_controller/include/mock/mock_congestion_observer.h"
|
|
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
|
|
#include "modules/pacing/mock/mock_paced_sender.h"
|
|
#include "modules/pacing/packet_router.h"
|
|
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
|
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
|
|
#include "rtc_base/socket.h"
|
|
#include "system_wrappers/include/clock.h"
|
|
#include "test/field_trial.h"
|
|
#include "test/gmock.h"
|
|
#include "test/gtest.h"
|
|
|
|
using testing::_;
|
|
using testing::AtLeast;
|
|
using testing::Ge;
|
|
using testing::NiceMock;
|
|
using testing::Return;
|
|
using testing::SaveArg;
|
|
using testing::StrictMock;
|
|
|
|
namespace webrtc {
|
|
|
|
namespace {
|
|
const webrtc::PacedPacketInfo kPacingInfo0(0, 5, 2000);
|
|
const webrtc::PacedPacketInfo kPacingInfo1(1, 8, 4000);
|
|
|
|
const uint32_t kInitialBitrateBps = 60000;
|
|
|
|
} // namespace
|
|
|
|
namespace test {
|
|
|
|
class SendSideCongestionControllerTest : public ::testing::Test {
|
|
protected:
|
|
SendSideCongestionControllerTest()
|
|
: clock_(123456), target_bitrate_observer_(this) {}
|
|
~SendSideCongestionControllerTest() override {}
|
|
|
|
void SetUp() override {
|
|
pacer_.reset(new NiceMock<MockPacedSender>());
|
|
controller_.reset(new SendSideCongestionController(
|
|
&clock_, &observer_, &event_log_, pacer_.get()));
|
|
bandwidth_observer_ = controller_->GetBandwidthObserver();
|
|
|
|
// Set the initial bitrate estimate and expect the |observer| and |pacer_|
|
|
// to be updated.
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps));
|
|
EXPECT_CALL(*pacer_, CreateProbeCluster(kInitialBitrateBps * 3));
|
|
EXPECT_CALL(*pacer_, CreateProbeCluster(kInitialBitrateBps * 5));
|
|
controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps);
|
|
}
|
|
|
|
// Custom setup - use an observer that tracks the target bitrate, without
|
|
// prescribing on which iterations it must change (like a mock would).
|
|
void TargetBitrateTrackingSetup() {
|
|
pacer_.reset(new NiceMock<MockPacedSender>());
|
|
controller_.reset(new SendSideCongestionController(
|
|
&clock_, &target_bitrate_observer_, &event_log_, pacer_.get()));
|
|
controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps);
|
|
}
|
|
|
|
void OnSentPacket(const PacketFeedback& packet_feedback) {
|
|
constexpr uint32_t ssrc = 0;
|
|
controller_->AddPacket(ssrc, packet_feedback.sequence_number,
|
|
packet_feedback.payload_size,
|
|
packet_feedback.pacing_info);
|
|
controller_->OnSentPacket(rtc::SentPacket(packet_feedback.sequence_number,
|
|
packet_feedback.send_time_ms));
|
|
}
|
|
|
|
// Allows us to track the target bitrate, without prescribing the exact
|
|
// iterations when this would hapen, like a mock would.
|
|
class TargetBitrateObserver : public NetworkChangedObserver {
|
|
public:
|
|
explicit TargetBitrateObserver(SendSideCongestionControllerTest* owner)
|
|
: owner_(owner) {}
|
|
~TargetBitrateObserver() override = default;
|
|
void OnNetworkChanged(uint32_t bitrate_bps,
|
|
uint8_t fraction_loss, // 0 - 255.
|
|
int64_t rtt_ms,
|
|
int64_t probing_interval_ms) override {
|
|
owner_->target_bitrate_bps_ = bitrate_bps;
|
|
}
|
|
|
|
private:
|
|
SendSideCongestionControllerTest* owner_;
|
|
};
|
|
|
|
void PacketTransmissionAndFeedbackBlock(uint16_t* seq_num,
|
|
int64_t runtime_ms,
|
|
int64_t delay) {
|
|
int64_t delay_buildup = 0;
|
|
int64_t start_time_ms = clock_.TimeInMilliseconds();
|
|
while (clock_.TimeInMilliseconds() - start_time_ms < runtime_ms) {
|
|
constexpr size_t kPayloadSize = 1000;
|
|
PacketFeedback packet(clock_.TimeInMilliseconds() + delay_buildup,
|
|
clock_.TimeInMilliseconds(), *seq_num, kPayloadSize,
|
|
PacedPacketInfo());
|
|
delay_buildup += delay; // Delay has to increase, or it's just RTT.
|
|
OnSentPacket(packet);
|
|
// Create expected feedback and send into adapter.
|
|
std::unique_ptr<rtcp::TransportFeedback> feedback(
|
|
new rtcp::TransportFeedback());
|
|
feedback->SetBase(packet.sequence_number, packet.arrival_time_ms * 1000);
|
|
EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number,
|
|
packet.arrival_time_ms * 1000));
|
|
rtc::Buffer raw_packet = feedback->Build();
|
|
feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(),
|
|
raw_packet.size());
|
|
EXPECT_TRUE(feedback.get() != nullptr);
|
|
controller_->OnTransportFeedback(*feedback.get());
|
|
clock_.AdvanceTimeMilliseconds(50);
|
|
controller_->Process();
|
|
++(*seq_num);
|
|
}
|
|
}
|
|
|
|
SimulatedClock clock_;
|
|
StrictMock<MockCongestionObserver> observer_;
|
|
TargetBitrateObserver target_bitrate_observer_;
|
|
NiceMock<MockRtcEventLog> event_log_;
|
|
RtcpBandwidthObserver* bandwidth_observer_;
|
|
PacketRouter packet_router_;
|
|
std::unique_ptr<NiceMock<MockPacedSender>> pacer_;
|
|
std::unique_ptr<SendSideCongestionController> controller_;
|
|
|
|
rtc::Optional<uint32_t> target_bitrate_bps_;
|
|
};
|
|
|
|
TEST_F(SendSideCongestionControllerTest, OnNetworkChanged) {
|
|
// Test no change.
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 2, _, _, _));
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps * 2));
|
|
bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2);
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps));
|
|
bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps);
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, OnSendQueueFull) {
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(PacedSender::kMaxQueueLengthMs + 1));
|
|
|
|
EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _));
|
|
controller_->Process();
|
|
|
|
// Let the pacer not be full next time the controller checks.
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(PacedSender::kMaxQueueLengthMs - 1));
|
|
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
|
|
controller_->Process();
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, OnSendQueueFullAndEstimateChange) {
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(PacedSender::kMaxQueueLengthMs + 1));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _));
|
|
controller_->Process();
|
|
|
|
// Receive new estimate but let the queue still be full.
|
|
bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2);
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(PacedSender::kMaxQueueLengthMs + 1));
|
|
// The send pacer should get the new estimate though.
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps * 2));
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
|
|
// Let the pacer not be full next time the controller checks.
|
|
// |OnNetworkChanged| should be called with the new estimate.
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(PacedSender::kMaxQueueLengthMs - 1));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 2, _, _, _));
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, SignalNetworkState) {
|
|
EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _));
|
|
controller_->SignalNetworkState(kNetworkDown);
|
|
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
|
|
controller_->SignalNetworkState(kNetworkUp);
|
|
|
|
EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _));
|
|
controller_->SignalNetworkState(kNetworkDown);
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, OnNetworkRouteChanged) {
|
|
int new_bitrate = 200000;
|
|
testing::Mock::VerifyAndClearExpectations(pacer_.get());
|
|
EXPECT_CALL(observer_, OnNetworkChanged(new_bitrate, _, _, _));
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(new_bitrate));
|
|
rtc::NetworkRoute route;
|
|
route.local_network_id = 1;
|
|
controller_->OnNetworkRouteChanged(route, new_bitrate, -1, -1);
|
|
|
|
// If the bitrate is reset to -1, the new starting bitrate will be
|
|
// the minimum default bitrate kMinBitrateBps.
|
|
EXPECT_CALL(
|
|
observer_,
|
|
OnNetworkChanged(congestion_controller::GetMinBitrateBps(), _, _, _));
|
|
EXPECT_CALL(*pacer_,
|
|
SetEstimatedBitrate(congestion_controller::GetMinBitrateBps()));
|
|
route.local_network_id = 2;
|
|
controller_->OnNetworkRouteChanged(route, -1, -1, -1);
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, OldFeedback) {
|
|
int new_bitrate = 200000;
|
|
testing::Mock::VerifyAndClearExpectations(pacer_.get());
|
|
EXPECT_CALL(observer_, OnNetworkChanged(new_bitrate, _, _, _));
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(new_bitrate));
|
|
|
|
// Send a few packets on the first network route.
|
|
std::vector<PacketFeedback> packets;
|
|
packets.push_back(PacketFeedback(0, 0, 0, 1500, kPacingInfo0));
|
|
packets.push_back(PacketFeedback(10, 10, 1, 1500, kPacingInfo0));
|
|
packets.push_back(PacketFeedback(20, 20, 2, 1500, kPacingInfo0));
|
|
packets.push_back(PacketFeedback(30, 30, 3, 1500, kPacingInfo1));
|
|
packets.push_back(PacketFeedback(40, 40, 4, 1500, kPacingInfo1));
|
|
|
|
for (const PacketFeedback& packet : packets)
|
|
OnSentPacket(packet);
|
|
|
|
// Change route and then insert a number of feedback packets.
|
|
rtc::NetworkRoute route;
|
|
route.local_network_id = 1;
|
|
controller_->OnNetworkRouteChanged(route, new_bitrate, -1, -1);
|
|
|
|
for (const PacketFeedback& packet : packets) {
|
|
rtcp::TransportFeedback feedback;
|
|
feedback.SetBase(packet.sequence_number, packet.arrival_time_ms * 1000);
|
|
|
|
EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
|
|
packet.arrival_time_ms * 1000));
|
|
feedback.Build();
|
|
controller_->OnTransportFeedback(feedback);
|
|
}
|
|
|
|
// If the bitrate is reset to -1, the new starting bitrate will be
|
|
// the minimum default bitrate kMinBitrateBps.
|
|
EXPECT_CALL(
|
|
observer_,
|
|
OnNetworkChanged(congestion_controller::GetMinBitrateBps(), _, _, _));
|
|
EXPECT_CALL(*pacer_,
|
|
SetEstimatedBitrate(congestion_controller::GetMinBitrateBps()));
|
|
route.local_network_id = 2;
|
|
controller_->OnNetworkRouteChanged(route, -1, -1, -1);
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest,
|
|
SignalNetworkStateAndQueueIsFullAndEstimateChange) {
|
|
// Send queue is full
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillRepeatedly(Return(PacedSender::kMaxQueueLengthMs + 1));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _));
|
|
controller_->Process();
|
|
|
|
// Queue is full and network is down. Expect no bitrate change.
|
|
controller_->SignalNetworkState(kNetworkDown);
|
|
controller_->Process();
|
|
|
|
// Queue is full but network is up. Expect no bitrate change.
|
|
controller_->SignalNetworkState(kNetworkUp);
|
|
controller_->Process();
|
|
|
|
// Receive new estimate but let the queue still be full.
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(kInitialBitrateBps * 2));
|
|
bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2);
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
|
|
// Let the pacer not be full next time the controller checks.
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(PacedSender::kMaxQueueLengthMs - 1));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 2, _, _, _));
|
|
controller_->Process();
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, GetPacerQueuingDelayMs) {
|
|
EXPECT_CALL(observer_, OnNetworkChanged(_, _, _, _)).Times(AtLeast(1));
|
|
|
|
const int64_t kQueueTimeMs = 123;
|
|
EXPECT_CALL(*pacer_, QueueInMs()).WillRepeatedly(Return(kQueueTimeMs));
|
|
EXPECT_EQ(kQueueTimeMs, controller_->GetPacerQueuingDelayMs());
|
|
|
|
// Expect zero pacer delay when network is down.
|
|
controller_->SignalNetworkState(kNetworkDown);
|
|
EXPECT_EQ(0, controller_->GetPacerQueuingDelayMs());
|
|
|
|
// Network is up, pacer delay should be reported.
|
|
controller_->SignalNetworkState(kNetworkUp);
|
|
EXPECT_EQ(kQueueTimeMs, controller_->GetPacerQueuingDelayMs());
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, GetProbingInterval) {
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(observer_, OnNetworkChanged(_, _, _, testing::Ne(0)));
|
|
EXPECT_CALL(*pacer_, SetEstimatedBitrate(_));
|
|
bandwidth_observer_->OnReceivedEstimatedBitrate(kInitialBitrateBps * 2);
|
|
clock_.AdvanceTimeMilliseconds(25);
|
|
controller_->Process();
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, ProbeOnRouteChange) {
|
|
testing::Mock::VerifyAndClearExpectations(pacer_.get());
|
|
EXPECT_CALL(*pacer_, CreateProbeCluster(kInitialBitrateBps * 6));
|
|
EXPECT_CALL(*pacer_, CreateProbeCluster(kInitialBitrateBps * 12));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 2, _, _, _));
|
|
rtc::NetworkRoute route;
|
|
route.local_network_id = 1;
|
|
controller_->OnNetworkRouteChanged(route, 2 * kInitialBitrateBps, 0,
|
|
20 * kInitialBitrateBps);
|
|
}
|
|
|
|
// Estimated bitrate reduced when the feedbacks arrive with such a long delay,
|
|
// that the send-time-history no longer holds the feedbacked packets.
|
|
TEST_F(SendSideCongestionControllerTest, LongFeedbackDelays) {
|
|
TargetBitrateTrackingSetup();
|
|
|
|
const int64_t kFeedbackTimeoutMs = 60001;
|
|
const int kMaxConsecutiveFailedLookups = 5;
|
|
for (int i = 0; i < kMaxConsecutiveFailedLookups; ++i) {
|
|
std::vector<PacketFeedback> packets;
|
|
packets.push_back(
|
|
PacketFeedback(i * 100, 2 * i * 100, 0, 1500, kPacingInfo0));
|
|
packets.push_back(
|
|
PacketFeedback(i * 100 + 10, 2 * i * 100 + 10, 1, 1500, kPacingInfo0));
|
|
packets.push_back(
|
|
PacketFeedback(i * 100 + 20, 2 * i * 100 + 20, 2, 1500, kPacingInfo0));
|
|
packets.push_back(
|
|
PacketFeedback(i * 100 + 30, 2 * i * 100 + 30, 3, 1500, kPacingInfo1));
|
|
packets.push_back(
|
|
PacketFeedback(i * 100 + 40, 2 * i * 100 + 40, 4, 1500, kPacingInfo1));
|
|
|
|
for (const PacketFeedback& packet : packets)
|
|
OnSentPacket(packet);
|
|
|
|
rtcp::TransportFeedback feedback;
|
|
feedback.SetBase(packets[0].sequence_number,
|
|
packets[0].arrival_time_ms * 1000);
|
|
|
|
for (const PacketFeedback& packet : packets) {
|
|
EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
|
|
packet.arrival_time_ms * 1000));
|
|
}
|
|
|
|
feedback.Build();
|
|
|
|
clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs);
|
|
PacketFeedback later_packet(kFeedbackTimeoutMs + i * 100 + 40,
|
|
kFeedbackTimeoutMs + i * 200 + 40, 5, 1500,
|
|
kPacingInfo1);
|
|
OnSentPacket(later_packet);
|
|
|
|
controller_->OnTransportFeedback(feedback);
|
|
|
|
// Check that packets have timed out.
|
|
for (PacketFeedback& packet : packets) {
|
|
packet.send_time_ms = PacketFeedback::kNoSendTime;
|
|
packet.payload_size = 0;
|
|
packet.pacing_info = PacedPacketInfo();
|
|
}
|
|
ComparePacketFeedbackVectors(packets,
|
|
controller_->GetTransportFeedbackVector());
|
|
}
|
|
|
|
controller_->Process();
|
|
|
|
EXPECT_EQ(kInitialBitrateBps / 2, target_bitrate_bps_);
|
|
|
|
// Test with feedback that isn't late enough to time out.
|
|
{
|
|
std::vector<PacketFeedback> packets;
|
|
packets.push_back(PacketFeedback(100, 200, 0, 1500, kPacingInfo0));
|
|
packets.push_back(PacketFeedback(110, 210, 1, 1500, kPacingInfo0));
|
|
packets.push_back(PacketFeedback(120, 220, 2, 1500, kPacingInfo0));
|
|
packets.push_back(PacketFeedback(130, 230, 3, 1500, kPacingInfo1));
|
|
packets.push_back(PacketFeedback(140, 240, 4, 1500, kPacingInfo1));
|
|
|
|
for (const PacketFeedback& packet : packets)
|
|
OnSentPacket(packet);
|
|
|
|
rtcp::TransportFeedback feedback;
|
|
feedback.SetBase(packets[0].sequence_number,
|
|
packets[0].arrival_time_ms * 1000);
|
|
|
|
for (const PacketFeedback& packet : packets) {
|
|
EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
|
|
packet.arrival_time_ms * 1000));
|
|
}
|
|
|
|
feedback.Build();
|
|
|
|
clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs - 1);
|
|
PacketFeedback later_packet(kFeedbackTimeoutMs + 140,
|
|
kFeedbackTimeoutMs + 240, 5, 1500,
|
|
kPacingInfo1);
|
|
OnSentPacket(later_packet);
|
|
|
|
controller_->OnTransportFeedback(feedback);
|
|
ComparePacketFeedbackVectors(packets,
|
|
controller_->GetTransportFeedbackVector());
|
|
}
|
|
}
|
|
|
|
// Bandwidth estimation is updated when feedbacks are received.
|
|
// Feedbacks which show an increasing delay cause the estimation to be reduced.
|
|
TEST_F(SendSideCongestionControllerTest, UpdatesDelayBasedEstimate) {
|
|
TargetBitrateTrackingSetup();
|
|
|
|
const int64_t kRunTimeMs = 6000;
|
|
uint16_t seq_num = 0;
|
|
|
|
// The test must run and insert packets/feedback long enough that the
|
|
// BWE computes a valid estimate. This is first done in an environment which
|
|
// simulates no bandwidth limitation, and therefore not built-up delay.
|
|
PacketTransmissionAndFeedbackBlock(&seq_num, kRunTimeMs, 0);
|
|
ASSERT_TRUE(target_bitrate_bps_);
|
|
|
|
// Repeat, but this time with a building delay, and make sure that the
|
|
// estimation is adjusted downwards.
|
|
uint32_t bitrate_before_delay = *target_bitrate_bps_;
|
|
PacketTransmissionAndFeedbackBlock(&seq_num, kRunTimeMs, 50);
|
|
EXPECT_LT(*target_bitrate_bps_, bitrate_before_delay);
|
|
}
|
|
|
|
TEST_F(SendSideCongestionControllerTest, PacerQueueEncodeRatePushback) {
|
|
ScopedFieldTrials pushback_field_trial(
|
|
"WebRTC-PacerPushbackExperiment/Enabled/");
|
|
SetUp();
|
|
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0));
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(100));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 0.9, _, _, _));
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(50));
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
|
|
controller_->Process();
|
|
|
|
const uint32_t kMinAdjustedBps = 50000;
|
|
int expected_queue_threshold =
|
|
1000 - kMinAdjustedBps * 1000.0 / kInitialBitrateBps;
|
|
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(expected_queue_threshold));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(Ge(kMinAdjustedBps), _, _, _));
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
|
|
.WillOnce(Return(expected_queue_threshold + 1));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _));
|
|
controller_->Process();
|
|
|
|
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0));
|
|
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
|
|
controller_->Process();
|
|
}
|
|
|
|
} // namespace test
|
|
} // namespace webrtc
|