aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc')
-rw-r--r--webrtc/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc495
1 files changed, 495 insertions, 0 deletions
diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc
new file mode 100644
index 0000000000..a0f56b73b7
--- /dev/null
+++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc
@@ -0,0 +1,495 @@
+/*
+ * Copyright (c) 2015 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 "webrtc/modules/remote_bitrate_estimator/test/estimators/nada.h"
+
+#include <algorithm>
+#include <numeric>
+
+#include "webrtc/base/common.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
+#include "webrtc/modules/remote_bitrate_estimator/test/packet.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h"
+#include "webrtc/test/testsupport/fileutils.h"
+
+namespace webrtc {
+namespace testing {
+namespace bwe {
+
+class FilterTest : public ::testing::Test {
+ public:
+ void MedianFilterConstantArray() {
+ std::fill_n(raw_signal_, kNumElements, kSignalValue);
+ for (int i = 0; i < kNumElements; ++i) {
+ int size = std::min(5, i + 1);
+ median_filtered_[i] =
+ NadaBweReceiver::MedianFilter(&raw_signal_[i + 1 - size], size);
+ }
+ }
+
+ void MedianFilterIntermittentNoise() {
+ const int kValue = 500;
+ const int kNoise = 100;
+
+ for (int i = 0; i < kNumElements; ++i) {
+ raw_signal_[i] = kValue + kNoise * (i % 10 == 9 ? 1 : 0);
+ }
+ for (int i = 0; i < kNumElements; ++i) {
+ int size = std::min(5, i + 1);
+ median_filtered_[i] =
+ NadaBweReceiver::MedianFilter(&raw_signal_[i + 1 - size], size);
+ EXPECT_EQ(median_filtered_[i], kValue);
+ }
+ }
+
+ void ExponentialSmoothingFilter(const int64_t raw_signal_[],
+ int num_elements,
+ int64_t exp_smoothed[]) {
+ exp_smoothed[0] =
+ NadaBweReceiver::ExponentialSmoothingFilter(raw_signal_[0], -1, kAlpha);
+ for (int i = 1; i < num_elements; ++i) {
+ exp_smoothed[i] = NadaBweReceiver::ExponentialSmoothingFilter(
+ raw_signal_[i], exp_smoothed[i - 1], kAlpha);
+ }
+ }
+
+ void ExponentialSmoothingConstantArray(int64_t exp_smoothed[]) {
+ std::fill_n(raw_signal_, kNumElements, kSignalValue);
+ ExponentialSmoothingFilter(raw_signal_, kNumElements, exp_smoothed);
+ }
+
+ protected:
+ static const int kNumElements = 1000;
+ static const int64_t kSignalValue;
+ static const float kAlpha;
+ int64_t raw_signal_[kNumElements];
+ int64_t median_filtered_[kNumElements];
+};
+
+const int64_t FilterTest::kSignalValue = 200;
+const float FilterTest::kAlpha = 0.1f;
+
+class TestBitrateObserver : public BitrateObserver {
+ public:
+ TestBitrateObserver()
+ : last_bitrate_(0), last_fraction_loss_(0), last_rtt_(0) {}
+
+ virtual void OnNetworkChanged(uint32_t bitrate,
+ uint8_t fraction_loss,
+ int64_t rtt) {
+ last_bitrate_ = bitrate;
+ last_fraction_loss_ = fraction_loss;
+ last_rtt_ = rtt;
+ }
+ uint32_t last_bitrate_;
+ uint8_t last_fraction_loss_;
+ int64_t last_rtt_;
+};
+
+class NadaSenderSideTest : public ::testing::Test {
+ public:
+ NadaSenderSideTest()
+ : observer_(),
+ simulated_clock_(0),
+ nada_sender_(&observer_, &simulated_clock_) {}
+ ~NadaSenderSideTest() {}
+
+ private:
+ TestBitrateObserver observer_;
+ SimulatedClock simulated_clock_;
+
+ protected:
+ NadaBweSender nada_sender_;
+};
+
+class NadaReceiverSideTest : public ::testing::Test {
+ public:
+ NadaReceiverSideTest() : nada_receiver_(kFlowId) {}
+ ~NadaReceiverSideTest() {}
+
+ protected:
+ const int kFlowId = 1; // Arbitrary.
+ NadaBweReceiver nada_receiver_;
+};
+
+class NadaFbGenerator {
+ public:
+ NadaFbGenerator();
+
+ static NadaFeedback NotCongestedFb(size_t receiving_rate,
+ int64_t ref_signal_ms,
+ int64_t send_time_ms) {
+ int64_t exp_smoothed_delay_ms = ref_signal_ms;
+ int64_t est_queuing_delay_signal_ms = ref_signal_ms;
+ int64_t congestion_signal_ms = ref_signal_ms;
+ float derivative = 0.0f;
+ return NadaFeedback(kFlowId, kNowMs, exp_smoothed_delay_ms,
+ est_queuing_delay_signal_ms, congestion_signal_ms,
+ derivative, receiving_rate, send_time_ms);
+ }
+
+ static NadaFeedback CongestedFb(size_t receiving_rate, int64_t send_time_ms) {
+ int64_t exp_smoothed_delay_ms = 1000;
+ int64_t est_queuing_delay_signal_ms = 800;
+ int64_t congestion_signal_ms = 1000;
+ float derivative = 1.0f;
+ return NadaFeedback(kFlowId, kNowMs, exp_smoothed_delay_ms,
+ est_queuing_delay_signal_ms, congestion_signal_ms,
+ derivative, receiving_rate, send_time_ms);
+ }
+
+ static NadaFeedback ExtremelyCongestedFb(size_t receiving_rate,
+ int64_t send_time_ms) {
+ int64_t exp_smoothed_delay_ms = 100000;
+ int64_t est_queuing_delay_signal_ms = 0;
+ int64_t congestion_signal_ms = 100000;
+ float derivative = 10000.0f;
+ return NadaFeedback(kFlowId, kNowMs, exp_smoothed_delay_ms,
+ est_queuing_delay_signal_ms, congestion_signal_ms,
+ derivative, receiving_rate, send_time_ms);
+ }
+
+ private:
+ // Arbitrary values, won't change these test results.
+ static const int kFlowId = 2;
+ static const int64_t kNowMs = 1000;
+};
+
+// Verify if AcceleratedRampUp is called and that bitrate increases.
+TEST_F(NadaSenderSideTest, AcceleratedRampUp) {
+ const int64_t kRefSignalMs = 1;
+ const int64_t kOneWayDelayMs = 50;
+ int original_bitrate = 2 * kMinBitrateKbps;
+ size_t receiving_rate = static_cast<size_t>(original_bitrate);
+ int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
+
+ NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
+ receiving_rate, kRefSignalMs, send_time_ms);
+
+ nada_sender_.set_original_operating_mode(true);
+ nada_sender_.set_bitrate_kbps(original_bitrate);
+
+ // Trigger AcceleratedRampUp mode.
+ nada_sender_.GiveFeedback(not_congested_fb);
+ int bitrate_1_kbps = nada_sender_.bitrate_kbps();
+ EXPECT_GT(bitrate_1_kbps, original_bitrate);
+ // Updates the bitrate according to the receiving rate and other constant
+ // parameters.
+ nada_sender_.AcceleratedRampUp(not_congested_fb);
+ EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps);
+
+ nada_sender_.set_original_operating_mode(false);
+ nada_sender_.set_bitrate_kbps(original_bitrate);
+ // Trigger AcceleratedRampUp mode.
+ nada_sender_.GiveFeedback(not_congested_fb);
+ bitrate_1_kbps = nada_sender_.bitrate_kbps();
+ EXPECT_GT(bitrate_1_kbps, original_bitrate);
+ nada_sender_.AcceleratedRampUp(not_congested_fb);
+ EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps);
+}
+
+// Verify if AcceleratedRampDown is called and if bitrate decreases.
+TEST_F(NadaSenderSideTest, AcceleratedRampDown) {
+ const int64_t kOneWayDelayMs = 50;
+ int original_bitrate = 3 * kMinBitrateKbps;
+ size_t receiving_rate = static_cast<size_t>(original_bitrate);
+ int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
+
+ NadaFeedback congested_fb =
+ NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
+
+ nada_sender_.set_original_operating_mode(false);
+ nada_sender_.set_bitrate_kbps(original_bitrate);
+ nada_sender_.GiveFeedback(congested_fb); // Trigger AcceleratedRampDown mode.
+ int bitrate_1_kbps = nada_sender_.bitrate_kbps();
+ EXPECT_LE(bitrate_1_kbps, original_bitrate * 0.9f + 0.5f);
+ EXPECT_LT(bitrate_1_kbps, original_bitrate);
+
+ // Updates the bitrate according to the receiving rate and other constant
+ // parameters.
+ nada_sender_.AcceleratedRampDown(congested_fb);
+ int bitrate_2_kbps = std::max(nada_sender_.bitrate_kbps(), kMinBitrateKbps);
+ EXPECT_EQ(bitrate_2_kbps, bitrate_1_kbps);
+}
+
+TEST_F(NadaSenderSideTest, GradualRateUpdate) {
+ const int64_t kDeltaSMs = 20;
+ const int64_t kRefSignalMs = 20;
+ const int64_t kOneWayDelayMs = 50;
+ int original_bitrate = 2 * kMinBitrateKbps;
+ size_t receiving_rate = static_cast<size_t>(original_bitrate);
+ int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
+
+ NadaFeedback congested_fb =
+ NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
+ NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
+ original_bitrate, kRefSignalMs, send_time_ms);
+
+ nada_sender_.set_bitrate_kbps(original_bitrate);
+ double smoothing_factor = 0.0;
+ nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor);
+ EXPECT_EQ(nada_sender_.bitrate_kbps(), original_bitrate);
+
+ smoothing_factor = 1.0;
+ nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor);
+ EXPECT_LT(nada_sender_.bitrate_kbps(), original_bitrate);
+
+ nada_sender_.set_bitrate_kbps(original_bitrate);
+ nada_sender_.GradualRateUpdate(not_congested_fb, kDeltaSMs, smoothing_factor);
+ EXPECT_GT(nada_sender_.bitrate_kbps(), original_bitrate);
+}
+
+// Sending bitrate should decrease and reach its Min bound.
+TEST_F(NadaSenderSideTest, VeryLowBandwith) {
+ const int64_t kOneWayDelayMs = 50;
+
+ size_t receiving_rate = static_cast<size_t>(kMinBitrateKbps);
+ int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
+
+ NadaFeedback extremely_congested_fb =
+ NadaFbGenerator::ExtremelyCongestedFb(receiving_rate, send_time_ms);
+ NadaFeedback congested_fb =
+ NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
+
+ nada_sender_.set_bitrate_kbps(5 * kMinBitrateKbps);
+ nada_sender_.set_original_operating_mode(true);
+ for (int i = 0; i < 100; ++i) {
+ // Trigger GradualRateUpdate mode.
+ nada_sender_.GiveFeedback(extremely_congested_fb);
+ }
+ // The original implementation doesn't allow the bitrate to stay at kMin,
+ // even if the congestion signal is very high.
+ EXPECT_GE(nada_sender_.bitrate_kbps(), kMinBitrateKbps);
+
+ nada_sender_.set_original_operating_mode(false);
+ nada_sender_.set_bitrate_kbps(5 * kMinBitrateKbps);
+
+ for (int i = 0; i < 1000; ++i) {
+ int previous_bitrate = nada_sender_.bitrate_kbps();
+ // Trigger AcceleratedRampDown mode.
+ nada_sender_.GiveFeedback(congested_fb);
+ EXPECT_LE(nada_sender_.bitrate_kbps(), previous_bitrate);
+ }
+ EXPECT_EQ(nada_sender_.bitrate_kbps(), kMinBitrateKbps);
+}
+
+// Sending bitrate should increase and reach its Max bound.
+TEST_F(NadaSenderSideTest, VeryHighBandwith) {
+ const int64_t kOneWayDelayMs = 50;
+ const size_t kRecentReceivingRate = static_cast<size_t>(kMaxBitrateKbps);
+ const int64_t kRefSignalMs = 1;
+ int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
+
+ NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
+ kRecentReceivingRate, kRefSignalMs, send_time_ms);
+
+ nada_sender_.set_original_operating_mode(true);
+ for (int i = 0; i < 100; ++i) {
+ int previous_bitrate = nada_sender_.bitrate_kbps();
+ nada_sender_.GiveFeedback(not_congested_fb);
+ EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate);
+ }
+ EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps);
+
+ nada_sender_.set_original_operating_mode(false);
+ nada_sender_.set_bitrate_kbps(kMinBitrateKbps);
+
+ for (int i = 0; i < 100; ++i) {
+ int previous_bitrate = nada_sender_.bitrate_kbps();
+ nada_sender_.GiveFeedback(not_congested_fb);
+ EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate);
+ }
+ EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps);
+}
+
+TEST_F(NadaReceiverSideTest, FeedbackInitialCases) {
+ rtc::scoped_ptr<NadaFeedback> nada_feedback(
+ static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(0)));
+ EXPECT_EQ(nada_feedback, nullptr);
+
+ nada_feedback.reset(
+ static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(100)));
+ EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), -1);
+ EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L);
+ EXPECT_EQ(nada_feedback->congestion_signal(), 0L);
+ EXPECT_EQ(nada_feedback->derivative(), 0.0f);
+ EXPECT_EQ(nada_feedback->receiving_rate(), 0.0f);
+}
+
+TEST_F(NadaReceiverSideTest, FeedbackEmptyQueues) {
+ const int64_t kTimeGapMs = 50; // Between each packet.
+ const int64_t kOneWayDelayMs = 50;
+
+ // No added latency, delay = kOneWayDelayMs.
+ for (int i = 1; i < 10; ++i) {
+ int64_t send_time_us = i * kTimeGapMs * 1000;
+ int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs;
+ uint16_t sequence_number = static_cast<uint16_t>(i);
+ // Payload sizes are not important here.
+ const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
+ nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
+ }
+
+ // Baseline delay will be equal kOneWayDelayMs.
+ rtc::scoped_ptr<NadaFeedback> nada_feedback(
+ static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(500)));
+ EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), 0L);
+ EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L);
+ EXPECT_EQ(nada_feedback->congestion_signal(), 0L);
+ EXPECT_EQ(nada_feedback->derivative(), 0.0f);
+}
+
+TEST_F(NadaReceiverSideTest, FeedbackIncreasingDelay) {
+ // Since packets are 100ms apart, each one corresponds to a feedback.
+ const int64_t kTimeGapMs = 100; // Between each packet.
+
+ // Raw delays are = [10 20 30 40 50 60 70 80] ms.
+ // Baseline delay will be 50 ms.
+ // Delay signals should be: [0 10 20 30 40 50 60 70] ms.
+ const int64_t kMedianFilteredDelaysMs[] = {0, 5, 10, 15, 20, 30, 40, 50};
+ const int kNumPackets = ARRAY_SIZE(kMedianFilteredDelaysMs);
+ const float kAlpha = 0.1f; // Used for exponential smoothing.
+
+ int64_t exp_smoothed_delays_ms[kNumPackets];
+ exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0];
+
+ for (int i = 1; i < kNumPackets; ++i) {
+ exp_smoothed_delays_ms[i] = static_cast<int64_t>(
+ kAlpha * kMedianFilteredDelaysMs[i] +
+ (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f);
+ }
+
+ for (int i = 0; i < kNumPackets; ++i) {
+ int64_t send_time_us = (i + 1) * kTimeGapMs * 1000;
+ int64_t arrival_time_ms = send_time_us / 1000 + 10 * (i + 1);
+ uint16_t sequence_number = static_cast<uint16_t>(i + 1);
+ // Payload sizes are not important here.
+ const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
+ nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
+
+ rtc::scoped_ptr<NadaFeedback> nada_feedback(static_cast<NadaFeedback*>(
+ nada_receiver_.GetFeedback(arrival_time_ms)));
+ EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(),
+ exp_smoothed_delays_ms[i]);
+ // Since delay signals are lower than 50ms, they will not be non-linearly
+ // warped.
+ EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(),
+ exp_smoothed_delays_ms[i]);
+ // Zero loss, congestion signal = queuing_delay
+ EXPECT_EQ(nada_feedback->congestion_signal(), exp_smoothed_delays_ms[i]);
+ if (i == 0) {
+ EXPECT_NEAR(nada_feedback->derivative(),
+ static_cast<float>(exp_smoothed_delays_ms[i]) / kTimeGapMs,
+ 0.005f);
+ } else {
+ EXPECT_NEAR(nada_feedback->derivative(),
+ static_cast<float>(exp_smoothed_delays_ms[i] -
+ exp_smoothed_delays_ms[i - 1]) /
+ kTimeGapMs,
+ 0.005f);
+ }
+ }
+}
+
+int64_t Warp(int64_t input) {
+ const int64_t kMinThreshold = 50; // Referred as d_th.
+ const int64_t kMaxThreshold = 400; // Referred as d_max.
+ if (input < kMinThreshold) {
+ return input;
+ } else if (input < kMaxThreshold) {
+ return static_cast<int64_t>(
+ pow((static_cast<double>(kMaxThreshold - input)) /
+ (kMaxThreshold - kMinThreshold),
+ 4.0) *
+ kMinThreshold);
+ } else {
+ return 0L;
+ }
+}
+
+TEST_F(NadaReceiverSideTest, FeedbackWarpedDelay) {
+ // Since packets are 100ms apart, each one corresponds to a feedback.
+ const int64_t kTimeGapMs = 100; // Between each packet.
+
+ // Raw delays are = [50 250 450 650 850 1050 1250 1450] ms.
+ // Baseline delay will be 50 ms.
+ // Delay signals should be: [0 200 400 600 800 1000 1200 1400] ms.
+ const int64_t kMedianFilteredDelaysMs[] = {
+ 0, 100, 200, 300, 400, 600, 800, 1000};
+ const int kNumPackets = ARRAY_SIZE(kMedianFilteredDelaysMs);
+ const float kAlpha = 0.1f; // Used for exponential smoothing.
+
+ int64_t exp_smoothed_delays_ms[kNumPackets];
+ exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0];
+
+ for (int i = 1; i < kNumPackets; ++i) {
+ exp_smoothed_delays_ms[i] = static_cast<int64_t>(
+ kAlpha * kMedianFilteredDelaysMs[i] +
+ (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f);
+ }
+
+ for (int i = 0; i < kNumPackets; ++i) {
+ int64_t send_time_us = (i + 1) * kTimeGapMs * 1000;
+ int64_t arrival_time_ms = send_time_us / 1000 + 50 + 200 * i;
+ uint16_t sequence_number = static_cast<uint16_t>(i + 1);
+ // Payload sizes are not important here.
+ const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
+ nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
+
+ rtc::scoped_ptr<NadaFeedback> nada_feedback(static_cast<NadaFeedback*>(
+ nada_receiver_.GetFeedback(arrival_time_ms)));
+ EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(),
+ exp_smoothed_delays_ms[i]);
+ // Delays can be non-linearly warped.
+ EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(),
+ Warp(exp_smoothed_delays_ms[i]));
+ // Zero loss, congestion signal = queuing_delay
+ EXPECT_EQ(nada_feedback->congestion_signal(),
+ Warp(exp_smoothed_delays_ms[i]));
+ }
+}
+
+TEST_F(FilterTest, MedianConstantArray) {
+ MedianFilterConstantArray();
+ for (int i = 0; i < kNumElements; ++i) {
+ EXPECT_EQ(median_filtered_[i], raw_signal_[i]);
+ }
+}
+
+TEST_F(FilterTest, MedianIntermittentNoise) {
+ MedianFilterIntermittentNoise();
+}
+
+TEST_F(FilterTest, ExponentialSmoothingConstantArray) {
+ int64_t exp_smoothed[kNumElements];
+ ExponentialSmoothingConstantArray(exp_smoothed);
+ for (int i = 0; i < kNumElements; ++i) {
+ EXPECT_EQ(exp_smoothed[i], kSignalValue);
+ }
+}
+
+TEST_F(FilterTest, ExponentialSmoothingInitialPertubation) {
+ const int64_t kSignal[] = {90000, 0, 0, 0, 0, 0};
+ const int kNumElements = ARRAY_SIZE(kSignal);
+ int64_t exp_smoothed[kNumElements];
+ ExponentialSmoothingFilter(kSignal, kNumElements, exp_smoothed);
+ for (int i = 1; i < kNumElements; ++i) {
+ EXPECT_EQ(
+ exp_smoothed[i],
+ static_cast<int64_t>(exp_smoothed[i - 1] * (1.0f - kAlpha) + 0.5f));
+ }
+}
+
+} // namespace bwe
+} // namespace testing
+} // namespace webrtc