Adds debug printing of network estimate.

Bug: webrtc:10498
Change-Id: Idce952675ef079b5981f973ca58ca2cd7e5d5332
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/134648
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27838}
diff --git a/api/transport/network_types.h b/api/transport/network_types.h
index 3e0615d..a9b9a2c 100644
--- a/api/transport/network_types.h
+++ b/api/transport/network_types.h
@@ -221,12 +221,12 @@
   DataRate link_capacity = DataRate::MinusInfinity();
   DataRate link_capacity_std_dev = DataRate::MinusInfinity();
   DataRate link_capacity_min = DataRate::MinusInfinity();
-  double cross_traffic_ratio;
+  double cross_traffic_ratio = NAN;
   TimeDelta pre_link_buffer_delay = TimeDelta::MinusInfinity();
   TimeDelta post_link_buffer_delay = TimeDelta::MinusInfinity();
   TimeDelta propagation_delay = TimeDelta::MinusInfinity();
-  double cross_delay_rate;
-  double spike_delay_rate;
+  double cross_delay_rate = NAN;
+  double spike_delay_rate = NAN;
 };
 }  // namespace webrtc
 
diff --git a/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc b/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
index da39f71..18dcd5b 100644
--- a/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
+++ b/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
@@ -11,6 +11,8 @@
 
 #include <math.h>
 
+#include <utility>
+
 #include "absl/types/optional.h"
 #include "modules/congestion_controller/goog_cc/alr_detector.h"
 #include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
