Adds debug printing for congestion controllers.

These are useful for plotting creating data files that can be used to
visualize and debug congestion controller behavior.

Bug: webrtc:9467
Change-Id: I75b03a309b4b7d562fefe82a828ae1e6a9f069c8
Reviewed-on: https://webrtc-review.googlesource.com/86126
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23822}
This commit is contained in:
Sebastian Jansson
2018-07-03 18:11:45 +02:00
committed by Commit Bot
parent d000b0a32e
commit 13171bdba8
13 changed files with 380 additions and 5 deletions

View File

@ -76,6 +76,21 @@ rtc_static_library("transport_feedback") {
}
if (rtc_include_tests) {
rtc_source_set("test_controller_printer") {
testonly = true
sources = [
"test/controller_printer.cc",
"test/controller_printer.h",
]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
deps = [
"../../api/transport:network_control",
"../../rtc_base:checks",
]
}
rtc_source_set("congestion_controller_unittests") {
testonly = true

View File

@ -113,6 +113,18 @@ rtc_source_set("windowed_filter") {
]
}
if (rtc_include_tests) {
rtc_source_set("test_bbr_printer") {
testonly = true
sources = [
"test/bbr_printer.cc",
"test/bbr_printer.h",
]
deps = [
":bbr",
":bbr_controller",
"..:test_controller_printer",
]
}
rtc_source_set("bbr_unittests") {
testonly = true
sources = [

View File

@ -237,7 +237,8 @@ void BbrNetworkController::Reset() {
}
}
NetworkControlUpdate BbrNetworkController::CreateRateUpdate(Timestamp at_time) {
NetworkControlUpdate BbrNetworkController::CreateRateUpdate(
Timestamp at_time) const {
DataRate bandwidth = BandwidthEstimate();
if (bandwidth.IsZero())
bandwidth = default_bandwidth_;

View File

@ -165,10 +165,10 @@ class BbrNetworkController : public NetworkControllerInterface {
NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override;
NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override;
NetworkControlUpdate CreateRateUpdate(Timestamp at_time) const;
private:
void Reset();
NetworkControlUpdate CreateRateUpdate(Timestamp at_time);
bool InSlowStart() const;
bool InRecovery() const;
bool IsProbingForMoreBandwidth() const;

View File

@ -0,0 +1,57 @@
/*
* Copyright 2018 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 "modules/congestion_controller/bbr/test/bbr_printer.h"
namespace webrtc {
BbrStatePrinter::BbrStatePrinter() = default;
BbrStatePrinter::~BbrStatePrinter() = default;
void BbrStatePrinter::Attach(bbr::BbrNetworkController* controller) {
controller_ = controller;
}
bool BbrStatePrinter::Attached() const {
return controller_ != nullptr;
}
void BbrStatePrinter::PrintHeaders(FILE* out) {
fprintf(out, "bbr_mode bbr_recovery_state round_trip_count gain_cycle_index");
}
void BbrStatePrinter::PrintValues(FILE* out) {
RTC_CHECK(controller_);
bbr::BbrNetworkController::DebugState debug(*controller_);
fprintf(out, "%i %i %i %i", debug.mode, debug.recovery_state,
static_cast<int>(debug.round_trip_count), debug.gain_cycle_index);
}
NetworkControlUpdate BbrStatePrinter::GetState(Timestamp at_time) const {
RTC_CHECK(controller_);
return controller_->CreateRateUpdate(at_time);
}
BbrDebugFactory::BbrDebugFactory(BbrStatePrinter* printer)
: printer_(printer) {}
std::unique_ptr<NetworkControllerInterface> BbrDebugFactory::Create(
NetworkControllerConfig config) {
RTC_CHECK(controller_ == nullptr);
auto controller = BbrNetworkControllerFactory::Create(config);
controller_ = static_cast<bbr::BbrNetworkController*>(controller.get());
printer_->Attach(controller_);
return controller;
}
bbr::BbrNetworkController* BbrDebugFactory::BbrController() {
return controller_;
}
} // namespace webrtc

View File

@ -0,0 +1,49 @@
/*
* Copyright 2018 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.
*/
#ifndef MODULES_CONGESTION_CONTROLLER_BBR_TEST_BBR_PRINTER_H_
#define MODULES_CONGESTION_CONTROLLER_BBR_TEST_BBR_PRINTER_H_
#include <memory>
#include "modules/congestion_controller/bbr/bbr_factory.h"
#include "modules/congestion_controller/bbr/bbr_network_controller.h"
#include "modules/congestion_controller/test/controller_printer.h"
namespace webrtc {
class BbrStatePrinter : public DebugStatePrinter {
public:
BbrStatePrinter();
~BbrStatePrinter() override;
void Attach(bbr::BbrNetworkController*);
bool Attached() const override;
void PrintHeaders(FILE* out) override;
void PrintValues(FILE* out) override;
NetworkControlUpdate GetState(Timestamp at_time) const override;
private:
bbr::BbrNetworkController* controller_ = nullptr;
};
class BbrDebugFactory : public BbrNetworkControllerFactory {
public:
explicit BbrDebugFactory(BbrStatePrinter* printer);
std::unique_ptr<NetworkControllerInterface> Create(
NetworkControllerConfig config) override;
bbr::BbrNetworkController* BbrController();
private:
BbrStatePrinter* printer_;
bbr::BbrNetworkController* controller_ = nullptr;
};
} // namespace webrtc
#endif // MODULES_CONGESTION_CONTROLLER_BBR_TEST_BBR_PRINTER_H_

View File

@ -143,6 +143,17 @@ rtc_source_set("delay_based_bwe") {
}
if (rtc_include_tests) {
rtc_source_set("test_goog_cc_printer") {
testonly = true
sources = [
"test/goog_cc_printer.cc",
"test/goog_cc_printer.h",
]
deps = [
":goog_cc",
"..:test_controller_printer",
]
}
rtc_source_set("goog_cc_unittests") {
testonly = true

View File

@ -336,6 +336,26 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
return update;
}
NetworkControlUpdate GoogCcNetworkController::GetNetworkState(
Timestamp at_time) const {
DataRate bandwidth = DataRate::bps(last_estimated_bitrate_bps_);
TimeDelta rtt = TimeDelta::ms(last_estimated_rtt_ms_);
NetworkControlUpdate update;
update.target_rate = TargetTransferRate();
update.target_rate->network_estimate.at_time = at_time;
update.target_rate->network_estimate.bandwidth = bandwidth;
update.target_rate->network_estimate.loss_rate_ratio =
last_estimated_fraction_loss_ / 255.0;
update.target_rate->network_estimate.round_trip_time = rtt;
update.target_rate->network_estimate.bwe_period =
TimeDelta::ms(delay_based_bwe_->GetExpectedBwePeriodMs());
update.target_rate->at_time = at_time;
update.target_rate->target_rate = bandwidth;
update.pacer_config = UpdatePacingRates(at_time);
update.congestion_window = current_data_window_;
return update;
}
absl::optional<DataSize>
GoogCcNetworkController::MaybeUpdateCongestionWindow() {
if (!in_cwnd_experiment_)
@ -432,7 +452,8 @@ NetworkControlUpdate GoogCcNetworkController::OnNetworkEstimate(
return update;
}
PacerConfig GoogCcNetworkController::UpdatePacingRates(Timestamp at_time) {
PacerConfig GoogCcNetworkController::UpdatePacingRates(
Timestamp at_time) const {
DataRate pacing_rate =
std::max(min_pacing_rate_, last_bandwidth_) * pacing_factor_;
DataRate padding_rate = std::min(max_padding_rate_, last_bandwidth_);

View File

@ -49,6 +49,8 @@ class GoogCcNetworkController : public NetworkControllerInterface {
NetworkControlUpdate OnTransportPacketsFeedback(
TransportPacketsFeedback msg) override;
NetworkControlUpdate GetNetworkState(Timestamp at_time) const;
private:
void UpdateBitrateConstraints(TargetRateConstraints constraints,
absl::optional<DataRate> starting_rate);
@ -59,7 +61,7 @@ class GoogCcNetworkController : public NetworkControllerInterface {
int64_t* rtt_ms,
Timestamp at_time);
NetworkControlUpdate OnNetworkEstimate(NetworkEstimate msg);
PacerConfig UpdatePacingRates(Timestamp at_time);
PacerConfig UpdatePacingRates(Timestamp at_time) const;
RtcEventLog* const event_log_;

View File

@ -0,0 +1,50 @@
/*
* Copyright 2018 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 "modules/congestion_controller/goog_cc/test/goog_cc_printer.h"
namespace webrtc {
GoogCcStatePrinter::GoogCcStatePrinter() = default;
GoogCcStatePrinter::~GoogCcStatePrinter() = default;
void GoogCcStatePrinter::Attach(
webrtc_cc::GoogCcNetworkController* controller) {
controller_ = controller;
}
bool GoogCcStatePrinter::Attached() const {
return controller_ != nullptr;
}
void GoogCcStatePrinter::PrintHeaders(FILE* out) {}
void GoogCcStatePrinter::PrintValues(FILE* out) {
RTC_CHECK(controller_);
}
NetworkControlUpdate GoogCcStatePrinter::GetState(Timestamp at_time) const {
RTC_CHECK(controller_);
return controller_->GetNetworkState(at_time);
}
GoogCcDebugFactory::GoogCcDebugFactory(RtcEventLog* event_log,
GoogCcStatePrinter* printer)
: GoogCcNetworkControllerFactory(event_log), printer_(printer) {}
std::unique_ptr<NetworkControllerInterface> GoogCcDebugFactory::Create(
NetworkControllerConfig config) {
RTC_CHECK(controller_ == nullptr);
auto controller = GoogCcNetworkControllerFactory::Create(config);
controller_ =
static_cast<webrtc_cc::GoogCcNetworkController*>(controller.get());
printer_->Attach(controller_);
return controller;
}
} // namespace webrtc

View File

@ -0,0 +1,48 @@
/*
* Copyright 2018 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.
*/
#ifndef MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_
#define MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_
#include <memory>
#include "modules/congestion_controller/goog_cc/goog_cc_network_control.h"
#include "modules/congestion_controller/goog_cc/include/goog_cc_factory.h"
#include "modules/congestion_controller/test/controller_printer.h"
namespace webrtc {
class GoogCcStatePrinter : public DebugStatePrinter {
public:
GoogCcStatePrinter();
~GoogCcStatePrinter() override;
void Attach(webrtc_cc::GoogCcNetworkController*);
bool Attached() const override;
void PrintHeaders(FILE* out) override;
void PrintValues(FILE* out) override;
NetworkControlUpdate GetState(Timestamp at_time) const override;
private:
webrtc_cc::GoogCcNetworkController* controller_ = nullptr;
};
class GoogCcDebugFactory : public GoogCcNetworkControllerFactory {
public:
GoogCcDebugFactory(RtcEventLog* event_log, GoogCcStatePrinter* printer);
std::unique_ptr<NetworkControllerInterface> Create(
NetworkControllerConfig config) override;
private:
GoogCcStatePrinter* printer_;
webrtc_cc::GoogCcNetworkController* controller_ = nullptr;
};
} // namespace webrtc
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_

View File

@ -0,0 +1,66 @@
/*
* Copyright 2018 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 "modules/congestion_controller/test/controller_printer.h"
#include <cmath>
#include <limits>
#include <utility>
#include "rtc_base/checks.h"
namespace webrtc {
ControlStatePrinter::ControlStatePrinter(
FILE* output,
std::unique_ptr<DebugStatePrinter> debug_printer)
: output_(output), debug_printer_(std::move(debug_printer)) {}
ControlStatePrinter::~ControlStatePrinter() = default;
void ControlStatePrinter::PrintHeaders() {
fprintf(output_, "time bandwidth rtt target pacing padding window");
if (debug_printer_) {
fprintf(output_, " ");
debug_printer_->PrintHeaders(output_);
}
fprintf(output_, "\n");
fflush(output_);
}
void ControlStatePrinter::PrintState(const Timestamp time,
const NetworkControlUpdate state) {
double timestamp = time.seconds<double>();
auto estimate = state.target_rate->network_estimate;
double bandwidth = estimate.bandwidth.bps() / 8.0;
double rtt = estimate.round_trip_time.seconds<double>();
double target_rate = state.target_rate->target_rate.bps() / 8.0;
double pacing_rate = state.pacer_config->data_rate().bps() / 8.0;
double padding_rate = state.pacer_config->pad_rate().bps() / 8.0;
double congestion_window = state.congestion_window
? state.congestion_window->bytes<double>()
: std::numeric_limits<double>::infinity();
fprintf(output_, "%f %f %f %f %f %f %f", timestamp, bandwidth, rtt,
target_rate, pacing_rate, padding_rate, congestion_window);
if (debug_printer_) {
fprintf(output_, " ");
debug_printer_->PrintValues(output_);
}
fprintf(output_, "\n");
fflush(output_);
}
void ControlStatePrinter::PrintState(const Timestamp time) {
if (debug_printer_ && debug_printer_->Attached()) {
PrintState(time, debug_printer_->GetState(time));
}
}
} // namespace webrtc

View File

@ -0,0 +1,43 @@
/*
* Copyright 2018 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.
*/
#ifndef MODULES_CONGESTION_CONTROLLER_TEST_CONTROLLER_PRINTER_H_
#define MODULES_CONGESTION_CONTROLLER_TEST_CONTROLLER_PRINTER_H_
#include <cstdio>
#include <memory>
#include "api/transport/network_control.h"
namespace webrtc {
class DebugStatePrinter {
public:
virtual bool Attached() const = 0;
virtual void PrintHeaders(FILE* out) = 0;
virtual void PrintValues(FILE* out) = 0;
virtual NetworkControlUpdate GetState(Timestamp at_time) const = 0;
virtual ~DebugStatePrinter() = default;
};
class ControlStatePrinter {
public:
ControlStatePrinter(FILE* output,
std::unique_ptr<DebugStatePrinter> debug_printer);
~ControlStatePrinter();
void PrintHeaders();
void PrintState(const Timestamp time, const NetworkControlUpdate state);
void PrintState(const Timestamp time);
private:
FILE* output_;
std::unique_ptr<DebugStatePrinter> debug_printer_;
};
} // namespace webrtc
#endif // MODULES_CONGESTION_CONTROLLER_TEST_CONTROLLER_PRINTER_H_