Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(879)

Unified Diff: webrtc/modules/remote_bitrate_estimator/test/packet_receiver.cc

Issue 1202253003: More Simulation Framework features (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressing trybot failures Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/remote_bitrate_estimator/test/packet_receiver.cc
diff --git a/webrtc/modules/remote_bitrate_estimator/test/packet_receiver.cc b/webrtc/modules/remote_bitrate_estimator/test/packet_receiver.cc
index c13f14437a5239be926acfeb7d6b7a772d35f239..90b61f2f89457f7a3fb2c355b13a3caf7f49d6b2 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/packet_receiver.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/packet_receiver.cc
@@ -31,24 +31,39 @@ PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
bool plot_delay,
bool plot_bwe)
: PacketProcessor(listener, flow_id, kReceiver),
+ now_ms_(0),
delay_log_prefix_(),
metric_log_prefix_(),
packet_loss_log_prefix_(),
+ available_capacity_log_prefix_(),
+ throughput_log_prefix_(),
last_delay_plot_ms_(0),
+ last_throughput_plot_ms_(0),
last_metric_plot_ms_(0),
last_packet_loss_plot_ms_(0),
+ last_total_capacity_plot_ms_(0),
+ last_per_flow_capacity_plot_ms_(0),
plot_delay_(plot_delay),
- // TODO(magalhaesc) Add separated plot_objective_function and
- // plot_packet_loss parameters to the constructor.
- plot_objective_function_(plot_delay),
- plot_packet_loss_(plot_delay),
+ // TODO(magalhaesc): Add following bool parameters to the constructor.
+ plot_throughput_(true),
+ plot_objective_function_(false),
+ plot_packet_loss_(true),
+ plot_total_available_capacity_(true),
+ plot_available_capacity_per_flow_(false),
bwe_receiver_(CreateBweReceiver(bwe_type, flow_id, plot_bwe)),
- total_delay_ms_(0),
- total_throughput_(0),
- number_packets_(0) {
+ delays_ms_(),
+ throughput_bytes_(),
+ weighted_estimate_error_(),
+ last_unweighted_estimate_error_(0),
+ optimal_throughput_bits_(0),
+ last_total_available_bitrate_kbps_(0),
+ last_available_bitrate_per_flow_kbps_(0),
+ start_computing_metrics_ms_(0),
+ started_computing_metrics_(false),
+ alg_name_(bwe_names[bwe_type]) {
// Setup the prefix ststd::rings used when logging.
std::stringstream ss1;
- ss1 << "Delay_" << flow_id << "#2";
+ ss1 << "Delay_ms_" << flow_id << "#2";
delay_log_prefix_ = ss1.str();
std::stringstream ss2;
@@ -58,6 +73,15 @@ PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
std::stringstream ss3;
ss3 << "Packet_Loss_" << flow_id << "#2";
packet_loss_log_prefix_ = ss3.str();
+
+ // Plot Available capacity together with throughputs.
+ std::stringstream ss4;
+ ss4 << "Throughput_kbps" << flow_id << "#1";
+ available_capacity_log_prefix_ = ss4.str();
+
+ std::stringstream ss5;
+ ss5 << "Throughput_kbps_" << flow_id << "#2";
+ throughput_log_prefix_ = ss5.str();
}
PacketReceiver::~PacketReceiver() {
@@ -81,12 +105,48 @@ void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) {
int64_t send_time_ms = (media_packet->creation_time_us() + 500) / 1000;
delay_stats_.Push(arrival_time_ms - send_time_ms);
PlotDelay(arrival_time_ms, send_time_ms);
+ PlotThroughput(arrival_time_ms);
+ PlotTotalAvailableCapacity(arrival_time_ms);
+ PlotAvailableCapacityPerFlow(arrival_time_ms);
PlotObjectiveFunction(arrival_time_ms);
PlotPacketLoss(arrival_time_ms);
- total_delay_ms_ += arrival_time_ms - send_time_ms;
- total_throughput_ += media_packet->payload_size();
- ++number_packets_;
+ int64_t current_capacity_per_flow_kbps =
+ static_cast<int64_t>(media_packet->get_capacity_per_flow_kbps());
+
+ if (arrival_time_ms >= start_computing_metrics_ms_) {
+ if (!started_computing_metrics_) {
+ start_computing_metrics_ms_ = arrival_time_ms;
+ now_ms_ = arrival_time_ms;
+ started_computing_metrics_ = true;
+ }
+
+ delays_ms_.push_back(arrival_time_ms - send_time_ms);
+ throughput_bytes_.push_back(media_packet->payload_size());
+
+ int64_t current_bitrate_diff_kbps =
+ static_cast<int64_t>(media_packet->get_sending_estimate_kbps()) -
+ current_capacity_per_flow_kbps;
+
+ // now_ms_ was still not updated here.
+ weighted_estimate_error_.push_back(
+ ((current_bitrate_diff_kbps + last_unweighted_estimate_error_) *
+ (arrival_time_ms - now_ms_)) /
+ 2);
+
+ optimal_throughput_bits_ += ((current_capacity_per_flow_kbps +
+ last_available_bitrate_per_flow_kbps_) *
+ (arrival_time_ms - now_ms_)) /
+ 2;
+
+ last_unweighted_estimate_error_ = current_bitrate_diff_kbps;
+ }
+
+ last_available_bitrate_per_flow_kbps_ = current_capacity_per_flow_kbps;
+ last_total_available_bitrate_kbps_ =
+ media_packet->get_total_capacity_kbps();
+
+ now_ms_ = std::max(now_ms_, arrival_time_ms);
stefan-webrtc 2015/06/25 14:44:05 Break this plotting stuff out to a method.
magalhaesc 2015/07/01 12:48:40 Done, moved to MetricRecorder
bwe_receiver_->ReceivePacket(arrival_time_ms, *media_packet);
FeedbackPacket* fb = bwe_receiver_->GetFeedback(arrival_time_ms);
@@ -107,16 +167,142 @@ void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) {
if (!plot_delay_)
return;
if (arrival_time_ms - last_delay_plot_ms_ > kDelayPlotIntervalMs) {
- BWE_TEST_LOGGING_PLOT(0, delay_log_prefix_, arrival_time_ms,
- arrival_time_ms - send_time_ms);
+ BWE_TEST_LOGGING_PLOT_WITH_NAME(0, delay_log_prefix_, arrival_time_ms,
+ arrival_time_ms - send_time_ms, alg_name_);
last_delay_plot_ms_ = arrival_time_ms;
}
}
+void PacketReceiver::PlotThroughput(int64_t arrival_time_ms) {
+ static const int kThroughputPlotIntervalMs = 1000;
+ if (!plot_throughput_)
+ return;
+ if (arrival_time_ms - last_throughput_plot_ms_ > kThroughputPlotIntervalMs) {
+ BWE_TEST_LOGGING_PLOT_WITH_NAME(0, throughput_log_prefix_, arrival_time_ms,
+ bwe_receiver_->RecentKbps(), alg_name_);
+ last_throughput_plot_ms_ = arrival_time_ms;
+ }
+}
+
+void PacketReceiver::PlotTotalAvailableCapacity(int64_t arrival_time_ms) {
+ static const int kAvailableCapacityPerFlowMs = 1000;
+ if (!plot_total_available_capacity_)
+ return;
+ if (arrival_time_ms - last_total_capacity_plot_ms_ >
+ kAvailableCapacityPerFlowMs) {
+ BWE_TEST_LOGGING_PLOT_WITH_NAME(
+ 0, available_capacity_log_prefix_, arrival_time_ms,
+ last_total_available_bitrate_kbps_, "Available");
+ last_total_capacity_plot_ms_ = arrival_time_ms;
+ }
+}
+
+void PacketReceiver::PlotAvailableCapacityPerFlow(int64_t arrival_time_ms) {
+ static const int kAvailableCapacityPerFlowMs = 1000;
+ if (!plot_available_capacity_per_flow_)
+ return;
+ if (arrival_time_ms - last_per_flow_capacity_plot_ms_ >
+ kAvailableCapacityPerFlowMs) {
+ BWE_TEST_LOGGING_PLOT_WITH_NAME(
+ 0, available_capacity_log_prefix_, arrival_time_ms,
+ last_available_bitrate_per_flow_kbps_, "Available_per_flow");
+ last_per_flow_capacity_plot_ms_ = arrival_time_ms;
+ }
+}
+
+template <typename T>
stefan-webrtc 2015/06/25 14:44:05 All of these methods should go in the beginning an
magalhaesc 2015/07/01 12:48:40 Done, moved to MetricReceiver
+inline T Sum(std::vector<T>& input) {
stefan-webrtc 2015/06/25 14:44:05 No need for inline.
magalhaesc 2015/07/01 12:48:40 Done.
+ T total = 0;
+ for (auto it = input.begin(); it != input.end(); ++it) {
+ total += *it;
+ }
+ return total;
+}
+
+template <typename T>
+inline double Average(std::vector<T>& array, size_t size) {
+ return static_cast<double>(Sum(array)) / size;
+}
+
+template <typename T>
+inline std::vector<T> Abs(std::vector<T>& input) {
+ std::vector<T> output;
+ for (auto it = input.begin(); it != input.end(); ++it) {
+ output.push_back(std::abs(*it));
+ }
+ return output;
+}
+
+template <typename T>
+inline std::vector<double> Pow(std::vector<T>& input, double p) {
+ std::vector<double> output;
+ for (auto it = input.begin(); it != input.end(); ++it) {
+ output.push_back(pow(static_cast<double>(*it), p));
+ }
+ return output;
+}
+
+template <typename T>
+inline double StandardDeviation(std::vector<T>& array, size_t size) {
+ double mean = Average(array, size);
+ std::vector<double> square_values = Pow(array, 2.0);
+ double var = Average(square_values, size) - mean * mean;
+ return sqrt(var);
+}
+
+// Holder mean, Manhattan distance for p=1, EuclidianNorm/sqrt(n) for p=2.
+template <typename T>
+inline double NormLp(std::vector<T>& array, size_t size, double p) {
+ std::vector<T> abs_values = Abs(array);
+ std::vector<double> pow_values = Pow(abs_values, p);
+ return pow(Sum(pow_values) / size, 1.0 / p);
+}
+
+template <typename T>
+inline std::vector<T> PositiveFilter(std::vector<T>& input) {
+ std::vector<T> output(input);
+ for (auto it = output.begin(); it != output.end(); ++it) {
+ (*it) = (*it) > 0 ? (*it) : 0;
+ }
+ return output;
+}
+
+template <typename T>
+inline std::vector<T> NegativeFilter(std::vector<T>& input) {
+ std::vector<T> output(input);
+ for (auto it = output.begin(); it != output.end(); ++it) {
+ (*it) = (*it) < 0 ? -(*it) : 0;
+ }
+ return output;
+}
+
+// The weighted_estimate_error_ was weighted based on time windows.
+// This function scales back the result before plotting.
+double PacketReceiver::Renormalize(double x) {
+ size_t num_packets_received = delays_ms_.size();
+ return (x * num_packets_received) / now_ms_;
+}
+
+inline double U(int64_t x, double alpha) {
+ if (alpha == 1.0) {
+ return log(static_cast<double>(x));
+ }
+ return pow(static_cast<double>(x), 1.0 - alpha) / (1.0 - alpha);
+}
+
+inline double U(size_t x, double alpha) {
+ return U(static_cast<int64_t>(x), alpha);
+}
+
+// TODO(magalhaesc): Update ObjectiveFunction.
double PacketReceiver::ObjectiveFunction() {
stefan-webrtc 2015/06/25 14:44:05 Not sure we ended up using this? Maybe better to r
magalhaesc 2015/07/01 12:48:40 They are now in the MetricRecorder file, so separa
- const double kDelta = 1.0; // Delay penalty factor.
- double throughput_metric = log(static_cast<double>(total_throughput_));
- double delay_penalty = kDelta * log(static_cast<double>(total_delay_ms_));
+ const double kDelta = 0.15; // Delay penalty factor.
+ const double kAlpha = 1.0;
+ const double kBeta = 1.0;
+
+ double throughput_metric = U(Sum(throughput_bytes_), kAlpha);
+ double delay_penalty = kDelta * U(Sum(delays_ms_), kBeta);
+
return throughput_metric - delay_penalty;
}
@@ -138,12 +324,98 @@ void PacketReceiver::PlotPacketLoss(int64_t arrival_time_ms) {
return;
}
if (arrival_time_ms - last_packet_loss_plot_ms_ > kPacketLossPlotIntervalMs) {
- BWE_TEST_LOGGING_PLOT(2, packet_loss_log_prefix_, arrival_time_ms,
- bwe_receiver_->RecentPacketLossRatio());
+ BWE_TEST_LOGGING_PLOT_WITH_NAME(
+ 2, "Recent_" + packet_loss_log_prefix_, arrival_time_ms,
+ bwe_receiver_->RecentPacketLossRatio(), alg_name_);
last_packet_loss_plot_ms_ = arrival_time_ms;
}
}
+void PacketReceiver::PlotThroughputHistogram(const std::string& title,
+ const std::string& bwe_name,
+ int num_flows,
+ int64_t extra_offset_ms,
+ const std::string optimum_id) {
+ size_t num_packets_received = delays_ms_.size();
+
+ int64_t duration_ms = now_ms_ - start_computing_metrics_ms_ - extra_offset_ms;
+
+ double average_bitrate_kbps =
+ static_cast<double>(8 * Sum(throughput_bytes_) / duration_ms);
+
+ double optimal_bitrate_per_flow_kbps =
+ static_cast<double>(optimal_throughput_bits_ / duration_ms);
+
+ std::vector<int64_t> positive = PositiveFilter(weighted_estimate_error_);
+ std::vector<int64_t> negative = NegativeFilter(weighted_estimate_error_);
+
+ double p_error = Renormalize(NormLp(positive, num_packets_received, 1.0));
+ double n_error = Renormalize(NormLp(negative, num_packets_received, 1.0));
+
+ // Prevent the error to be too close to zero (plotting issue).
+ double extra_error = average_bitrate_kbps / 500;
+
+ std::string optimum_title =
+ optimum_id.empty() ? "optimal_bitrate" : "optimal_bitrates#" + optimum_id;
+
+ BWE_TEST_LOGGING_LABEL(4, title, "average_bitrate_(kbps)", num_flows);
+ BWE_TEST_LOGGING_LIMITERRORBAR(
+ 4, bwe_name, average_bitrate_kbps,
+ average_bitrate_kbps - n_error - extra_error,
+ average_bitrate_kbps + p_error + extra_error, "estimate_error",
+ optimal_bitrate_per_flow_kbps, optimum_title, *flow_ids().begin());
+
+ // Silencing unused variable compiling error.
+ (void)p_error;
+ (void)n_error;
+ (void)extra_error;
+ (void)optimal_bitrate_per_flow_kbps;
stefan-webrtc 2015/06/25 14:44:05 RTC_UNUSED
magalhaesc 2015/07/01 12:48:40 Done.
+}
+
+void PacketReceiver::PlotThroughputHistogram(const std::string& title,
+ const std::string& bwe_name,
+ int num_flows,
+ int64_t extra_offset_ms) {
+ PlotThroughputHistogram(title, bwe_name, num_flows, extra_offset_ms, "");
+}
+
+void PacketReceiver::PlotDelayHistogram(const std::string& title,
+ const std::string& bwe_name,
+ int num_flows) {
+ size_t num_packets_received = delays_ms_.size();
+ double average_delay_ms = Average(delays_ms_, num_packets_received);
+
+ // Prevent the error to be too close to zero (plotting issue).
+ double extra_error = average_delay_ms / 500;
+
+ double tenth_sigma_ms =
+ StandardDeviation(delays_ms_, num_packets_received) / 10.0 + extra_error;
+
+ BWE_TEST_LOGGING_LABEL(5, title, "average_delay_(ms)", num_flows)
+ BWE_TEST_LOGGING_ERRORBAR(
+ 5, bwe_name, average_delay_ms, average_delay_ms - tenth_sigma_ms,
+ average_delay_ms + tenth_sigma_ms, "sigma/10", *flow_ids().begin());
+
+ // Silencing unused variable compiling error.
+ (void)tenth_sigma_ms;
stefan-webrtc 2015/06/25 14:44:05 RTC_UNUSED
magalhaesc 2015/07/01 12:48:40 Done.
+}
+
+void PacketReceiver::PlotLossHistogram(const std::string& title,
+ const std::string& bwe_name,
+ int num_flows) {
+ BWE_TEST_LOGGING_LABEL(6, title, "packet_loss_ratio_(%)", num_flows)
+ BWE_TEST_LOGGING_BAR(6, bwe_name,
+ 100.0f * bwe_receiver_->GlobalReceiverPacketLossRatio(),
+ *flow_ids().begin());
+}
+
+void PacketReceiver::PlotObjectiveHistogram(const std::string& title,
+ const std::string& bwe_name,
+ int num_flows) {
+ BWE_TEST_LOGGING_LABEL(7, title, "objective_function", num_flows)
+ BWE_TEST_LOGGING_BAR(7, bwe_name, ObjectiveFunction(), *flow_ids().begin());
+}
+
Stats<double> PacketReceiver::GetDelayStats() const {
return delay_stats_;
}

Powered by Google App Engine
This is Rietveld 408576698