Include pacing buffer size in congestion window.

Bug: webrtc:10171
Change-Id: I9e21880a8b6f325415b62397081c301ee904f2ea
Reviewed-on: https://webrtc-review.googlesource.com/c/116068
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Commit-Queue: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26175}
This commit is contained in:
Christoffer Rodbro 2019-01-08 10:49:19 +01:00 committed by Commit Bot
parent 9c277dd1dd
commit c610e26be5
10 changed files with 80 additions and 6 deletions

View File

@ -81,4 +81,8 @@ bool PacedPacketInfo::operator==(const PacedPacketInfo& rhs) const {
probe_cluster_min_bytes == rhs.probe_cluster_min_bytes;
}
ProcessInterval::ProcessInterval() = default;
ProcessInterval::ProcessInterval(const ProcessInterval&) = default;
ProcessInterval::~ProcessInterval() = default;
} // namespace webrtc

View File

@ -202,7 +202,11 @@ struct NetworkControlUpdate {
// Process control
struct ProcessInterval {
ProcessInterval();
ProcessInterval(const ProcessInterval&);
~ProcessInterval();
Timestamp at_time = Timestamp::PlusInfinity();
absl::optional<DataSize> pacer_queue;
};
} // namespace webrtc

View File

@ -130,6 +130,8 @@ RtpTransportControllerSend::RtpTransportControllerSend(
!field_trial::IsEnabled("WebRTC-Bwe-NoFeedbackReset")),
send_side_bwe_with_overhead_(
webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
add_pacing_to_cwin_(
field_trial::IsEnabled("WebRTC-AddPacingToCongestionWindowPushback")),
transport_overhead_bytes_per_packet_(0),
network_available_(false),
packet_feedback_available_(false),
@ -600,6 +602,8 @@ void RtpTransportControllerSend::UpdateControllerWithTimeInterval() {
RTC_DCHECK(controller_);
ProcessInterval msg;
msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
if (add_pacing_to_cwin_)
msg.pacer_queue = DataSize::bytes(pacer_.QueueSizeBytes());
PostUpdates(controller_->OnProcessInterval(msg));
}

View File

@ -174,6 +174,7 @@ class RtpTransportControllerSend final
const bool reset_feedback_on_route_change_;
const bool send_side_bwe_with_overhead_;
const bool add_pacing_to_cwin_;
// Transport overhead is written by OnNetworkRouteChanged and read by
// AddPacket.
// TODO(srte): Remove atomic when feedback adapter runs on task queue.

View File

@ -19,6 +19,8 @@
namespace webrtc {
namespace {
// When CongestionWindowPushback is enabled, the pacer is oblivious to
// the congestion window. The relation between outstanding data and
// the congestion window affects encoder allocations directly.
@ -41,7 +43,11 @@ bool ReadCongestionWindowPushbackExperimentParameter(
return false;
}
CongestionWindowPushbackController::CongestionWindowPushbackController() {
} // namespace
CongestionWindowPushbackController::CongestionWindowPushbackController()
: add_pacing_(field_trial::IsEnabled(
"WebRTC-AddPacingToCongestionWindowPushback")) {
if (!ReadCongestionWindowPushbackExperimentParameter(
&min_pushback_target_bitrate_bps_)) {
min_pushback_target_bitrate_bps_ = kDefaultMinPushbackTargetBitrateBps;
@ -50,12 +56,18 @@ CongestionWindowPushbackController::CongestionWindowPushbackController() {
CongestionWindowPushbackController::CongestionWindowPushbackController(
uint32_t min_pushback_target_bitrate_bps)
: min_pushback_target_bitrate_bps_(min_pushback_target_bitrate_bps) {}
: add_pacing_(
field_trial::IsEnabled("WebRTC-AddPacingToCongestionWindowPushback")),
min_pushback_target_bitrate_bps_(min_pushback_target_bitrate_bps) {}
void CongestionWindowPushbackController::UpdateOutstandingData(
size_t outstanding_bytes) {
int64_t outstanding_bytes) {
outstanding_bytes_ = outstanding_bytes;
}
void CongestionWindowPushbackController::UpdatePacingQueue(
int64_t pacing_bytes) {
pacing_bytes_ = pacing_bytes;
}
void CongestionWindowPushbackController::UpdateMaxOutstandingData(
size_t max_outstanding_bytes) {
@ -74,8 +86,11 @@ uint32_t CongestionWindowPushbackController::UpdateTargetBitrate(
uint32_t bitrate_bps) {
if (!current_data_window_ || current_data_window_->IsZero())
return bitrate_bps;
int64_t total_bytes = outstanding_bytes_;
if (add_pacing_)
total_bytes += pacing_bytes_;
double fill_ratio =
outstanding_bytes_ / static_cast<double>(current_data_window_->bytes());
total_bytes / static_cast<double>(current_data_window_->bytes());
if (fill_ratio > 1.5) {
encoding_rate_ratio_ *= 0.9;
} else if (fill_ratio > 1) {

View File

@ -29,14 +29,17 @@ class CongestionWindowPushbackController {
CongestionWindowPushbackController();
explicit CongestionWindowPushbackController(
uint32_t min_pushback_target_bitrate_bps);
void UpdateOutstandingData(size_t outstanding_bytes);
void UpdateOutstandingData(int64_t outstanding_bytes);
void UpdatePacingQueue(int64_t pacing_bytes);
void UpdateMaxOutstandingData(size_t max_outstanding_bytes);
uint32_t UpdateTargetBitrate(uint32_t bitrate_bps);
void SetDataWindow(DataSize data_window);
private:
absl::optional<DataSize> current_data_window_;
size_t outstanding_bytes_ = 0;
int64_t outstanding_bytes_ = 0;
int64_t pacing_bytes_ = 0;
const bool add_pacing_;
uint32_t min_pushback_target_bitrate_bps_;
double encoding_rate_ratio_ = 1.0;
};

View File

@ -275,6 +275,10 @@ NetworkControlUpdate GoogCcNetworkController::OnProcessInterval(
bandwidth_estimation_->UpdateDelayBasedEstimate(
msg.at_time, delay_based_controller_->target_rate());
}
if (congestion_window_pushback_controller_ && msg.pacer_queue) {
congestion_window_pushback_controller_->UpdatePacingQueue(
msg.pacer_queue->bytes());
}
bandwidth_estimation_->UpdateEstimate(msg.at_time);
absl::optional<int64_t> start_time_ms =
alr_detector_->GetApplicationLimitedRegionStartTime();

View File

@ -114,5 +114,37 @@ TEST(GoogCcNetworkControllerTest, DetectsHighRateInSafeResetTrial) {
EXPECT_GT(client->send_bandwidth().kbps(), kNewLinkCapacity.kbps() - 300);
}
TEST(GoogCcNetworkControllerTest,
TargetRateReducedOnPacingBufferBuildupInTrial) {
// Configure strict pacing to ensure build-up.
ScopedFieldTrials trial(
"WebRTC-CongestionWindowPushback/Enabled/WebRTC-CwndExperiment/"
"Enabled-100/WebRTC-Video-Pacing/factor:1.0/"
"WebRTC-AddPacingToCongestionWindowPushback/Enabled/");
const DataRate kLinkCapacity = DataRate::kbps(1000);
const DataRate kStartRate = DataRate::kbps(1000);
Scenario s("googcc_unit/pacing_buffer_buildup", true);
auto* net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
c->simulation.bandwidth = kLinkCapacity;
c->simulation.delay = TimeDelta::ms(50);
});
// TODO(srte): replace with SimulatedTimeClient when it supports pacing.
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
c->transport.rates.start_rate = kStartRate;
});
auto* route = s.CreateRoutes(client, {net},
s.CreateClient("return", CallClientConfig()),
{s.CreateSimulationNode(NetworkNodeConfig())});
s.CreateVideoStream(route->forward(), VideoStreamConfig());
// Allow some time for the buffer to build up.
s.RunFor(TimeDelta::seconds(5));
// Without trial, pacer delay reaches ~250 ms.
EXPECT_LT(client->GetStats().pacer_delay_ms, 150);
}
} // namespace test
} // namespace webrtc

View File

@ -232,6 +232,11 @@ size_t PacedSender::QueueSizePackets() const {
return packets_.SizeInPackets();
}
int64_t PacedSender::QueueSizeBytes() const {
rtc::CritScope cs(&critsect_);
return packets_.SizeInBytes();
}
int64_t PacedSender::FirstSentPacketTimeMs() const {
rtc::CritScope cs(&critsect_);
return first_sent_packet_ms_;

View File

@ -13,6 +13,7 @@
#include <stddef.h>
#include <stdint.h>
#include <atomic>
#include <memory>
#include "absl/types/optional.h"
@ -118,6 +119,7 @@ class PacedSender : public Pacer {
virtual int64_t QueueInMs() const;
virtual size_t QueueSizePackets() const;
virtual int64_t QueueSizeBytes() const;
// Returns the time when the first packet was sent, or -1 if no packet is
// sent.