@@ -19,8 +21,89 @@
 #include "rtc_base/checks.h"
 
 namespace webrtc {
+namespace {
+void WriteTypedValue(RtcEventLogOutput* out, int value) {
+  LogWriteFormat(out, "%i", value);
+}
+void WriteTypedValue(RtcEventLogOutput* out, double value) {
+  LogWriteFormat(out, "%.6f", value);
+}
+void WriteTypedValue(RtcEventLogOutput* out, absl::optional<DataRate> value) {
+  LogWriteFormat(out, "%.0f", value ? value->bytes_per_sec<double>() : NAN);
+}
+void WriteTypedValue(RtcEventLogOutput* out, absl::optional<TimeDelta> value) {
+  LogWriteFormat(out, "%.3f", value ? value->seconds<double>() : NAN);
+}
+template <typename F>
+class TypedFieldLogger : public FieldLogger {
+ public:
+  TypedFieldLogger(std::string name, F&& getter)
+      : name_(std::move(name)), getter_(std::forward<F>(getter)) {}
+  const std::string& name() const override { return name_; }
+  void WriteValue(RtcEventLogOutput* out) override {
+    WriteTypedValue(out, getter_());
+  }
 
-GoogCcStatePrinter::GoogCcStatePrinter() = default;
+ private:
+  std::string name_;
+  F getter_;
+};
+
+template <typename F>
+FieldLogger* Log(std::string name, F&& getter) {
+  return new TypedFieldLogger<F>(std::move(name), std::forward<F>(getter));
+}
+
+}  // namespace
+GoogCcStatePrinter::GoogCcStatePrinter() {
+  for (auto* logger : CreateLoggers()) {
+    loggers_.emplace_back(logger);
+  }
+}
+const NetworkStateEstimate& GoogCcStatePrinter::GetEst() {
+  static NetworkStateEstimate kFallback;
+  if (controller_->network_estimator_ &&
+      controller_->network_estimator_->GetCurrentEstimate())
+    return *controller_->network_estimator_->GetCurrentEstimate();
+  return kFallback;
+}
+std::deque<FieldLogger*> GoogCcStatePrinter::CreateLoggers() {
+  auto stable_estimate = [this] {
+    return DataRate::kbps(
+        controller_->delay_based_bwe_->rate_control_.link_capacity_
+            .estimate_kbps_.value_or(-INFINITY));
+  };
+  auto rate_control_state = [this] {
+    return static_cast<int>(
+        controller_->delay_based_bwe_->rate_control_.rate_control_state_);
+  };
+  auto trend = [this] {
+    return reinterpret_cast<TrendlineEstimator*>(
+        controller_->delay_based_bwe_->delay_detector_.get());
+  };
+  auto acknowledged_rate = [this] {
+    return controller_->acknowledged_bitrate_estimator_->bitrate();
+  };
+  std::deque<FieldLogger*> loggers({
+      Log("rate_control_state", [=] { return rate_control_state(); }),
+      Log("stable_estimate", [=] { return stable_estimate(); }),
+      Log("trendline", [=] { return trend()->prev_trend_; }),
+      Log("trendline_modified_offset",
+          [=] { return trend()->prev_modified_trend_; }),
+      Log("trendline_offset_threshold", [=] { return trend()->threshold_; }),
+      Log("acknowledged_rate", [=] { return acknowledged_rate(); }),
+      Log("est_capacity", [=] { return GetEst().link_capacity; }),
+      Log("est_capacity_dev", [=] { return GetEst().link_capacity_std_dev; }),
+      Log("est_capacity_min", [=] { return GetEst().link_capacity_min; }),
+      Log("est_cross_traffic", [=] { return GetEst().cross_traffic_ratio; }),
+      Log("est_cross_delay", [=] { return GetEst().cross_delay_rate; }),
+      Log("est_spike_delay", [=] { return GetEst().spike_delay_rate; }),
+      Log("est_pre_buffer", [=] { return GetEst().pre_link_buffer_delay; }),
+      Log("est_post_buffer", [=] { return GetEst().post_link_buffer_delay; }),
+      Log("est_propagation", [=] { return GetEst().propagation_delay; }),
+  });
+  return loggers;
+}
 GoogCcStatePrinter::~GoogCcStatePrinter() = default;
 
 void GoogCcStatePrinter::Attach(GoogCcNetworkController* controller) {
@@ -32,25 +115,22 @@
 }
 
 void GoogCcStatePrinter::PrintHeaders(RtcEventLogOutput* out) {
-  out->Write(
-      "rate_control_state stable_estimate alr_state"
-      " trendline trendline_modified_offset trendline_offset_threshold");
+  int ix = 0;
+  for (const auto& logger : loggers_) {
+    if (ix++)
+      out->Write(" ");
+    out->Write(logger->name());
+  }
 }
 
 void GoogCcStatePrinter::PrintValues(RtcEventLogOutput* out) {
   RTC_CHECK(controller_);
-  auto* detector = controller_->delay_based_bwe_->delay_detector_.get();
-  auto* trendline_estimator = reinterpret_cast<TrendlineEstimator*>(detector);
-  LogWriteFormat(
-      out, "%i %f %i %.6lf %.6lf %.6lf",
-      controller_->delay_based_bwe_->rate_control_.rate_control_state_,
-      controller_->delay_based_bwe_->rate_control_.link_capacity_.estimate_kbps_
-              .value_or(NAN) *
-          1000 / 8,
-      controller_->alr_detector_->alr_started_time_ms_.has_value(),
-      trendline_estimator->prev_trend_,
-      trendline_estimator->prev_modified_trend_,
-      trendline_estimator->threshold_);
+  int ix = 0;
+  for (const auto& logger : loggers_) {
+    if (ix++)
+      out->Write(" ");
+    logger->WriteValue(out);
+  }
 }
 
 NetworkControlUpdate GoogCcStatePrinter::GetState(Timestamp at_time) const {
@@ -59,8 +139,7 @@
 }
 
 GoogCcDebugFactory::GoogCcDebugFactory(GoogCcStatePrinter* printer)
-    : GoogCcNetworkControllerFactory(GoogCcFactoryConfig()),
-      printer_(printer) {}
+    : printer_(printer) {}
 
 std::unique_ptr<NetworkControllerInterface> GoogCcDebugFactory::Create(
     NetworkControllerConfig config) {
diff --git a/modules/congestion_controller/goog_cc/test/goog_cc_printer.h b/modules/congestion_controller/goog_cc/test/goog_cc_printer.h
index c09138f..179a70a 100644
--- a/modules/congestion_controller/goog_cc/test/goog_cc_printer.h
+++ b/modules/congestion_controller/goog_cc/test/goog_cc_printer.h
@@ -10,8 +10,9 @@
 #ifndef MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_
 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_
 
-#include <stdio.h>
+#include <deque>
 #include <memory>
+#include <string>
 
 #include "api/transport/goog_cc_factory.h"
 #include "api/transport/network_control.h"
@@ -22,9 +23,19 @@
 #include "modules/congestion_controller/test/controller_printer.h"
 
 namespace webrtc {
+
+class FieldLogger {
+ public:
+  virtual ~FieldLogger() = default;
+  virtual const std::string& name() const = 0;
+  virtual void WriteValue(RtcEventLogOutput* out) = 0;
+};
+
 class GoogCcStatePrinter : public DebugStatePrinter {
  public:
   GoogCcStatePrinter();
+  GoogCcStatePrinter(const GoogCcStatePrinter&) = delete;
+  GoogCcStatePrinter& operator=(const GoogCcStatePrinter&) = delete;
   ~GoogCcStatePrinter() override;
   void Attach(GoogCcNetworkController*);
   bool Attached() const override;
@@ -35,6 +46,10 @@
   NetworkControlUpdate GetState(Timestamp at_time) const override;
 
  private:
+  const NetworkStateEstimate& GetEst();
+  std::deque<FieldLogger*> CreateLoggers();
+
+  std::deque<std::unique_ptr<FieldLogger>> loggers_;
   GoogCcNetworkController* controller_ = nullptr;
 };
 
@@ -48,7 +63,6 @@
   GoogCcStatePrinter* printer_;
   GoogCcNetworkController* controller_ = nullptr;
 };
-
 }  // namespace webrtc
 
 #endif  // MODULES_CONGESTION_CONTROLLER_GOOG_CC_TEST_GOOG_CC_PRINTER_H_