From 12561e06ce27c302e162ed82374f420cd4de572a Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Fri, 7 Jun 2019 17:54:00 +0200 Subject: [PATCH] Removes legacy remote bitrate estimator test framework. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It isn't actively maintained to be up to date but depends on internals increasing maintenance burden. There's now better tools available to evaluate congestion controller performance that should be used if we want to start maintaining this functionality again. Bug: webrtc:9883 Change-Id: I097747e6f31a3d1522ef8dfda84f995e33f3a697 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/140887 Commit-Queue: Sebastian Jansson Reviewed-by: Björn Terelius Cr-Commit-Position: refs/heads/master@{#28205} --- modules/remote_bitrate_estimator/BUILD.gn | 126 +-- .../bwe_simulations.cc | 560 --------- .../remote_bitrate_estimators_test.cc | 248 ---- .../test/bbr_paced_sender.cc | 139 --- .../test/bbr_paced_sender.h | 93 -- modules/remote_bitrate_estimator/test/bwe.cc | 266 ----- modules/remote_bitrate_estimator/test/bwe.h | 197 ---- .../remote_bitrate_estimator/test/bwe_test.cc | 1005 ----------------- .../remote_bitrate_estimator/test/bwe_test.h | 197 ---- .../test/bwe_test_baselinefile.cc | 165 --- .../test/bwe_test_baselinefile.h | 45 - .../test/bwe_test_fileutils.cc | 96 -- .../test/bwe_test_fileutils.h | 58 - .../test/bwe_test_framework.cc | 812 ------------- .../test/bwe_test_framework.h | 463 -------- .../test/bwe_test_framework_unittest.cc | 975 ---------------- .../test/bwe_unittest.cc | 393 ------- .../test/estimators/bbr.cc | 582 ---------- .../test/estimators/bbr.h | 233 ---- .../test/estimators/congestion_window.cc | 66 -- .../test/estimators/congestion_window.h | 51 - .../estimators/congestion_window_unittest.cc | 63 -- .../test/estimators/max_bandwidth_filter.cc | 86 -- .../test/estimators/max_bandwidth_filter.h | 48 - .../max_bandwidth_filter_unittest.cc | 84 -- .../test/estimators/min_rtt_filter.cc | 23 - .../test/estimators/min_rtt_filter.h | 72 -- .../estimators/min_rtt_filter_unittest.cc | 42 - .../test/estimators/nada.cc | 289 ----- .../test/estimators/nada.h | 110 -- .../test/estimators/nada_unittest.cc | 494 -------- .../test/estimators/remb.cc | 156 --- .../test/estimators/remb.h | 87 -- .../test/estimators/send_side.cc | 190 ---- .../test/estimators/send_side.h | 91 -- .../test/estimators/tcp.cc | 45 - .../test/estimators/tcp.h | 40 - .../test/metric_recorder.cc | 453 -------- .../test/metric_recorder.h | 190 ---- .../test/metric_recorder_unittest.cc | 112 -- .../remote_bitrate_estimator/test/packet.cc | 100 -- .../remote_bitrate_estimator/test/packet.h | 214 ---- .../test/packet_receiver.cc | 142 --- .../test/packet_receiver.h | 74 -- .../test/packet_sender.cc | 533 --------- .../test/packet_sender.h | 206 ---- .../test/plot_bars.sh | 286 ----- .../test/plot_dynamics.py | 182 --- 48 files changed, 2 insertions(+), 11180 deletions(-) delete mode 100644 modules/remote_bitrate_estimator/bwe_simulations.cc delete mode 100644 modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc delete mode 100644 modules/remote_bitrate_estimator/test/bbr_paced_sender.cc delete mode 100644 modules/remote_bitrate_estimator/test/bbr_paced_sender.h delete mode 100644 modules/remote_bitrate_estimator/test/bwe.cc delete mode 100644 modules/remote_bitrate_estimator/test/bwe.h delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test.cc delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test.h delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test_fileutils.cc delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test_fileutils.h delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test_framework.cc delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test_framework.h delete mode 100644 modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc delete mode 100644 modules/remote_bitrate_estimator/test/bwe_unittest.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/bbr.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/bbr.h delete mode 100644 modules/remote_bitrate_estimator/test/estimators/congestion_window.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/congestion_window.h delete mode 100644 modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h delete mode 100644 modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h delete mode 100644 modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/nada.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/nada.h delete mode 100644 modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/remb.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/remb.h delete mode 100644 modules/remote_bitrate_estimator/test/estimators/send_side.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/send_side.h delete mode 100644 modules/remote_bitrate_estimator/test/estimators/tcp.cc delete mode 100644 modules/remote_bitrate_estimator/test/estimators/tcp.h delete mode 100644 modules/remote_bitrate_estimator/test/metric_recorder.cc delete mode 100644 modules/remote_bitrate_estimator/test/metric_recorder.h delete mode 100644 modules/remote_bitrate_estimator/test/metric_recorder_unittest.cc delete mode 100644 modules/remote_bitrate_estimator/test/packet.cc delete mode 100644 modules/remote_bitrate_estimator/test/packet.h delete mode 100644 modules/remote_bitrate_estimator/test/packet_receiver.cc delete mode 100644 modules/remote_bitrate_estimator/test/packet_receiver.h delete mode 100644 modules/remote_bitrate_estimator/test/packet_sender.cc delete mode 100644 modules/remote_bitrate_estimator/test/packet_sender.h delete mode 100755 modules/remote_bitrate_estimator/test/plot_bars.sh delete mode 100755 modules/remote_bitrate_estimator/test/plot_dynamics.py diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn index ea2a5279fb..b4fe0d5b97 100644 --- a/modules/remote_bitrate_estimator/BUILD.gn +++ b/modules/remote_bitrate_estimator/BUILD.gn @@ -80,108 +80,9 @@ if (!build_with_chromium) { } if (rtc_include_tests) { - rtc_static_library("bwe_simulator_lib") { - testonly = true - sources = [ - "test/bbr_paced_sender.cc", - "test/bbr_paced_sender.h", - "test/bwe.cc", - "test/bwe.h", - "test/bwe_test.cc", - "test/bwe_test.h", - "test/bwe_test_baselinefile.cc", - "test/bwe_test_baselinefile.h", - "test/bwe_test_fileutils.cc", - "test/bwe_test_fileutils.h", - "test/bwe_test_framework.cc", - "test/bwe_test_framework.h", - "test/bwe_test_logging.h", - "test/estimators/bbr.cc", - "test/estimators/bbr.h", - "test/estimators/congestion_window.cc", - "test/estimators/congestion_window.h", - "test/estimators/max_bandwidth_filter.cc", - "test/estimators/max_bandwidth_filter.h", - "test/estimators/min_rtt_filter.cc", - "test/estimators/min_rtt_filter.h", - "test/estimators/nada.cc", - "test/estimators/nada.h", - "test/estimators/remb.cc", - "test/estimators/remb.h", - "test/estimators/send_side.cc", - "test/estimators/send_side.h", - "test/estimators/tcp.cc", - "test/estimators/tcp.h", - "test/metric_recorder.cc", - "test/metric_recorder.h", - "test/packet.cc", - "test/packet.h", - "test/packet_receiver.cc", - "test/packet_receiver.h", - "test/packet_sender.cc", - "test/packet_sender.h", - ] - - if (rtc_enable_bwe_test_logging) { - defines = [ "BWE_TEST_LOGGING_COMPILE_TIME_ENABLE=1" ] - } else { - defines = [ "BWE_TEST_LOGGING_COMPILE_TIME_ENABLE=0" ] - } - - deps = [ - ":remote_bitrate_estimator", - "..:module_api", - "..:module_api_public", - "../..:webrtc_common", - "../../api:rtp_headers", - "../../api/transport:field_trial_based_config", - "../../api/transport:network_control", - "../../logging:mocks", - "../../rtc_base", - "../../rtc_base:checks", - "../../rtc_base:gtest_prod", - "../../rtc_base:rtc_base_approved", - "../../rtc_base:rtc_numerics", - "../../rtc_base:safe_minmax", - "../../rtc_base/experiments:alr_experiment", - "../../rtc_base/system:fallthrough", - "../../rtc_base/system:unused", - "../../system_wrappers", - "../../system_wrappers:field_trial", - "../../test:fileutils", - "../../test:perf_test", - "../../test:test_support", - "../bitrate_controller", - "../congestion_controller", - "../congestion_controller:transport_feedback", - "../congestion_controller/goog_cc:delay_based_bwe", - "../congestion_controller/goog_cc:estimators", - "../congestion_controller/rtp:transport_feedback", - "../pacing", - "../rtp_rtcp", - "../rtp_rtcp:rtp_rtcp_format", - "../video_coding:video_coding_utility", - "//testing/gtest", - "//third_party/abseil-cpp/absl/memory", - "//third_party/abseil-cpp/absl/types:optional", - ] - } - + # TODO(srte): Remove this target when the dependency in root BUILD.gn is removed. rtc_source_set("remote_bitrate_estimator_perf_tests") { testonly = true - - sources = [ - "remote_bitrate_estimators_test.cc", - ] - deps = [ - ":bwe_simulator_lib", - ":remote_bitrate_estimator", - "../../rtc_base:rtc_base_approved", - "../../system_wrappers", - "../../test:field_trial", - "../../test:fileutils", - "../../test:test_support", - ] } rtc_source_set("remote_bitrate_estimator_unittests") { @@ -196,16 +97,8 @@ if (rtc_include_tests) { "remote_bitrate_estimator_unittest_helper.cc", "remote_bitrate_estimator_unittest_helper.h", "remote_estimator_proxy_unittest.cc", - "test/bwe_test_framework_unittest.cc", - "test/bwe_unittest.cc", - "test/estimators/congestion_window_unittest.cc", - "test/estimators/max_bandwidth_filter_unittest.cc", - "test/estimators/min_rtt_filter_unittest.cc", - "test/estimators/nada_unittest.cc", - "test/metric_recorder_unittest.cc", ] deps = [ - ":bwe_simulator_lib", ":remote_bitrate_estimator", "..:module_api_public", "../..:webrtc_common", @@ -222,27 +115,12 @@ if (rtc_include_tests) { ] } + # TODO(srte): Remove this target when the dependency in root BUILD.gn is removed. rtc_test("bwe_simulations_tests") { testonly = true - - sources = [ - "bwe_simulations.cc", - ] deps = [ - ":bwe_simulator_lib", - ":remote_bitrate_estimator", - "../..:webrtc_common", - "../../rtc_base:rtc_base_approved", - "../../system_wrappers", - "../../test:fileutils", "../../test:test_main", - "../../test:test_support", "//testing/gtest", ] - data = [ - "//resources/sprint-uplink.rx", - "//resources/verizon4g-downlink.rx", - "//resources/google-wifi-3mbps.rx", - ] } } diff --git a/modules/remote_bitrate_estimator/bwe_simulations.cc b/modules/remote_bitrate_estimator/bwe_simulations.cc deleted file mode 100644 index 68ba01cb42..0000000000 --- a/modules/remote_bitrate_estimator/bwe_simulations.cc +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Copyright (c) 2014 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 -#include -#include -#include -#include - -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "modules/remote_bitrate_estimator/test/packet_receiver.h" -#include "modules/remote_bitrate_estimator/test/packet_sender.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/random.h" -#include "system_wrappers/include/clock.h" -#include "test/gtest.h" -#include "test/testsupport/file_utils.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -// This test fixture is used to instantiate tests running with adaptive video -// senders. -class BweSimulation : public BweTest, - public ::testing::TestWithParam { - public: - BweSimulation() - : BweTest(), random_(Clock::GetRealTimeClock()->TimeInMicroseconds()) {} - ~BweSimulation() override {} - - protected: - void SetUp() override { - BweTest::SetUp(); - VerboseLogging(true); - } - - Random random_; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(BweSimulation); -}; - -INSTANTIATE_TEST_SUITE_P(VideoSendersTest, - BweSimulation, - ::testing::Values(kRembEstimator, - kSendSideEstimator, - kNadaEstimator, - kBbrEstimator)); - -TEST_P(BweSimulation, SprintUplinkTest) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - RateCounterFilter counter1(&uplink_, 0, "sender_output", - bwe_names[GetParam()]); - TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity"); - RateCounterFilter counter2(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - ASSERT_TRUE(filter.Init(test::ResourcePath("sprint-uplink", "rx"))); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, Verizon4gDownlinkTest) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&downlink_, &source, GetParam()); - RateCounterFilter counter1(&downlink_, 0, "sender_output", - std::string() + bwe_names[GetParam()] + "_up"); - TraceBasedDeliveryFilter filter(&downlink_, 0, "link_capacity"); - RateCounterFilter counter2(&downlink_, 0, "Receiver", - std::string() + bwe_names[GetParam()] + "_down"); - PacketReceiver receiver(&downlink_, 0, GetParam(), true, true); - ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx"))); - RunFor(22 * 60 * 1000); -} - -TEST_P(BweSimulation, Choke1000kbps500kbps1000kbpsBiDirectional) { - const int kFlowIds[] = {0, 1}; - const size_t kNumFlows = sizeof(kFlowIds) / sizeof(kFlowIds[0]); - - AdaptiveVideoSource source(kFlowIds[0], 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter choke(&uplink_, kFlowIds[0]); - RateCounterFilter counter(&uplink_, kFlowIds[0], "Receiver_0", - bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, kFlowIds[0], GetParam(), true, false); - - AdaptiveVideoSource source2(kFlowIds[1], 30, 300, 0, 0); - VideoSender sender2(&downlink_, &source2, GetParam()); - ChokeFilter choke2(&downlink_, kFlowIds[1]); - DelayFilter delay(&downlink_, CreateFlowIds(kFlowIds, kNumFlows)); - RateCounterFilter counter2(&downlink_, kFlowIds[1], "Receiver_1", - bwe_names[GetParam()]); - PacketReceiver receiver2(&downlink_, kFlowIds[1], GetParam(), true, false); - - choke2.set_capacity_kbps(500); - delay.SetOneWayDelayMs(0); - - choke.set_capacity_kbps(1000); - choke.set_max_delay_ms(500); - RunFor(60 * 1000); - choke.set_capacity_kbps(500); - RunFor(60 * 1000); - choke.set_capacity_kbps(1000); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter choke(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, false); - - choke.set_capacity_kbps(1000); - choke.set_max_delay_ms(500); - RunFor(60 * 1000); - choke.set_capacity_kbps(500); - RunFor(60 * 1000); - choke.set_capacity_kbps(1000); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, SimulationsCompiled) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, GetParam()); - int zero = 0; - // CreateFlowIds() doesn't support passing int as a flow id, so we pass - // pointer instead. - DelayFilter delay(&uplink_, CreateFlowIds(&zero, 1)); - delay.SetOneWayDelayMs(100); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_max_delay_ms(500); - filter.set_capacity_kbps(1000); - RunFor(60 * 1000); - filter.set_capacity_kbps(500); - RunFor(50 * 1000); - filter.set_capacity_kbps(1000); - RunFor(60 * 1000); - filter.set_capacity_kbps(200); - RunFor(60 * 1000); - filter.set_capacity_kbps(50); - RunFor(60 * 1000); - filter.set_capacity_kbps(200); - RunFor(60 * 1000); - filter.set_capacity_kbps(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(300); - RunFor(60 * 1000); - filter.set_capacity_kbps(1000); - RunFor(60 * 1000); - const int kStartingCapacityKbps = 150; - const int kEndingCapacityKbps = 1500; - const int kStepKbps = 5; - const int kStepTimeMs = 1000; - for (int i = kStartingCapacityKbps; i <= kEndingCapacityKbps; - i += kStepKbps) { - filter.set_capacity_kbps(i); - RunFor(kStepTimeMs); - } - for (int i = kEndingCapacityKbps; i >= kStartingCapacityKbps; - i -= kStepKbps) { - filter.set_capacity_kbps(i); - RunFor(kStepTimeMs); - } - filter.set_capacity_kbps(150); - RunFor(120 * 1000); - filter.set_capacity_kbps(500); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, GetParam()); - const int kFlowId = 0; - // CreateFlowIds() doesn't support passing int as a flow id, so we pass - // pointer instead. - DelayFilter delay(&uplink_, CreateFlowIds(&kFlowId, 1)); - delay.SetOneWayDelayMs(100); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_capacity_kbps(1000); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(1000); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, PacerChoke10000kbps) { - PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_capacity_kbps(10000); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_capacity_kbps(200); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(30); - RunFor(60 * 1000); - filter.set_capacity_kbps(200); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, Choke200kbps30kbps200kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_capacity_kbps(200); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(30); - RunFor(60 * 1000); - filter.set_capacity_kbps(200); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, PacerChoke50kbps15kbps50kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_capacity_kbps(50); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(15); - RunFor(60 * 1000); - filter.set_capacity_kbps(50); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, Choke50kbps15kbps50kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_capacity_kbps(50); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(15); - RunFor(60 * 1000); - filter.set_capacity_kbps(50); - RunFor(60 * 1000); -} - -TEST_P(BweSimulation, GoogleWifiTrace3Mbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - RateCounterFilter counter1(&uplink_, 0, "sender_output", - bwe_names[GetParam()]); - TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity"); - filter.set_max_delay_ms(500); - RateCounterFilter counter2(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx"))); - RunFor(300 * 1000); -} - -TEST_P(BweSimulation, LinearIncreasingCapacity) { - PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000000); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_max_delay_ms(500); - const int kStartingCapacityKbps = 150; - const int kEndingCapacityKbps = 1500; - const int kStepKbps = 5; - const int kStepTimeMs = 1000; - - for (int i = kStartingCapacityKbps; i <= kEndingCapacityKbps; - i += kStepKbps) { - filter.set_capacity_kbps(i); - RunFor(kStepTimeMs); - } -} - -TEST_P(BweSimulation, LinearDecreasingCapacity) { - PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000000); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - filter.set_max_delay_ms(500); - const int kStartingCapacityKbps = 1500; - const int kEndingCapacityKbps = 150; - const int kStepKbps = -5; - const int kStepTimeMs = 1000; - - for (int i = kStartingCapacityKbps; i >= kEndingCapacityKbps; - i += kStepKbps) { - filter.set_capacity_kbps(i); - RunFor(kStepTimeMs); - } -} - -TEST_P(BweSimulation, PacerGoogleWifiTrace3Mbps) { - PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000); - PacedVideoSender sender(&uplink_, &source, GetParam()); - int kFlowId = 0; - // CreateFlowIds() doesn't support passing int as a flow id, so we pass - // pointer instead. - DelayFilter delay(&uplink_, CreateFlowIds(&kFlowId, 1)); - delay.SetOneWayDelayMs(100); - RateCounterFilter counter1(&uplink_, 0, "sender_output", - bwe_names[GetParam()]); - TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity"); - filter.set_max_delay_ms(500); - RateCounterFilter counter2(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx"))); - RunFor(300 * 1000); -} - -TEST_P(BweSimulation, PacerGoogleWifiTrace3MbpsLowFramerate) { - PeriodicKeyFrameSource source(0, 5, 300, 0, 0, 1000); - PacedVideoSender sender(&uplink_, &source, GetParam()); - RateCounterFilter counter1(&uplink_, 0, "sender_output", - bwe_names[GetParam()]); - TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity"); - filter.set_max_delay_ms(500); - RateCounterFilter counter2(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), true, true); - ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx"))); - RunFor(300 * 1000); -} - -TEST_P(BweSimulation, SelfFairnessTest) { - Random prng(Clock::GetRealTimeClock()->TimeInMicroseconds()); - const int kAllFlowIds[] = {0, 1, 2, 3}; - const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]); - std::unique_ptr sources[kNumFlows]; - std::unique_ptr senders[kNumFlows]; - for (size_t i = 0; i < kNumFlows; ++i) { - // Streams started 20 seconds apart to give them different advantage when - // competing for the bandwidth. - sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, - i * prng.Rand(39999))); - senders[i].reset(new VideoSender(&uplink_, sources[i].get(), GetParam())); - } - - ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows)); - choke.set_capacity_kbps(1000); - - std::unique_ptr rate_counters[kNumFlows]; - for (size_t i = 0; i < kNumFlows; ++i) { - rate_counters[i].reset( - new RateCounterFilter(&uplink_, CreateFlowIds(&kAllFlowIds[i], 1), - "Receiver", bwe_names[GetParam()])); - } - - RateCounterFilter total_utilization( - &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization", - "Total_link_utilization"); - - std::unique_ptr receivers[kNumFlows]; - for (size_t i = 0; i < kNumFlows; ++i) { - receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], GetParam(), - i == 0, false)); - } - - RunFor(30 * 60 * 1000); -} - -TEST_P(BweSimulation, PacedSelfFairness50msTest) { - const int64_t kAverageOffsetMs = 20 * 1000; - const int kNumRmcatFlows = 4; - int64_t offsets_ms[kNumRmcatFlows]; - offsets_ms[0] = random_.Rand(2 * kAverageOffsetMs); - for (int i = 1; i < kNumRmcatFlows; ++i) { - offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(2 * kAverageOffsetMs); - } - RunFairnessTest(GetParam(), kNumRmcatFlows, 0, 1000, 3000, 50, 50, 0, - offsets_ms); -} - -TEST_P(BweSimulation, PacedSelfFairness500msTest) { - const int64_t kAverageOffsetMs = 20 * 1000; - const int kNumRmcatFlows = 4; - int64_t offsets_ms[kNumRmcatFlows]; - offsets_ms[0] = random_.Rand(2 * kAverageOffsetMs); - for (int i = 1; i < kNumRmcatFlows; ++i) { - offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(2 * kAverageOffsetMs); - } - RunFairnessTest(GetParam(), kNumRmcatFlows, 0, 1000, 3000, 500, 50, 0, - offsets_ms); -} - -TEST_P(BweSimulation, PacedSelfFairness1000msTest) { - const int64_t kAverageOffsetMs = 20 * 1000; - const int kNumRmcatFlows = 4; - int64_t offsets_ms[kNumRmcatFlows]; - offsets_ms[0] = random_.Rand(2 * kAverageOffsetMs); - for (int i = 1; i < kNumRmcatFlows; ++i) { - offsets_ms[i] = offsets_ms[i - 1] + random_.Rand(2 * kAverageOffsetMs); - } - RunFairnessTest(GetParam(), 4, 0, 1000, 3000, 1000, 50, 0, offsets_ms); -} - -TEST_P(BweSimulation, TcpFairness50msTest) { - const int64_t kAverageOffsetMs = 20 * 1000; - int64_t offset_ms[] = {random_.Rand(2 * kAverageOffsetMs), 0}; - RunFairnessTest(GetParam(), 1, 1, 1000, 2000, 50, 50, 0, offset_ms); -} - -TEST_P(BweSimulation, TcpFairness500msTest) { - const int64_t kAverageOffsetMs = 20 * 1000; - int64_t offset_ms[] = {random_.Rand(2 * kAverageOffsetMs), 0}; - RunFairnessTest(GetParam(), 1, 1, 1000, 2000, 500, 50, 0, offset_ms); -} - -TEST_P(BweSimulation, TcpFairness1000msTest) { - const int kAverageOffsetMs = 20 * 1000; - int64_t offset_ms[] = {random_.Rand(2 * kAverageOffsetMs), 0}; - RunFairnessTest(GetParam(), 1, 1, 1000, 2000, 1000, 50, 0, offset_ms); -} - -// The following test cases begin with "Evaluation" as a reference to the -// Internet draft https://tools.ietf.org/html/draft-ietf-rmcat-eval-test-01. - -TEST_P(BweSimulation, Evaluation1) { - RunVariableCapacity1SingleFlow(GetParam()); -} - -TEST_P(BweSimulation, Evaluation2) { - const size_t kNumFlows = 2; - RunVariableCapacity2MultipleFlows(GetParam(), kNumFlows); -} - -TEST_P(BweSimulation, Evaluation3) { - RunBidirectionalFlow(GetParam()); -} - -TEST_P(BweSimulation, Evaluation4) { - RunSelfFairness(GetParam()); -} - -TEST_P(BweSimulation, Evaluation5) { - RunRoundTripTimeFairness(GetParam()); -} - -TEST_P(BweSimulation, Evaluation6) { - RunLongTcpFairness(GetParam()); -} - -// Different calls to the Evaluation7 will create the same FileSizes -// and StartingTimes as long as the seeds remain unchanged. This is essential -// when calling it with multiple estimators for comparison purposes. -TEST_P(BweSimulation, Evaluation7) { - const int kNumTcpFiles = 10; - RunMultipleShortTcpFairness(GetParam(), - BweTest::GetFileSizesBytes(kNumTcpFiles), - BweTest::GetStartingTimesMs(kNumTcpFiles)); -} - -TEST_P(BweSimulation, Evaluation8) { - RunPauseResumeFlows(GetParam()); -} - -// Following test cases begin with "GoogCcComparison" run the -// evaluation test cases for both GoogCc and other calling RMCAT. - -TEST_P(BweSimulation, GoogCcComparison1) { - RunVariableCapacity1SingleFlow(GetParam()); - BweTest goog_cc_test(false); - goog_cc_test.RunVariableCapacity1SingleFlow(kSendSideEstimator); -} - -TEST_P(BweSimulation, GoogCcComparison2) { - const size_t kNumFlows = 2; - RunVariableCapacity2MultipleFlows(GetParam(), kNumFlows); - BweTest goog_cc_test(false); - goog_cc_test.RunVariableCapacity2MultipleFlows(kSendSideEstimator, kNumFlows); -} - -TEST_P(BweSimulation, GoogCcComparison3) { - RunBidirectionalFlow(GetParam()); - BweTest goog_cc_test(false); - goog_cc_test.RunBidirectionalFlow(kSendSideEstimator); -} - -TEST_P(BweSimulation, GoogCcComparison4) { - RunSelfFairness(GetParam()); - BweTest goog_cc_test(false); - goog_cc_test.RunSelfFairness(GetParam()); -} - -TEST_P(BweSimulation, GoogCcComparison5) { - RunRoundTripTimeFairness(GetParam()); - BweTest goog_cc_test(false); - goog_cc_test.RunRoundTripTimeFairness(kSendSideEstimator); -} - -TEST_P(BweSimulation, GoogCcComparison6) { - RunLongTcpFairness(GetParam()); - BweTest goog_cc_test(false); - goog_cc_test.RunLongTcpFairness(kSendSideEstimator); -} - -TEST_P(BweSimulation, GoogCcComparison7) { - const int kNumTcpFiles = 10; - - std::vector tcp_file_sizes_bytes = - BweTest::GetFileSizesBytes(kNumTcpFiles); - std::vector tcp_starting_times_ms = - BweTest::GetStartingTimesMs(kNumTcpFiles); - - RunMultipleShortTcpFairness(GetParam(), tcp_file_sizes_bytes, - tcp_starting_times_ms); - - BweTest goog_cc_test(false); - goog_cc_test.RunMultipleShortTcpFairness( - kSendSideEstimator, tcp_file_sizes_bytes, tcp_starting_times_ms); -} - -TEST_P(BweSimulation, GoogCcComparison8) { - RunPauseResumeFlows(GetParam()); - BweTest goog_cc_test(false); - goog_cc_test.RunPauseResumeFlows(kSendSideEstimator); -} - -TEST_P(BweSimulation, GoogCcComparisonChoke) { - int array[] = {1000, 500, 1000}; - std::vector capacities_kbps(array, array + 3); - RunChoke(GetParam(), capacities_kbps); - - BweTest goog_cc_test(false); - goog_cc_test.RunChoke(kSendSideEstimator, capacities_kbps); -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc deleted file mode 100644 index f58e9d3995..0000000000 --- a/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2013 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 WEBRTC_WIN -#include -#endif - -#include -#include - -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "modules/remote_bitrate_estimator/test/packet_receiver.h" -#include "modules/remote_bitrate_estimator/test/packet_sender.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/random.h" -#include "system_wrappers/include/clock.h" -#include "test/field_trial.h" -#include "test/gtest.h" -#include "test/testsupport/file_utils.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -// This test fixture is used to instantiate tests running with adaptive video -// senders. -class BweFeedbackTest - : public BweTest, - public ::testing::TestWithParam { - public: -#ifdef WEBRTC_WIN - BweFeedbackTest() - : BweTest(), random_(Clock::GetRealTimeClock()->TimeInMicroseconds()) {} -#else - BweFeedbackTest() - : BweTest(), - // Multiply the time by a random-ish odd number derived from the PID. - random_((getpid() | 1) * - Clock::GetRealTimeClock()->TimeInMicroseconds()) {} -#endif - virtual ~BweFeedbackTest() {} - - protected: - Random random_; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(BweFeedbackTest); -}; - -INSTANTIATE_TEST_SUITE_P(VideoSendersTest, - BweFeedbackTest, - ::testing::Values(kRembEstimator, kSendSideEstimator)); - -TEST_P(BweFeedbackTest, ConstantCapacity) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), false, false); - const int kCapacityKbps = 1000; - filter.set_capacity_kbps(kCapacityKbps); - filter.set_max_delay_ms(500); - RunFor(180 * 1000); - PrintResults(kCapacityKbps, counter.GetBitrateStats(), 0, - receiver.GetDelayStats(), counter.GetBitrateStats()); -} - -TEST_P(BweFeedbackTest, Choke1000kbps500kbps1000kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), false, false); - const int kHighCapacityKbps = 1000; - const int kLowCapacityKbps = 500; - filter.set_capacity_kbps(kHighCapacityKbps); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(kLowCapacityKbps); - RunFor(60 * 1000); - filter.set_capacity_kbps(kHighCapacityKbps); - RunFor(60 * 1000); - PrintResults((2 * kHighCapacityKbps + kLowCapacityKbps) / 3.0, - counter.GetBitrateStats(), 0, receiver.GetDelayStats(), - counter.GetBitrateStats()); -} - -TEST_P(BweFeedbackTest, Choke200kbps30kbps200kbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, GetParam()); - ChokeFilter filter(&uplink_, 0); - RateCounterFilter counter(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), false, false); - const int kHighCapacityKbps = 200; - const int kLowCapacityKbps = 30; - filter.set_capacity_kbps(kHighCapacityKbps); - filter.set_max_delay_ms(500); - RunFor(60 * 1000); - filter.set_capacity_kbps(kLowCapacityKbps); - RunFor(60 * 1000); - filter.set_capacity_kbps(kHighCapacityKbps); - RunFor(60 * 1000); - - PrintResults((2 * kHighCapacityKbps + kLowCapacityKbps) / 3.0, - counter.GetBitrateStats(), 0, receiver.GetDelayStats(), - counter.GetBitrateStats()); -} - -TEST_P(BweFeedbackTest, Verizon4gDownlinkTest) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - RateCounterFilter counter1(&uplink_, 0, "sender_output", - bwe_names[GetParam()]); - TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity"); - RateCounterFilter counter2(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), false, false); - ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx"))); - RunFor(22 * 60 * 1000); - PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(), - 0, receiver.GetDelayStats(), counter2.GetBitrateStats()); -} - -// webrtc:3277 -TEST_P(BweFeedbackTest, GoogleWifiTrace3Mbps) { - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - RateCounterFilter counter1(&uplink_, 0, "sender_output", - bwe_names[GetParam()]); - TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity"); - filter.set_max_delay_ms(500); - RateCounterFilter counter2(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), false, false); - ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx"))); - RunFor(300 * 1000); - PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(), - 0, receiver.GetDelayStats(), counter2.GetBitrateStats()); -} - -TEST_P(BweFeedbackTest, GoogleWifiTrace3MbpsStreaming) { - test::ScopedFieldTrials override_field_trials( - "WebRTC-BweWindowSizeInPackets/Enabled-100/" - "WebRTC-BweBackOffFactor/Enabled-0.95/"); - AdaptiveVideoSource source(0, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, GetParam()); - RateCounterFilter counter1(&uplink_, 0, "sender_output", - bwe_names[GetParam()]); - TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity"); - filter.set_max_delay_ms(500); - RateCounterFilter counter2(&uplink_, 0, "Receiver", bwe_names[GetParam()]); - PacketReceiver receiver(&uplink_, 0, GetParam(), false, false); - ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx"))); - RunFor(300 * 1000); - PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(), - 0, receiver.GetDelayStats(), counter2.GetBitrateStats()); -} - -TEST_P(BweFeedbackTest, PacedSelfFairness50msTest) { - int64_t kRttMs = 100; - int64_t kMaxJitterMs = 15; - - const int kNumRmcatFlows = 4; - int64_t offset_ms[kNumRmcatFlows]; - for (int i = 0; i < kNumRmcatFlows; ++i) { - offset_ms[i] = std::max(0, 5000 * i + random_.Rand(-1000, 1000)); - } - - RunFairnessTest(GetParam(), kNumRmcatFlows, 0, 300, 3000, 50, kRttMs, - kMaxJitterMs, offset_ms); -} - -TEST_P(BweFeedbackTest, PacedSelfFairness500msTest) { - int64_t kRttMs = 100; - int64_t kMaxJitterMs = 15; - - const int kNumRmcatFlows = 4; - int64_t offset_ms[kNumRmcatFlows]; - for (int i = 0; i < kNumRmcatFlows; ++i) { - offset_ms[i] = std::max(0, 5000 * i + random_.Rand(-1000, 1000)); - } - - RunFairnessTest(GetParam(), kNumRmcatFlows, 0, 300, 3000, 500, kRttMs, - kMaxJitterMs, offset_ms); -} - -TEST_P(BweFeedbackTest, PacedSelfFairness1000msTest) { - int64_t kRttMs = 100; - int64_t kMaxJitterMs = 15; - - const int kNumRmcatFlows = 4; - int64_t offset_ms[kNumRmcatFlows]; - for (int i = 0; i < kNumRmcatFlows; ++i) { - offset_ms[i] = std::max(0, 5000 * i + random_.Rand(-1000, 1000)); - } - - RunFairnessTest(GetParam(), kNumRmcatFlows, 0, 300, 3000, 1000, kRttMs, - kMaxJitterMs, offset_ms); -} - -TEST_P(BweFeedbackTest, TcpFairness50msTest) { - int64_t kRttMs = 100; - int64_t kMaxJitterMs = 15; - - int64_t offset_ms[2]; // One TCP, one RMCAT flow. - for (int i = 0; i < 2; ++i) { - offset_ms[i] = std::max(0, 5000 * i + random_.Rand(-1000, 1000)); - } - - RunFairnessTest(GetParam(), 1, 1, 300, 2000, 50, kRttMs, kMaxJitterMs, - offset_ms); -} - -TEST_P(BweFeedbackTest, TcpFairness500msTest) { - int64_t kRttMs = 100; - int64_t kMaxJitterMs = 15; - - int64_t offset_ms[2]; // One TCP, one RMCAT flow. - for (int i = 0; i < 2; ++i) { - offset_ms[i] = std::max(0, 5000 * i + random_.Rand(-1000, 1000)); - } - - RunFairnessTest(GetParam(), 1, 1, 300, 2000, 500, kRttMs, kMaxJitterMs, - offset_ms); -} - -TEST_P(BweFeedbackTest, TcpFairness1000msTest) { - int64_t kRttMs = 100; - int64_t kMaxJitterMs = 15; - - int64_t offset_ms[2]; // One TCP, one RMCAT flow. - for (int i = 0; i < 2; ++i) { - offset_ms[i] = std::max(0, 5000 * i + random_.Rand(-1000, 1000)); - } - - RunFairnessTest(GetParam(), 1, 1, 300, 2000, 1000, kRttMs, kMaxJitterMs, - offset_ms); -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bbr_paced_sender.cc b/modules/remote_bitrate_estimator/test/bbr_paced_sender.cc deleted file mode 100644 index 620fd1bb0c..0000000000 --- a/modules/remote_bitrate_estimator/test/bbr_paced_sender.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2017 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/remote_bitrate_estimator/test/bbr_paced_sender.h" - -#include - -#include "api/transport/network_types.h" -#include "modules/pacing/paced_sender.h" -#include "modules/remote_bitrate_estimator/test/estimators/congestion_window.h" -#include "system_wrappers/include/clock.h" - -namespace webrtc { - -BbrPacedSender::BbrPacedSender(Clock* clock, - PacedSender::PacketSender* packet_sender, - RtcEventLog* event_log) - : clock_(clock), - packet_sender_(packet_sender), - estimated_bitrate_bps_(100000), - min_send_bitrate_kbps_(0), - pacing_bitrate_kbps_(0), - time_last_update_us_(clock->TimeInMicroseconds()), - time_last_update_ms_(clock->TimeInMilliseconds()), - next_packet_send_time_(clock_->TimeInMilliseconds()), - rounding_error_time_ms_(0.0f), - packets_(), - max_data_inflight_bytes_(10000), - congestion_window_(new testing::bwe::CongestionWindow()) {} -BbrPacedSender::~BbrPacedSender() {} - -void BbrPacedSender::SetEstimatedBitrateAndCongestionWindow( - uint32_t bitrate_bps, - bool in_probe_rtt, - uint64_t congestion_window) { - estimated_bitrate_bps_ = bitrate_bps; - max_data_inflight_bytes_ = congestion_window; -} - -void BbrPacedSender::SetMinBitrate(int min_send_bitrate_bps) { - min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; - pacing_bitrate_kbps_ = - std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000); -} - -void BbrPacedSender::InsertPacket(RtpPacketSender::Priority priority, - uint32_t ssrc, - uint16_t sequence_number, - int64_t capture_time_ms, - size_t bytes, - bool retransmission) { - int64_t now_ms = clock_->TimeInMilliseconds(); - if (capture_time_ms < 0) - capture_time_ms = now_ms; - packets_.push_back(new Packet(priority, ssrc, sequence_number, - capture_time_ms, now_ms, bytes, - retransmission)); -} - -int64_t BbrPacedSender::TimeUntilNextProcess() { - // Once errors absolute value hits 1 millisecond, add compensating term to - // the |next_packet_send_time_|, so that we can send packet earlier or later, - // depending on the error. - rounding_error_time_ms_ = std::min(rounding_error_time_ms_, 1.0f); - if (rounding_error_time_ms_ < -0.9f) - rounding_error_time_ms_ = -1.0f; - int64_t result = - std::max(next_packet_send_time_ + time_last_update_ms_ - - clock_->TimeInMilliseconds(), - 0); - if (rounding_error_time_ms_ == 1.0f || rounding_error_time_ms_ == -1.0f) { - next_packet_send_time_ -= rounding_error_time_ms_; - result = std::max(next_packet_send_time_ + time_last_update_ms_ - - clock_->TimeInMilliseconds(), - 0); - rounding_error_time_ms_ = 0; - } - return result; -} - -void BbrPacedSender::OnBytesAcked(size_t bytes) { - congestion_window_->AckReceived(bytes); -} - -void BbrPacedSender::Process() { - pacing_bitrate_kbps_ = - std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000); - // If we have nothing to send, try sending again in 1 millisecond. - if (packets_.empty()) { - next_packet_send_time_ = 1; - return; - } - // If congestion window doesn't allow sending, try again in 1 millisecond. - if (packets_.front()->size_in_bytes + congestion_window_->data_inflight() > - max_data_inflight_bytes_) { - next_packet_send_time_ = 1; - return; - } - bool sent = TryToSendPacket(packets_.front()); - if (sent) { - congestion_window_->PacketSent(packets_.front()->size_in_bytes); - delete packets_.front(); - packets_.pop_front(); - time_last_update_ms_ = clock_->TimeInMilliseconds(); - if (!packets_.empty()) { - // Calculate in what time we should send current packet. - next_packet_send_time_ = (packets_.front()->size_in_bytes * 8000 + - estimated_bitrate_bps_ / 2) / - estimated_bitrate_bps_; - // As rounding errors may happen, |rounding_error_time_ms_| could be - // positive or negative depending on packet was sent earlier or later, - // after it hits certain threshold we will send a packet earlier or later - // depending on error we had so far. - rounding_error_time_ms_ += - (next_packet_send_time_ - packets_.front()->size_in_bytes * 8000.0f / - estimated_bitrate_bps_ * 1.0f); - } else { - // If sending was unsuccessful try again in 1 millisecond. - next_packet_send_time_ = 1; - } - } -} - -bool BbrPacedSender::TryToSendPacket(Packet* packet) { - PacedPacketInfo pacing_info; - return packet_sender_->TimeToSendPacket( - packet->ssrc, packet->sequence_number, packet->capture_time_ms, - packet->retransmission, - pacing_info) != RtpPacketSendResult::kTransportUnavailable; -} - -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bbr_paced_sender.h b/modules/remote_bitrate_estimator/test/bbr_paced_sender.h deleted file mode 100644 index c782fd946d..0000000000 --- a/modules/remote_bitrate_estimator/test/bbr_paced_sender.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2017 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_REMOTE_BITRATE_ESTIMATOR_TEST_BBR_PACED_SENDER_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BBR_PACED_SENDER_H_ - -#include -#include - -#include "modules/pacing/paced_sender.h" -#include "modules/pacing/pacer.h" - -namespace webrtc { -namespace testing { -namespace bwe { -class CongestionWindow; -} -} // namespace testing - -struct Packet { - Packet(RtpPacketSender::Priority priority, - uint32_t ssrc, - uint16_t seq_number, - int64_t capture_time_ms, - int64_t enqueue_time_ms, - size_t size_in_bytes, - bool retransmission) - : priority(priority), - ssrc(ssrc), - sequence_number(seq_number), - capture_time_ms(capture_time_ms), - enqueue_time_ms(enqueue_time_ms), - size_in_bytes(size_in_bytes), - retransmission(retransmission) {} - RtpPacketSender::Priority priority; - uint32_t ssrc; - uint16_t sequence_number; - int64_t capture_time_ms; - int64_t enqueue_time_ms; - size_t size_in_bytes; - bool retransmission; -}; - -class Clock; -class RtcEventLog; -struct Packet; -class BbrPacedSender : public Pacer { - public: - BbrPacedSender(Clock* clock, - PacedSender::PacketSender* packet_sender, - RtcEventLog* event_log); - ~BbrPacedSender() override; - void SetEstimatedBitrateAndCongestionWindow( - uint32_t bitrate_bps, - bool in_probe_rtt, - uint64_t congestion_window) override; - void SetMinBitrate(int min_send_bitrate_bps); - void InsertPacket(RtpPacketSender::Priority priority, - uint32_t ssrc, - uint16_t sequence_number, - int64_t capture_time_ms, - size_t bytes, - bool retransmission) override; - void SetAccountForAudioPackets(bool account_for_audio) override {} - int64_t TimeUntilNextProcess() override; - void OnBytesAcked(size_t bytes) override; - void Process() override; - bool TryToSendPacket(Packet* packet); - - private: - Clock* const clock_; - PacedSender::PacketSender* const packet_sender_; - uint32_t estimated_bitrate_bps_; - uint32_t min_send_bitrate_kbps_; - uint32_t pacing_bitrate_kbps_; - int64_t time_last_update_us_; - int64_t time_last_update_ms_; - int64_t next_packet_send_time_; - float rounding_error_time_ms_; - std::list packets_; - // TODO(gnish): integrate |max_data_inflight| into congestion window class. - size_t max_data_inflight_bytes_; - std::unique_ptr congestion_window_; -}; -} // namespace webrtc -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BBR_PACED_SENDER_H_ diff --git a/modules/remote_bitrate_estimator/test/bwe.cc b/modules/remote_bitrate_estimator/test/bwe.cc deleted file mode 100644 index b672ddde06..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe.cc +++ /dev/null @@ -1,266 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/bwe.h" - -#include -#include - -#include "modules/remote_bitrate_estimator/test/estimators/bbr.h" -#include "modules/remote_bitrate_estimator/test/estimators/nada.h" -#include "modules/remote_bitrate_estimator/test/estimators/remb.h" -#include "modules/remote_bitrate_estimator/test/estimators/send_side.h" -#include "modules/remote_bitrate_estimator/test/estimators/tcp.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/numerics/safe_conversions.h" -#include "rtc_base/system/fallthrough.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -const int kSetCapacity = 1000; - -BweReceiver::BweReceiver(int flow_id) - : flow_id_(flow_id), - received_packets_(kSetCapacity), - rate_counter_(), - loss_account_() {} - -BweReceiver::BweReceiver(int flow_id, int64_t window_size_ms) - : flow_id_(flow_id), - received_packets_(kSetCapacity), - rate_counter_(window_size_ms), - loss_account_() {} - -void BweReceiver::ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) { - if (received_packets_.size() == kSetCapacity) { - RelieveSetAndUpdateLoss(); - } - - received_packets_.Insert(media_packet.sequence_number(), - media_packet.send_time_ms(), arrival_time_ms, - media_packet.payload_size()); - - rate_counter_.UpdateRates(media_packet.send_time_ms() * 1000, - static_cast(media_packet.payload_size())); -} - -FeedbackPacket* BweReceiver::GetFeedback(int64_t now_ms) { - return nullptr; -} - -class NullBweSender : public BweSender { - public: - NullBweSender() {} - ~NullBweSender() override {} - - int GetFeedbackIntervalMs() const override { return 1000; } - void GiveFeedback(const FeedbackPacket& feedback) override {} - void OnPacketsSent(const Packets& packets) override {} - int64_t TimeUntilNextProcess() override { - return std::numeric_limits::max(); - } - void Process() override {} - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(NullBweSender); -}; - -int64_t GetAbsSendTimeInMs(uint32_t abs_send_time) { - const int kInterArrivalShift = 26; - const int kAbsSendTimeInterArrivalUpshift = 8; - const double kTimestampToMs = - 1000.0 / static_cast(1 << kInterArrivalShift); - uint32_t timestamp = abs_send_time << kAbsSendTimeInterArrivalUpshift; - return static_cast(timestamp) * kTimestampToMs; -} - -BweSender* CreateBweSender(BandwidthEstimatorType estimator, - int kbps, - BitrateObserver* observer, - Clock* clock) { - switch (estimator) { - case kRembEstimator: - return new RembBweSender(kbps, observer, clock); - case kSendSideEstimator: - return new SendSideBweSender(kbps, observer, clock); - case kNadaEstimator: - return new NadaBweSender(kbps, observer, clock); - case kBbrEstimator: - return new BbrBweSender(observer, clock); - case kTcpEstimator: - RTC_FALLTHROUGH(); - case kNullEstimator: - return new NullBweSender(); - } - assert(false); - return NULL; -} - -BweReceiver* CreateBweReceiver(BandwidthEstimatorType type, - int flow_id, - bool plot) { - switch (type) { - case kRembEstimator: - return new RembReceiver(flow_id, plot); - case kSendSideEstimator: - return new SendSideBweReceiver(flow_id); - case kNadaEstimator: - return new NadaBweReceiver(flow_id); - case kBbrEstimator: - return new BbrBweReceiver(flow_id); - case kTcpEstimator: - return new TcpBweReceiver(flow_id); - case kNullEstimator: - return new BweReceiver(flow_id); - } - assert(false); - return NULL; -} - -// Take into account all LinkedSet content. -void BweReceiver::UpdateLoss() { - loss_account_.Add(LinkedSetPacketLossRatio()); -} - -// Preserve 10% latest packets and update packet loss based on the oldest -// 90%, that will be removed. -void BweReceiver::RelieveSetAndUpdateLoss() { - // Compute Loss for the whole LinkedSet and updates loss_account_. - UpdateLoss(); - - size_t num_preserved_elements = received_packets_.size() / 10; - PacketNodeIt it = received_packets_.begin(); - std::advance(it, num_preserved_elements); - - while (it != received_packets_.end()) { - received_packets_.Erase(it++); - } - - // Compute Loss for the preserved elements - loss_account_.Subtract(LinkedSetPacketLossRatio()); -} - -float BweReceiver::GlobalReceiverPacketLossRatio() { - UpdateLoss(); - return loss_account_.LossRatio(); -} - -// This function considers at most kSetCapacity = 1000 packets. -LossAccount BweReceiver::LinkedSetPacketLossRatio() { - if (received_packets_.empty()) { - return LossAccount(); - } - - size_t set_total_packets = received_packets_.Range(); - size_t set_received_packets = received_packets_.size(); - size_t set_lost_packets = set_total_packets - set_received_packets; - - return LossAccount(set_total_packets, set_lost_packets); -} - -uint32_t BweReceiver::RecentKbps() const { - return (rate_counter_.bits_per_second() + 500) / 1000; -} - -// Go through a fixed time window of most recent packets received and -// counts packets missing to obtain the packet loss ratio. If an unordered -// packet falls out of the timewindow it will be counted as missing. -// E.g.: for a timewindow covering 5 packets of the following arrival sequence -// {10 7 9 5 6} 8 3 2 4 1, the output will be 1/6 (#8 is considered as missing). -float BweReceiver::RecentPacketLossRatio() { - if (received_packets_.empty()) { - return 0.0f; - } - int number_packets_received = 0; - - PacketNodeIt node_it = received_packets_.begin(); // Latest. - - // Lowest timestamp limit, oldest one that should be checked. - int64_t time_limit_ms = node_it->arrival_time_ms - kPacketLossTimeWindowMs; - // Oldest and newest values found within the given time window. - int64_t oldest_seq_num = node_it->unwrapped_sequence_number; - int64_t newest_seq_num = oldest_seq_num; - - while (node_it != received_packets_.end()) { - if (node_it->arrival_time_ms < time_limit_ms) { - break; - } - int64_t seq_num = node_it->unwrapped_sequence_number; - newest_seq_num = std::max(newest_seq_num, seq_num); - oldest_seq_num = std::min(oldest_seq_num, seq_num); - ++node_it; - ++number_packets_received; - } - // Interval width between oldest and newest sequence number. - int gap = rtc::dchecked_cast(newest_seq_num - oldest_seq_num + 1); - - return static_cast(gap - number_packets_received) / gap; -} - -LinkedSet::LinkedSet(int capacity) : capacity_(capacity) {} - -LinkedSet::~LinkedSet() { -} - -void LinkedSet::Insert(uint16_t sequence_number, - int64_t send_time_ms, - int64_t arrival_time_ms, - size_t payload_size) { - auto unwrapped_sequence_number = unwrapper_.Unwrap(sequence_number); - auto it = map_.find(unwrapped_sequence_number); - // Handle duplicate unwrapped sequence number. - if (it != map_.end()) { - PacketNodeIt node_it = it->second; - PacketIdentifierNode& node = *node_it; - node.arrival_time_ms = arrival_time_ms; - // Move to front, without invalidating iterators. - list_.splice(list_.begin(), list_, node_it); - } else { - if (size() == capacity_) { - RemoveTail(); - } - // Push new element to the front of the list and insert it in the map. - PacketIdentifierNode new_head(unwrapped_sequence_number, send_time_ms, - arrival_time_ms, payload_size); - list_.push_front(new_head); - map_[unwrapped_sequence_number] = list_.begin(); - } -} - -void LinkedSet::RemoveTail() { - Erase(--list_.end()); -} - -void LinkedSet::Erase(PacketNodeIt node_it) { - map_.erase(node_it->unwrapped_sequence_number); - list_.erase(node_it); -} - -void LossAccount::Add(LossAccount rhs) { - num_total += rhs.num_total; - num_lost += rhs.num_lost; -} -void LossAccount::Subtract(LossAccount rhs) { - num_total -= rhs.num_total; - num_lost -= rhs.num_lost; -} - -float LossAccount::LossRatio() { - if (num_total == 0) - return 0.0f; - return static_cast(num_lost) / num_total; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bwe.h b/modules/remote_bitrate_estimator/test/bwe.h deleted file mode 100644 index cf2517c822..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_H_ - -#include -#include -#include -#include -#include -#include - -#include "modules/bitrate_controller/include/bitrate_controller.h" -#include "modules/include/module.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "modules/remote_bitrate_estimator/test/packet.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/gtest_prod_util.h" -#include "rtc_base/numerics/sequence_number_util.h" -#include "system_wrappers/include/clock.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -// Holds information for computing global packet loss. -struct LossAccount { - LossAccount() : num_total(0), num_lost(0) {} - LossAccount(size_t num_total, size_t num_lost) - : num_total(num_total), num_lost(num_lost) {} - void Add(LossAccount rhs); - void Subtract(LossAccount rhs); - float LossRatio(); - size_t num_total; - size_t num_lost; -}; - -// Holds only essential information about packets to be saved for -// further use, e.g. for calculating packet loss and receiving rate. -struct PacketIdentifierNode { - PacketIdentifierNode(int64_t unwrapped_sequence_number, - int64_t send_time_ms, - int64_t arrival_time_ms, - size_t payload_size) - : unwrapped_sequence_number(unwrapped_sequence_number), - send_time_ms(send_time_ms), - arrival_time_ms(arrival_time_ms), - payload_size(payload_size) {} - - int64_t unwrapped_sequence_number; - int64_t send_time_ms; - int64_t arrival_time_ms; - size_t payload_size; -}; - -typedef std::list::iterator PacketNodeIt; - -// FIFO implementation for a limited capacity set. -// Used for keeping the latest arrived packets while avoiding duplicates. -// Allows efficient insertion, deletion and search. -class LinkedSet { - public: - explicit LinkedSet(int capacity); - ~LinkedSet(); - - // If the arriving packet (identified by its sequence number) is already - // in the LinkedSet, move its Node to the head of the list. - // Else, add a PacketIdentifierNode n_ at the head of the list, - // calling RemoveTail() if the LinkedSet reached its maximum capacity. - void Insert(uint16_t sequence_number, - int64_t send_time_ms, - int64_t arrival_time_ms, - size_t payload_size); - - PacketNodeIt begin() { return list_.begin(); } - PacketNodeIt end() { return list_.end(); } - - bool empty() const { return list_.empty(); } - size_t size() const { return list_.size(); } - size_t capacity() const { return capacity_; } - - // Return size of interval covering current set, i.e.: - // unwrapped newest seq number - unwrapped oldest seq number + 1 - int64_t Range() const { - return empty() ? 0 : map_.rbegin()->first - map_.begin()->first + 1; - } - - void Erase(PacketNodeIt node_it); - - private: - // Pop oldest element from the back of the list and remove it from the map. - void RemoveTail(); - size_t capacity_; - // We want to keep track of the current oldest and newest sequence_numbers. - // To get strict weak ordering, we unwrap uint16_t into an int64_t. - SeqNumUnwrapper unwrapper_; - std::map map_; - std::list list_; -}; - -const int kMinBitrateKbps = 10; -const int kMaxBitrateKbps = 25000; - -class BweSender : public Module { - public: - BweSender() {} - explicit BweSender(int bitrate_kbps) : bitrate_kbps_(bitrate_kbps) {} - ~BweSender() override {} - - virtual int GetFeedbackIntervalMs() const = 0; - virtual void GiveFeedback(const FeedbackPacket& feedback) = 0; - virtual void OnPacketsSent(const Packets& packets) = 0; - - protected: - int bitrate_kbps_; - - private: - RTC_DISALLOW_COPY_AND_ASSIGN(BweSender); -}; - -class BweReceiver { - public: - explicit BweReceiver(int flow_id); - BweReceiver(int flow_id, int64_t window_size_ms); - - virtual ~BweReceiver() {} - - virtual void ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet); - virtual FeedbackPacket* GetFeedback(int64_t now_ms); - - size_t GetSetCapacity() { return received_packets_.capacity(); } - double BitrateWindowS() const { return rate_counter_.BitrateWindowS(); } - uint32_t RecentKbps() const; // Receiving Rate. - - // Computes packet loss during an entire simulation, up to 4 billion packets. - float GlobalReceiverPacketLossRatio(); // Plot histogram. - float RecentPacketLossRatio(); // Plot dynamics. - - static const int64_t kPacketLossTimeWindowMs = 500; - static const int64_t kReceivingRateTimeWindowMs = 1000; - - protected: - int flow_id_; - // Deals with packets sent more than once. - LinkedSet received_packets_; - // Used for calculating recent receiving rate. - RateCounter rate_counter_; - - private: - FRIEND_TEST_ALL_PREFIXES(BweReceiverTest, RecentKbps); - FRIEND_TEST_ALL_PREFIXES(BweReceiverTest, Loss); - - void UpdateLoss(); - void RelieveSetAndUpdateLoss(); - // Packet loss for packets stored in the LinkedSet, up to 1000 packets. - // Used to update global loss account whenever the set is filled and cleared. - LossAccount LinkedSetPacketLossRatio(); - - // Used for calculating global packet loss ratio. - LossAccount loss_account_; -}; - -enum BandwidthEstimatorType { - kNullEstimator, - kNadaEstimator, - kRembEstimator, - kSendSideEstimator, - kTcpEstimator, - kBbrEstimator -}; - -const char* const bwe_names[] = {"Null", "NADA", "REMB", - "GoogCc", "TCP", "BBR"}; - -int64_t GetAbsSendTimeInMs(uint32_t abs_send_time); - -BweSender* CreateBweSender(BandwidthEstimatorType estimator, - int kbps, - BitrateObserver* observer, - Clock* clock); - -BweReceiver* CreateBweReceiver(BandwidthEstimatorType type, - int flow_id, - bool plot); -} // namespace bwe -} // namespace testing -} // namespace webrtc -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_H_ diff --git a/modules/remote_bitrate_estimator/test/bwe_test.cc b/modules/remote_bitrate_estimator/test/bwe_test.cc deleted file mode 100644 index 9fad58dc28..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test.cc +++ /dev/null @@ -1,1005 +0,0 @@ -/* - * Copyright (c) 2013 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/remote_bitrate_estimator/test/bwe_test.h" - -#include -#include - -#include "modules/include/module_common_types.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "modules/remote_bitrate_estimator/test/metric_recorder.h" -#include "modules/remote_bitrate_estimator/test/packet_receiver.h" -#include "modules/remote_bitrate_estimator/test/packet_sender.h" -#include "rtc_base/arraysize.h" -#include "system_wrappers/include/clock.h" -#include "system_wrappers/include/field_trial.h" -#include "test/testsupport/perf_test.h" - -using std::vector; - -namespace { -const int kQuickTestTimeoutMs = 500; - -double SafeDiv(double a, double b) { - return b ? a / b : 0; -} -} - -namespace webrtc { -namespace testing { -namespace bwe { - -PacketProcessorRunner::PacketProcessorRunner(PacketProcessor* processor) - : processor_(processor) {} - -PacketProcessorRunner::PacketProcessorRunner( - const PacketProcessorRunner& runner) = default; - -PacketProcessorRunner::~PacketProcessorRunner() { - for (Packet* packet : queue_) - delete packet; -} - -bool PacketProcessorRunner::RunsProcessor( - const PacketProcessor* processor) const { - return processor == processor_; -} - -void PacketProcessorRunner::RunFor(int64_t time_ms, - int64_t time_now_ms, - Packets* in_out) { - Packets to_process; - FindPacketsToProcess(processor_->flow_ids(), in_out, &to_process); - processor_->RunFor(time_ms, &to_process); - QueuePackets(&to_process, time_now_ms * 1000); - if (!to_process.empty()) { - processor_->Plot(to_process.back()->send_time_ms()); - } - in_out->merge(to_process, DereferencingComparator); -} - -void PacketProcessorRunner::FindPacketsToProcess(const FlowIds& flow_ids, - Packets* in, - Packets* out) { - assert(out->empty()); - for (Packets::iterator it = in->begin(); it != in->end();) { - // TODO(holmer): Further optimize this by looking for consecutive flow ids - // in the packet list and only doing the binary search + splice once for a - // sequence. - if (flow_ids.find((*it)->flow_id()) != flow_ids.end()) { - Packets::iterator next = it; - ++next; - out->splice(out->end(), *in, it); - it = next; - } else { - ++it; - } - } -} - -void PacketProcessorRunner::QueuePackets(Packets* batch, - int64_t end_of_batch_time_us) { - queue_.merge(*batch, DereferencingComparator); - if (queue_.empty()) { - return; - } - Packets::iterator it = queue_.begin(); - for (; it != queue_.end(); ++it) { - if ((*it)->send_time_us() > end_of_batch_time_us) { - break; - } - } - Packets to_transfer; - to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it); - batch->merge(to_transfer, DereferencingComparator); -} - -// Plot link capacity by default. -BweTest::BweTest() : BweTest(true) {} - -BweTest::BweTest(bool plot_capacity) - : run_time_ms_(0), - time_now_ms_(-1), - simulation_interval_ms_(-1), - plot_total_available_capacity_(plot_capacity) { - links_.push_back(&uplink_); - links_.push_back(&downlink_); -} - -BweTest::~BweTest() { - for (Packet* packet : packets_) - delete packet; -} - -void BweTest::SetUp() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - std::string test_name = std::string(test_info->test_case_name()) + "_" + - std::string(test_info->name()); - BWE_TEST_LOGGING_GLOBAL_CONTEXT(test_name); - BWE_TEST_LOGGING_GLOBAL_ENABLE(false); -} - -Link::Link() = default; -Link::~Link() = default; - -void Link::AddPacketProcessor(PacketProcessor* processor, - ProcessorType processor_type) { - assert(processor); - switch (processor_type) { - case kSender: - senders_.push_back(static_cast(processor)); - break; - case kReceiver: - receivers_.push_back(static_cast(processor)); - break; - case kRegular: - break; - } - processors_.push_back(PacketProcessorRunner(processor)); -} - -void Link::RemovePacketProcessor(PacketProcessor* processor) { - for (std::vector::iterator it = processors_.begin(); - it != processors_.end(); ++it) { - if (it->RunsProcessor(processor)) { - processors_.erase(it); - return; - } - } - assert(false); -} - -// Ownership of the created packets is handed over to the caller. -void Link::Run(int64_t run_for_ms, int64_t now_ms, Packets* packets) { - for (auto& processor : processors_) { - processor.RunFor(run_for_ms, now_ms, packets); - } -} - -void BweTest::VerboseLogging(bool enable) { - BWE_TEST_LOGGING_GLOBAL_ENABLE(enable); -} - -void BweTest::RunFor(int64_t time_ms) { - // Set simulation interval from first packet sender. - // TODO(holmer): Support different feedback intervals for different flows. - - // For quick perf tests ignore passed timeout - if (field_trial::IsEnabled("WebRTC-QuickPerfTest")) { - time_ms = kQuickTestTimeoutMs; - } - if (!uplink_.senders().empty()) { - simulation_interval_ms_ = uplink_.senders()[0]->GetFeedbackIntervalMs(); - } else if (!downlink_.senders().empty()) { - simulation_interval_ms_ = downlink_.senders()[0]->GetFeedbackIntervalMs(); - } - assert(simulation_interval_ms_ > 0); - if (time_now_ms_ == -1) { - time_now_ms_ = simulation_interval_ms_; - } - for (run_time_ms_ += time_ms; - time_now_ms_ <= run_time_ms_ - simulation_interval_ms_; - time_now_ms_ += simulation_interval_ms_) { - // Packets are first generated on the first link, passed through all the - // PacketProcessors and PacketReceivers. The PacketReceivers produces - // FeedbackPackets which are then processed by the next link, where they - // at some point will be consumed by a PacketSender. - for (Link* link : links_) - link->Run(simulation_interval_ms_, time_now_ms_, &packets_); - } -} - -std::string BweTest::GetTestName() const { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - return std::string(test_info->name()); -} - -void BweTest::PrintResults(double max_throughput_kbps, - Stats throughput_kbps, - int flow_id, - Stats flow_delay_ms, - Stats flow_throughput_kbps) { - std::map> flow_delays_ms; - flow_delays_ms[flow_id] = flow_delay_ms; - std::map> flow_throughputs_kbps; - flow_throughputs_kbps[flow_id] = flow_throughput_kbps; - PrintResults(max_throughput_kbps, throughput_kbps, flow_delays_ms, - flow_throughputs_kbps); -} - -void BweTest::PrintResults(double max_throughput_kbps, - Stats throughput_kbps, - std::map> flow_delay_ms, - std::map> flow_throughput_kbps) { - double utilization = SafeDiv(throughput_kbps.GetMean(), max_throughput_kbps); - webrtc::test::PrintResult("BwePerformance", GetTestName(), "Utilization", - utilization * 100.0, "%", false); - webrtc::test::PrintResult( - "BwePerformance", GetTestName(), "Utilization var coeff", - SafeDiv(throughput_kbps.GetStdDev(), throughput_kbps.GetMean()), "", - false); - std::stringstream ss; - for (auto& kv : flow_throughput_kbps) { - ss.str(""); - ss << "Throughput flow " << kv.first; - webrtc::test::PrintResultMeanAndError("BwePerformance", GetTestName(), - ss.str(), kv.second.GetMean(), - kv.second.GetStdDev(), "kbps", false); - } - for (auto& kv : flow_delay_ms) { - ss.str(""); - ss << "Delay flow " << kv.first; - webrtc::test::PrintResultMeanAndError("BwePerformance", GetTestName(), - ss.str(), kv.second.GetMean(), - kv.second.GetStdDev(), "ms", false); - } - double fairness_index = 1.0; - if (!flow_throughput_kbps.empty()) { - double squared_bitrate_sum = 0.0; - fairness_index = 0.0; - for (auto kv : flow_throughput_kbps) { - squared_bitrate_sum += kv.second.GetMean() * kv.second.GetMean(); - fairness_index += kv.second.GetMean(); - } - fairness_index *= SafeDiv( - fairness_index, flow_throughput_kbps.size() * squared_bitrate_sum); - } - webrtc::test::PrintResult("BwePerformance", GetTestName(), "Fairness", - fairness_index * 100, "%", false); -} - -void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type, - size_t num_media_flows, - size_t num_tcp_flows, - int64_t run_time_seconds, - uint32_t capacity_kbps, - int64_t max_delay_ms, - int64_t rtt_ms, - int64_t max_jitter_ms, - const int64_t* offsets_ms) { - RunFairnessTest(bwe_type, num_media_flows, num_tcp_flows, run_time_seconds, - capacity_kbps, max_delay_ms, rtt_ms, max_jitter_ms, - offsets_ms, "Fairness_test", bwe_names[bwe_type]); -} - -void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type, - size_t num_media_flows, - size_t num_tcp_flows, - int64_t run_time_seconds, - uint32_t capacity_kbps, - int64_t max_delay_ms, - int64_t rtt_ms, - int64_t max_jitter_ms, - const int64_t* offsets_ms, - const std::string& title, - const std::string& flow_name) { - std::set all_flow_ids; - std::set media_flow_ids; - std::set tcp_flow_ids; - int next_flow_id = 0; - for (size_t i = 0; i < num_media_flows; ++i) { - media_flow_ids.insert(next_flow_id); - all_flow_ids.insert(next_flow_id); - ++next_flow_id; - } - for (size_t i = 0; i < num_tcp_flows; ++i) { - tcp_flow_ids.insert(next_flow_id); - all_flow_ids.insert(next_flow_id); - ++next_flow_id; - } - - std::vector sources; - std::vector senders; - std::vector metric_recorders; - - int64_t max_offset_ms = 0; - - for (int media_flow : media_flow_ids) { - sources.push_back(new AdaptiveVideoSource(media_flow, 30, 300, 0, - offsets_ms[media_flow])); - senders.push_back(new PacedVideoSender(&uplink_, sources.back(), bwe_type)); - max_offset_ms = std::max(max_offset_ms, offsets_ms[media_flow]); - } - - for (int tcp_flow : tcp_flow_ids) { - senders.push_back(new TcpSender(&uplink_, tcp_flow, offsets_ms[tcp_flow])); - max_offset_ms = std::max(max_offset_ms, offsets_ms[tcp_flow]); - } - - ChokeFilter choke(&uplink_, all_flow_ids); - choke.set_capacity_kbps(capacity_kbps); - choke.set_max_delay_ms(max_delay_ms); - LinkShare link_share(&choke); - - int64_t one_way_delay_ms = rtt_ms / 2; - DelayFilter delay_uplink(&uplink_, all_flow_ids); - delay_uplink.SetOneWayDelayMs(one_way_delay_ms); - - JitterFilter jitter(&uplink_, all_flow_ids); - jitter.SetMaxJitter(max_jitter_ms); - - std::vector rate_counters; - rate_counters.reserve(media_flow_ids.size()); - for (int flow : media_flow_ids) { - rate_counters.push_back( - new RateCounterFilter(&uplink_, flow, "Receiver", bwe_names[bwe_type])); - } - for (int flow : tcp_flow_ids) { - rate_counters.push_back(new RateCounterFilter(&uplink_, flow, "Receiver", - bwe_names[kTcpEstimator])); - } - - RateCounterFilter total_utilization( - &uplink_, all_flow_ids, "total_utilization", "Total_link_utilization"); - - std::vector receivers; - // Delays is being plotted only for the first flow. - // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). - for (int media_flow : media_flow_ids) { - metric_recorders.push_back( - new MetricRecorder(bwe_names[bwe_type], static_cast(media_flow), - senders[media_flow], &link_share)); - receivers.push_back(new PacketReceiver(&uplink_, media_flow, bwe_type, - media_flow == 0, false, - metric_recorders[media_flow])); - metric_recorders[media_flow]->set_plot_available_capacity( - media_flow == 0 && plot_total_available_capacity_); - metric_recorders[media_flow]->set_start_computing_metrics_ms(max_offset_ms); - } - // Delays is not being plotted only for TCP flows. To plot all of them, - // replace first "false" occurence with "true" on new PacketReceiver(). - for (int tcp_flow : tcp_flow_ids) { - metric_recorders.push_back( - new MetricRecorder(bwe_names[kTcpEstimator], static_cast(tcp_flow), - senders[tcp_flow], &link_share)); - receivers.push_back(new PacketReceiver(&uplink_, tcp_flow, kTcpEstimator, - false, false, - metric_recorders[tcp_flow])); - metric_recorders[tcp_flow]->set_plot_available_capacity( - tcp_flow == 0 && plot_total_available_capacity_); - } - - DelayFilter delay_downlink(&downlink_, all_flow_ids); - delay_downlink.SetOneWayDelayMs(one_way_delay_ms); - - RunFor(run_time_seconds * 1000); - - std::map> flow_throughput_kbps; - for (RateCounterFilter* rate_counter : rate_counters) { - int flow_id = *rate_counter->flow_ids().begin(); - flow_throughput_kbps[flow_id] = rate_counter->GetBitrateStats(); - } - - std::map> flow_delay_ms; - for (PacketReceiver* receiver : receivers) { - int flow_id = *receiver->flow_ids().begin(); - flow_delay_ms[flow_id] = receiver->GetDelayStats(); - } - - PrintResults(capacity_kbps, total_utilization.GetBitrateStats(), - flow_delay_ms, flow_throughput_kbps); - - if (!field_trial::IsEnabled("WebRTC-QuickPerfTest")) { - for (int i : all_flow_ids) { - metric_recorders[i]->PlotThroughputHistogram( - title, flow_name, static_cast(num_media_flows), 0); - - metric_recorders[i]->PlotLossHistogram(title, flow_name, - static_cast(num_media_flows), - receivers[i]->GlobalPacketLoss()); - } - - // Pointless to show delay histogram for TCP flow. - for (int i : media_flow_ids) { - metric_recorders[i]->PlotDelayHistogram(title, bwe_names[bwe_type], - static_cast(num_media_flows), - one_way_delay_ms); - BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], one_way_delay_ms, i); - } - } - - for (VideoSource* source : sources) - delete source; - for (PacketSender* sender : senders) - delete sender; - for (RateCounterFilter* rate_counter : rate_counters) - delete rate_counter; - for (PacketReceiver* receiver : receivers) - delete receiver; - for (MetricRecorder* recorder : metric_recorders) - delete recorder; -} - -void BweTest::RunChoke(BandwidthEstimatorType bwe_type, - std::vector capacities_kbps) { - int flow_id = bwe_type; - AdaptiveVideoSource source(flow_id, 30, 300, 0, 0); - VideoSender sender(&uplink_, &source, bwe_type); - ChokeFilter choke(&uplink_, flow_id); - LinkShare link_share(&choke); - MetricRecorder metric_recorder(bwe_names[bwe_type], flow_id, &sender, - &link_share); - PacketReceiver receiver(&uplink_, flow_id, bwe_type, true, false, - &metric_recorder); - metric_recorder.set_plot_available_capacity(plot_total_available_capacity_); - - choke.set_max_delay_ms(500); - const int64_t kRunTimeMs = 60 * 1000; - - std::stringstream title("Choke"); - char delimiter = '_'; - - for (auto it = capacities_kbps.begin(); it != capacities_kbps.end(); ++it) { - choke.set_capacity_kbps(*it); - RunFor(kRunTimeMs); - title << delimiter << (*it); - delimiter = '-'; - } - - title << "_kbps,_" << (kRunTimeMs / 1000) << "s_each"; - metric_recorder.PlotThroughputHistogram(title.str(), bwe_names[bwe_type], 1, - 0); - metric_recorder.PlotDelayHistogram(title.str(), bwe_names[bwe_type], 1, 0); - // receiver.PlotLossHistogram(title, bwe_names[bwe_type], 1); - // receiver.PlotObjectiveHistogram(title, bwe_names[bwe_type], 1); -} - -// 5.1. Single Video and Audio media traffic, forward direction. -void BweTest::RunVariableCapacity1SingleFlow(BandwidthEstimatorType bwe_type) { - const int kFlowId = 0; // Arbitrary value. - AdaptiveVideoSource source(kFlowId, 30, 300, 0, 0); - PacedVideoSender sender(&uplink_, &source, bwe_type); - - DefaultEvaluationFilter up_filter(&uplink_, kFlowId); - LinkShare link_share(&(up_filter.choke)); - MetricRecorder metric_recorder(bwe_names[bwe_type], kFlowId, &sender, - &link_share); - - PacketReceiver receiver(&uplink_, kFlowId, bwe_type, true, true, - &metric_recorder); - - metric_recorder.set_plot_available_capacity(plot_total_available_capacity_); - - DelayFilter down_filter(&downlink_, kFlowId); - down_filter.SetOneWayDelayMs(kOneWayDelayMs); - - // Test also with one way propagation delay = 100ms. - // up_filter.delay.SetOneWayDelayMs(100); - // down_filter.SetOneWayDelayMs(100); - - up_filter.choke.set_capacity_kbps(1000); - RunFor(40 * 1000); // 0-40s. - up_filter.choke.set_capacity_kbps(2500); - RunFor(20 * 1000); // 40-60s. - up_filter.choke.set_capacity_kbps(600); - RunFor(20 * 1000); // 60-80s. - up_filter.choke.set_capacity_kbps(1000); - RunFor(20 * 1000); // 80-100s. - - std::string title("5.1_Variable_capacity_single_flow"); - metric_recorder.PlotThroughputHistogram(title, bwe_names[bwe_type], 1, 0); - metric_recorder.PlotDelayHistogram(title, bwe_names[bwe_type], 1, - kOneWayDelayMs); - metric_recorder.PlotLossHistogram(title, bwe_names[bwe_type], 1, - receiver.GlobalPacketLoss()); - BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, kFlowId); -} - -// 5.2. Two forward direction competing flows, variable capacity. -void BweTest::RunVariableCapacity2MultipleFlows(BandwidthEstimatorType bwe_type, - size_t num_flows) { - std::vector sources; - std::vector senders; - std::vector metric_recorders; - std::vector receivers; - - const int64_t kStartingApartMs = 0; // Flows initialized simultaneously. - - for (size_t i = 0; i < num_flows; ++i) { - sources.push_back(new AdaptiveVideoSource(static_cast(i), 30, 300, 0, - i * kStartingApartMs)); - senders.push_back(new VideoSender(&uplink_, sources[i], bwe_type)); - } - - FlowIds flow_ids = CreateFlowIdRange(0, static_cast(num_flows - 1)); - - DefaultEvaluationFilter up_filter(&uplink_, flow_ids); - LinkShare link_share(&(up_filter.choke)); - - RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization", - "Total_link_utilization"); - - // Delays is being plotted only for the first flow. - // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). - for (size_t i = 0; i < num_flows; ++i) { - metric_recorders.push_back(new MetricRecorder( - bwe_names[bwe_type], static_cast(i), senders[i], &link_share)); - - receivers.push_back(new PacketReceiver(&uplink_, static_cast(i), - bwe_type, i == 0, false, - metric_recorders[i])); - metric_recorders[i]->set_plot_available_capacity( - i == 0 && plot_total_available_capacity_); - } - - DelayFilter down_filter(&downlink_, flow_ids); - down_filter.SetOneWayDelayMs(kOneWayDelayMs); - // Test also with one way propagation delay = 100ms. - // up_filter.delay.SetOneWayDelayMs(100); - // down_filter.SetOneWayDelayMs(100); - - up_filter.choke.set_capacity_kbps(4000); - RunFor(25 * 1000); // 0-25s. - up_filter.choke.set_capacity_kbps(2000); - RunFor(25 * 1000); // 25-50s. - up_filter.choke.set_capacity_kbps(3500); - RunFor(25 * 1000); // 50-75s. - up_filter.choke.set_capacity_kbps(1000); - RunFor(25 * 1000); // 75-100s. - up_filter.choke.set_capacity_kbps(2000); - RunFor(25 * 1000); // 100-125s. - - std::string title("5.2_Variable_capacity_two_flows"); - for (size_t i = 0; i < num_flows; ++i) { - metric_recorders[i]->PlotThroughputHistogram(title, bwe_names[bwe_type], - num_flows, 0); - metric_recorders[i]->PlotDelayHistogram(title, bwe_names[bwe_type], - num_flows, kOneWayDelayMs); - metric_recorders[i]->PlotLossHistogram(title, bwe_names[bwe_type], - num_flows, - receivers[i]->GlobalPacketLoss()); - BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); - } - - for (VideoSource* source : sources) - delete source; - for (PacketSender* sender : senders) - delete sender; - for (MetricRecorder* recorder : metric_recorders) - delete recorder; - for (PacketReceiver* receiver : receivers) - delete receiver; -} - -// 5.3. Bi-directional RMCAT flows. -void BweTest::RunBidirectionalFlow(BandwidthEstimatorType bwe_type) { - enum direction { kForward = 0, kBackward }; - const size_t kNumFlows = 2; - std::unique_ptr sources[kNumFlows]; - std::unique_ptr senders[kNumFlows]; - std::unique_ptr metric_recorders[kNumFlows]; - std::unique_ptr receivers[kNumFlows]; - - sources[kForward].reset(new AdaptiveVideoSource(kForward, 30, 300, 0, 0)); - senders[kForward].reset( - new VideoSender(&uplink_, sources[kForward].get(), bwe_type)); - - sources[kBackward].reset(new AdaptiveVideoSource(kBackward, 30, 300, 0, 0)); - senders[kBackward].reset( - new VideoSender(&downlink_, sources[kBackward].get(), bwe_type)); - - DefaultEvaluationFilter up_filter(&uplink_, kForward); - LinkShare up_link_share(&(up_filter.choke)); - - metric_recorders[kForward].reset(new MetricRecorder( - bwe_names[bwe_type], kForward, senders[kForward].get(), &up_link_share)); - receivers[kForward].reset( - new PacketReceiver(&uplink_, kForward, bwe_type, true, false, - metric_recorders[kForward].get())); - - metric_recorders[kForward].get()->set_plot_available_capacity( - plot_total_available_capacity_); - - DefaultEvaluationFilter down_filter(&downlink_, kBackward); - LinkShare down_link_share(&(down_filter.choke)); - - metric_recorders[kBackward].reset( - new MetricRecorder(bwe_names[bwe_type], kBackward, - senders[kBackward].get(), &down_link_share)); - receivers[kBackward].reset( - new PacketReceiver(&downlink_, kBackward, bwe_type, true, false, - metric_recorders[kBackward].get())); - - metric_recorders[kBackward].get()->set_plot_available_capacity( - plot_total_available_capacity_); - - // Test also with one way propagation delay = 100ms. - // up_filter.delay.SetOneWayDelayMs(100); - // down_filter.delay.SetOneWayDelayMs(100); - - up_filter.choke.set_capacity_kbps(2000); - down_filter.choke.set_capacity_kbps(2000); - RunFor(20 * 1000); // 0-20s. - - up_filter.choke.set_capacity_kbps(1000); - RunFor(15 * 1000); // 20-35s. - - down_filter.choke.set_capacity_kbps(800); - RunFor(5 * 1000); // 35-40s. - - up_filter.choke.set_capacity_kbps(500); - RunFor(20 * 1000); // 40-60s. - - up_filter.choke.set_capacity_kbps(2000); - RunFor(10 * 1000); // 60-70s. - - down_filter.choke.set_capacity_kbps(2000); - RunFor(30 * 1000); // 70-100s. - - std::string title("5.3_Bidirectional_flows"); - for (size_t i = 0; i < kNumFlows; ++i) { - metric_recorders[i].get()->PlotThroughputHistogram( - title, bwe_names[bwe_type], kNumFlows, 0); - metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], - kNumFlows, kOneWayDelayMs); - metric_recorders[i].get()->PlotLossHistogram( - title, bwe_names[bwe_type], kNumFlows, - receivers[i].get()->GlobalPacketLoss()); - BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); - } -} - -// 5.4. Three forward direction competing flows, constant capacity. -void BweTest::RunSelfFairness(BandwidthEstimatorType bwe_type) { - const int kNumRmcatFlows = 3; - const int kNumTcpFlows = 0; - const int64_t kRunTimeS = 120; - const int kLinkCapacity = 3500; - - int64_t max_delay_ms = kMaxQueueingDelayMs; - int64_t rtt_ms = 2 * kOneWayDelayMs; - - const int64_t kStartingApartMs = 20 * 1000; - int64_t offsets_ms[kNumRmcatFlows]; - for (int i = 0; i < kNumRmcatFlows; ++i) { - offsets_ms[i] = kStartingApartMs * i; - } - - // Test also with one way propagation delay = 100ms. - // rtt_ms = 2 * 100; - // Test also with bottleneck queue size = 20ms and 1000ms. - // max_delay_ms = 20; - // max_delay_ms = 1000; - - std::string title("5.4_Self_fairness_test"); - - // Test also with one way propagation delay = 100ms. - RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS, - kLinkCapacity, max_delay_ms, rtt_ms, kMaxJitterMs, offsets_ms, - title, bwe_names[bwe_type]); -} - -// 5.5. Five competing RMCAT flows under different RTTs. -void BweTest::RunRoundTripTimeFairness(BandwidthEstimatorType bwe_type) { - const int kAllFlowIds[] = {0, 1, 2, 3, 4}; // Five RMCAT flows. - const int64_t kAllOneWayDelayMs[] = {10, 25, 50, 100, 150}; - const size_t kNumFlows = arraysize(kAllFlowIds); - std::unique_ptr sources[kNumFlows]; - std::unique_ptr senders[kNumFlows]; - std::unique_ptr metric_recorders[kNumFlows]; - - // Flows initialized 10 seconds apart. - const int64_t kStartingApartMs = 10 * 1000; - - for (size_t i = 0; i < kNumFlows; ++i) { - sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, - i * kStartingApartMs)); - senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type)); - } - - ChokeFilter choke_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows)); - LinkShare link_share(&choke_filter); - - JitterFilter jitter_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows)); - - std::unique_ptr up_delay_filters[kNumFlows]; - for (size_t i = 0; i < kNumFlows; ++i) { - up_delay_filters[i].reset(new DelayFilter(&uplink_, kAllFlowIds[i])); - } - - RateCounterFilter total_utilization( - &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization", - "Total_link_utilization"); - - // Delays is being plotted only for the first flow. - // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). - std::unique_ptr receivers[kNumFlows]; - for (size_t i = 0; i < kNumFlows; ++i) { - metric_recorders[i].reset( - new MetricRecorder(bwe_names[bwe_type], static_cast(i), - senders[i].get(), &link_share)); - - receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type, - i == 0, false, - metric_recorders[i].get())); - metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs * - (kNumFlows - 1)); - metric_recorders[i].get()->set_plot_available_capacity( - i == 0 && plot_total_available_capacity_); - } - - std::unique_ptr down_delay_filters[kNumFlows]; - for (size_t i = 0; i < kNumFlows; ++i) { - down_delay_filters[i].reset(new DelayFilter(&downlink_, kAllFlowIds[i])); - } - - jitter_filter.SetMaxJitter(kMaxJitterMs); - choke_filter.set_max_delay_ms(kMaxQueueingDelayMs); - - for (size_t i = 0; i < kNumFlows; ++i) { - up_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]); - down_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]); - } - - choke_filter.set_capacity_kbps(3500); - - RunFor(300 * 1000); // 0-300s. - - std::string title("5.5_Round_Trip_Time_Fairness"); - for (size_t i = 0; i < kNumFlows; ++i) { - metric_recorders[i].get()->PlotThroughputHistogram( - title, bwe_names[bwe_type], kNumFlows, 0); - metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], - kNumFlows, kOneWayDelayMs); - metric_recorders[i].get()->PlotLossHistogram( - title, bwe_names[bwe_type], kNumFlows, - receivers[i].get()->GlobalPacketLoss()); - BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kAllOneWayDelayMs[i], - i); - } -} - -// 5.6. RMCAT Flow competing with a long TCP Flow. -void BweTest::RunLongTcpFairness(BandwidthEstimatorType bwe_type) { - const size_t kNumRmcatFlows = 1; - const size_t kNumTcpFlows = 1; - const int64_t kRunTimeS = 120; - const int kCapacityKbps = 2000; - // Tcp starts at t = 0, media flow at t = 5s. - const int64_t kOffSetsMs[] = {5000, 0}; - - int64_t max_delay_ms = kMaxQueueingDelayMs; - int64_t rtt_ms = 2 * kOneWayDelayMs; - - // Test also with one way propagation delay = 100ms. - // rtt_ms = 2 * 100; - // Test also with bottleneck queue size = 20ms and 1000ms. - // max_delay_ms = 20; - // max_delay_ms = 1000; - - std::string title("5.6_Long_TCP_Fairness"); - std::string flow_name = - std::string() + bwe_names[bwe_type] + 'x' + bwe_names[kTcpEstimator]; - - RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS, - kCapacityKbps, max_delay_ms, rtt_ms, kMaxJitterMs, kOffSetsMs, - title, flow_name); -} - -// 5.7. RMCAT Flows competing with multiple short TCP Flows. -void BweTest::RunMultipleShortTcpFairness( - BandwidthEstimatorType bwe_type, - std::vector tcp_file_sizes_bytes, - std::vector tcp_starting_times_ms) { - // Two RMCAT flows and ten TCP flows. - const int kAllRmcatFlowIds[] = {0, 1}; - const int kAllTcpFlowIds[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - - assert(tcp_starting_times_ms.size() == tcp_file_sizes_bytes.size() && - tcp_starting_times_ms.size() == arraysize(kAllTcpFlowIds)); - - const size_t kNumRmcatFlows = arraysize(kAllRmcatFlowIds); - const size_t kNumTotalFlows = kNumRmcatFlows + arraysize(kAllTcpFlowIds); - - std::unique_ptr sources[kNumRmcatFlows]; - std::unique_ptr senders[kNumTotalFlows]; - std::unique_ptr metric_recorders[kNumTotalFlows]; - std::unique_ptr receivers[kNumTotalFlows]; - - // RMCAT Flows are initialized simultaneosly at t=5 seconds. - const int64_t kRmcatStartingTimeMs = 5 * 1000; - for (size_t id : kAllRmcatFlowIds) { - sources[id].reset(new AdaptiveVideoSource(static_cast(id), 30, 300, 0, - kRmcatStartingTimeMs)); - senders[id].reset(new VideoSender(&uplink_, sources[id].get(), bwe_type)); - } - - for (size_t id : kAllTcpFlowIds) { - senders[id].reset(new TcpSender(&uplink_, static_cast(id), - tcp_starting_times_ms[id - kNumRmcatFlows], - tcp_file_sizes_bytes[id - kNumRmcatFlows])); - } - - FlowIds flow_ids = CreateFlowIdRange(0, static_cast(kNumTotalFlows - 1)); - DefaultEvaluationFilter up_filter(&uplink_, flow_ids); - - LinkShare link_share(&(up_filter.choke)); - - RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization", - "Total_link_utilization"); - - // Delays is being plotted only for the first flow. - // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). - for (size_t id : kAllRmcatFlowIds) { - metric_recorders[id].reset( - new MetricRecorder(bwe_names[bwe_type], static_cast(id), - senders[id].get(), &link_share)); - receivers[id].reset(new PacketReceiver(&uplink_, static_cast(id), - bwe_type, id == 0, false, - metric_recorders[id].get())); - metric_recorders[id].get()->set_start_computing_metrics_ms( - kRmcatStartingTimeMs); - metric_recorders[id].get()->set_plot_available_capacity( - id == 0 && plot_total_available_capacity_); - } - - // Delays is not being plotted only for TCP flows. To plot all of them, - // replace first "false" occurence with "true" on new PacketReceiver(). - for (size_t id : kAllTcpFlowIds) { - metric_recorders[id].reset( - new MetricRecorder(bwe_names[kTcpEstimator], static_cast(id), - senders[id].get(), &link_share)); - receivers[id].reset(new PacketReceiver(&uplink_, static_cast(id), - kTcpEstimator, false, false, - metric_recorders[id].get())); - metric_recorders[id].get()->set_plot_available_capacity( - id == 0 && plot_total_available_capacity_); - } - - DelayFilter down_filter(&downlink_, flow_ids); - down_filter.SetOneWayDelayMs(kOneWayDelayMs); - - // Test also with one way propagation delay = 100ms. - // up_filter.delay.SetOneWayDelayMs(100); - // down_filter.SetOneWayDelayms(100); - - // Test also with bottleneck queue size = 20ms and 1000ms. - // up_filter.choke.set_max_delay_ms(20); - // up_filter.choke.set_max_delay_ms(1000); - - // Test also with no Jitter: - // up_filter.jitter.SetMaxJitter(0); - - up_filter.choke.set_capacity_kbps(2000); - - RunFor(300 * 1000); // 0-300s. - - std::string title("5.7_Multiple_short_TCP_flows"); - for (size_t id : kAllRmcatFlowIds) { - metric_recorders[id].get()->PlotThroughputHistogram( - title, bwe_names[bwe_type], kNumRmcatFlows, 0); - metric_recorders[id].get()->PlotDelayHistogram( - title, bwe_names[bwe_type], kNumRmcatFlows, kOneWayDelayMs); - metric_recorders[id].get()->PlotLossHistogram( - title, bwe_names[bwe_type], kNumRmcatFlows, - receivers[id].get()->GlobalPacketLoss()); - BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, id); - } -} - -// 5.8. Three forward direction competing flows, constant capacity. -// During the test, one of the flows is paused and later resumed. -void BweTest::RunPauseResumeFlows(BandwidthEstimatorType bwe_type) { - const int kAllFlowIds[] = {0, 1, 2}; // Three RMCAT flows. - const size_t kNumFlows = arraysize(kAllFlowIds); - - std::unique_ptr sources[kNumFlows]; - std::unique_ptr senders[kNumFlows]; - std::unique_ptr metric_recorders[kNumFlows]; - std::unique_ptr receivers[kNumFlows]; - - // Flows initialized simultaneously. - const int64_t kStartingApartMs = 0; - - for (size_t i = 0; i < kNumFlows; ++i) { - sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, - i * kStartingApartMs)); - senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type)); - } - - DefaultEvaluationFilter filter(&uplink_, - CreateFlowIds(kAllFlowIds, kNumFlows)); - - LinkShare link_share(&(filter.choke)); - - RateCounterFilter total_utilization( - &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization", - "Total_link_utilization"); - - // Delays is being plotted only for the first flow. - // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). - for (size_t i = 0; i < kNumFlows; ++i) { - metric_recorders[i].reset( - new MetricRecorder(bwe_names[bwe_type], static_cast(i), - senders[i].get(), &link_share)); - receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type, - i == 0, false, - metric_recorders[i].get())); - metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs * - (kNumFlows - 1)); - metric_recorders[i].get()->set_plot_available_capacity( - i == 0 && plot_total_available_capacity_); - } - - // Test also with one way propagation delay = 100ms. - // filter.delay.SetOneWayDelayMs(100); - filter.choke.set_capacity_kbps(3500); - - RunFor(40 * 1000); // 0-40s. - senders[0].get()->Pause(); - RunFor(20 * 1000); // 40-60s. - senders[0].get()->Resume(20 * 1000); - RunFor(60 * 1000); // 60-120s. - - int64_t paused[] = {20 * 1000, 0, 0}; - - // First flow is being paused, hence having a different optimum. - const std::string optima_lines[] = {"1", "2", "2"}; - - std::string title("5.8_Pause_and_resume_media_flow"); - for (size_t i = 0; i < kNumFlows; ++i) { - metric_recorders[i].get()->PlotThroughputHistogram( - title, bwe_names[bwe_type], kNumFlows, paused[i], optima_lines[i]); - metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], - kNumFlows, kOneWayDelayMs); - metric_recorders[i].get()->PlotLossHistogram( - title, bwe_names[bwe_type], kNumFlows, - receivers[i].get()->GlobalPacketLoss()); - BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); - } -} - -// Following functions are used for randomizing TCP file size and -// starting time, used on 5.7 RunMultipleShortTcpFairness. -// They are pseudo-random generators, creating always the same -// value sequence for a given Random seed. - -std::vector BweTest::GetFileSizesBytes(int num_files) { - // File size chosen from uniform distribution between [100,1000] kB. - const int kMinKbytes = 100; - const int kMaxKbytes = 1000; - - Random random(0x12345678); - std::vector tcp_file_sizes_bytes; - - while (num_files-- > 0) { - tcp_file_sizes_bytes.push_back(random.Rand(kMinKbytes, kMaxKbytes) * 1000); - } - - return tcp_file_sizes_bytes; -} - -std::vector BweTest::GetStartingTimesMs(int num_files) { - // OFF state behaves as an exp. distribution with mean = 10 seconds. - const float kMeanMs = 10000.0f; - Random random(0x12345678); - - std::vector tcp_starting_times_ms; - - // Two TCP Flows are initialized simultaneosly at t=0 seconds. - for (int i = 0; i < 2; ++i, --num_files) { - tcp_starting_times_ms.push_back(0); - } - - // Other TCP Flows are initialized in an OFF state. - while (num_files-- > 0) { - tcp_starting_times_ms.push_back( - static_cast(random.Exponential(1.0f / kMeanMs))); - } - - return tcp_starting_times_ms; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bwe_test.h b/modules/remote_bitrate_estimator/test/bwe_test.h deleted file mode 100644 index 275a69637c..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2013 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_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_H_ - -#include -#include -#include - -#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "rtc_base/constructor_magic.h" -#include "test/gtest.h" - -namespace webrtc { - -namespace testing { -namespace bwe { - -class BweReceiver; -class PacketReceiver; -class PacketSender; - -class PacketProcessorRunner { - public: - explicit PacketProcessorRunner(PacketProcessor* processor); - PacketProcessorRunner(const PacketProcessorRunner&); - ~PacketProcessorRunner(); - - bool RunsProcessor(const PacketProcessor* processor) const; - void RunFor(int64_t time_ms, int64_t time_now_ms, Packets* in_out); - - private: - void FindPacketsToProcess(const FlowIds& flow_ids, Packets* in, Packets* out); - void QueuePackets(Packets* batch, int64_t end_of_batch_time_us); - - PacketProcessor* processor_; - Packets queue_; -}; - -class Link : public PacketProcessorListener { - public: - Link(); - ~Link() override; - - void AddPacketProcessor(PacketProcessor* processor, - ProcessorType type) override; - void RemovePacketProcessor(PacketProcessor* processor) override; - - void Run(int64_t run_for_ms, int64_t now_ms, Packets* packets); - - const std::vector& senders() { return senders_; } - const std::vector& processors() { return processors_; } - - private: - std::vector senders_; - std::vector receivers_; - std::vector processors_; -}; - -class BweTest { - public: - BweTest(); - explicit BweTest(bool plot_capacity); - ~BweTest(); - - void RunChoke(BandwidthEstimatorType bwe_type, - std::vector capacities_kbps); - - void RunVariableCapacity1SingleFlow(BandwidthEstimatorType bwe_type); - void RunVariableCapacity2MultipleFlows(BandwidthEstimatorType bwe_type, - size_t num_flows); - void RunBidirectionalFlow(BandwidthEstimatorType bwe_type); - void RunSelfFairness(BandwidthEstimatorType bwe_type); - void RunRoundTripTimeFairness(BandwidthEstimatorType bwe_type); - void RunLongTcpFairness(BandwidthEstimatorType bwe_type); - void RunMultipleShortTcpFairness(BandwidthEstimatorType bwe_type, - std::vector tcp_file_sizes_bytes, - std::vector tcp_starting_times_ms); - void RunPauseResumeFlows(BandwidthEstimatorType bwe_type); - - void RunFairnessTest(BandwidthEstimatorType bwe_type, - size_t num_media_flows, - size_t num_tcp_flows, - int64_t run_time_seconds, - uint32_t capacity_kbps, - int64_t max_delay_ms, - int64_t rtt_ms, - int64_t max_jitter_ms, - const int64_t* offsets_ms); - - void RunFairnessTest(BandwidthEstimatorType bwe_type, - size_t num_media_flows, - size_t num_tcp_flows, - int64_t run_time_seconds, - uint32_t capacity_kbps, - int64_t max_delay_ms, - int64_t rtt_ms, - int64_t max_jitter_ms, - const int64_t* offsets_ms, - const std::string& title, - const std::string& flow_name); - - static std::vector GetFileSizesBytes(int num_files); - static std::vector GetStartingTimesMs(int num_files); - - protected: - void SetUp(); - - void VerboseLogging(bool enable); - void RunFor(int64_t time_ms); - std::string GetTestName() const; - - void PrintResults(double max_throughput_kbps, - Stats throughput_kbps, - int flow_id, - Stats flow_delay_ms, - Stats flow_throughput_kbps); - - void PrintResults(double max_throughput_kbps, - Stats throughput_kbps, - std::map> flow_delay_ms, - std::map> flow_throughput_kbps); - - Link downlink_; - Link uplink_; - - private: - void FindPacketsToProcess(const FlowIds& flow_ids, Packets* in, Packets* out); - void GiveFeedbackToAffectedSenders(PacketReceiver* receiver); - - int64_t run_time_ms_; - int64_t time_now_ms_; - int64_t simulation_interval_ms_; - std::vector links_; - Packets packets_; - bool plot_total_available_capacity_; - - RTC_DISALLOW_COPY_AND_ASSIGN(BweTest); -}; - -// Default Evaluation parameters: -// Link capacity: 4000ms; -// Queueing delay capacity: 300ms. -// One-Way propagation delay: 50ms. -// Jitter model: Truncated gaussian. -// Maximum end-to-end jitter: 30ms = 2*standard_deviation. -// Bottleneck queue type: Drop tail. -// Path loss ratio: 0%. - -const int kOneWayDelayMs = 50; -const int kMaxQueueingDelayMs = 300; -const int kMaxCapacityKbps = 4000; -const int kMaxJitterMs = 15; - -struct DefaultEvaluationFilter { - DefaultEvaluationFilter(PacketProcessorListener* listener, int flow_id) - : choke(listener, flow_id), - delay(listener, flow_id), - jitter(listener, flow_id) { - SetDefaultParameters(); - } - - DefaultEvaluationFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids) - : choke(listener, flow_ids), - delay(listener, flow_ids), - jitter(listener, flow_ids) { - SetDefaultParameters(); - } - - void SetDefaultParameters() { - delay.SetOneWayDelayMs(kOneWayDelayMs); - choke.set_max_delay_ms(kMaxQueueingDelayMs); - choke.set_capacity_kbps(kMaxCapacityKbps); - jitter.SetMaxJitter(kMaxJitterMs); - } - - ChokeFilter choke; - DelayFilter delay; - JitterFilter jitter; -}; - -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_H_ diff --git a/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc b/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc deleted file mode 100644 index 8e4b7b4ec8..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2013 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/remote_bitrate_estimator/test/bwe_test_baselinefile.h" - -#include -#include -#include -#include -#include - -#include "modules/remote_bitrate_estimator/test/bwe_test_fileutils.h" -#include "rtc_base/constructor_magic.h" -#include "test/testsupport/file_utils.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -// The format of BWE test baseline files is extremely simple: -// 1. All read/written entities are 32-bit unsigned integers in network byte -// order (Big Endian). -// 2. Files beging with a 2 word header containing a magic marker and file -// format version indicator. The Magic marker reads "BWE!" in a hex dump. -// 3. Each estimate is logged as a pair of words: time in milliseconds and -// estimated bit rate, in bits per second. -const uint32_t kMagicMarker = 0x42574521; -const uint32_t kFileVersion1 = 0x00000001; -const char kResourceSubDir[] = "remote_bitrate_estimator"; - -class BaseLineFileVerify : public BaseLineFileInterface { - public: - // If |allow_missing_file| is set, VerifyOrWrite() will return true even if - // the baseline file is missing. This is the default when verifying files, but - // not when updating (i.e. we always write it out if missing). - BaseLineFileVerify(const std::string& filepath, bool allow_missing_file) - : reader_(), fail_to_read_response_(false) { - std::unique_ptr reader; - reader.reset(ResourceFileReader::Create(filepath, "bin")); - if (!reader.get()) { - printf("WARNING: Missing baseline file for BWE test: %s.bin\n", - filepath.c_str()); - fail_to_read_response_ = allow_missing_file; - } else { - uint32_t magic_marker = 0; - uint32_t file_version = 0; - if (reader->Read(&magic_marker) && magic_marker == kMagicMarker && - reader->Read(&file_version) && file_version == kFileVersion1) { - reader_.swap(reader); - } else { - printf("WARNING: Bad baseline file header for BWE test: %s.bin\n", - filepath.c_str()); - } - } - } - ~BaseLineFileVerify() override {} - - void Estimate(int64_t time_ms, uint32_t estimate_bps) override { - if (reader_.get()) { - uint32_t read_ms = 0; - uint32_t read_bps = 0; - if (reader_->Read(&read_ms) && read_ms == time_ms && - reader_->Read(&read_bps) && read_bps == estimate_bps) { - } else { - printf("ERROR: Baseline differs starting at: %d ms (%d vs %d)!\n", - static_cast(time_ms), estimate_bps, read_bps); - reader_.reset(NULL); - } - } - } - - bool VerifyOrWrite() override { - if (reader_.get()) { - if (reader_->IsAtEnd()) { - return true; - } else { - printf("ERROR: Baseline file contains more data!\n"); - return false; - } - } - return fail_to_read_response_; - } - - private: - std::unique_ptr reader_; - bool fail_to_read_response_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BaseLineFileVerify); -}; - -class BaseLineFileUpdate : public BaseLineFileInterface { - public: - BaseLineFileUpdate(const std::string& filepath, - BaseLineFileInterface* verifier) - : verifier_(verifier), output_content_(), filepath_(filepath) { - output_content_.push_back(kMagicMarker); - output_content_.push_back(kFileVersion1); - } - ~BaseLineFileUpdate() override {} - - void Estimate(int64_t time_ms, uint32_t estimate_bps) override { - verifier_->Estimate(time_ms, estimate_bps); - output_content_.push_back(static_cast(time_ms)); - output_content_.push_back(estimate_bps); - } - - bool VerifyOrWrite() override { - if (!verifier_->VerifyOrWrite()) { - std::string dir_path = webrtc::test::OutputPath() + kResourceSubDir; - if (!webrtc::test::CreateDir(dir_path)) { - printf("WARNING: Cannot create output dir: %s\n", dir_path.c_str()); - return false; - } - std::unique_ptr writer; - writer.reset(OutputFileWriter::Create(filepath_, "bin")); - if (!writer.get()) { - printf("WARNING: Cannot create output file: %s.bin\n", - filepath_.c_str()); - return false; - } - printf("NOTE: Writing baseline file for BWE test: %s.bin\n", - filepath_.c_str()); - for (std::vector::iterator it = output_content_.begin(); - it != output_content_.end(); ++it) { - writer->Write(*it); - } - return true; - } - printf("NOTE: No change, not writing: %s\n", filepath_.c_str()); - return true; - } - - private: - std::unique_ptr verifier_; - std::vector output_content_; - std::string filepath_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BaseLineFileUpdate); -}; - -BaseLineFileInterface* BaseLineFileInterface::Create( - const std::string& filename, - bool write_output_file) { - std::string filepath = filename; - std::replace(filepath.begin(), filepath.end(), '/', '_'); - filepath = std::string(kResourceSubDir) + "/" + filepath; - - std::unique_ptr result; - result.reset(new BaseLineFileVerify(filepath, !write_output_file)); - if (write_output_file) { - // Takes ownership of the |verifier| instance. - result.reset(new BaseLineFileUpdate(filepath, result.release())); - } - return result.release(); -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h b/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h deleted file mode 100644 index d9f22c02b1..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2013 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_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_BASELINEFILE_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_BASELINEFILE_H_ - -#include -#include - -namespace webrtc { -namespace testing { -namespace bwe { - -class BaseLineFileInterface { - public: - virtual ~BaseLineFileInterface() {} - - // Compare, or log, one estimate against the baseline file. - virtual void Estimate(int64_t time_ms, uint32_t estimate_bps) = 0; - - // Verify whether there are any differences between the logged estimates and - // those read from the baseline file. If updating the baseline file, write out - // new file if there were differences. Return true if logged estimates are - // identical, or if output file was updated successfully. - virtual bool VerifyOrWrite() = 0; - - // Create an instance for either verifying estimates against a baseline file - // with name |filename|, living in the resources/ directory or, if the flag - // |write_updated_file| is set, write logged estimates to a file with the same - // name, living in the out/ directory. - static BaseLineFileInterface* Create(const std::string& filename, - bool write_updated_file); -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_BASELINEFILE_H_ diff --git a/modules/remote_bitrate_estimator/test/bwe_test_fileutils.cc b/modules/remote_bitrate_estimator/test/bwe_test_fileutils.cc deleted file mode 100644 index a69f67225a..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test_fileutils.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2013 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/remote_bitrate_estimator/test/bwe_test_fileutils.h" - -#ifdef WIN32 -#include -#else -#include -#endif -#include - -#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" -#include "test/testsupport/file_utils.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -ResourceFileReader::~ResourceFileReader() { - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - } -} - -bool ResourceFileReader::IsAtEnd() { - int32_t current_pos = ftell(file_); - fseek(file_, 0, SEEK_END); - int32_t end_pos = ftell(file_); - fseek(file_, current_pos, SEEK_SET); - return current_pos == end_pos; -} - -bool ResourceFileReader::Read(uint32_t* out) { - assert(out); - uint32_t tmp = 0; - if (fread(&tmp, 1, sizeof(uint32_t), file_) != sizeof(uint32_t)) { - printf("Error reading!\n"); - return false; - } - *out = ntohl(tmp); - return true; -} - -ResourceFileReader* ResourceFileReader::Create(const std::string& filename, - const std::string& extension) { - std::string filepath = webrtc::test::ResourcePath(filename, extension); - FILE* file = fopen(filepath.c_str(), "rb"); - if (file == NULL) { - BWE_TEST_LOGGING_CONTEXT("ResourceFileReader"); - BWE_TEST_LOGGING_LOG1("Create", "Can't read file: %s", filepath.c_str()); - return 0; - } else { - return new ResourceFileReader(file); - } -} - -OutputFileWriter::~OutputFileWriter() { - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - } -} - -bool OutputFileWriter::Write(uint32_t value) { - uint32_t tmp = htonl(value); - if (fwrite(&tmp, 1, sizeof(uint32_t), file_) != sizeof(uint32_t)) { - return false; - } - return true; -} - -OutputFileWriter* OutputFileWriter::Create(const std::string& filename, - const std::string& extension) { - std::string filepath = - webrtc::test::OutputPath() + filename + "." + extension; - FILE* file = fopen(filepath.c_str(), "wb"); - if (file == NULL) { - BWE_TEST_LOGGING_CONTEXT("OutputFileWriter"); - BWE_TEST_LOGGING_LOG1("Create", "Can't write file: %s", filepath.c_str()); - return NULL; - } else { - return new OutputFileWriter(file); - } -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bwe_test_fileutils.h b/modules/remote_bitrate_estimator/test/bwe_test_fileutils.h deleted file mode 100644 index c38bc10104..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test_fileutils.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013 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_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FILEUTILS_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FILEUTILS_H_ - -#include -#include -#include - -#include "rtc_base/constructor_magic.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -class ResourceFileReader { - public: - ~ResourceFileReader(); - - bool IsAtEnd(); - bool Read(uint32_t* out); - - static ResourceFileReader* Create(const std::string& filename, - const std::string& extension); - - private: - explicit ResourceFileReader(FILE* file) : file_(file) {} - FILE* file_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ResourceFileReader); -}; - -class OutputFileWriter { - public: - ~OutputFileWriter(); - - bool Write(uint32_t value); - - static OutputFileWriter* Create(const std::string& filename, - const std::string& extension); - - private: - explicit OutputFileWriter(FILE* file) : file_(file) {} - FILE* file_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(OutputFileWriter); -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FILEUTILS_H_ diff --git a/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/modules/remote_bitrate_estimator/test/bwe_test_framework.cc deleted file mode 100644 index 81d77e1726..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test_framework.cc +++ /dev/null @@ -1,812 +0,0 @@ -/* - * Copyright (c) 2013 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/remote_bitrate_estimator/test/bwe_test_framework.h" - -#include -#include -#include -#include -#include - -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "modules/rtp_rtcp/source/rtp_packet_received.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/numerics/safe_minmax.h" -#include "rtc_base/system/unused.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -RateCounter::RateCounter(int64_t window_size_ms) - : window_size_us_(1000 * window_size_ms), - recently_received_packets_(0), - recently_received_bytes_(0), - last_accumulated_us_(0), - window_() {} - -RateCounter::RateCounter() : RateCounter(1000) {} - -RateCounter::~RateCounter() = default; - -class DelayCapHelper { - public: - // Max delay = 0 stands for +infinite. - DelayCapHelper() : max_delay_us_(0), delay_stats_() {} - - void set_max_delay_ms(int64_t max_delay_ms) { - BWE_TEST_LOGGING_ENABLE(false); - BWE_TEST_LOGGING_LOG1("Max Delay", "%d ms", static_cast(max_delay_ms)); - assert(max_delay_ms >= 0); - max_delay_us_ = max_delay_ms * 1000; - } - - bool ShouldSendPacket(int64_t send_time_us, int64_t arrival_time_us) { - int64_t packet_delay_us = send_time_us - arrival_time_us; - delay_stats_.Push((std::min(packet_delay_us, max_delay_us_) + 500) / 1000); - return (max_delay_us_ == 0 || max_delay_us_ >= packet_delay_us); - } - - const Stats& delay_stats() const { return delay_stats_; } - - private: - int64_t max_delay_us_; - Stats delay_stats_; - - RTC_DISALLOW_COPY_AND_ASSIGN(DelayCapHelper); -}; - -const FlowIds CreateFlowIds(const int* flow_ids_array, size_t num_flow_ids) { - FlowIds flow_ids(&flow_ids_array[0], flow_ids_array + num_flow_ids); - return flow_ids; -} - -const FlowIds CreateFlowIdRange(int initial_value, int last_value) { - int size = last_value - initial_value + 1; - assert(size > 0); - int* flow_ids_array = new int[size]; - for (int i = initial_value; i <= last_value; ++i) { - flow_ids_array[i - initial_value] = i; - } - return CreateFlowIds(flow_ids_array, size); -} - -void RateCounter::UpdateRates(int64_t send_time_us, uint32_t payload_size) { - ++recently_received_packets_; - recently_received_bytes_ += payload_size; - last_accumulated_us_ = send_time_us; - window_.push_back(std::make_pair(send_time_us, payload_size)); - while (!window_.empty()) { - const TimeSizePair& packet = window_.front(); - if (packet.first > (last_accumulated_us_ - window_size_us_)) { - break; - } - assert(recently_received_packets_ >= 1); - assert(recently_received_bytes_ >= packet.second); - --recently_received_packets_; - recently_received_bytes_ -= packet.second; - window_.pop_front(); - } -} - -uint32_t RateCounter::bits_per_second() const { - return (8 * recently_received_bytes_) / BitrateWindowS(); -} - -uint32_t RateCounter::packets_per_second() const { - return recently_received_packets_ / BitrateWindowS(); -} - -double RateCounter::BitrateWindowS() const { - return static_cast(window_size_us_) / (1000 * 1000); -} - -MediaPacket::MediaPacket() { - memset(&header_, 0, sizeof(header_)); -} - -MediaPacket::MediaPacket(int flow_id, - int64_t send_time_us, - size_t payload_size, - uint16_t sequence_number) - : Packet(flow_id, send_time_us, payload_size) { - header_ = RTPHeader(); - header_.sequenceNumber = sequence_number; -} - -MediaPacket::MediaPacket(int flow_id, - int64_t send_time_us, - size_t payload_size, - const RTPHeader& header) - : Packet(flow_id, send_time_us, payload_size), header_(header) {} - -MediaPacket::MediaPacket(int64_t send_time_us, uint16_t sequence_number) - : Packet(0, send_time_us, 0) { - header_ = RTPHeader(); - header_.sequenceNumber = sequence_number; -} - -void MediaPacket::SetAbsSendTimeMs(int64_t abs_send_time_ms) { - header_.extension.hasAbsoluteSendTime = true; - header_.extension.absoluteSendTime = - ((static_cast(abs_send_time_ms * (1 << 18)) + 500) / 1000) & - 0x00fffffful; -} - -// Copies payload size and sequence number. -RtpPacketReceived MediaPacket::GetRtpPacket() const { - RtpPacketReceived packet; - - packet.SetPayloadSize(payload_size()); - packet.SetSequenceNumber(header_.sequenceNumber); - return packet; -} - -BbrBweFeedback::BbrBweFeedback( - int flow_id, - int64_t send_time_us, - int64_t latest_send_time_ms, - const std::vector& packet_feedback_vector) - : FeedbackPacket(flow_id, send_time_us, latest_send_time_ms), - packet_feedback_vector_(packet_feedback_vector) {} - -RembFeedback::RembFeedback(int flow_id, - int64_t send_time_us, - int64_t last_send_time_ms, - uint32_t estimated_bps, - RTCPReportBlock report_block) - : FeedbackPacket(flow_id, send_time_us, last_send_time_ms), - estimated_bps_(estimated_bps), - report_block_(report_block) {} - -SendSideBweFeedback::SendSideBweFeedback( - int flow_id, - int64_t send_time_us, - int64_t last_send_time_ms, - const std::vector& packet_feedback_vector) - : FeedbackPacket(flow_id, send_time_us, last_send_time_ms), - packet_feedback_vector_(packet_feedback_vector) {} - -bool IsTimeSorted(const Packets& packets) { - PacketsConstIt last_it = packets.begin(); - for (PacketsConstIt it = last_it; it != packets.end(); ++it) { - if (it != last_it && **it < **last_it) { - return false; - } - last_it = it; - } - return true; -} - -PacketProcessor::PacketProcessor(PacketProcessorListener* listener, - int flow_id, - ProcessorType type) - : listener_(listener), flow_ids_(&flow_id, &flow_id + 1) { - if (listener_) { - listener_->AddPacketProcessor(this, type); - } -} - -PacketProcessor::PacketProcessor(PacketProcessorListener* listener, - const FlowIds& flow_ids, - ProcessorType type) - : listener_(listener), flow_ids_(flow_ids) { - if (listener_) { - listener_->AddPacketProcessor(this, type); - } -} - -PacketProcessor::~PacketProcessor() { - if (listener_) { - listener_->RemovePacketProcessor(this); - } -} - -uint32_t PacketProcessor::packets_per_second() const { - return rate_counter_.packets_per_second(); -} - -uint32_t PacketProcessor::bits_per_second() const { - return rate_counter_.bits_per_second(); -} - -RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, - int flow_id, - const char* name, - const std::string& algorithm_name) - : PacketProcessor(listener, flow_id, kRegular), - packets_per_second_stats_(), - kbps_stats_(), - start_plotting_time_ms_(0), - flow_id_(flow_id), - name_(name), - algorithm_name_(algorithm_name) { - // Only used when compiling with BWE test logging enabled. - RTC_UNUSED(flow_id_); -} - -RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids, - const char* name, - const std::string& algorithm_name) - : PacketProcessor(listener, flow_ids, kRegular), - packets_per_second_stats_(), - kbps_stats_(), - start_plotting_time_ms_(0), - name_(name), - algorithm_name_(algorithm_name) { - // TODO(terelius): Appending the flow IDs to the algorithm name is a hack to - // keep the current plot functionality without having to print the full - // context for each PLOT line. It is unclear whether multiple flow IDs are - // needed at all in the long term. - std::stringstream ss; - ss << algorithm_name_; - for (int flow_id : flow_ids) { - ss << ',' << flow_id; - } - algorithm_name_ = ss.str(); -} - -RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids, - const char* name, - int64_t start_plotting_time_ms, - const std::string& algorithm_name) - : RateCounterFilter(listener, flow_ids, name, algorithm_name) { - start_plotting_time_ms_ = start_plotting_time_ms; -} - -RateCounterFilter::~RateCounterFilter() { - LogStats(); -} - -void RateCounterFilter::LogStats() { - BWE_TEST_LOGGING_CONTEXT("RateCounterFilter"); - packets_per_second_stats_.Log("pps"); - kbps_stats_.Log("kbps"); -} - -Stats RateCounterFilter::GetBitrateStats() const { - return kbps_stats_; -} - -void RateCounterFilter::Plot(int64_t timestamp_ms) { - // TODO(stefan): Reorganize logging configuration to reduce amount - // of preprocessor conditionals in the code. - uint32_t plot_kbps = 0; - if (timestamp_ms >= start_plotting_time_ms_) { - plot_kbps = rate_counter_.bits_per_second() / 1000.0; - } - BWE_TEST_LOGGING_CONTEXT(name_.c_str()); - if (algorithm_name_.empty()) { - BWE_TEST_LOGGING_PLOT_WITH_SSRC(0, "Throughput_kbps#1", timestamp_ms, - plot_kbps, flow_id_); - } else { - BWE_TEST_LOGGING_PLOT_WITH_NAME_AND_SSRC(0, "Throughput_kbps#1", - timestamp_ms, plot_kbps, flow_id_, - algorithm_name_); - } - RTC_UNUSED(plot_kbps); -} - -void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { - assert(in_out); - for (const Packet* packet : *in_out) { - rate_counter_.UpdateRates(packet->send_time_us(), - static_cast(packet->payload_size())); - } - packets_per_second_stats_.Push(rate_counter_.packets_per_second()); - kbps_stats_.Push(rate_counter_.bits_per_second() / 1000.0); -} - -LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id) - : PacketProcessor(listener, flow_id, kRegular), - random_(0x12345678), - loss_fraction_(0.0f) {} - -LossFilter::LossFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids) - : PacketProcessor(listener, flow_ids, kRegular), - random_(0x12345678), - loss_fraction_(0.0f) {} - -void LossFilter::SetLoss(float loss_percent) { - BWE_TEST_LOGGING_ENABLE(false); - BWE_TEST_LOGGING_LOG1("Loss", "%f%%", loss_percent); - assert(loss_percent >= 0.0f); - assert(loss_percent <= 100.0f); - loss_fraction_ = loss_percent * 0.01f; -} - -void LossFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { - assert(in_out); - for (PacketsIt it = in_out->begin(); it != in_out->end();) { - if (random_.Rand() < loss_fraction_) { - delete *it; - it = in_out->erase(it); - } else { - ++it; - } - } -} - -const int64_t kDefaultOneWayDelayUs = 0; - -DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id) - : PacketProcessor(listener, flow_id, kRegular), - one_way_delay_us_(kDefaultOneWayDelayUs), - last_send_time_us_(0) {} - -DelayFilter::DelayFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids) - : PacketProcessor(listener, flow_ids, kRegular), - one_way_delay_us_(kDefaultOneWayDelayUs), - last_send_time_us_(0) {} - -void DelayFilter::SetOneWayDelayMs(int64_t one_way_delay_ms) { - BWE_TEST_LOGGING_ENABLE(false); - BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast(one_way_delay_ms)); - assert(one_way_delay_ms >= 0); - one_way_delay_us_ = one_way_delay_ms * 1000; -} - -void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { - assert(in_out); - for (Packet* packet : *in_out) { - int64_t new_send_time_us = packet->send_time_us() + one_way_delay_us_; - last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us); - packet->set_send_time_us(last_send_time_us_); - } -} - -JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id) - : PacketProcessor(listener, flow_id, kRegular), - random_(0x89674523), - stddev_jitter_us_(0), - last_send_time_us_(0), - reordering_(false) {} - -JitterFilter::JitterFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids) - : PacketProcessor(listener, flow_ids, kRegular), - random_(0x89674523), - stddev_jitter_us_(0), - last_send_time_us_(0), - reordering_(false) {} - -const int kN = 3; // Truncated N sigma gaussian. - -void JitterFilter::SetMaxJitter(int64_t max_jitter_ms) { - BWE_TEST_LOGGING_ENABLE(false); - BWE_TEST_LOGGING_LOG1("Max Jitter", "%d ms", static_cast(max_jitter_ms)); - assert(max_jitter_ms >= 0); - // Truncated gaussian, Max jitter = kN*sigma. - stddev_jitter_us_ = (max_jitter_ms * 1000 + kN / 2) / kN; -} - -namespace { -inline int64_t TruncatedNSigmaGaussian(Random* const random, - int64_t mean, - int64_t std_dev) { - const int64_t gaussian_random = random->Gaussian(mean, std_dev); - return rtc::SafeClamp(gaussian_random, -kN * std_dev, kN * std_dev); -} -} // namespace - -void JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { - assert(in_out); - for (Packet* packet : *in_out) { - int64_t jitter_us = - std::abs(TruncatedNSigmaGaussian(&random_, 0, stddev_jitter_us_)); - int64_t new_send_time_us = packet->send_time_us() + jitter_us; - - if (!reordering_) { - new_send_time_us = std::max(last_send_time_us_, new_send_time_us); - } - - // Receiver timestamp cannot be lower than sender timestamp. - assert(new_send_time_us >= packet->sender_timestamp_us()); - - packet->set_send_time_us(new_send_time_us); - last_send_time_us_ = new_send_time_us; - } -} - -// Computes the expected value for a right sided (abs) truncated gaussian. -// Does not take into account possible reoerdering updates. -int64_t JitterFilter::MeanUs() { - const double kPi = 3.1415926535897932; - double max_jitter_us = static_cast(kN * stddev_jitter_us_); - double right_sided_mean_us = - static_cast(stddev_jitter_us_) / sqrt(kPi / 2.0); - double truncated_mean_us = - right_sided_mean_us * - (1.0 - exp(-pow(static_cast(kN), 2.0) / 2.0)) + - max_jitter_us * erfc(static_cast(kN)); - return static_cast(truncated_mean_us + 0.5); -} - -ReorderFilter::ReorderFilter(PacketProcessorListener* listener, int flow_id) - : PacketProcessor(listener, flow_id, kRegular), - random_(0x27452389), - reorder_fraction_(0.0f) {} - -ReorderFilter::ReorderFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids) - : PacketProcessor(listener, flow_ids, kRegular), - random_(0x27452389), - reorder_fraction_(0.0f) {} - -void ReorderFilter::SetReorder(float reorder_percent) { - BWE_TEST_LOGGING_ENABLE(false); - BWE_TEST_LOGGING_LOG1("Reordering", "%f%%", reorder_percent); - assert(reorder_percent >= 0.0f); - assert(reorder_percent <= 100.0f); - reorder_fraction_ = reorder_percent * 0.01f; -} - -void ReorderFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { - assert(in_out); - if (in_out->size() >= 2) { - PacketsIt last_it = in_out->begin(); - PacketsIt it = last_it; - while (++it != in_out->end()) { - if (random_.Rand() < reorder_fraction_) { - int64_t t1 = (*last_it)->send_time_us(); - int64_t t2 = (*it)->send_time_us(); - std::swap(*last_it, *it); - (*last_it)->set_send_time_us(t1); - (*it)->set_send_time_us(t2); - } - last_it = it; - } - } -} - -const uint32_t kDefaultKbps = 1200; - -ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id) - : PacketProcessor(listener, flow_id, kRegular), - capacity_kbps_(kDefaultKbps), - last_send_time_us_(0), - delay_cap_helper_(new DelayCapHelper()) {} - -ChokeFilter::ChokeFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids) - : PacketProcessor(listener, flow_ids, kRegular), - capacity_kbps_(kDefaultKbps), - last_send_time_us_(0), - delay_cap_helper_(new DelayCapHelper()) {} - -ChokeFilter::~ChokeFilter() {} - -void ChokeFilter::set_capacity_kbps(uint32_t kbps) { - BWE_TEST_LOGGING_ENABLE(false); - BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps); - capacity_kbps_ = kbps; -} - -uint32_t ChokeFilter::capacity_kbps() { - return capacity_kbps_; -} - -void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) { - assert(in_out); - for (PacketsIt it = in_out->begin(); it != in_out->end();) { - int64_t earliest_send_time_us = - std::max(last_send_time_us_, (*it)->send_time_us()); - int64_t new_send_time_us = - earliest_send_time_us + - ((*it)->payload_size() * 8 * 1000 + capacity_kbps_ / 2) / - capacity_kbps_; - BWE_TEST_LOGGING_PLOT(0, "MaxThroughput_", new_send_time_us / 1000, - capacity_kbps_); - if (delay_cap_helper_->ShouldSendPacket(new_send_time_us, - (*it)->send_time_us())) { - (*it)->set_send_time_us(new_send_time_us); - last_send_time_us_ = new_send_time_us; - ++it; - } else { - delete *it; - it = in_out->erase(it); - } - } -} - -void ChokeFilter::set_max_delay_ms(int64_t max_delay_ms) { - delay_cap_helper_->set_max_delay_ms(max_delay_ms); -} - -Stats ChokeFilter::GetDelayStats() const { - return delay_cap_helper_->delay_stats(); -} - -TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( - PacketProcessorListener* listener, - int flow_id) - : PacketProcessor(listener, flow_id, kRegular), - current_offset_us_(0), - delivery_times_us_(), - next_delivery_it_(), - local_time_us_(-1), - rate_counter_(new RateCounter), - name_(""), - delay_cap_helper_(new DelayCapHelper()), - packets_per_second_stats_(), - kbps_stats_() {} - -TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( - PacketProcessorListener* listener, - const FlowIds& flow_ids) - : PacketProcessor(listener, flow_ids, kRegular), - current_offset_us_(0), - delivery_times_us_(), - next_delivery_it_(), - local_time_us_(-1), - rate_counter_(new RateCounter), - name_(""), - delay_cap_helper_(new DelayCapHelper()), - packets_per_second_stats_(), - kbps_stats_() {} - -TraceBasedDeliveryFilter::TraceBasedDeliveryFilter( - PacketProcessorListener* listener, - int flow_id, - const char* name) - : PacketProcessor(listener, flow_id, kRegular), - current_offset_us_(0), - delivery_times_us_(), - next_delivery_it_(), - local_time_us_(-1), - rate_counter_(new RateCounter), - name_(name), - delay_cap_helper_(new DelayCapHelper()), - packets_per_second_stats_(), - kbps_stats_() {} - -TraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() {} - -bool TraceBasedDeliveryFilter::Init(const std::string& filename) { - FILE* trace_file = fopen(filename.c_str(), "r"); - if (!trace_file) { - return false; - } - int64_t first_timestamp = -1; - while (!feof(trace_file)) { - const size_t kMaxLineLength = 100; - char line[kMaxLineLength]; - if (fgets(line, kMaxLineLength, trace_file)) { - std::string line_string(line); - std::istringstream buffer(line_string); - int64_t timestamp; - buffer >> timestamp; - timestamp /= 1000; // Convert to microseconds. - if (first_timestamp == -1) - first_timestamp = timestamp; - assert(delivery_times_us_.empty() || - timestamp - first_timestamp - delivery_times_us_.back() >= 0); - delivery_times_us_.push_back(timestamp - first_timestamp); - } - } - assert(!delivery_times_us_.empty()); - next_delivery_it_ = delivery_times_us_.begin(); - fclose(trace_file); - return true; -} - -void TraceBasedDeliveryFilter::Plot(int64_t timestamp_ms) { - BWE_TEST_LOGGING_CONTEXT(name_.c_str()); - // This plots the max possible throughput of the trace-based delivery filter, - // which will be reached if a packet sent on every packet slot of the trace. - BWE_TEST_LOGGING_PLOT(0, "MaxThroughput_#1", timestamp_ms, - rate_counter_->bits_per_second() / 1000.0); -} - -void TraceBasedDeliveryFilter::RunFor(int64_t time_ms, Packets* in_out) { - assert(in_out); - for (PacketsIt it = in_out->begin(); it != in_out->end();) { - while (local_time_us_ < (*it)->send_time_us()) { - ProceedToNextSlot(); - } - // Drop any packets that have been queued for too long. - while (!delay_cap_helper_->ShouldSendPacket(local_time_us_, - (*it)->send_time_us())) { - delete *it; - it = in_out->erase(it); - if (it == in_out->end()) { - return; - } - } - if (local_time_us_ >= (*it)->send_time_us()) { - (*it)->set_send_time_us(local_time_us_); - ProceedToNextSlot(); - } - ++it; - } - packets_per_second_stats_.Push(rate_counter_->packets_per_second()); - kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0); -} - -void TraceBasedDeliveryFilter::set_max_delay_ms(int64_t max_delay_ms) { - delay_cap_helper_->set_max_delay_ms(max_delay_ms); -} - -Stats TraceBasedDeliveryFilter::GetDelayStats() const { - return delay_cap_helper_->delay_stats(); -} - -Stats TraceBasedDeliveryFilter::GetBitrateStats() const { - return kbps_stats_; -} - -void TraceBasedDeliveryFilter::ProceedToNextSlot() { - if (*next_delivery_it_ <= local_time_us_) { - ++next_delivery_it_; - if (next_delivery_it_ == delivery_times_us_.end()) { - // When the trace wraps we allow two packets to be sent back-to-back. - for (int64_t& delivery_time_us : delivery_times_us_) { - delivery_time_us += local_time_us_ - current_offset_us_; - } - current_offset_us_ += local_time_us_ - current_offset_us_; - next_delivery_it_ = delivery_times_us_.begin(); - } - } - local_time_us_ = *next_delivery_it_; - const int kPayloadSize = 1200; - rate_counter_->UpdateRates(local_time_us_, kPayloadSize); -} - -VideoSource::VideoSource(int flow_id, - float fps, - uint32_t kbps, - uint32_t ssrc, - int64_t first_frame_offset_ms) - : kMaxPayloadSizeBytes(1200), - kTimestampBase(0xff80ff00ul), - frame_period_ms_(1000.0 / fps), - bits_per_second_(1000 * kbps), - frame_size_bytes_(bits_per_second_ / 8 / fps), - random_(0x12345678), - flow_id_(flow_id), - next_frame_ms_(first_frame_offset_ms), - next_frame_rand_ms_(0), - now_ms_(0), - prototype_header_() { - memset(&prototype_header_, 0, sizeof(prototype_header_)); - prototype_header_.ssrc = ssrc; - prototype_header_.sequenceNumber = 0xf000u; -} - -int VideoSource::flow_id() const { - return flow_id_; -} - -uint32_t VideoSource::NextFrameSize() { - return frame_size_bytes_; -} - -int64_t VideoSource::GetTimeUntilNextFrameMs() const { - return next_frame_ms_ + next_frame_rand_ms_ - now_ms_; -} - -uint32_t VideoSource::NextPacketSize(uint32_t frame_size, - uint32_t remaining_payload) { - return std::min(kMaxPayloadSizeBytes, remaining_payload); -} - -void VideoSource::RunFor(int64_t time_ms, Packets* in_out) { - assert(in_out); - - now_ms_ += time_ms; - Packets new_packets; - - while (now_ms_ >= next_frame_ms_) { - const int64_t kRandAmplitude = 2; - // A variance picked uniformly from {-1, 0, 1} ms is added to the frame - // timestamp. - next_frame_rand_ms_ = kRandAmplitude * (random_.Rand() - 0.5); - - // Ensure frame will not have a negative timestamp. - int64_t next_frame_ms = - std::max(next_frame_ms_ + next_frame_rand_ms_, 0); - - prototype_header_.timestamp = - kTimestampBase + static_cast(next_frame_ms * 90.0); - prototype_header_.extension.transmissionTimeOffset = 0; - - // Generate new packets for this frame, all with the same timestamp, - // but the payload size is capped, so if the whole frame doesn't fit in - // one packet, we will see a number of equally sized packets followed by - // one smaller at the tail. - - int64_t send_time_us = next_frame_ms * 1000.0; - - uint32_t frame_size = NextFrameSize(); - uint32_t payload_size = frame_size; - - while (payload_size > 0) { - ++prototype_header_.sequenceNumber; - uint32_t size = NextPacketSize(frame_size, payload_size); - MediaPacket* new_packet = - new MediaPacket(flow_id_, send_time_us, size, prototype_header_); - new_packets.push_back(new_packet); - new_packet->SetAbsSendTimeMs(next_frame_ms); - new_packet->set_sender_timestamp_us(send_time_us); - payload_size -= size; - } - - next_frame_ms_ += frame_period_ms_; - } - - in_out->merge(new_packets, DereferencingComparator); -} - -AdaptiveVideoSource::AdaptiveVideoSource(int flow_id, - float fps, - uint32_t kbps, - uint32_t ssrc, - int64_t first_frame_offset_ms) - : VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) {} - -void AdaptiveVideoSource::SetBitrateBps(int bitrate_bps) { - bits_per_second_ = bitrate_bps; - frame_size_bytes_ = (bits_per_second_ / 8 * frame_period_ms_ + 500) / 1000; -} - -PeriodicKeyFrameSource::PeriodicKeyFrameSource(int flow_id, - float fps, - uint32_t kbps, - uint32_t ssrc, - int64_t first_frame_offset_ms, - int key_frame_interval) - : AdaptiveVideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms), - key_frame_interval_(key_frame_interval), - frame_counter_(0), - compensation_bytes_(0), - compensation_per_frame_(0) {} - -uint32_t PeriodicKeyFrameSource::NextFrameSize() { - uint32_t payload_size = frame_size_bytes_; - if (frame_counter_ == 0) { - payload_size = kMaxPayloadSizeBytes * 12; - compensation_bytes_ = 4 * frame_size_bytes_; - compensation_per_frame_ = compensation_bytes_ / 30; - } else if (key_frame_interval_ > 0 && - (frame_counter_ % key_frame_interval_ == 0)) { - payload_size *= 5; - compensation_bytes_ = payload_size - frame_size_bytes_; - compensation_per_frame_ = compensation_bytes_ / 30; - } else if (compensation_bytes_ > 0) { - if (compensation_per_frame_ > static_cast(payload_size)) { - // Skip this frame. - compensation_bytes_ -= payload_size; - payload_size = 0; - } else { - payload_size -= compensation_per_frame_; - compensation_bytes_ -= compensation_per_frame_; - } - } - if (compensation_bytes_ < 0) - compensation_bytes_ = 0; - ++frame_counter_; - return payload_size; -} - -uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size, - uint32_t remaining_payload) { - uint32_t fragments = - (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes; - uint32_t avg_size = (frame_size + fragments - 1) / fragments; - return std::min(avg_size, remaining_payload); -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bwe_test_framework.h b/modules/remote_bitrate_estimator/test/bwe_test_framework.h deleted file mode 100644 index cd1af97698..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test_framework.h +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (c) 2013 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_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "modules/bitrate_controller/include/bitrate_controller.h" -#include "modules/include/module_common_types.h" -#include "modules/pacing/paced_sender.h" -#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" -#include "modules/remote_bitrate_estimator/test/packet.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/random.h" -#include "rtc_base/strings/string_builder.h" -#include "system_wrappers/include/clock.h" - -namespace webrtc { - -class RtcpBandwidthObserver; - -namespace testing { -namespace bwe { - -class DelayCapHelper; - -class RateCounter { - public: - explicit RateCounter(int64_t window_size_ms); - RateCounter(); - ~RateCounter(); - - void UpdateRates(int64_t send_time_us, uint32_t payload_size); - - int64_t window_size_ms() const { return (window_size_us_ + 500) / 1000; } - uint32_t packets_per_second() const; - uint32_t bits_per_second() const; - - double BitrateWindowS() const; - - private: - typedef std::pair TimeSizePair; - - int64_t window_size_us_; - uint32_t recently_received_packets_; - uint32_t recently_received_bytes_; - int64_t last_accumulated_us_; - std::list window_; -}; - -typedef std::set FlowIds; -const FlowIds CreateFlowIds(const int* flow_ids_array, size_t num_flow_ids); -const FlowIds CreateFlowIdRange(int initial_value, int last_value); - -template -bool DereferencingComparator(const T* const& a, const T* const& b) { - assert(a != NULL); - assert(b != NULL); - return *a < *b; -} - -template -class Stats { - public: - Stats() - : data_(), - last_mean_count_(0), - last_variance_count_(0), - last_minmax_count_(0), - mean_(0), - variance_(0), - min_(0), - max_(0) {} - - void Push(T data_point) { data_.push_back(data_point); } - - T GetMean() { - if (last_mean_count_ != data_.size()) { - last_mean_count_ = data_.size(); - mean_ = std::accumulate(data_.begin(), data_.end(), static_cast(0)); - assert(last_mean_count_ != 0); - mean_ /= static_cast(last_mean_count_); - } - return mean_; - } - T GetVariance() { - if (last_variance_count_ != data_.size()) { - last_variance_count_ = data_.size(); - T mean = GetMean(); - variance_ = 0; - for (const auto& sample : data_) { - T diff = (sample - mean); - variance_ += diff * diff; - } - assert(last_variance_count_ != 0); - variance_ /= static_cast(last_variance_count_); - } - return variance_; - } - T GetStdDev() { return sqrt(static_cast(GetVariance())); } - T GetMin() { - RefreshMinMax(); - return min_; - } - T GetMax() { - RefreshMinMax(); - return max_; - } - - std::string AsString() { - rtc::StringBuilder ss; - ss << (GetMean() >= 0 ? GetMean() : -1) << ", " - << (GetStdDev() >= 0 ? GetStdDev() : -1); - return ss.Release(); - } - - void Log(const std::string& units) { - BWE_TEST_LOGGING_LOG5("", "%f %s\t+/-%f\t[%f,%f]", GetMean(), units.c_str(), - GetStdDev(), GetMin(), GetMax()); - } - - private: - void RefreshMinMax() { - if (last_minmax_count_ != data_.size()) { - last_minmax_count_ = data_.size(); - min_ = max_ = 0; - if (data_.empty()) { - return; - } - typename std::vector::const_iterator it = data_.begin(); - min_ = max_ = *it; - while (++it != data_.end()) { - min_ = std::min(min_, *it); - max_ = std::max(max_, *it); - } - } - } - - std::vector data_; - typename std::vector::size_type last_mean_count_; - typename std::vector::size_type last_variance_count_; - typename std::vector::size_type last_minmax_count_; - T mean_; - T variance_; - T min_; - T max_; -}; - -bool IsTimeSorted(const Packets& packets); - -class PacketProcessor; - -enum ProcessorType { kSender, kReceiver, kRegular }; - -class PacketProcessorListener { - public: - virtual ~PacketProcessorListener() {} - - virtual void AddPacketProcessor(PacketProcessor* processor, - ProcessorType type) = 0; - virtual void RemovePacketProcessor(PacketProcessor* processor) = 0; -}; - -class PacketProcessor { - public: - PacketProcessor(PacketProcessorListener* listener, - int flow_id, - ProcessorType type); - PacketProcessor(PacketProcessorListener* listener, - const FlowIds& flow_ids, - ProcessorType type); - virtual ~PacketProcessor(); - - // Called after each simulation batch to allow the processor to plot any - // internal data. - virtual void Plot(int64_t timestamp_ms) {} - - // Run simulation for |time_ms| milliseconds, consuming packets from, and - // producing packets into in_out. The outgoing packet list must be sorted on - // |send_time_us_|. The simulation time |time_ms| is optional to use. - virtual void RunFor(int64_t time_ms, Packets* in_out) = 0; - - const FlowIds& flow_ids() const { return flow_ids_; } - - uint32_t packets_per_second() const; - uint32_t bits_per_second() const; - - protected: - RateCounter rate_counter_; - - private: - PacketProcessorListener* listener_; - const FlowIds flow_ids_; - - RTC_DISALLOW_COPY_AND_ASSIGN(PacketProcessor); -}; - -class RateCounterFilter : public PacketProcessor { - public: - RateCounterFilter(PacketProcessorListener* listener, - int flow_id, - const char* name, - const std::string& algorithm_name); - RateCounterFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids, - const char* name, - const std::string& algorithm_name); - RateCounterFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids, - const char* name, - int64_t start_plotting_time_ms, - const std::string& algorithm_name); - ~RateCounterFilter() override; - - void LogStats(); - Stats GetBitrateStats() const; - void Plot(int64_t timestamp_ms) override; - void RunFor(int64_t time_ms, Packets* in_out) override; - - private: - Stats packets_per_second_stats_; - Stats kbps_stats_; - int64_t start_plotting_time_ms_; - int flow_id_ = 0; - std::string name_; - // Algorithm name if single flow, Total link utilization if all flows. - std::string algorithm_name_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RateCounterFilter); -}; - -class LossFilter : public PacketProcessor { - public: - LossFilter(PacketProcessorListener* listener, int flow_id); - LossFilter(PacketProcessorListener* listener, const FlowIds& flow_ids); - ~LossFilter() override {} - - void SetLoss(float loss_percent); - void RunFor(int64_t time_ms, Packets* in_out) override; - - private: - Random random_; - float loss_fraction_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(LossFilter); -}; - -class DelayFilter : public PacketProcessor { - public: - DelayFilter(PacketProcessorListener* listener, int flow_id); - DelayFilter(PacketProcessorListener* listener, const FlowIds& flow_ids); - ~DelayFilter() override {} - - void SetOneWayDelayMs(int64_t one_way_delay_ms); - void RunFor(int64_t time_ms, Packets* in_out) override; - - private: - int64_t one_way_delay_us_; - int64_t last_send_time_us_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayFilter); -}; - -class JitterFilter : public PacketProcessor { - public: - JitterFilter(PacketProcessorListener* listener, int flow_id); - JitterFilter(PacketProcessorListener* listener, const FlowIds& flow_ids); - ~JitterFilter() override {} - - void SetMaxJitter(int64_t stddev_jitter_ms); - void RunFor(int64_t time_ms, Packets* in_out) override; - void set_reorderdering(bool reordering) { reordering_ = reordering; } - int64_t MeanUs(); - - private: - Random random_; - int64_t stddev_jitter_us_; - int64_t last_send_time_us_; - bool reordering_; // False by default. - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(JitterFilter); -}; - -// Reorders two consecutive packets with a probability of reorder_percent. -class ReorderFilter : public PacketProcessor { - public: - ReorderFilter(PacketProcessorListener* listener, int flow_id); - ReorderFilter(PacketProcessorListener* listener, const FlowIds& flow_ids); - ~ReorderFilter() override {} - - void SetReorder(float reorder_percent); - void RunFor(int64_t time_ms, Packets* in_out) override; - - private: - Random random_; - float reorder_fraction_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ReorderFilter); -}; - -// Apply a bitrate choke with an infinite queue on the packet stream. -class ChokeFilter : public PacketProcessor { - public: - ChokeFilter(PacketProcessorListener* listener, int flow_id); - ChokeFilter(PacketProcessorListener* listener, const FlowIds& flow_ids); - ~ChokeFilter() override; - - void set_capacity_kbps(uint32_t kbps); - void set_max_delay_ms(int64_t max_queueing_delay_ms); - - uint32_t capacity_kbps(); - - void RunFor(int64_t time_ms, Packets* in_out) override; - - Stats GetDelayStats() const; - - private: - uint32_t capacity_kbps_; - int64_t last_send_time_us_; - std::unique_ptr delay_cap_helper_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ChokeFilter); -}; - -class TraceBasedDeliveryFilter : public PacketProcessor { - public: - TraceBasedDeliveryFilter(PacketProcessorListener* listener, int flow_id); - TraceBasedDeliveryFilter(PacketProcessorListener* listener, - const FlowIds& flow_ids); - TraceBasedDeliveryFilter(PacketProcessorListener* listener, - int flow_id, - const char* name); - ~TraceBasedDeliveryFilter() override; - - // The file should contain nanosecond timestamps corresponding to the time - // when the network can accept another packet. The timestamps should be - // separated by new lines, e.g., "100000000\n125000000\n321000000\n..." - bool Init(const std::string& filename); - void Plot(int64_t timestamp_ms) override; - void RunFor(int64_t time_ms, Packets* in_out) override; - - void set_max_delay_ms(int64_t max_delay_ms); - Stats GetDelayStats() const; - Stats GetBitrateStats() const; - - private: - void ProceedToNextSlot(); - - typedef std::vector TimeList; - int64_t current_offset_us_; - TimeList delivery_times_us_; - TimeList::const_iterator next_delivery_it_; - int64_t local_time_us_; - std::unique_ptr rate_counter_; - std::string name_; - std::unique_ptr delay_cap_helper_; - Stats packets_per_second_stats_; - Stats kbps_stats_; - - RTC_DISALLOW_COPY_AND_ASSIGN(TraceBasedDeliveryFilter); -}; - -class VideoSource { - public: - VideoSource(int flow_id, - float fps, - uint32_t kbps, - uint32_t ssrc, - int64_t first_frame_offset_ms); - virtual ~VideoSource() {} - - virtual void RunFor(int64_t time_ms, Packets* in_out); - - int flow_id() const; - virtual void SetBitrateBps(int bitrate_bps) {} - uint32_t bits_per_second() const { return bits_per_second_; } - uint32_t max_payload_size_bytes() const { return kMaxPayloadSizeBytes; } - int64_t GetTimeUntilNextFrameMs() const; - - protected: - virtual uint32_t NextFrameSize(); - virtual uint32_t NextPacketSize(uint32_t frame_size, - uint32_t remaining_payload); - - const uint32_t kMaxPayloadSizeBytes; - const uint32_t kTimestampBase; - const double frame_period_ms_; - uint32_t bits_per_second_; - uint32_t frame_size_bytes_; - - private: - Random random_; - const int flow_id_; - int64_t next_frame_ms_; - int64_t next_frame_rand_ms_; - int64_t now_ms_; - RTPHeader prototype_header_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(VideoSource); -}; - -class AdaptiveVideoSource : public VideoSource { - public: - AdaptiveVideoSource(int flow_id, - float fps, - uint32_t kbps, - uint32_t ssrc, - int64_t first_frame_offset_ms); - ~AdaptiveVideoSource() override {} - - void SetBitrateBps(int bitrate_bps) override; - - private: - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveVideoSource); -}; - -class PeriodicKeyFrameSource : public AdaptiveVideoSource { - public: - PeriodicKeyFrameSource(int flow_id, - float fps, - uint32_t kbps, - uint32_t ssrc, - int64_t first_frame_offset_ms, - int key_frame_interval); - ~PeriodicKeyFrameSource() override {} - - protected: - uint32_t NextFrameSize() override; - uint32_t NextPacketSize(uint32_t frame_size, - uint32_t remaining_payload) override; - - private: - int key_frame_interval_; - uint32_t frame_counter_; - int compensation_bytes_; - int compensation_per_frame_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PeriodicKeyFrameSource); -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_ diff --git a/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc b/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc deleted file mode 100644 index f9da01eaf1..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc +++ /dev/null @@ -1,975 +0,0 @@ -/* - * Copyright (c) 2013 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/remote_bitrate_estimator/test/bwe_test_framework.h" - -#include "modules/include/module_common_types_public.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/packet.h" -#include "modules/remote_bitrate_estimator/test/packet_sender.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "rtc_base/constructor_magic.h" -#include "test/gtest.h" -#include "test/testsupport/file_utils.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -static bool IsSequenceNumberSorted(const Packets& packets) { - PacketsConstIt last_it = packets.begin(); - for (PacketsConstIt it = last_it; it != packets.end(); ++it) { - const MediaPacket* packet = static_cast(*it); - const MediaPacket* last_packet = static_cast(*last_it); - if (IsNewerSequenceNumber(last_packet->header().sequenceNumber, - packet->header().sequenceNumber)) { - return false; - } - last_it = it; - } - return true; -} - -TEST(BweTestFramework_PacketTest, IsTimeSorted) { - Packets packets; - // Insert some packets in order... - EXPECT_TRUE(IsTimeSorted(packets)); - - packets.push_back(new MediaPacket(100, 0)); - EXPECT_TRUE(IsTimeSorted(packets)); - - packets.push_back(new MediaPacket(110, 0)); - EXPECT_TRUE(IsTimeSorted(packets)); - - // ...and one out-of-order... - packets.push_back(new MediaPacket(100, 0)); - EXPECT_FALSE(IsTimeSorted(packets)); - - // ...remove the out-of-order packet, insert another in-order packet. - delete packets.back(); - packets.pop_back(); - packets.push_back(new MediaPacket(120, 0)); - EXPECT_TRUE(IsTimeSorted(packets)); - - for (auto* packet : packets) - delete packet; -} - -TEST(BweTestFramework_PacketTest, IsSequenceNumberSorted) { - Packets packets; - // Insert some packets in order... - EXPECT_TRUE(IsSequenceNumberSorted(packets)); - - packets.push_back(new MediaPacket(0, 100)); - EXPECT_TRUE(IsSequenceNumberSorted(packets)); - - packets.push_back(new MediaPacket(0, 110)); - EXPECT_TRUE(IsSequenceNumberSorted(packets)); - - // ...and one out-of-order... - packets.push_back(new MediaPacket(0, 100)); - EXPECT_FALSE(IsSequenceNumberSorted(packets)); - - // ...remove the out-of-order packet, insert another in-order packet. - delete packets.back(); - packets.pop_back(); - packets.push_back(new MediaPacket(0, 120)); - EXPECT_TRUE(IsSequenceNumberSorted(packets)); - - for (auto* packet : packets) - delete packet; -} - -TEST(BweTestFramework_StatsTest, Mean) { - Stats stats; - EXPECT_EQ(0, stats.GetMean()); - - stats.Push(1); - stats.Push(3); - EXPECT_EQ(2, stats.GetMean()); - - // Integer division rounds (1+3-3)/3 to 0. - stats.Push(-3); - EXPECT_EQ(0, stats.GetMean()); -} - -TEST(BweTestFramework_StatsTest, Variance) { - Stats stats; - EXPECT_EQ(0, stats.GetVariance()); - - // Mean is 2 ; ((1-2)*(1-2)+(3-2)*(3-2))/2 = (1+1)/2 = 1 - stats.Push(1); - stats.Push(3); - EXPECT_EQ(1, stats.GetVariance()); - - // Integer division rounds 26/3 to 8 - // Mean is 0 ; (1*1+3*3+(-4)*(-4))/3 = (1+9+16)/3 = 8 - stats.Push(-4); - EXPECT_EQ(8, stats.GetVariance()); -} - -TEST(BweTestFramework_StatsTest, StdDev) { - Stats stats; - EXPECT_EQ(0, stats.GetStdDev()); - - // Variance is 1 ; sqrt(1) = 1 - stats.Push(1); - stats.Push(3); - EXPECT_EQ(1, stats.GetStdDev()); - - // Variance is 8 ; sqrt(8) = 2 with integers. - stats.Push(-4); - EXPECT_EQ(2, stats.GetStdDev()); -} - -TEST(BweTestFramework_StatsTest, MinMax) { - Stats stats; - EXPECT_EQ(0, stats.GetMin()); - EXPECT_EQ(0, stats.GetMax()); - - stats.Push(1); - EXPECT_EQ(1, stats.GetMin()); - EXPECT_EQ(1, stats.GetMax()); - - stats.Push(3); - EXPECT_EQ(1, stats.GetMin()); - EXPECT_EQ(3, stats.GetMax()); - - stats.Push(-4); - EXPECT_EQ(-4, stats.GetMin()); - EXPECT_EQ(3, stats.GetMax()); -} - -class BweTestFramework_RateCounterFilterTest : public ::testing::Test { - public: - BweTestFramework_RateCounterFilterTest() - : filter_(NULL, 0, "", ""), now_ms_(0) {} - virtual ~BweTestFramework_RateCounterFilterTest() {} - - protected: - void TestRateCounter(int64_t run_for_ms, - uint32_t payload_bits, - uint32_t expected_pps, - uint32_t expected_bps) { - Packets packets; - RTPHeader header; - // "Send" a packet every 10 ms. - for (int64_t i = 0; i < run_for_ms; i += 10, now_ms_ += 10) { - packets.push_back( - new MediaPacket(0, now_ms_ * 1000, payload_bits / 8, header)); - } - filter_.RunFor(run_for_ms, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - EXPECT_EQ(expected_pps, filter_.packets_per_second()); - EXPECT_EQ(expected_bps, filter_.bits_per_second()); - - for (auto* packet : packets) - delete packet; - } - - private: - RateCounterFilter filter_; - int64_t now_ms_; - - RTC_DISALLOW_COPY_AND_ASSIGN(BweTestFramework_RateCounterFilterTest); -}; - -TEST_F(BweTestFramework_RateCounterFilterTest, Short) { - // 100ms, 100 bytes per packet, should result in 10 pps and 8 kbps. We're - // generating one packet every 10 ms ; 10 * 800 = 8k - TestRateCounter(100, 800, 10, 8000); -} - -TEST_F(BweTestFramework_RateCounterFilterTest, Medium) { - // 100ms, like above. - TestRateCounter(100, 800, 10, 8000); - // 1000ms, 100 bpp, should result in 100 pps and 80 kbps. We're still - // generating packets every 10 ms. - TestRateCounter(900, 800, 100, 80000); -} - -TEST_F(BweTestFramework_RateCounterFilterTest, Long) { - // 100ms, 1000ms, like above. - TestRateCounter(100, 800, 10, 8000); - TestRateCounter(900, 800, 100, 80000); - // 2000ms, should only see rate of last second, so 100 pps, and 40 kbps now. - TestRateCounter(1000, 400, 100, 40000); - // 2500ms, half a second with zero payload size. We should get same pps as - // before, but kbps should drop to half of previous rate. - TestRateCounter(500, 0, 100, 20000); - // Another half second with zero payload size. Now the kbps rate should drop - // to zero. - TestRateCounter(500, 0, 100, 0); - // Increate payload size again. 200 * 100 * 0.5 = 10 kbps. - TestRateCounter(500, 200, 100, 10000); -} - -static void TestLossFilter(float loss_percent, bool zero_tolerance) { - LossFilter filter(NULL, 0); - filter.SetLoss(loss_percent); - Packets::size_type sent_packets = 0; - Packets::size_type remaining_packets = 0; - - // No input should yield no output - { - Packets packets; - sent_packets += packets.size(); - filter.RunFor(0, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - ASSERT_TRUE(IsSequenceNumberSorted(packets)); - remaining_packets += packets.size(); - EXPECT_EQ(0u, sent_packets); - EXPECT_EQ(0u, remaining_packets); - for (auto* packet : packets) - delete packet; - } - - // Generate and process 10000 packets in different batch sizes (some empty) - for (int i = 0; i < 2225; ++i) { - Packets packets; - for (int j = 0; j < i % 10; ++j) - packets.push_back(new MediaPacket(i, i)); - sent_packets += packets.size(); - filter.RunFor(0, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - ASSERT_TRUE(IsSequenceNumberSorted(packets)); - remaining_packets += packets.size(); - for (auto* packet : packets) - delete packet; - } - - float loss_fraction = 0.01f * (100.0f - loss_percent); - Packets::size_type expected_packets = loss_fraction * sent_packets; - if (zero_tolerance) { - EXPECT_EQ(expected_packets, remaining_packets); - } else { - // Require within 1% of expected - EXPECT_NEAR(expected_packets, remaining_packets, 100); - } -} - -TEST(BweTestFramework_LossFilterTest, Loss0) { - // With 0% loss, the result should be exact (no loss). - TestLossFilter(0.0f, true); -} - -TEST(BweTestFramework_LossFilterTest, Loss10) { - TestLossFilter(10.0f, false); -} - -TEST(BweTestFramework_LossFilterTest, Loss50) { - TestLossFilter(50.0f, false); -} - -TEST(BweTestFramework_LossFilterTest, Loss100) { - // With 100% loss, the result should be exact (no packets out). - TestLossFilter(100.0f, true); -} - -class BweTestFramework_DelayFilterTest : public ::testing::Test { - public: - BweTestFramework_DelayFilterTest() - : filter_(NULL, 0), now_ms_(0), sequence_number_(0) {} - virtual ~BweTestFramework_DelayFilterTest() { - for (auto* packet : accumulated_packets_) - delete packet; - } - - protected: - void TestDelayFilter(int64_t run_for_ms, - uint32_t in_packets, - uint32_t out_packets) { - Packets packets; - for (uint32_t i = 0; i < in_packets; ++i) { - packets.push_back(new MediaPacket( - now_ms_ * 1000 + (sequence_number_ >> 4), sequence_number_)); - sequence_number_++; - } - filter_.RunFor(run_for_ms, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - ASSERT_TRUE(IsSequenceNumberSorted(packets)); - for (PacketsConstIt it = packets.begin(); it != packets.end(); ++it) { - EXPECT_LE(now_ms_ * 1000, (*it)->send_time_us()); - } - EXPECT_EQ(out_packets, packets.size()); - accumulated_packets_.splice(accumulated_packets_.end(), packets); - now_ms_ += run_for_ms; - } - - void TestDelayFilter(int64_t delay_ms) { - filter_.SetOneWayDelayMs(delay_ms); - TestDelayFilter(1, 0, 0); // No input should yield no output - - // Single packet - TestDelayFilter(0, 1, 1); - TestDelayFilter(delay_ms, 0, 0); - - for (int i = 0; i < delay_ms; ++i) { - filter_.SetOneWayDelayMs(i); - TestDelayFilter(1, 10, 10); - } - TestDelayFilter(0, 0, 0); - TestDelayFilter(delay_ms, 0, 0); - - // Wait a little longer - should still see no output - TestDelayFilter(delay_ms, 0, 0); - - for (int i = 1; i < delay_ms + 1; ++i) { - filter_.SetOneWayDelayMs(i); - TestDelayFilter(1, 5, 5); - } - TestDelayFilter(0, 0, 0); - filter_.SetOneWayDelayMs(2 * delay_ms); - TestDelayFilter(1, 0, 0); - TestDelayFilter(delay_ms, 13, 13); - TestDelayFilter(delay_ms, 0, 0); - - // Wait a little longer - should still see no output - TestDelayFilter(delay_ms, 0, 0); - - for (int i = 0; i < 2 * delay_ms; ++i) { - filter_.SetOneWayDelayMs(2 * delay_ms - i - 1); - TestDelayFilter(1, 5, 5); - } - TestDelayFilter(0, 0, 0); - filter_.SetOneWayDelayMs(0); - TestDelayFilter(0, 7, 7); - - ASSERT_TRUE(IsTimeSorted(accumulated_packets_)); - ASSERT_TRUE(IsSequenceNumberSorted(accumulated_packets_)); - } - - DelayFilter filter_; - Packets accumulated_packets_; - - private: - int64_t now_ms_; - uint16_t sequence_number_; - - RTC_DISALLOW_COPY_AND_ASSIGN(BweTestFramework_DelayFilterTest); -}; - -TEST_F(BweTestFramework_DelayFilterTest, Delay0) { - TestDelayFilter(1, 0, 0); // No input should yield no output - TestDelayFilter(1, 10, 10); // Expect no delay (delay time is zero) - TestDelayFilter(1, 0, 0); // Check no packets are still in buffer - filter_.SetOneWayDelayMs(0); - TestDelayFilter(1, 5, 5); // Expect no delay (delay time is zero) - TestDelayFilter(1, 0, 0); // Check no packets are still in buffer -} - -TEST_F(BweTestFramework_DelayFilterTest, Delay1) { - TestDelayFilter(1); -} - -TEST_F(BweTestFramework_DelayFilterTest, Delay2) { - TestDelayFilter(2); -} - -TEST_F(BweTestFramework_DelayFilterTest, Delay20) { - TestDelayFilter(20); -} - -TEST_F(BweTestFramework_DelayFilterTest, Delay100) { - TestDelayFilter(100); -} - -TEST_F(BweTestFramework_DelayFilterTest, JumpToZeroDelay) { - DelayFilter delay(NULL, 0); - Packets acc; - Packets packets; - - // Delay a bunch of packets, accumulate them to the 'acc' list. - delay.SetOneWayDelayMs(100.0f); - for (uint32_t i = 0; i < 10; ++i) { - packets.push_back(new MediaPacket(i * 100, i)); - } - delay.RunFor(1000, &packets); - acc.splice(acc.end(), packets); - ASSERT_TRUE(IsTimeSorted(acc)); - ASSERT_TRUE(IsSequenceNumberSorted(acc)); - - // Drop delay to zero, send a few more packets through the delay, append them - // to the 'acc' list and verify that it is all sorted. - delay.SetOneWayDelayMs(0.0f); - for (uint32_t i = 10; i < 50; ++i) { - packets.push_back(new MediaPacket(i * 100, i)); - } - delay.RunFor(1000, &packets); - acc.splice(acc.end(), packets); - ASSERT_TRUE(IsTimeSorted(acc)); - ASSERT_TRUE(IsSequenceNumberSorted(acc)); - - for (auto* packet : acc) - delete packet; -} - -TEST_F(BweTestFramework_DelayFilterTest, IncreasingDelay) { - // Gradually increase delay. - for (int i = 1; i < 50; i += 4) { - TestDelayFilter(i); - } - // Reach a steady state. - filter_.SetOneWayDelayMs(100); - TestDelayFilter(1, 20, 20); - TestDelayFilter(2, 0, 0); - TestDelayFilter(99, 20, 20); - // Drop delay back down to zero. - filter_.SetOneWayDelayMs(0); - TestDelayFilter(1, 100, 100); - TestDelayFilter(23010, 0, 0); - ASSERT_TRUE(IsTimeSorted(accumulated_packets_)); - ASSERT_TRUE(IsSequenceNumberSorted(accumulated_packets_)); -} - -static void TestJitterFilter(int64_t max_jitter_ms) { - JitterFilter filter(NULL, 0); - filter.SetMaxJitter(max_jitter_ms); - - int64_t now_ms = 0; - uint16_t sequence_number = 0; - - // Generate packets, add jitter to them, accumulate the altered packets. - Packets original; - Packets jittered; - for (uint32_t i = 0; i < 1000; ++i) { - Packets packets; - for (uint32_t j = 0; j < i % 100; ++j) { - packets.push_back(new MediaPacket(now_ms * 1000, sequence_number)); - original.push_back(new MediaPacket(now_ms * 1000, sequence_number)); - ++sequence_number; - now_ms += 5 * max_jitter_ms; - } - filter.RunFor(max_jitter_ms, &packets); - jittered.splice(jittered.end(), packets); - } - - // Jittered packets should still be in order. - ASSERT_TRUE(IsTimeSorted(original)); - ASSERT_TRUE(IsTimeSorted(jittered)); - ASSERT_TRUE(IsSequenceNumberSorted(original)); - ASSERT_TRUE(IsSequenceNumberSorted(jittered)); - EXPECT_EQ(original.size(), jittered.size()); - - // Make sure jittered and original packets are in same order. Collect time - // difference (jitter) in stats, then check that mean jitter is close to zero - // and standard deviation of jitter is what we set it to. - Stats jitter_us; - int64_t max_jitter_obtained_us = 0; - for (PacketsIt it1 = original.begin(), it2 = jittered.begin(); - it1 != original.end() && it2 != jittered.end(); ++it1, ++it2) { - const MediaPacket* packet1 = static_cast(*it1); - const MediaPacket* packet2 = static_cast(*it2); - EXPECT_EQ(packet1->header().sequenceNumber, - packet2->header().sequenceNumber); - max_jitter_obtained_us = - std::max(max_jitter_obtained_us, - packet2->send_time_us() - packet1->send_time_us()); - jitter_us.Push(packet2->send_time_us() - packet1->send_time_us()); - } - EXPECT_NEAR(filter.MeanUs(), jitter_us.GetMean(), - max_jitter_ms * 1000.0 * 0.01); - EXPECT_NEAR(max_jitter_ms * 1000.0, max_jitter_obtained_us, - max_jitter_ms * 1000.0 * 0.01); - for (auto* packet : original) - delete packet; - for (auto* packet : jittered) - delete packet; -} - -TEST(BweTestFramework_JitterFilterTest, Jitter0) { - TestJitterFilter(0); -} - -TEST(BweTestFramework_JitterFilterTest, Jitter1) { - TestJitterFilter(1); -} - -TEST(BweTestFramework_JitterFilterTest, Jitter5) { - TestJitterFilter(5); -} - -TEST(BweTestFramework_JitterFilterTest, Jitter10) { - TestJitterFilter(10); -} - -TEST(BweTestFramework_JitterFilterTest, Jitter1031) { - TestJitterFilter(1031); -} - -static void TestReorderFilter(uint16_t reorder_percent) { - const uint16_t kPacketCount = 10000; - - // Generate packets with 10 ms interval. - Packets packets; - int64_t now_ms = 0; - uint16_t sequence_number = 1; - for (uint16_t i = 0; i < kPacketCount; ++i, now_ms += 10) { - packets.push_back(new MediaPacket(now_ms * 1000, sequence_number++)); - } - ASSERT_TRUE(IsTimeSorted(packets)); - ASSERT_TRUE(IsSequenceNumberSorted(packets)); - - // Reorder packets, verify that send times are still in order. - ReorderFilter filter(NULL, 0); - filter.SetReorder(reorder_percent); - filter.RunFor(now_ms, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - - // We measure the amount of reordering by summing the distance by which out- - // of-order packets have been moved in the stream. - uint16_t distance = 0; - uint16_t last_sequence_number = 0; - for (auto* packet : packets) { - const MediaPacket* media_packet = static_cast(packet); - uint16_t sequence_number = media_packet->header().sequenceNumber; - // The expected position for sequence number s is in position s-1. - if (sequence_number < last_sequence_number) { - distance += last_sequence_number - sequence_number; - } - last_sequence_number = sequence_number; - } - - // The probability that two elements are swapped is p = reorder_percent / 100. - double p = static_cast(reorder_percent) / 100; - // The expected number of swaps we perform is p * (PacketCount - 1), - // and each swap increases the distance by one. - double mean = p * (kPacketCount - 1); - // If pair i is chosen to be swapped with probability p, the variance for that - // pair is p * (1 - p). Since there are (kPacketCount - 1) independent pairs, - // the variance for the number of swaps is (kPacketCount - 1) * p * (1 - p). - double std_deviation = sqrt((kPacketCount - 1) * p * (1 - p)); - EXPECT_NEAR(mean, distance, 3 * std_deviation); - - for (auto* packet : packets) - delete packet; -} - -TEST(BweTestFramework_ReorderFilterTest, Reorder0) { - // For 0% reordering, no packets should have been moved, so result is exact. - TestReorderFilter(0); -} - -TEST(BweTestFramework_ReorderFilterTest, Reorder10) { - TestReorderFilter(10); -} - -TEST(BweTestFramework_ReorderFilterTest, Reorder20) { - TestReorderFilter(20); -} - -TEST(BweTestFramework_ReorderFilterTest, Reorder50) { - TestReorderFilter(50); -} - -TEST(BweTestFramework_ReorderFilterTest, Reorder70) { - TestReorderFilter(70); -} - -TEST(BweTestFramework_ReorderFilterTest, Reorder100) { - // Note that because the implementation works by optionally swapping two - // adjacent packets, when the likelihood of a swap is 1.0, a swap will always - // occur, so the stream will be in order except for the first packet, which - // has been moved to the end. Therefore we expect the result to be exact here. - TestReorderFilter(100.0); -} - -class BweTestFramework_ChokeFilterTest : public ::testing::Test { - public: - BweTestFramework_ChokeFilterTest() - : now_ms_(0), sequence_number_(0), output_packets_(), send_times_us_() {} - virtual ~BweTestFramework_ChokeFilterTest() { - for (auto* packet : output_packets_) - delete packet; - } - - protected: - void TestChoke(PacketProcessor* filter, - int64_t run_for_ms, - uint32_t packets_to_generate, - size_t expected_kbit_transmitted) { - // Generate a bunch of packets, apply choke, verify output is ordered. - Packets packets; - RTPHeader header; - for (uint32_t i = 0; i < packets_to_generate; ++i) { - int64_t send_time_ms = now_ms_ + (i * run_for_ms) / packets_to_generate; - header.sequenceNumber = sequence_number_++; - // Payload is 1000 bits. - packets.push_back(new MediaPacket(0, send_time_ms * 1000, 125, header)); - send_times_us_.push_back(send_time_ms * 1000); - } - ASSERT_TRUE(IsTimeSorted(packets)); - filter->RunFor(run_for_ms, &packets); - now_ms_ += run_for_ms; - output_packets_.splice(output_packets_.end(), packets); - ASSERT_TRUE(IsTimeSorted(output_packets_)); - ASSERT_TRUE(IsSequenceNumberSorted(output_packets_)); - - // Sum up the transmitted bytes up until the current time. - size_t bytes_transmitted = 0; - while (!output_packets_.empty()) { - const Packet* packet = output_packets_.front(); - if (packet->send_time_us() > now_ms_ * 1000) { - break; - } - bytes_transmitted += packet->payload_size(); - delete output_packets_.front(); - output_packets_.pop_front(); - } - EXPECT_EQ(expected_kbit_transmitted, (bytes_transmitted * 8 + 500) / 1000); - } - - void CheckMaxDelay(int64_t max_delay_ms) { - for (const auto* packet : output_packets_) { - const MediaPacket* media_packet = static_cast(packet); - int64_t delay_us = media_packet->send_time_us() - - send_times_us_[media_packet->header().sequenceNumber]; - EXPECT_GE(max_delay_ms * 1000, delay_us); - } - } - - private: - int64_t now_ms_; - uint16_t sequence_number_; - Packets output_packets_; - std::vector send_times_us_; - - RTC_DISALLOW_COPY_AND_ASSIGN(BweTestFramework_ChokeFilterTest); -}; - -TEST_F(BweTestFramework_ChokeFilterTest, NoQueue) { - const int kCapacityKbps = 10; - const size_t kPacketSizeBytes = 125; - const int64_t kExpectedSendTimeUs = - (kPacketSizeBytes * 8 * 1000 + kCapacityKbps / 2) / kCapacityKbps; - uint16_t sequence_number = 0; - int64_t send_time_us = 0; - ChokeFilter filter(NULL, 0); - filter.set_capacity_kbps(10); - Packets packets; - RTPHeader header; - for (int i = 0; i < 2; ++i) { - header.sequenceNumber = sequence_number++; - // Payload is 1000 bits. - packets.push_back( - new MediaPacket(0, send_time_us, kPacketSizeBytes, header)); - // Packets are sent far enough a part plus an extra millisecond so that they - // will never be in the choke queue at the same time. - send_time_us += kExpectedSendTimeUs + 1000; - } - ASSERT_TRUE(IsTimeSorted(packets)); - filter.RunFor(2 * kExpectedSendTimeUs + 1000, &packets); - EXPECT_EQ(kExpectedSendTimeUs, packets.front()->send_time_us()); - delete packets.front(); - packets.pop_front(); - EXPECT_EQ(2 * kExpectedSendTimeUs + 1000, packets.front()->send_time_us()); - delete packets.front(); - packets.pop_front(); -} - -TEST_F(BweTestFramework_ChokeFilterTest, Short) { - // 100ms, 100 packets, 10 kbps choke -> 1 kbit of data should have propagated. - // That is actually just a single packet, since each packet has 1000 bits of - // payload. - ChokeFilter filter(NULL, 0); - filter.set_capacity_kbps(10); - TestChoke(&filter, 100, 100, 1); -} - -TEST_F(BweTestFramework_ChokeFilterTest, Medium) { - // 100ms, 10 packets, 10 kbps choke -> 1 packet through, or 1 kbit. - ChokeFilter filter(NULL, 0); - filter.set_capacity_kbps(10); - TestChoke(&filter, 100, 10, 1); - // 200ms, no new packets -> another packet through. - TestChoke(&filter, 100, 0, 1); - // 1000ms, no new packets -> 8 more packets. - TestChoke(&filter, 800, 0, 8); - // 2000ms, no new packets -> queue is empty so no output. - TestChoke(&filter, 1000, 0, 0); -} - -TEST_F(BweTestFramework_ChokeFilterTest, Long) { - // 100ms, 100 packets in queue, 10 kbps choke -> 1 packet through, or 1 kbit. - ChokeFilter filter(NULL, 0); - filter.set_capacity_kbps(10); - TestChoke(&filter, 100, 100, 1); - // 200ms, no input, another packet through. - TestChoke(&filter, 100, 0, 1); - // 1000ms, no input, 8 packets through. - TestChoke(&filter, 800, 0, 8); - // 10000ms, no input, raise choke to 100 kbps. Remaining 90 packets in queue - // should be propagated, for a total of 90 kbps. - filter.set_capacity_kbps(100); - TestChoke(&filter, 9000, 0, 90); - // 10100ms, 20 more packets -> 10 packets or 10 kbit through. - TestChoke(&filter, 100, 20, 10); - // 10300ms, 10 more packets -> 20 packets out. - TestChoke(&filter, 200, 10, 20); - // 11300ms, no input, queue should be empty. - filter.set_capacity_kbps(10); - TestChoke(&filter, 1000, 0, 0); -} - -TEST_F(BweTestFramework_ChokeFilterTest, MaxDelay) { - // 10 kbps choke, 500 ms delay cap - ChokeFilter filter(NULL, 0); - filter.set_capacity_kbps(10); - filter.set_max_delay_ms(500); - // 100ms, 100 packets in queue, 10 kbps choke -> 1 packet through, or 1 kbit. - TestChoke(&filter, 100, 100, 1); - CheckMaxDelay(500); - // 500ms, no input, 4 more packets through. - TestChoke(&filter, 400, 0, 4); - // 10000ms, no input, remaining packets should have been dropped. - TestChoke(&filter, 9500, 0, 0); - - // 100 ms delay cap - filter.set_max_delay_ms(100); - // 10100ms, 50 more packets -> 1 packets or 1 kbit through. - TestChoke(&filter, 100, 50, 1); - CheckMaxDelay(100); - // 20000ms, no input, remaining packets in queue should have been dropped. - TestChoke(&filter, 9900, 0, 0); - - // Reset delay cap (0 is no cap) and verify no packets are dropped. - filter.set_capacity_kbps(10); - filter.set_max_delay_ms(0); - TestChoke(&filter, 100, 100, 1); - TestChoke(&filter, 9900, 0, 99); -} - -TEST_F(BweTestFramework_ChokeFilterTest, ShortTrace) { - // According to the input file 6 packets should be transmitted within - // 100 milliseconds. - TraceBasedDeliveryFilter filter(NULL, 0); - ASSERT_TRUE(filter.Init(test::ResourcePath("synthetic-trace", "rx"))); - TestChoke(&filter, 100, 100, 6); -} - -TEST_F(BweTestFramework_ChokeFilterTest, ShortTraceTwoWraps) { - // According to the input file 19 packets should be transmitted within - // 280 milliseconds (at the wrapping point two packets are sent back to back). - TraceBasedDeliveryFilter filter(NULL, 0); - ASSERT_TRUE(filter.Init(test::ResourcePath("synthetic-trace", "rx"))); - TestChoke(&filter, 280, 100, 19); -} - -TEST_F(BweTestFramework_ChokeFilterTest, ShortTraceMaxDelay) { - TraceBasedDeliveryFilter filter(NULL, 0); - filter.set_max_delay_ms(25); - ASSERT_TRUE(filter.Init(test::ResourcePath("synthetic-trace", "rx"))); - // Uses all slots up to 110 ms. Several packets are being dropped. - TestChoke(&filter, 110, 20, 9); - CheckMaxDelay(25); - // Simulate enough time for the next slot (at 135 ms) to be used. This makes - // sure that a slot isn't missed between runs. - TestChoke(&filter, 25, 1, 1); -} - -void TestVideoSender(VideoSender* sender, - int64_t run_for_ms, - uint32_t expected_packets, - uint32_t expected_payload_size, - size_t expected_total_payload_size) { - assert(sender); - Packets packets; - sender->RunFor(run_for_ms, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - ASSERT_TRUE(IsSequenceNumberSorted(packets)); - EXPECT_EQ(expected_packets, packets.size()); - - int64_t send_time_us = -1; - size_t total_payload_size = 0; - uint32_t absolute_send_time = 0; - uint32_t absolute_send_time_wraps = 0; - uint32_t rtp_timestamp = 0; - uint32_t rtp_timestamp_wraps = 0; - - for (const auto* packet : packets) { - const MediaPacket* media_packet = static_cast(packet); - EXPECT_LE(send_time_us, media_packet->send_time_us()); - send_time_us = media_packet->send_time_us(); - if (sender->source()->max_payload_size_bytes() != - media_packet->payload_size()) { - EXPECT_EQ(expected_payload_size, media_packet->payload_size()); - } - total_payload_size += media_packet->payload_size(); - if (absolute_send_time > - media_packet->header().extension.absoluteSendTime) { - absolute_send_time_wraps++; - } - absolute_send_time = media_packet->header().extension.absoluteSendTime; - if (rtp_timestamp > media_packet->header().timestamp) { - rtp_timestamp_wraps++; - } - rtp_timestamp = media_packet->header().timestamp; - } - - EXPECT_EQ(expected_total_payload_size, total_payload_size); - EXPECT_GE(1u, absolute_send_time_wraps); - EXPECT_GE(1u, rtp_timestamp_wraps); - - for (auto* packet : packets) - delete packet; -} - -// Random {-1, 0, +1} ms was added to frame timestamps. - -TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s) { - // 1 fps, 80 kbps - VideoSource source(0, 1.0f, 80, 0x1234, 0); - VideoSender sender(NULL, &source, kNullEstimator); - EXPECT_EQ(80000u, source.bits_per_second()); - // We're at 1 fps, so all packets should be generated on first call, giving 10 - // packets of each 1000 bytes, total 10000 bytes. - TestVideoSender(&sender, 1, 9, 400, 10000); - // 998ms, should see no output here. - TestVideoSender(&sender, 997, 0, 0, 0); - // 1001ms, should get data for one more frame. - TestVideoSender(&sender, 3, 9, 400, 10000); - // 1998ms, should see no output here. - TestVideoSender(&sender, 997, 0, 0, 0); - // 2001ms, one more frame. - TestVideoSender(&sender, 3, 9, 400, 10000); - // 2998ms, should see nothing. - TestVideoSender(&sender, 997, 0, 0, 0); -} - -TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s_Offset) { - // 1 fps, 80 kbps, offset 0.5 of a frame period, ==0.5s in this case. - VideoSource source(0, 1.0f, 80, 0x1234, 500); - VideoSender sender(NULL, &source, kNullEstimator); - EXPECT_EQ(80000u, source.bits_per_second()); - // 498ms, no output. - TestVideoSender(&sender, 498, 0, 0, 0); - // 501ms, first frame (this is the offset we set), 10 packets of 1000 bytes. - TestVideoSender(&sender, 3, 9, 400, 10000); - // 1498ms, nothing. - TestVideoSender(&sender, 997, 0, 0, 0); - // 1501ms, second frame. - TestVideoSender(&sender, 3, 9, 400, 10000); - // 2498ms, nothing. - TestVideoSender(&sender, 997, 0, 0, 0); - // 2501ms, third frame. - TestVideoSender(&sender, 3, 9, 400, 10000); - // 3498ms, nothing. - TestVideoSender(&sender, 997, 0, 0, 0); -} - -TEST(BweTestFramework_VideoSenderTest, Fps50Kpbs80_11s) { - // 50 fps, 80 kbps. - VideoSource source(0, 50.0f, 80, 0x1234, 0); - VideoSender sender(NULL, &source, kNullEstimator); - EXPECT_EQ(80000u, source.bits_per_second()); - // 9981, should see 500 frames, 200 byte payloads, total 100000 bytes. - TestVideoSender(&sender, 9981, 500, 200, 100000); - // 9998ms, nothing. - TestVideoSender(&sender, 17, 0, 0, 0); - // 10001ms, 501st frame as a single packet. - TestVideoSender(&sender, 3, 1, 200, 200); - // 10981ms, 49 more frames. - TestVideoSender(&sender, 981, 49, 200, 9800); - // 10998ms, nothing. - TestVideoSender(&sender, 17, 0, 0, 0); -} - -TEST(BweTestFramework_VideoSenderTest, Fps20Kpbs120_1s) { - // 20 fps, 120 kbps. - VideoSource source(0, 20.0f, 120, 0x1234, 0); - VideoSender sender(NULL, &source, kNullEstimator); - EXPECT_EQ(120000u, source.bits_per_second()); - // 451ms, 10 frames with 750 byte payloads, total 7500 bytes. - TestVideoSender(&sender, 451, 10, 750, 7500); - // 498ms, nothing. - TestVideoSender(&sender, 47, 0, 0, 0); - // 501ms, one more frame. - TestVideoSender(&sender, 3, 1, 750, 750); - // 951ms, 9 more frames. - TestVideoSender(&sender, 450, 9, 750, 6750); - // 998ms, nothing. - TestVideoSender(&sender, 47, 0, 0, 0); -} - -TEST(BweTestFramework_VideoSenderTest, Fps25Kbps820_20s) { - // 25 fps, 820 kbps. - VideoSource source(0, 25.0f, 820, 0x1234, 0); - VideoSender sender(NULL, &source, kNullEstimator); - EXPECT_EQ(820000u, source.bits_per_second()); - // 9961ms, 250 frames. 820 kbps = 102500 bytes/s, so total should be 1025000. - // Each frame is 102500/25=4100 bytes, or 5 packets (4 @1000 bytes, 1 @100), - // so packet count should be 5*250=1250 and last packet of each frame has - // 100 bytes of payload. - TestVideoSender(&sender, 9961, 1000, 500, 1025000); - // 9998ms, nothing. - TestVideoSender(&sender, 37, 0, 0, 0); - // 19961ms, 250 more frames. - TestVideoSender(&sender, 9963, 1000, 500, 1025000); - // 19998ms, nothing. - TestVideoSender(&sender, 37, 0, 0, 0); - // 20001ms, one more frame, as described above (25fps == 40ms/frame). - TestVideoSender(&sender, 3, 4, 500, 4100); - // 20038ms, nothing. - TestVideoSender(&sender, 37, 0, 0, 0); -} - -TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) { - // 1 fps, 80 kbps, 250ms offset. - VideoSource source1(0, 1.0f, 80, 0x1234, 250); - VideoSender sender1(NULL, &source1, kNullEstimator); - EXPECT_EQ(80000u, source1.bits_per_second()); - Packets packets; - // Generate some packets, verify they are sorted. - sender1.RunFor(999, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - ASSERT_TRUE(IsSequenceNumberSorted(packets)); - EXPECT_EQ(9u, packets.size()); - // Generate some more packets and verify they are appended to end of list. - sender1.RunFor(1000, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - ASSERT_TRUE(IsSequenceNumberSorted(packets)); - EXPECT_EQ(18u, packets.size()); - - // Another sender, 2 fps, 160 kbps, 150ms offset - VideoSource source2(0, 2.0f, 160, 0x2234, 150); - VideoSender sender2(NULL, &source2, kNullEstimator); - EXPECT_EQ(160000u, source2.bits_per_second()); - // Generate some packets, verify that they are merged with the packets already - // on the list. - sender2.RunFor(999, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - EXPECT_EQ(36u, packets.size()); - // Generate some more. - sender2.RunFor(1000, &packets); - ASSERT_TRUE(IsTimeSorted(packets)); - EXPECT_EQ(54u, packets.size()); - - for (auto* packet : packets) - delete packet; -} - -TEST(BweTestFramework_VideoSenderTest, FeedbackIneffective) { - VideoSource source(0, 25.0f, 820, 0x1234, 0); - VideoSender sender(NULL, &source, kNullEstimator); - - EXPECT_EQ(820000u, source.bits_per_second()); - TestVideoSender(&sender, 9961, 1000, 500, 1025000); - - // Make sure feedback has no effect on a regular video sender. - RembFeedback* feedback = new RembFeedback(0, 0, 0, 512000, RTCPReportBlock()); - Packets packets; - packets.push_back(feedback); - sender.RunFor(0, &packets); - EXPECT_EQ(820000u, source.bits_per_second()); - TestVideoSender(&sender, 10000, 1000, 500, 1025000); -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/bwe_unittest.cc b/modules/remote_bitrate_estimator/test/bwe_unittest.cc deleted file mode 100644 index 15bccd9096..0000000000 --- a/modules/remote_bitrate_estimator/test/bwe_unittest.cc +++ /dev/null @@ -1,393 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/bwe.h" - -#include -#include -#include -#include - -#include "rtc_base/arraysize.h" -#include "test/gtest.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -const int kSetCapacity = 1000; - -class LinkedSetTest : public ::testing::Test { - public: - LinkedSetTest() : linked_set_(kSetCapacity) {} - - ~LinkedSetTest() {} - - protected: - LinkedSet linked_set_; -}; - -TEST_F(LinkedSetTest, EmptySet) { - EXPECT_EQ(linked_set_.Range(), 0); -} - -TEST_F(LinkedSetTest, SinglePacket) { - const uint16_t kSeqNumber = 1; // Arbitrary. - // Other parameters don't matter here. - linked_set_.Insert(kSeqNumber, 0, 0, 0); - - EXPECT_EQ(linked_set_.Range(), 1); -} - -TEST_F(LinkedSetTest, MultiplePackets) { - const uint16_t kNumberPackets = 100; - - std::vector sequence_numbers; - for (size_t i = 0; i < kNumberPackets; ++i) { - sequence_numbers.push_back(static_cast(i + 1)); - } - std::shuffle(sequence_numbers.begin(), sequence_numbers.end(), - std::mt19937(std::random_device()())); - - for (size_t i = 0; i < kNumberPackets; ++i) { - // Other parameters don't matter here. - linked_set_.Insert(static_cast(i), 0, 0, 0); - } - - // Packets arriving out of order should not affect the following value: - EXPECT_EQ(linked_set_.Range(), kNumberPackets); -} - -TEST_F(LinkedSetTest, Overflow) { - const int kFirstSeqNumber = -100; - const int kLastSeqNumber = 100; - - for (int i = kFirstSeqNumber; i <= kLastSeqNumber; ++i) { - // Other parameters don't matter here. - linked_set_.Insert(static_cast(i), 0, 0, 0); - } - - // Wrapping shouldn't matter - EXPECT_EQ(linked_set_.Range(), kLastSeqNumber - kFirstSeqNumber + 1); -} - -TEST_F(LinkedSetTest, SameSequenceNumbers) { - // Test correct behavior when - // sequence numbers wrap (after 0xFFFF). - - // Choose step such as step*capacity < 0x8000 - // (received packets in a reasonable window) - const int kStep = 0x20; - // Choose iteration such as step*iteration > 0x10000 - // (imply wrap) - const int kIterations = 0x1000; - - int kSeqNumber = 1; - for (int i = 0; i < kIterations; ++i) { - // Other parameters don't matter here. - linked_set_.Insert(static_cast(kSeqNumber), 0, 0, 0); - kSeqNumber += kStep; - } - - EXPECT_EQ(linked_set_.Range(), (kSetCapacity - 1) * kStep + 1); -} - -class LossAccountTest : public ::testing::Test { - public: - LossAccountTest() {} - ~LossAccountTest() {} - - protected: - LossAccount loss_account_; -}; - -TEST_F(LossAccountTest, Operations) { - const size_t kTotal = 100; // Arbitrary values. - const size_t kLost = 10; - - LossAccount rhs(kTotal, kLost); - - loss_account_.Add(rhs); - EXPECT_EQ(loss_account_.num_total, kTotal); - EXPECT_EQ(loss_account_.num_lost, kLost); - EXPECT_NEAR(loss_account_.LossRatio(), static_cast(kLost) / kTotal, - 0.001f); - - loss_account_.Subtract(rhs); - EXPECT_EQ(loss_account_.num_total, 0UL); - EXPECT_EQ(loss_account_.num_lost, 0UL); - EXPECT_NEAR(loss_account_.LossRatio(), 0.0f, 0.001f); -} - -class BweReceiverTest : public ::testing::Test { - public: - BweReceiverTest() : bwe_receiver_(kFlowId) {} - ~BweReceiverTest() {} - - protected: - const int kFlowId = 1; // Arbitrary. - BweReceiver bwe_receiver_; -}; - -TEST_F(BweReceiverTest, ReceivingRateNoPackets) { - EXPECT_EQ(bwe_receiver_.RecentKbps(), static_cast(0)); -} - -TEST_F(BweReceiverTest, ReceivingRateSinglePacket) { - const size_t kPayloadSizeBytes = 500 * 1000; - const int64_t kSendTimeUs = 300 * 1000; - const int64_t kArrivalTimeMs = kSendTimeUs / 1000 + 100; - const uint16_t kSequenceNumber = 1; - const int64_t kTimeWindowMs = BweReceiver::kReceivingRateTimeWindowMs; - - const MediaPacket media_packet(kFlowId, kSendTimeUs, kPayloadSizeBytes, - kSequenceNumber); - bwe_receiver_.ReceivePacket(kArrivalTimeMs, media_packet); - - const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeWindowMs; - - EXPECT_NEAR(bwe_receiver_.RecentKbps(), kReceivingRateKbps, - static_cast(kReceivingRateKbps) / 100.0f); -} - -TEST_F(BweReceiverTest, ReceivingRateSmallPackets) { - const size_t kPayloadSizeBytes = 100 * 1000; - const int64_t kTimeGapMs = 50; // Between each packet. - const int64_t kOneWayDelayMs = 50; - - for (int i = 1; i < 50; ++i) { - int64_t send_time_us = i * kTimeGapMs * 1000; - int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; - uint16_t sequence_number = i; - const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes, - sequence_number); - bwe_receiver_.ReceivePacket(arrival_time_ms, media_packet); - } - - const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeGapMs; - EXPECT_NEAR(bwe_receiver_.RecentKbps(), kReceivingRateKbps, - static_cast(kReceivingRateKbps) / 100.0f); -} - -TEST_F(BweReceiverTest, PacketLossNoPackets) { - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); -} - -TEST_F(BweReceiverTest, PacketLossSinglePacket) { - const MediaPacket media_packet(kFlowId, 0, 0, 0); - bwe_receiver_.ReceivePacket(0, media_packet); - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); -} - -TEST_F(BweReceiverTest, PacketLossContiguousPackets) { - const int64_t kTimeWindowMs = BweReceiver::kPacketLossTimeWindowMs; - size_t set_capacity = bwe_receiver_.GetSetCapacity(); - - for (int i = 0; i < 10; ++i) { - uint16_t sequence_number = static_cast(i); - // Sequence_number and flow_id are the only members that matter here. - const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); - // Arrival time = 0, all packets will be considered. - bwe_receiver_.ReceivePacket(0, media_packet); - } - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); - - for (int i = 30; i > 20; i--) { - uint16_t sequence_number = static_cast(i); - // Sequence_number and flow_id are the only members that matter here. - const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); - // Only the packets sent in this for loop will be considered. - bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet); - } - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); - - // Should handle uint16_t overflow. - for (int i = 0xFFFF - 10; i < 0xFFFF + 10; ++i) { - uint16_t sequence_number = static_cast(i); - const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); - // Only the packets sent in this for loop will be considered. - bwe_receiver_.ReceivePacket(4 * kTimeWindowMs, media_packet); - } - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); - - // Should handle set overflow. - for (int i = 0; i < set_capacity * 1.5; ++i) { - uint16_t sequence_number = static_cast(i); - const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); - // Only the packets sent in this for loop will be considered. - bwe_receiver_.ReceivePacket(6 * kTimeWindowMs, media_packet); - } - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); -} - -// Should handle duplicates. -TEST_F(BweReceiverTest, PacketLossDuplicatedPackets) { - const int64_t kTimeWindowMs = BweReceiver::kPacketLossTimeWindowMs; - - for (int i = 0; i < 10; ++i) { - const MediaPacket media_packet(kFlowId, 0, 0, 0); - // Arrival time = 0, all packets will be considered. - bwe_receiver_.ReceivePacket(0, media_packet); - } - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); - - // Missing the element 5. - const uint16_t kSequenceNumbers[] = {1, 2, 3, 4, 6, 7, 8}; - const int kNumPackets = arraysize(kSequenceNumbers); - - // Insert each sequence number twice. - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < kNumPackets; j++) { - const MediaPacket media_packet(kFlowId, 0, 0, kSequenceNumbers[j]); - // Only the packets sent in this for loop will be considered. - bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet); - } - } - - EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 1.0f / (kNumPackets + 1), - 0.1f / (kNumPackets + 1)); -} - -TEST_F(BweReceiverTest, PacketLossLakingPackets) { - size_t set_capacity = bwe_receiver_.GetSetCapacity(); - EXPECT_LT(set_capacity, static_cast(0xFFFF)); - - // Missing every other packet. - for (size_t i = 0; i < set_capacity; ++i) { - if ((i & 1) == 0) { // Only even sequence numbers. - uint16_t sequence_number = static_cast(i); - const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); - // Arrival time = 0, all packets will be considered. - bwe_receiver_.ReceivePacket(0, media_packet); - } - } - EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 0.5f, 0.01f); -} - -TEST_F(BweReceiverTest, PacketLossLakingFewPackets) { - size_t set_capacity = bwe_receiver_.GetSetCapacity(); - EXPECT_LT(set_capacity, static_cast(0xFFFF)); - - const int kPeriod = 100; - // Missing one for each kPeriod packets. - for (size_t i = 0; i < set_capacity; ++i) { - if ((i % kPeriod) != 0) { - uint16_t sequence_number = static_cast(i); - const MediaPacket media_packet(kFlowId, 0, 0, sequence_number); - // Arrival time = 0, all packets will be considered. - bwe_receiver_.ReceivePacket(0, media_packet); - } - } - EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 1.0f / kPeriod, - 0.1f / kPeriod); -} - -// Packet's sequence numbers greatly apart, expect high loss. -TEST_F(BweReceiverTest, PacketLossWideGap) { - const int64_t kTimeWindowMs = BweReceiver::kPacketLossTimeWindowMs; - - const MediaPacket media_packet1(0, 0, 0, 1); - const MediaPacket media_packet2(0, 0, 0, 1000); - // Only these two packets will be considered. - bwe_receiver_.ReceivePacket(0, media_packet1); - bwe_receiver_.ReceivePacket(0, media_packet2); - EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 0.998f, 0.0001f); - - const MediaPacket media_packet3(0, 0, 0, 0); - const MediaPacket media_packet4(0, 0, 0, 0x8000); - // Only these two packets will be considered. - bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet3); - bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet4); - EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 0.99994f, 0.00001f); -} - -// Packets arriving unordered should not be counted as losted. -TEST_F(BweReceiverTest, PacketLossUnorderedPackets) { - size_t num_packets = bwe_receiver_.GetSetCapacity() / 2; - std::vector sequence_numbers; - - for (size_t i = 0; i < num_packets; ++i) { - sequence_numbers.push_back(static_cast(i + 1)); - } - - std::shuffle(sequence_numbers.begin(), sequence_numbers.end(), - std::mt19937(std::random_device()())); - - for (size_t i = 0; i < num_packets; ++i) { - const MediaPacket media_packet(kFlowId, 0, 0, sequence_numbers[i]); - // Arrival time = 0, all packets will be considered. - bwe_receiver_.ReceivePacket(0, media_packet); - } - - EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f); -} - -TEST_F(BweReceiverTest, RecentKbps) { - EXPECT_EQ(bwe_receiver_.RecentKbps(), 0U); - - const size_t kPacketSizeBytes = 1200; - const int kNumPackets = 100; - - double window_size_s = bwe_receiver_.BitrateWindowS(); - - // Receive packets at the same time. - for (int i = 0; i < kNumPackets; ++i) { - MediaPacket packet(kFlowId, 0L, kPacketSizeBytes, static_cast(i)); - bwe_receiver_.ReceivePacket(0, packet); - } - - EXPECT_NEAR(bwe_receiver_.RecentKbps(), - (8 * kNumPackets * kPacketSizeBytes) / (1000 * window_size_s), - 10); - - int64_t time_gap_ms = - 2 * 1000 * window_size_s; // Larger than rate_counter time window. - - MediaPacket packet(kFlowId, time_gap_ms * 1000, kPacketSizeBytes, - static_cast(kNumPackets)); - bwe_receiver_.ReceivePacket(time_gap_ms, packet); - - EXPECT_NEAR(bwe_receiver_.RecentKbps(), - (8 * kPacketSizeBytes) / (1000 * window_size_s), 10); -} - -TEST_F(BweReceiverTest, Loss) { - EXPECT_NEAR(bwe_receiver_.GlobalReceiverPacketLossRatio(), 0.0f, 0.001f); - - LossAccount loss_account = bwe_receiver_.LinkedSetPacketLossRatio(); - EXPECT_NEAR(loss_account.LossRatio(), 0.0f, 0.001f); - - // Insert packets 1-50 and 151-200; - for (int i = 1; i <= 200; ++i) { - // Packet size and timestamp do not matter here. - MediaPacket packet(kFlowId, 0L, 0UL, static_cast(i)); - bwe_receiver_.ReceivePacket(0, packet); - if (i == 50) { - i += 100; - } - } - - loss_account = bwe_receiver_.LinkedSetPacketLossRatio(); - EXPECT_NEAR(loss_account.LossRatio(), 0.5f, 0.001f); - - bwe_receiver_.RelieveSetAndUpdateLoss(); - EXPECT_EQ(bwe_receiver_.received_packets_.size(), 100U / 10); - - // No packet loss within the preserved packets. - loss_account = bwe_receiver_.LinkedSetPacketLossRatio(); - EXPECT_NEAR(loss_account.LossRatio(), 0.0f, 0.001f); - - // RelieveSetAndUpdateLoss automatically updates loss account. - EXPECT_NEAR(bwe_receiver_.GlobalReceiverPacketLossRatio(), 0.5f, 0.001f); -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/bbr.cc b/modules/remote_bitrate_estimator/test/estimators/bbr.cc deleted file mode 100644 index b7daa81f7a..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/bbr.cc +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Copyright (c) 2017 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/remote_bitrate_estimator/test/estimators/bbr.h" - -#include -#include -#include - -#include "modules/remote_bitrate_estimator/test/estimators/congestion_window.h" -#include "modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h" -#include "modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h" - -namespace webrtc { -namespace testing { -namespace bwe { -namespace { -const int kFeedbackIntervalsMs = 5; -// BBR uses this value to double sending rate each round trip. Design document -// suggests using this value. -const float kHighGain = 2.885f; -// BBR uses this value to drain queues created during STARTUP in one round trip -// time. -const float kDrainGain = 1 / kHighGain; -// kStartupGrowthTarget and kMaxRoundsWithoutGrowth are chosen from -// experiments, according to the design document. -const float kStartupGrowthTarget = 1.25f; -const int kMaxRoundsWithoutGrowth = 3; -// Pacing gain values for Probe Bandwidth mode. -const float kPacingGain[] = {1.1f, 0.9f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; -const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]); -// Least number of rounds PROBE_RTT should last. -const int kProbeRttDurationRounds = 1; -// The least amount of milliseconds PROBE_RTT mode should last. -const int kProbeRttDurationMs = 200; -// Gain value for congestion window for assuming that network has no queues. -const float kTargetCongestionWindowGain = 1; -// Gain value for congestion window in PROBE_BW mode. In theory it should be -// equal to 1, but in practice because of delayed acks and the way networks -// work, it is nice to have some extra room in congestion window for full link -// utilization. Value chosen by observations on different tests. -const float kCruisingCongestionWindowGain = 2; -// Pacing gain specific for Recovery mode. Chosen by experiments in simulation -// tool. -const float kRecoveryPacingGain = 0.5f; -// Congestion window gain specific for Recovery mode. Chosen by experiments in -// simulation tool. -const float kRecoveryCongestionWindowGain = 1.5f; -// Number of rounds over which average RTT is stored for Recovery mode. -const size_t kPastRttsFilterSize = 1; -// Threshold to assume average RTT has increased for a round. Chosen by -// experiments in simulation tool. -const float kRttIncreaseThreshold = 3; -// Threshold to assume average RTT has decreased for a round. Chosen by -// experiments in simulation tool. -const float kRttDecreaseThreshold = 1.5f; -// If |kCongestionWindowThreshold| of the congestion window is filled up, tell -// encoder to stop, to avoid building sender side queues. -const float kCongestionWindowThreshold = 0.69f; -// Duration we send at |kDefaultRatebps| in order to ensure BBR has data to work -// with. -const int64_t kDefaultDurationMs = 200; -const int64_t kDefaultRatebps = 300000; -// Congestion window gain for PROBE_RTT mode. -const float kProbeRttCongestionWindowGain = 0.65f; -// We need to be sure that data inflight has increased by at least -// |kTargetCongestionWindowGainForHighGain| compared to the congestion window in -// PROBE_BW's high gain phase, to make ramp-up quicker. As high gain value has -// been decreased from 1.25 to 1.1 we need to make -// |kTargetCongestionWindowGainForHighGain| slightly higher than the actual high -// gain value. -const float kTargetCongestionWindowGainForHighGain = 1.15f; -// Encoder rate gain value for PROBE_RTT mode. -const float kEncoderRateGainForProbeRtt = 0.1f; -} // namespace - -BbrBweSender::BbrBweSender(BitrateObserver* observer, Clock* clock) - : BweSender(0), - observer_(observer), - clock_(clock), - mode_(STARTUP), - max_bandwidth_filter_(new MaxBandwidthFilter()), - min_rtt_filter_(new MinRttFilter()), - congestion_window_(new CongestionWindow()), - rand_(new Random(time(NULL))), - round_count_(0), - round_trip_end_(0), - full_bandwidth_reached_(false), - cycle_start_time_ms_(0), - cycle_index_(0), - bytes_acked_(0), - probe_rtt_start_time_ms_(0), - minimum_congestion_window_start_time_ms_(0), - minimum_congestion_window_start_round_(0), - bytes_sent_(0), - last_packet_sent_sequence_number_(0), - last_packet_acked_sequence_number_(0), - last_packet_ack_time_(0), - last_packet_send_time_(0), - pacing_rate_bps_(0), - last_packet_send_time_during_high_gain_ms_(-1), - data_sent_before_high_gain_started_bytes_(-1), - data_sent_before_high_gain_ended_bytes_(-1), - first_packet_ack_time_during_high_gain_ms_(-1), - last_packet_ack_time_during_high_gain_ms_(-1), - data_acked_before_high_gain_started_bytes_(-1), - data_acked_before_high_gain_ended_bytes_(-1), - first_packet_seq_num_during_high_gain_(0), - last_packet_seq_num_during_high_gain_(0), - high_gain_over_(false), - packet_stats_(), - past_rtts_() { - // Initially enter Startup mode. - EnterStartup(); -} - -BbrBweSender::~BbrBweSender() {} - -BbrBweSender::PacketStats::PacketStats() = default; - -BbrBweSender::PacketStats::PacketStats( - uint16_t sequence_number_, - int64_t last_sent_packet_send_time_ms_, - int64_t send_time_ms_, - int64_t ack_time_ms_, - int64_t last_acked_packet_ack_time_ms_, - size_t payload_size_bytes_, - size_t data_sent_bytes_, - size_t data_sent_before_last_sent_packet_bytes_, - size_t data_acked_bytes_, - size_t data_acked_before_last_acked_packet_bytes_) - : sequence_number(sequence_number_), - last_sent_packet_send_time_ms(last_sent_packet_send_time_ms_), - send_time_ms(send_time_ms_), - ack_time_ms(ack_time_ms_), - last_acked_packet_ack_time_ms(last_acked_packet_ack_time_ms_), - payload_size_bytes(payload_size_bytes_), - data_sent_bytes(data_sent_bytes_), - data_sent_before_last_sent_packet_bytes( - data_sent_before_last_sent_packet_bytes_), - data_acked_bytes(data_acked_bytes_), - data_acked_before_last_acked_packet_bytes( - data_acked_before_last_acked_packet_bytes_) {} - -BbrBweSender::PacketStats::PacketStats(const PacketStats&) = default; - -int BbrBweSender::GetFeedbackIntervalMs() const { - return kFeedbackIntervalsMs; -} - -void BbrBweSender::CalculatePacingRate() { - pacing_rate_bps_ = - max_bandwidth_filter_->max_bandwidth_estimate_bps() * pacing_gain_; -} - -// Declare lost packets as acked. -void BbrBweSender::HandleLoss(uint64_t last_acked_packet, - uint64_t recently_acked_packet) { - for (uint16_t i = last_acked_packet + 1; - AheadOrAt(recently_acked_packet - 1, i); i++) { - congestion_window_->AckReceived(packet_stats_[i].payload_size_bytes); - observer_->OnBytesAcked(packet_stats_[i].payload_size_bytes); - } -} - -void BbrBweSender::AddToPastRtts(int64_t rtt_sample_ms) { - uint64_t last_round = 0; - if (!past_rtts_.empty()) - last_round = past_rtts_.back().round; - - // Try to add the sample to the last round. - if (last_round == round_count_ && !past_rtts_.empty()) { - past_rtts_.back().sum_of_rtts_ms += rtt_sample_ms; - past_rtts_.back().num_samples++; - } else { - // If the sample belongs to a new round, keep number of rounds in the window - // equal to |kPastRttsFilterSize|. - if (past_rtts_.size() == kPastRttsFilterSize) - past_rtts_.pop_front(); - past_rtts_.push_back( - BbrBweSender::AverageRtt(rtt_sample_ms, 1, round_count_)); - } -} - -void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) { - int64_t now_ms = clock_->TimeInMilliseconds(); - last_packet_ack_time_ = now_ms; - const BbrBweFeedback& fb = static_cast(feedback); - // feedback_vector holds values of acknowledged packets' sequence numbers. - const std::vector& feedback_vector = fb.packet_feedback_vector(); - // Go through all the packets acked, update variables/containers accordingly. - for (uint16_t sequence_number : feedback_vector) { - // Completing packet information with a recently received ack. - PacketStats* packet = &packet_stats_[sequence_number]; - bytes_acked_ += packet->payload_size_bytes; - packet->data_sent_bytes = bytes_sent_; - packet->last_sent_packet_send_time_ms = last_packet_send_time_; - packet->data_acked_bytes = bytes_acked_; - packet->ack_time_ms = now_ms; - // Logic specific to applying "bucket" to high gain, in order to have - // quicker ramp-up. We check if we started receiving acks for the packets - // sent during high gain phase. - if (packet->sequence_number == first_packet_seq_num_during_high_gain_) { - first_packet_ack_time_during_high_gain_ms_ = now_ms; - // Substracting half of the packet's size to avoid overestimation. - data_acked_before_high_gain_started_bytes_ = - bytes_acked_ - packet->payload_size_bytes / 2; - } - // If the last packet of high gain phase has been acked, high gain phase is - // over. - if (packet->sequence_number == last_packet_seq_num_during_high_gain_) { - last_packet_ack_time_during_high_gain_ms_ = now_ms; - data_acked_before_high_gain_ended_bytes_ = - bytes_acked_ - packet->payload_size_bytes / 2; - high_gain_over_ = true; - } - observer_->OnBytesAcked(packet->payload_size_bytes); - congestion_window_->AckReceived(packet->payload_size_bytes); - HandleLoss(last_packet_acked_sequence_number_, packet->sequence_number); - last_packet_acked_sequence_number_ = packet->sequence_number; - // Logic for wrapping sequence numbers. If round started with packet number - // x, it can never end on y, if x > y. That could happen when sequence - // numbers are wrapped after some point. - if (packet->sequence_number == 0) - round_trip_end_ = 0; - } - // Check if new round started for the connection. - bool new_round_started = false; - if (!feedback_vector.empty()) { - if (last_packet_acked_sequence_number_ > round_trip_end_) { - new_round_started = true; - round_count_++; - round_trip_end_ = last_packet_sent_sequence_number_; - } - } - TryEnteringProbeRtt(now_ms); - UpdateBandwidthAndMinRtt(now_ms, feedback_vector, bytes_acked_); - if (new_round_started && !full_bandwidth_reached_) { - full_bandwidth_reached_ = max_bandwidth_filter_->FullBandwidthReached( - kStartupGrowthTarget, kMaxRoundsWithoutGrowth); - } - switch (mode_) { - break; - case STARTUP: - TryExitingStartup(); - break; - case DRAIN: - TryExitingDrain(now_ms); - break; - case PROBE_BW: - TryUpdatingCyclePhase(now_ms); - break; - case PROBE_RTT: - TryExitingProbeRtt(now_ms, round_count_); - break; - case RECOVERY: - TryExitingRecovery(new_round_started); - break; - } - TryEnteringRecovery(new_round_started); // Comment this line to disable - // entering Recovery mode. - for (uint16_t f : feedback_vector) - AddToPastRtts(packet_stats_[f].ack_time_ms - packet_stats_[f].send_time_ms); - CalculatePacingRate(); - size_t cwnd = congestion_window_->GetCongestionWindow( - mode_, max_bandwidth_filter_->max_bandwidth_estimate_bps(), - min_rtt_filter_->min_rtt_ms(), congestion_window_gain_); - // Make sure we don't get stuck when pacing_rate is 0, because of simulation - // tool specifics. - if (!pacing_rate_bps_) - pacing_rate_bps_ = 100; - BWE_TEST_LOGGING_PLOT(1, "SendRate", now_ms, pacing_rate_bps_ / 1000); - int64_t rate_for_pacer_bps = pacing_rate_bps_; - int64_t rate_for_encoder_bps = pacing_rate_bps_; - if (congestion_window_->data_inflight() >= cwnd * kCongestionWindowThreshold) - rate_for_encoder_bps = 0; - // We dont completely stop sending during PROBE_RTT, so we need encoder to - // produce something, another way of doing this would be telling encoder to - // stop and send padding instead of actual data. - if (mode_ == PROBE_RTT) - rate_for_encoder_bps = rate_for_pacer_bps * kEncoderRateGainForProbeRtt; - // Send for 300 kbps for first 200 ms, so that BBR has data to work with. - if (now_ms <= kDefaultDurationMs) - observer_->OnNetworkChanged( - kDefaultRatebps, kDefaultRatebps, false, - clock_->TimeInMicroseconds() + kFeedbackIntervalsMs * 1000, cwnd); - else - observer_->OnNetworkChanged( - rate_for_encoder_bps, rate_for_pacer_bps, mode_ == PROBE_RTT, - clock_->TimeInMicroseconds() + kFeedbackIntervalsMs * 1000, cwnd); -} - -size_t BbrBweSender::TargetCongestionWindow(float gain) { - size_t target_congestion_window = - congestion_window_->GetTargetCongestionWindow( - max_bandwidth_filter_->max_bandwidth_estimate_bps(), - min_rtt_filter_->min_rtt_ms(), gain); - return target_congestion_window; -} - -absl::optional BbrBweSender::CalculateBandwidthSample( - size_t data_sent_bytes, - int64_t send_time_delta_ms, - size_t data_acked_bytes, - int64_t ack_time_delta_ms) { - absl::optional bandwidth_sample; - if (send_time_delta_ms > 0) - bandwidth_sample.emplace(data_sent_bytes * 8000 / send_time_delta_ms); - absl::optional ack_rate; - if (ack_time_delta_ms > 0) - ack_rate.emplace(data_acked_bytes * 8000 / ack_time_delta_ms); - // If send rate couldn't be calculated automaticaly set |bandwidth_sample| to - // ack_rate. - if (!bandwidth_sample) - bandwidth_sample = ack_rate; - if (bandwidth_sample && ack_rate) - bandwidth_sample.emplace(std::min(*bandwidth_sample, *ack_rate)); - return bandwidth_sample; -} - -void BbrBweSender::AddSampleForHighGain() { - if (!high_gain_over_) - return; - high_gain_over_ = false; - // Calculate data sent/acked and time elapsed only for packets sent during - // high gain phase. - size_t data_sent_bytes = data_sent_before_high_gain_ended_bytes_ - - data_sent_before_high_gain_started_bytes_; - int64_t send_time_delta_ms = last_packet_send_time_during_high_gain_ms_ - - *first_packet_send_time_during_high_gain_ms_; - size_t data_acked_bytes = data_acked_before_high_gain_ended_bytes_ - - data_acked_before_high_gain_started_bytes_; - int64_t ack_time_delta_ms = last_packet_ack_time_during_high_gain_ms_ - - first_packet_ack_time_during_high_gain_ms_; - absl::optional bandwidth_sample = CalculateBandwidthSample( - data_sent_bytes, send_time_delta_ms, data_acked_bytes, ack_time_delta_ms); - if (bandwidth_sample) - max_bandwidth_filter_->AddBandwidthSample(*bandwidth_sample, round_count_); - first_packet_send_time_during_high_gain_ms_.reset(); -} - -void BbrBweSender::UpdateBandwidthAndMinRtt( - int64_t now_ms, - const std::vector& feedback_vector, - int64_t bytes_acked) { - absl::optional min_rtt_sample_ms; - for (uint16_t f : feedback_vector) { - PacketStats packet = packet_stats_[f]; - size_t data_sent_bytes = - packet.data_sent_bytes - packet.data_sent_before_last_sent_packet_bytes; - int64_t send_time_delta_ms = - packet.last_sent_packet_send_time_ms - packet.send_time_ms; - size_t data_acked_bytes = packet.data_acked_bytes - - packet.data_acked_before_last_acked_packet_bytes; - int64_t ack_time_delta_ms = - packet.ack_time_ms - packet.last_acked_packet_ack_time_ms; - absl::optional bandwidth_sample = - CalculateBandwidthSample(data_sent_bytes, send_time_delta_ms, - data_acked_bytes, ack_time_delta_ms); - if (bandwidth_sample) - max_bandwidth_filter_->AddBandwidthSample(*bandwidth_sample, - round_count_); - // AddSampleForHighGain(); // Comment to disable bucket for high gain. - if (!min_rtt_sample_ms) - min_rtt_sample_ms.emplace(packet.ack_time_ms - packet.send_time_ms); - else - *min_rtt_sample_ms = std::min(*min_rtt_sample_ms, - packet.ack_time_ms - packet.send_time_ms); - BWE_TEST_LOGGING_PLOT(1, "MinRtt", now_ms, - packet.ack_time_ms - packet.send_time_ms); - } - // We only feed RTT samples into the min_rtt filter which were not produced - // during 1.1 gain phase, to ensure they contain no queueing delay. But if the - // rtt sample from 1.1 gain phase improves the current estimate then we should - // make it as a new best estimate. - if (pacing_gain_ <= 1.0f || !min_rtt_filter_->min_rtt_ms() || - *min_rtt_filter_->min_rtt_ms() >= *min_rtt_sample_ms) - min_rtt_filter_->AddRttSample(*min_rtt_sample_ms, now_ms); -} - -void BbrBweSender::EnterStartup() { - mode_ = STARTUP; - pacing_gain_ = kHighGain; - congestion_window_gain_ = kHighGain; -} - -void BbrBweSender::TryExitingStartup() { - if (full_bandwidth_reached_) { - mode_ = DRAIN; - pacing_gain_ = kDrainGain; - congestion_window_gain_ = kHighGain; - } -} - -void BbrBweSender::TryExitingDrain(int64_t now_ms) { - if (congestion_window_->data_inflight() <= - TargetCongestionWindow(kTargetCongestionWindowGain)) - EnterProbeBw(now_ms); -} - -// Start probing with a random gain value, which is different form 0.75, -// starting with 0.75 doesn't offer any benefits as there are no queues to be -// drained. -void BbrBweSender::EnterProbeBw(int64_t now_ms) { - mode_ = PROBE_BW; - congestion_window_gain_ = kCruisingCongestionWindowGain; - int index = rand_->Rand(kGainCycleLength - 2); - if (index == 1) - index = kGainCycleLength - 1; - pacing_gain_ = kPacingGain[index]; - cycle_start_time_ms_ = now_ms; - cycle_index_ = index; -} - -void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) { - // Each phase should last rougly min_rtt ms time. - bool advance_cycle_phase = false; - if (min_rtt_filter_->min_rtt_ms()) - advance_cycle_phase = - now_ms - cycle_start_time_ms_ > *min_rtt_filter_->min_rtt_ms(); - // If BBR was probing and it couldn't increase data inflight sufficiently in - // one min_rtt time, continue probing. BBR design doc isn't clear about this, - // but condition helps in quicker ramp-up and performs better. - if (pacing_gain_ > 1.0 && - congestion_window_->data_inflight() < - TargetCongestionWindow(kTargetCongestionWindowGainForHighGain)) - advance_cycle_phase = false; - // If BBR has already drained queues there is no point in continuing draining - // phase. - if (pacing_gain_ < 1.0 && - congestion_window_->data_inflight() <= TargetCongestionWindow(1)) - advance_cycle_phase = true; - if (advance_cycle_phase) { - cycle_index_++; - cycle_index_ %= kGainCycleLength; - pacing_gain_ = kPacingGain[cycle_index_]; - cycle_start_time_ms_ = now_ms; - } -} - -void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) { - if (min_rtt_filter_->MinRttExpired(now_ms) && mode_ != PROBE_RTT) { - mode_ = PROBE_RTT; - pacing_gain_ = 1; - congestion_window_gain_ = kProbeRttCongestionWindowGain; - probe_rtt_start_time_ms_ = now_ms; - minimum_congestion_window_start_time_ms_.reset(); - } -} - -// |minimum_congestion_window_start_time_|'s value is set to the first moment -// when data inflight was less then -// |CongestionWindow::kMinimumCongestionWindowBytes|, we should make sure that -// BBR has been in PROBE_RTT mode for at least one round or 200ms. -void BbrBweSender::TryExitingProbeRtt(int64_t now_ms, int64_t round) { - if (!minimum_congestion_window_start_time_ms_) { - if (congestion_window_->data_inflight() <= - TargetCongestionWindow(kProbeRttCongestionWindowGain)) { - minimum_congestion_window_start_time_ms_.emplace(now_ms); - minimum_congestion_window_start_round_ = round; - } - } else { - if (now_ms - *minimum_congestion_window_start_time_ms_ >= - kProbeRttDurationMs && - round - minimum_congestion_window_start_round_ >= - kProbeRttDurationRounds) { - EnterProbeBw(now_ms); - } - } -} - -void BbrBweSender::TryEnteringRecovery(bool new_round_started) { - if (mode_ == RECOVERY || !new_round_started || !full_bandwidth_reached_ || - !min_rtt_filter_->min_rtt_ms()) - return; - uint64_t increased_rtt_round_counter = 0; - // If average RTT for past |kPastRttsFilterSize| rounds has been more than - // some multiplier of min_rtt_ms enter Recovery. - for (BbrBweSender::AverageRtt i : past_rtts_) { - if (i.sum_of_rtts_ms / (int64_t)i.num_samples >= - *min_rtt_filter_->min_rtt_ms() * kRttIncreaseThreshold) - increased_rtt_round_counter++; - } - if (increased_rtt_round_counter < kPastRttsFilterSize) - return; - mode_ = RECOVERY; - pacing_gain_ = kRecoveryPacingGain; - congestion_window_gain_ = kRecoveryCongestionWindowGain; -} - -void BbrBweSender::TryExitingRecovery(bool new_round_started) { - if (mode_ != RECOVERY || !new_round_started || !full_bandwidth_reached_) - return; - // If average RTT for the past round has decreased sufficiently exit Recovery. - if (!past_rtts_.empty()) { - BbrBweSender::AverageRtt last_round_sample = past_rtts_.back(); - if (last_round_sample.sum_of_rtts_ms / last_round_sample.num_samples <= - *min_rtt_filter_->min_rtt_ms() * kRttDecreaseThreshold) { - EnterProbeBw(clock_->TimeInMilliseconds()); - } - } -} - -int64_t BbrBweSender::TimeUntilNextProcess() { - return 50; -} - -void BbrBweSender::OnPacketsSent(const Packets& packets) { - for (Packet* packet : packets) { - if (packet->GetPacketType() == Packet::kMedia) { - MediaPacket* media_packet = static_cast(packet); - bytes_sent_ += media_packet->payload_size(); - PacketStats packet_stats = PacketStats( - media_packet->sequence_number(), 0, - media_packet->sender_timestamp_ms(), 0, last_packet_ack_time_, - media_packet->payload_size(), 0, bytes_sent_, 0, bytes_acked_); - packet_stats_[media_packet->sequence_number()] = packet_stats; - last_packet_send_time_ = media_packet->sender_timestamp_ms(); - last_packet_sent_sequence_number_ = media_packet->sequence_number(); - // If this is the first packet sent for high gain phase, save data for it. - if (!first_packet_send_time_during_high_gain_ms_ && pacing_gain_ > 1) { - first_packet_send_time_during_high_gain_ms_.emplace( - last_packet_send_time_); - data_sent_before_high_gain_started_bytes_ = - bytes_sent_ - media_packet->payload_size() / 2; - first_packet_seq_num_during_high_gain_ = - media_packet->sequence_number(); - } - // This condition ensures that |last_packet_seq_num_during_high_gain_| - // will contain a sequence number of the last packet sent during high gain - // phase. - if (pacing_gain_ > 1) { - last_packet_send_time_during_high_gain_ms_ = last_packet_send_time_; - data_sent_before_high_gain_ended_bytes_ = - bytes_sent_ - media_packet->payload_size() / 2; - last_packet_seq_num_during_high_gain_ = media_packet->sequence_number(); - } - congestion_window_->PacketSent(media_packet->payload_size()); - } - } -} - -void BbrBweSender::Process() {} - -BbrBweReceiver::BbrBweReceiver(int flow_id) - : BweReceiver(flow_id, kReceivingRateTimeWindowMs), - clock_(0), - packet_feedbacks_(), - last_feedback_ms_(0) {} - -BbrBweReceiver::~BbrBweReceiver() {} - -void BbrBweReceiver::ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) { - packet_feedbacks_.push_back(media_packet.sequence_number()); - BweReceiver::ReceivePacket(arrival_time_ms, media_packet); -} - -FeedbackPacket* BbrBweReceiver::GetFeedback(int64_t now_ms) { - last_feedback_ms_ = now_ms; - int64_t corrected_send_time_ms = 0L; - if (!received_packets_.empty()) { - PacketIdentifierNode& latest = *(received_packets_.begin()); - corrected_send_time_ms = - latest.send_time_ms + now_ms - latest.arrival_time_ms; - } - FeedbackPacket* fb = new BbrBweFeedback( - flow_id_, now_ms * 1000, corrected_send_time_ms, packet_feedbacks_); - packet_feedbacks_.clear(); - return fb; -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/bbr.h b/modules/remote_bitrate_estimator/test/estimators/bbr.h deleted file mode 100644 index f715b96bca..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/bbr.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2017 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_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_BBR_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_BBR_H_ - -#include -#include -#include -#include - -#include "absl/types/optional.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "rtc_base/numerics/sequence_number_util.h" -#include "rtc_base/random.h" - -namespace webrtc { -namespace testing { -namespace bwe { -class MaxBandwidthFilter; -class MinRttFilter; -class CongestionWindow; -class BbrBweSender : public BweSender { - public: - explicit BbrBweSender(BitrateObserver* observer, Clock* clock); - ~BbrBweSender() override; - enum Mode { - // Startup phase. - STARTUP, - // Queue draining phase, which where created during startup. - DRAIN, - // Cruising, probing new bandwidth. - PROBE_BW, - // Temporarily limiting congestion window size in order to measure - // minimum RTT. - PROBE_RTT, - // Temporarily reducing pacing rate and congestion window, in order to - // ensure no queues are built. - RECOVERY - }; - - struct PacketStats { - PacketStats(); - PacketStats(uint16_t sequence_number_, - int64_t last_sent_packet_send_time_ms_, - int64_t send_time_ms_, - int64_t ack_time_ms_, - int64_t last_acked_packet_ack_time_ms_, - size_t payload_size_bytes_, - size_t data_sent_bytes_, - size_t data_sent_before_last_sent_packet_bytes_, - size_t data_acked_bytes_, - size_t data_acked_before_last_acked_packet_bytes_); - PacketStats(const PacketStats&); - - // Sequence number of this packet. - uint16_t sequence_number; - // Send time of the last sent packet at ack time of this packet. - int64_t last_sent_packet_send_time_ms; - // Send time of this packet. - int64_t send_time_ms; - // Ack time of this packet. - int64_t ack_time_ms; - // Ack time of the last acked packet at send time of this packet. - int64_t last_acked_packet_ack_time_ms; - // Payload size of this packet. - size_t payload_size_bytes; - // Amount of data sent before this packet was sent. - size_t data_sent_bytes; - // Amount of data sent, before last sent packet. - size_t data_sent_before_last_sent_packet_bytes; - // Amount of data acked, before this packet was acked. - size_t data_acked_bytes; - // Amount of data acked, before last acked packet. - size_t data_acked_before_last_acked_packet_bytes; - }; - struct AverageRtt { - AverageRtt() {} - AverageRtt(int64_t sum_of_rtts_ms_, int64_t num_samples_, uint64_t round_) - : sum_of_rtts_ms(sum_of_rtts_ms_), - num_samples(num_samples_), - round(round_) {} - // Sum of RTTs over the round. - int64_t sum_of_rtts_ms; - // Number of RTT samples over the round. - int64_t num_samples; - // The number of the round average RTT is recorded for. - uint64_t round; - }; - void OnPacketsSent(const Packets& packets) override; - int GetFeedbackIntervalMs() const override; - void GiveFeedback(const FeedbackPacket& feedback) override; - int64_t TimeUntilNextProcess() override; - void Process() override; - - private: - void EnterStartup(); - void UpdateBandwidthAndMinRtt(int64_t now_ms, - const std::vector& feedback_vector, - int64_t bytes_acked); - void TryExitingStartup(); - void TryExitingDrain(int64_t now_ms); - void EnterProbeBw(int64_t now_ms); - void TryUpdatingCyclePhase(int64_t now_ms); - void TryEnteringProbeRtt(int64_t now_ms); - void TryExitingProbeRtt(int64_t now_ms, int64_t round); - void TryEnteringRecovery(bool new_round_started); - void TryExitingRecovery(bool new_round_started); - size_t TargetCongestionWindow(float gain); - void CalculatePacingRate(); - - // Calculates and returns bandwidth sample as minimum between send rate and - // ack rate, returns nothing if sample cannot be calculated. - absl::optional CalculateBandwidthSample(size_t data_sent, - int64_t send_time_delta_ms, - size_t data_acked, - int64_t ack_time_delta_ms); - - // Calculate and add bandwidth sample only for packets' sent during high gain - // phase. Motivation of having a seperate bucket for high gain phase is to - // achieve quicker ramp up. Slight overestimations may happen due to window - // not being as large as usual. - void AddSampleForHighGain(); - - // Declares lost packets as acked. Implements simple logic by looking at the - // gap between sequence numbers. If there is a gap between sequence numbers we - // declare those packets as lost immediately. - void HandleLoss(uint64_t last_acked_packet, uint64_t recently_acked_packet); - void AddToPastRtts(int64_t rtt_sample_ms); - BitrateObserver* observer_; - Clock* const clock_; - Mode mode_; - std::unique_ptr max_bandwidth_filter_; - std::unique_ptr min_rtt_filter_; - std::unique_ptr congestion_window_; - std::unique_ptr rand_; - uint64_t round_count_; - uint64_t round_trip_end_; - float pacing_gain_; - float congestion_window_gain_; - - // If optimal bandwidth has been discovered and reached, (for example after - // Startup mode) set this variable to true. - bool full_bandwidth_reached_; - - // Entering time for PROBE_BW mode's cycle phase. - int64_t cycle_start_time_ms_; - - // Index number of the currently used gain value in PROBE_BW mode, from 0 to - // kGainCycleLength - 1. - int64_t cycle_index_; - size_t bytes_acked_; - - // Time we entered PROBE_RTT mode. - int64_t probe_rtt_start_time_ms_; - - // First moment of time when data inflight decreased below - // kMinimumCongestionWindow in PROBE_RTT mode. - absl::optional minimum_congestion_window_start_time_ms_; - - // First round when data inflight decreased below kMinimumCongestionWindow in - // PROBE_RTT mode. - int64_t minimum_congestion_window_start_round_; - size_t bytes_sent_; - uint16_t last_packet_sent_sequence_number_; - uint16_t last_packet_acked_sequence_number_; - int64_t last_packet_ack_time_; - int64_t last_packet_send_time_; - int64_t pacing_rate_bps_; - - // Send time of a packet sent first during high gain phase. Also serves as a - // flag, holding value means that we are already in high gain. - absl::optional first_packet_send_time_during_high_gain_ms_; - - // Send time of a packet sent last during high gain phase. - int64_t last_packet_send_time_during_high_gain_ms_; - - // Amount of data sent, before first packet was sent during high gain phase. - int64_t data_sent_before_high_gain_started_bytes_; - - // Amount of data sent, before last packet was sent during high gain phase. - int64_t data_sent_before_high_gain_ended_bytes_; - - // Ack time of a packet acked first during high gain phase. - int64_t first_packet_ack_time_during_high_gain_ms_; - - // Ack time of a packet acked last during high gain phase. - int64_t last_packet_ack_time_during_high_gain_ms_; - - // Amount of data acked, before the first packet was acked during high gain - // phase. - int64_t data_acked_before_high_gain_started_bytes_; - - // Amount of data acked, before the last packet was acked during high gain - // phase. - int64_t data_acked_before_high_gain_ended_bytes_; - - // Sequence number of the first packet sent during high gain phase. - uint16_t first_packet_seq_num_during_high_gain_; - - // Sequence number of the last packet sent during high gain phase. - uint16_t last_packet_seq_num_during_high_gain_; - bool high_gain_over_; - std::map packet_stats_; - std::list past_rtts_; -}; - -class BbrBweReceiver : public BweReceiver { - public: - explicit BbrBweReceiver(int flow_id); - ~BbrBweReceiver() override; - void ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) override; - FeedbackPacket* GetFeedback(int64_t now_ms) override; - - private: - SimulatedClock clock_; - std::vector packet_feedbacks_; - int64_t last_feedback_ms_; -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_BBR_H_ diff --git a/modules/remote_bitrate_estimator/test/estimators/congestion_window.cc b/modules/remote_bitrate_estimator/test/estimators/congestion_window.cc deleted file mode 100644 index 9f2377fa04..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/congestion_window.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017 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/remote_bitrate_estimator/test/estimators/congestion_window.h" - -#include "modules/remote_bitrate_estimator/test/estimators/bbr.h" -#include "rtc_base/checks.h" - -namespace webrtc { -namespace testing { -namespace bwe { -namespace { -// kStartingCongestionWindowBytes is used to set congestion window when -// bandwidth delay product is equal to zero, so that we don't set window to zero -// as well. Chosen randomly by me, because this value shouldn't make any -// significant difference, as bandwidth delay product is more than zero almost -// every time. -const int kStartingCongestionWindowBytes = 6000; -} // namespace - -CongestionWindow::CongestionWindow() : data_inflight_bytes_(0) {} - -CongestionWindow::~CongestionWindow() {} - -int CongestionWindow::GetCongestionWindow(BbrBweSender::Mode mode, - int64_t bandwidth_estimate_bps, - absl::optional min_rtt_ms, - float gain) { - return GetTargetCongestionWindow(bandwidth_estimate_bps, min_rtt_ms, gain); -} - -void CongestionWindow::PacketSent(size_t sent_packet_size_bytes) { - data_inflight_bytes_ += sent_packet_size_bytes; -} - -void CongestionWindow::AckReceived(size_t received_packet_size_bytes) { - RTC_DCHECK_GE(data_inflight_bytes_ >= received_packet_size_bytes, true); - data_inflight_bytes_ -= received_packet_size_bytes; -} - -int CongestionWindow::GetTargetCongestionWindow( - int64_t bandwidth_estimate_bps, - absl::optional min_rtt_ms, - float gain) { - // If we have no rtt sample yet, return the starting congestion window size. - if (!min_rtt_ms) - return gain * kStartingCongestionWindowBytes; - int bdp = *min_rtt_ms * bandwidth_estimate_bps / 8000; - int congestion_window = bdp * gain; - // Congestion window could be zero in rare cases, when either no bandwidth - // estimate is available, or path's min_rtt value is zero. - if (!congestion_window) - congestion_window = gain * kStartingCongestionWindowBytes; - return congestion_window; -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/congestion_window.h b/modules/remote_bitrate_estimator/test/estimators/congestion_window.h deleted file mode 100644 index f7ae4328d3..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/congestion_window.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 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_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_CONGESTION_WINDOW_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_CONGESTION_WINDOW_H_ - -#include -#include - -#include "absl/types/optional.h" -#include "modules/remote_bitrate_estimator/test/estimators/bbr.h" - -namespace webrtc { -namespace testing { -namespace bwe { -class CongestionWindow { - public: - CongestionWindow(); - ~CongestionWindow(); - int GetCongestionWindow(BbrBweSender::Mode mode, - int64_t bandwidth_estimate, - absl::optional min_rtt, - float gain); - int GetTargetCongestionWindow(int64_t bandwidth_estimate, - absl::optional min_rtt, - float gain); - // Packet sent from sender, meaning it is inflight until we receive it and we - // should add packet's size to data_inflight. - void PacketSent(size_t sent_packet_size); - - // Ack was received by sender, meaning packet is no longer inflight. - void AckReceived(size_t received_packet_size); - - size_t data_inflight() { return data_inflight_bytes_; } - - private: - size_t data_inflight_bytes_; -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_CONGESTION_WINDOW_H_ diff --git a/modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc b/modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc deleted file mode 100644 index 9b394b7b62..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2017 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/remote_bitrate_estimator/test/estimators/congestion_window.h" -#include "modules/remote_bitrate_estimator/test/estimators/bbr.h" - -#include "test/gtest.h" - -namespace webrtc { -namespace testing { -namespace bwe { -namespace { -// Same value used in CongestionWindow class. -const int64_t kStartingCongestionWindow = 6000; -} // namespace - -TEST(CongestionWindowTest, InitializationCheck) { - CongestionWindow congestion_window; - congestion_window.PacketSent(0); - EXPECT_EQ(congestion_window.data_inflight(), 0u); - congestion_window.AckReceived(0); - EXPECT_EQ(congestion_window.data_inflight(), 0u); -} - -TEST(CongestionWindowTest, DataInflight) { - CongestionWindow congestion_window; - congestion_window.PacketSent(13); - EXPECT_EQ(congestion_window.data_inflight(), 13u); - congestion_window.AckReceived(12); - EXPECT_EQ(congestion_window.data_inflight(), 1u); - congestion_window.PacketSent(10); - congestion_window.PacketSent(9); - EXPECT_EQ(congestion_window.data_inflight(), 20u); - congestion_window.AckReceived(20); - EXPECT_EQ(congestion_window.data_inflight(), 0u); -} - -TEST(CongestionWindowTest, ZeroBandwidthDelayProduct) { - CongestionWindow congestion_window; - int64_t target_congestion_window = - congestion_window.GetTargetCongestionWindow(100, 0, 2.885f); - EXPECT_EQ(target_congestion_window, 2.885f * kStartingCongestionWindow); -} - -TEST(CongestionWindowTest, CalculateCongestionWindow) { - CongestionWindow congestion_window; - int64_t cwnd = congestion_window.GetCongestionWindow(BbrBweSender::STARTUP, - 800000, 100l, 2.885f); - EXPECT_EQ(cwnd, 28850); - cwnd = congestion_window.GetCongestionWindow(BbrBweSender::STARTUP, 400000, - 200l, 2.885f); - EXPECT_EQ(cwnd, 28850); -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc b/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc deleted file mode 100644 index 49efcdccc9..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2017 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/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -const size_t MaxBandwidthFilter::kBandwidthWindowFilterSize; - -MaxBandwidthFilter::MaxBandwidthFilter() - : bandwidth_last_round_bytes_per_ms_(0), - max_bandwidth_estimate_bps_(0), - rounds_without_growth_(0) {} - -MaxBandwidthFilter::~MaxBandwidthFilter() {} - -// For detailed explanation about implementing bandwidth filter this way visit -// "Bbr design" doc. |sample_bps| was measured during |round|. -void MaxBandwidthFilter::AddBandwidthSample(int64_t sample_bps, int64_t round) { - if (bandwidth_samples_[0].first == 0 || - sample_bps >= bandwidth_samples_[0].first || - round - bandwidth_samples_[2].second >= - MaxBandwidthFilter::kBandwidthWindowFilterSize) - bandwidth_samples_[0] = bandwidth_samples_[1] = - bandwidth_samples_[2] = {sample_bps, round}; - if (sample_bps >= bandwidth_samples_[1].first) { - bandwidth_samples_[1] = {sample_bps, round}; - bandwidth_samples_[2] = bandwidth_samples_[1]; - } else { - if (sample_bps >= bandwidth_samples_[2].first) - bandwidth_samples_[2] = {sample_bps, round}; - } - if (round - bandwidth_samples_[0].second >= - MaxBandwidthFilter::kBandwidthWindowFilterSize) { - bandwidth_samples_[0] = bandwidth_samples_[1]; - bandwidth_samples_[1] = bandwidth_samples_[2]; - bandwidth_samples_[2] = {sample_bps, round}; - if (round - bandwidth_samples_[0].second >= - MaxBandwidthFilter::kBandwidthWindowFilterSize) { - bandwidth_samples_[0] = bandwidth_samples_[1]; - bandwidth_samples_[1] = bandwidth_samples_[2]; - } - max_bandwidth_estimate_bps_ = bandwidth_samples_[0].first; - return; - } - if (bandwidth_samples_[1].first == bandwidth_samples_[0].first && - round - bandwidth_samples_[1].second > - MaxBandwidthFilter::kBandwidthWindowFilterSize / 4) { - bandwidth_samples_[2] = bandwidth_samples_[1] = {sample_bps, round}; - max_bandwidth_estimate_bps_ = bandwidth_samples_[0].first; - return; - } - if (bandwidth_samples_[2].first == bandwidth_samples_[1].first && - round - bandwidth_samples_[2].second > - MaxBandwidthFilter::kBandwidthWindowFilterSize / 2) - bandwidth_samples_[2] = {sample_bps, round}; - max_bandwidth_estimate_bps_ = bandwidth_samples_[0].first; -} - -bool MaxBandwidthFilter::FullBandwidthReached(float growth_target, - int max_rounds_without_growth) { - // Minimal bandwidth necessary to assume that better bandwidth can still be - // found and full bandwidth is not reached. - int64_t minimal_bandwidth = - bandwidth_last_round_bytes_per_ms_ * growth_target; - if (max_bandwidth_estimate_bps_ >= minimal_bandwidth) { - bandwidth_last_round_bytes_per_ms_ = max_bandwidth_estimate_bps_; - rounds_without_growth_ = 0; - return false; - } - rounds_without_growth_++; - return rounds_without_growth_ >= max_rounds_without_growth; -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h b/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h deleted file mode 100644 index 99c80203d6..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017 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_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MAX_BANDWIDTH_FILTER_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MAX_BANDWIDTH_FILTER_H_ - -#include -#include -#include - -namespace webrtc { -namespace testing { -namespace bwe { -class MaxBandwidthFilter { - public: - // Number of rounds for bandwidth estimate to expire. - static const size_t kBandwidthWindowFilterSize = 10; - - MaxBandwidthFilter(); - ~MaxBandwidthFilter(); - int64_t max_bandwidth_estimate_bps() { return max_bandwidth_estimate_bps_; } - - // Adds bandwidth sample to the bandwidth filter. - void AddBandwidthSample(int64_t sample, int64_t round); - - // Checks if bandwidth has grown by certain multiplier for past x rounds, - // to decide whether or full bandwidth was reached. - bool FullBandwidthReached(float growth_target, int max_rounds_without_growth); - - private: - int64_t bandwidth_last_round_bytes_per_ms_; - int64_t max_bandwidth_estimate_bps_; - int64_t rounds_without_growth_; - std::pair bandwidth_samples_[3]; -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MAX_BANDWIDTH_FILTER_H_ diff --git a/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc b/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc deleted file mode 100644 index 46b6d78422..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2017 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/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h" - -#include "test/gtest.h" - -namespace webrtc { -namespace testing { -namespace bwe { -TEST(MaxBandwidthFilterTest, InitializationCheck) { - MaxBandwidthFilter max_bandwidth_filter; - EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bps(), 0); -} - -TEST(MaxBandwidthFilterTest, AddOneBandwidthSample) { - MaxBandwidthFilter max_bandwidth_filter; - max_bandwidth_filter.AddBandwidthSample(13, 4); - EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bps(), 13); -} - -TEST(MaxBandwidthFilterTest, AddSeveralBandwidthSamples) { - MaxBandwidthFilter max_bandwidth_filter; - max_bandwidth_filter.AddBandwidthSample(10, 5); - max_bandwidth_filter.AddBandwidthSample(13, 6); - EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bps(), 13); -} - -TEST(MaxBandwidthFilterTest, FirstSampleTimeOut) { - MaxBandwidthFilter max_bandwidth_filter; - max_bandwidth_filter.AddBandwidthSample(13, 5); - max_bandwidth_filter.AddBandwidthSample(10, 15); - EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bps(), 10); -} - -TEST(MaxBandwidthFilterTest, SecondSampleBecomesTheFirst) { - MaxBandwidthFilter max_bandwidth_filter; - max_bandwidth_filter.AddBandwidthSample(4, 5); - max_bandwidth_filter.AddBandwidthSample(3, 10); - max_bandwidth_filter.AddBandwidthSample(2, 15); - EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bps(), 3); -} - -TEST(MaxBandwidthFilterTest, ThirdSampleBecomesTheFirst) { - MaxBandwidthFilter max_bandwidth_filter; - max_bandwidth_filter.AddBandwidthSample(4, 5); - max_bandwidth_filter.AddBandwidthSample(3, 10); - max_bandwidth_filter.AddBandwidthSample(2, 25); - EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bps(), 2); -} - -TEST(MaxBandwidthFilterTest, FullBandwidthReached) { - MaxBandwidthFilter max_bandwidth_filter; - max_bandwidth_filter.AddBandwidthSample(100, 1); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); - max_bandwidth_filter.AddBandwidthSample(110, 2); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); - max_bandwidth_filter.AddBandwidthSample(120, 3); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); - max_bandwidth_filter.AddBandwidthSample(124, 4); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), true); -} - -TEST(MaxBandwidthFilterTest, FullBandwidthNotReached) { - MaxBandwidthFilter max_bandwidth_filter; - max_bandwidth_filter.AddBandwidthSample(100, 1); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); - max_bandwidth_filter.AddBandwidthSample(110, 2); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); - max_bandwidth_filter.AddBandwidthSample(120, 3); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); - max_bandwidth_filter.AddBandwidthSample(125, 4); - EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.cc b/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.cc deleted file mode 100644 index 8f699ce169..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.cc +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 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/remote_bitrate_estimator/test/estimators/min_rtt_filter.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -MinRttFilter::MinRttFilter() = default; -MinRttFilter::~MinRttFilter() = default; - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h b/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h deleted file mode 100644 index 4ac392b5ac..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2017 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_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MIN_RTT_FILTER_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MIN_RTT_FILTER_H_ - -#include -#include - -#include "absl/types/optional.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -// Average rtt for past |kRttFilterSize| packets should grow by -// |kRttIncreaseThresholdForExpiry| in order to enter PROBE_RTT mode and expire. -// old min_rtt estimate. -const float kRttIncreaseThresholdForExpiry = 2.3f; -const size_t kRttFilterSize = 25; - -class MinRttFilter { - public: - // This class implements a simple filter to ensure that PROBE_RTT is only - // entered when RTTs start to increase, instead of fixed 10 second window as - // in orginal BBR design doc, to avoid unnecessary freezes in stream. - MinRttFilter(); - ~MinRttFilter(); - - absl::optional min_rtt_ms() { return min_rtt_ms_; } - void AddRttSample(int64_t rtt_ms, int64_t now_ms) { - if (!min_rtt_ms_ || rtt_ms <= *min_rtt_ms_ || MinRttExpired(now_ms)) { - min_rtt_ms_.emplace(rtt_ms); - } - rtt_samples_.push_back(rtt_ms); - if (rtt_samples_.size() > kRttFilterSize) - rtt_samples_.pop_front(); - } - - // Checks whether or not last RTT values for past |kRttFilterSize| packets - // started to increase, meaning we have to update min_rtt estimate. - bool MinRttExpired(int64_t now_ms) { - if (rtt_samples_.size() < kRttFilterSize || !min_rtt_ms_) - return false; - int64_t sum_of_rtts_ms = 0; - for (int64_t i : rtt_samples_) - sum_of_rtts_ms += i; - if (sum_of_rtts_ms >= - *min_rtt_ms_ * kRttIncreaseThresholdForExpiry * kRttFilterSize) { - rtt_samples_.clear(); - return true; - } - return false; - } - - private: - absl::optional min_rtt_ms_; - std::list rtt_samples_; -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MIN_RTT_FILTER_H_ diff --git a/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc b/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc deleted file mode 100644 index 53767e0db7..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2017 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/remote_bitrate_estimator/test/estimators/min_rtt_filter.h" - -#include "test/gtest.h" - -namespace webrtc { -namespace testing { -namespace bwe { -TEST(MinRttFilterTest, InitializationCheck) { - MinRttFilter min_rtt_filter; - EXPECT_FALSE(min_rtt_filter.min_rtt_ms()); -} - -TEST(MinRttFilterTest, AddRttSample) { - MinRttFilter min_rtt_filter; - min_rtt_filter.AddRttSample(120, 5); - EXPECT_EQ(*min_rtt_filter.min_rtt_ms(), 120); - min_rtt_filter.AddRttSample(121, 6); - min_rtt_filter.AddRttSample(119, 7); - min_rtt_filter.AddRttSample(140, 10007); - EXPECT_EQ(*min_rtt_filter.min_rtt_ms(), 119); -} - -TEST(MinRttFilterTest, MinRttExpired) { - MinRttFilter min_rtt_filter; - for (int i = 1; i <= 25; i++) - min_rtt_filter.AddRttSample(i, i); - EXPECT_EQ(min_rtt_filter.MinRttExpired(25), true); - EXPECT_EQ(min_rtt_filter.MinRttExpired(24), false); -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/nada.cc b/modules/remote_bitrate_estimator/test/estimators/nada.cc deleted file mode 100644 index b7f5c9a40f..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/nada.cc +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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. - * - */ - -// Implementation of Network-Assisted Dynamic Adaptation's (NADA's) proposal. -// Version according to Draft Document (mentioned in references) -// http://tools.ietf.org/html/draft-zhu-rmcat-nada-06 -// From March 26, 2015. - -#include -#include -#include -#include -#include -#include - -#include "modules/remote_bitrate_estimator/test/estimators/nada.h" -#include "modules/rtp_rtcp/include/receive_statistics.h" -#include "rtc_base/arraysize.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -namespace { -// Used as an upper bound for calling AcceleratedRampDown. -const float kMaxCongestionSignalMs = - 40.0f + NadaBweSender::kMinNadaBitrateKbps / 15; -} // namespace - -const int NadaBweSender::kMinNadaBitrateKbps = 50; -const int64_t NadaBweReceiver::kReceivingRateTimeWindowMs = 500; - -NadaBweReceiver::NadaBweReceiver(int flow_id) - : BweReceiver(flow_id, kReceivingRateTimeWindowMs), - clock_(0), - last_feedback_ms_(0), - recv_stats_(ReceiveStatistics::Create(&clock_)), - baseline_delay_ms_(10000), // Initialized as an upper bound. - delay_signal_ms_(0), - last_congestion_signal_ms_(0), - last_delays_index_(0), - exp_smoothed_delay_ms_(-1), - est_queuing_delay_signal_ms_(0) {} - -NadaBweReceiver::~NadaBweReceiver() {} - -void NadaBweReceiver::ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) { - const float kAlpha = 0.1f; // Used for exponential smoothing. - const int64_t kDelayLowThresholdMs = 50; // Referred as d_th. - const int64_t kDelayMaxThresholdMs = 400; // Referred as d_max. - - clock_.AdvanceTimeMilliseconds(arrival_time_ms - clock_.TimeInMilliseconds()); - recv_stats_->OnRtpPacket(media_packet.GetRtpPacket()); - // Refered as x_n. - int64_t delay_ms = arrival_time_ms - media_packet.sender_timestamp_ms(); - - // The min should be updated within the first 10 minutes. - if (clock_.TimeInMilliseconds() < 10 * 60 * 1000) { - baseline_delay_ms_ = std::min(baseline_delay_ms_, delay_ms); - } - - delay_signal_ms_ = delay_ms - baseline_delay_ms_; // Refered as d_n. - const int kMedian = arraysize(last_delays_ms_); - last_delays_ms_[(last_delays_index_++) % kMedian] = delay_signal_ms_; - int size = std::min(last_delays_index_, kMedian); - - int64_t median_filtered_delay_ms_ = MedianFilter(last_delays_ms_, size); - exp_smoothed_delay_ms_ = ExponentialSmoothingFilter( - median_filtered_delay_ms_, exp_smoothed_delay_ms_, kAlpha); - - if (exp_smoothed_delay_ms_ < kDelayLowThresholdMs) { - est_queuing_delay_signal_ms_ = exp_smoothed_delay_ms_; - } else if (exp_smoothed_delay_ms_ < kDelayMaxThresholdMs) { - est_queuing_delay_signal_ms_ = static_cast( - pow((static_cast(kDelayMaxThresholdMs - - exp_smoothed_delay_ms_)) / - (kDelayMaxThresholdMs - kDelayLowThresholdMs), - 4.0) * - kDelayLowThresholdMs); - } else { - est_queuing_delay_signal_ms_ = 0; - } - - // Log received packet information. - BweReceiver::ReceivePacket(arrival_time_ms, media_packet); -} - -FeedbackPacket* NadaBweReceiver::GetFeedback(int64_t now_ms) { - const int64_t kPacketLossPenaltyMs = 1000; // Referred as d_L. - - if (now_ms - last_feedback_ms_ < 100) { - return NULL; - } - - float loss_fraction = RecentPacketLossRatio(); - - int64_t loss_signal_ms = - static_cast(loss_fraction * kPacketLossPenaltyMs + 0.5f); - int64_t congestion_signal_ms = est_queuing_delay_signal_ms_ + loss_signal_ms; - - float derivative = 0.0f; - if (last_feedback_ms_ > 0) { - derivative = (congestion_signal_ms - last_congestion_signal_ms_) / - static_cast(now_ms - last_feedback_ms_); - } - last_feedback_ms_ = now_ms; - last_congestion_signal_ms_ = congestion_signal_ms; - - int64_t corrected_send_time_ms = 0L; - - if (!received_packets_.empty()) { - PacketIdentifierNode& latest = *(received_packets_.begin()); - corrected_send_time_ms = - latest.send_time_ms + now_ms - latest.arrival_time_ms; - } - - // Sends a tuple containing latest values of and additional information. - return new NadaFeedback(flow_id_, now_ms * 1000, exp_smoothed_delay_ms_, - est_queuing_delay_signal_ms_, congestion_signal_ms, - derivative, RecentKbps(), corrected_send_time_ms); -} - -// If size is even, the median is the average of the two middlemost numbers. -int64_t NadaBweReceiver::MedianFilter(int64_t* last_delays_ms, int size) { - std::vector array_copy(last_delays_ms, last_delays_ms + size); - std::nth_element(array_copy.begin(), array_copy.begin() + size / 2, - array_copy.end()); - if (size % 2 == 1) { - // Typically, size = 5. For odd size values, right and left are equal. - return array_copy.at(size / 2); - } - int64_t right = array_copy.at(size / 2); - std::nth_element(array_copy.begin(), array_copy.begin() + (size - 1) / 2, - array_copy.end()); - int64_t left = array_copy.at((size - 1) / 2); - return (left + right + 1) / 2; -} - -int64_t NadaBweReceiver::ExponentialSmoothingFilter(int64_t new_value, - int64_t last_smoothed_value, - float alpha) { - if (last_smoothed_value < 0) { - return new_value; // Handling initial case. - } - return static_cast(alpha * new_value + - (1.0f - alpha) * last_smoothed_value + 0.5f); -} - -// Implementation according to Cisco's proposal by default. -NadaBweSender::NadaBweSender(int kbps, BitrateObserver* observer, Clock* clock) - : BweSender(kbps), // Referred as "Reference Rate" = R_n., - clock_(clock), - observer_(observer), - original_operating_mode_(true) {} - -NadaBweSender::NadaBweSender(BitrateObserver* observer, Clock* clock) - : BweSender(kMinNadaBitrateKbps), // Referred as "Reference Rate" = R_n. - clock_(clock), - observer_(observer), - original_operating_mode_(true) {} - -NadaBweSender::~NadaBweSender() {} - -int NadaBweSender::GetFeedbackIntervalMs() const { - return 100; -} - -void NadaBweSender::GiveFeedback(const FeedbackPacket& feedback) { - const NadaFeedback& fb = static_cast(feedback); - - // Following parameters might be optimized. - const int64_t kQueuingDelayUpperBoundMs = 10; - const float kDerivativeUpperBound = - 10.0f / std::max(1, min_feedback_delay_ms_); - // In the modified version, a higher kMinUpperBound allows a higher d_hat - // upper bound for calling AcceleratedRampUp. - const float kProportionalityDelayBits = 20.0f; - - int64_t now_ms = clock_->TimeInMilliseconds(); - float delta_s = now_ms - last_feedback_ms_; - last_feedback_ms_ = now_ms; - // Update delta_0. - min_feedback_delay_ms_ = - std::min(min_feedback_delay_ms_, static_cast(delta_s)); - - // Update RTT_0. - int64_t rtt_ms = now_ms - fb.latest_send_time_ms(); - min_round_trip_time_ms_ = std::min(min_round_trip_time_ms_, rtt_ms); - - // Independent limits for AcceleratedRampUp conditions variables: - // x_n, d_tilde and x'_n in the original implementation, plus - // d_hat and receiving_rate in the modified one. - // There should be no packet losses/marking, hence x_n == d_tilde. - if (original_operating_mode_) { - // Original if conditions and rate update. - if (fb.congestion_signal() == fb.est_queuing_delay_signal_ms() && - fb.est_queuing_delay_signal_ms() < kQueuingDelayUpperBoundMs && - fb.derivative() < kDerivativeUpperBound) { - AcceleratedRampUp(fb); - } else { - GradualRateUpdate(fb, delta_s, 1.0); - } - } else { - // Modified if conditions and rate update; new ramp down mode. - if (fb.congestion_signal() == fb.est_queuing_delay_signal_ms() && - fb.est_queuing_delay_signal_ms() < kQueuingDelayUpperBoundMs && - fb.exp_smoothed_delay_ms() < - kMinNadaBitrateKbps / kProportionalityDelayBits && - fb.derivative() < kDerivativeUpperBound && - fb.receiving_rate() > kMinNadaBitrateKbps) { - AcceleratedRampUp(fb); - } else if (fb.congestion_signal() > kMaxCongestionSignalMs || - fb.exp_smoothed_delay_ms() > kMaxCongestionSignalMs) { - AcceleratedRampDown(fb); - } else { - double bitrate_reference = - (2.0 * bitrate_kbps_) / (kMaxBitrateKbps + kMinNadaBitrateKbps); - double smoothing_factor = pow(bitrate_reference, 0.75); - GradualRateUpdate(fb, delta_s, smoothing_factor); - } - } - - bitrate_kbps_ = std::min(bitrate_kbps_, kMaxBitrateKbps); - bitrate_kbps_ = std::max(bitrate_kbps_, kMinNadaBitrateKbps); - - observer_->OnNetworkChanged(1000 * bitrate_kbps_, 0, rtt_ms); -} - -int64_t NadaBweSender::TimeUntilNextProcess() { - return 100; -} - -void NadaBweSender::Process() {} - -void NadaBweSender::AcceleratedRampUp(const NadaFeedback& fb) { - const int kMaxRampUpQueuingDelayMs = 50; // Referred as T_th. - const float kGamma0 = 0.5f; // Referred as gamma_0. - - float gamma = - std::min(kGamma0, static_cast(kMaxRampUpQueuingDelayMs) / - (min_round_trip_time_ms_ + min_feedback_delay_ms_)); - - bitrate_kbps_ = static_cast((1.0f + gamma) * fb.receiving_rate() + 0.5f); -} - -void NadaBweSender::AcceleratedRampDown(const NadaFeedback& fb) { - const float kGamma0 = 0.9f; - float gamma = 3.0f * kMaxCongestionSignalMs / - (fb.congestion_signal() + fb.exp_smoothed_delay_ms()); - gamma = std::min(gamma, kGamma0); - bitrate_kbps_ = gamma * fb.receiving_rate() + 0.5f; -} - -void NadaBweSender::GradualRateUpdate(const NadaFeedback& fb, - float delta_s, - double smoothing_factor) { - const float kTauOMs = 500.0f; // Referred as tau_o. - const float kEta = 2.0f; // Referred as eta. - const float kKappa = 1.0f; // Referred as kappa. - const float kReferenceDelayMs = 10.0f; // Referred as x_ref. - const float kPriorityWeight = 1.0f; // Referred as w. - - float x_hat = fb.congestion_signal() + kEta * kTauOMs * fb.derivative(); - - float kTheta = kPriorityWeight * (kMaxBitrateKbps - kMinNadaBitrateKbps) * - kReferenceDelayMs; - - int original_increase = static_cast( - (kKappa * delta_s * - (kTheta - (bitrate_kbps_ - kMinNadaBitrateKbps) * x_hat)) / - (kTauOMs * kTauOMs) + - 0.5f); - - bitrate_kbps_ = bitrate_kbps_ + smoothing_factor * original_increase; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/nada.h b/modules/remote_bitrate_estimator/test/estimators/nada.h deleted file mode 100644 index 3ba923f564..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/nada.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - * - */ - -// Implementation of Network-Assisted Dynamic Adaptation's (NADA's) proposal -// Version according to Draft Document (mentioned in references) -// http://tools.ietf.org/html/draft-zhu-rmcat-nada-06 -// From March 26, 2015. - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_NADA_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_NADA_H_ - -#include -#include -#include - -#include "modules/include/module_common_types.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -class ReceiveStatistics; - -namespace testing { -namespace bwe { - -class NadaBweReceiver : public BweReceiver { - public: - explicit NadaBweReceiver(int flow_id); - ~NadaBweReceiver() override; - - void ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) override; - FeedbackPacket* GetFeedback(int64_t now_ms) override; - - static int64_t MedianFilter(int64_t* v, int size); - static int64_t ExponentialSmoothingFilter(int64_t new_value, - int64_t last_smoothed_value, - float alpha); - - static const int64_t kReceivingRateTimeWindowMs; - - private: - SimulatedClock clock_; - int64_t last_feedback_ms_; - std::unique_ptr recv_stats_; - int64_t baseline_delay_ms_; // Referred as d_f. - int64_t delay_signal_ms_; // Referred as d_n. - int64_t last_congestion_signal_ms_; - int last_delays_index_; - int64_t exp_smoothed_delay_ms_; // Referred as d_hat_n. - int64_t est_queuing_delay_signal_ms_; // Referred as d_tilde_n. - int64_t last_delays_ms_[5]; // Used for Median Filter. -}; - -class NadaBweSender : public BweSender { - public: - static const int kMinNadaBitrateKbps; - - NadaBweSender(int kbps, BitrateObserver* observer, Clock* clock); - NadaBweSender(BitrateObserver* observer, Clock* clock); - ~NadaBweSender() override; - - int GetFeedbackIntervalMs() const override; - // Updates the min_feedback_delay_ms_ and the min_round_trip_time_ms_. - void GiveFeedback(const FeedbackPacket& feedback) override; - void OnPacketsSent(const Packets& packets) override {} - int64_t TimeUntilNextProcess() override; - void Process() override; - void AcceleratedRampUp(const NadaFeedback& fb); - void AcceleratedRampDown(const NadaFeedback& fb); - void GradualRateUpdate(const NadaFeedback& fb, - float delta_s, - double smoothing_factor); - - int bitrate_kbps() const { return bitrate_kbps_; } - void set_bitrate_kbps(int bitrate_kbps) { bitrate_kbps_ = bitrate_kbps; } - bool original_operating_mode() const { return original_operating_mode_; } - void set_original_operating_mode(bool original_operating_mode) { - original_operating_mode_ = original_operating_mode; - } - int64_t NowMs() const { return clock_->TimeInMilliseconds(); } - - private: - Clock* const clock_; - BitrateObserver* const observer_; - // Referred as R_min, default initialization for bitrate R_n. - int64_t last_feedback_ms_ = 0; - // Referred as delta_0, initialized as an upper bound. - int64_t min_feedback_delay_ms_ = 200; - // Referred as RTT_0, initialized as an upper bound. - int64_t min_round_trip_time_ms_ = 100; - bool original_operating_mode_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(NadaBweSender); -}; - -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_NADA_H_ diff --git a/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc b/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc deleted file mode 100644 index abad4ad2e3..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc +++ /dev/null @@ -1,494 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/estimators/nada.h" - -#include -#include -#include -#include - -#include "modules/remote_bitrate_estimator/test/packet.h" -#include "rtc_base/arraysize.h" -#include "test/gtest.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 * NadaBweSender::kMinNadaBitrateKbps; - size_t receiving_rate = static_cast(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 * NadaBweSender::kMinNadaBitrateKbps; - size_t receiving_rate = static_cast(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(), NadaBweSender::kMinNadaBitrateKbps); - 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 = 5 * NadaBweSender::kMinNadaBitrateKbps; - size_t receiving_rate = static_cast(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(NadaBweSender::kMinNadaBitrateKbps); - 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 * NadaBweSender::kMinNadaBitrateKbps); - 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(), NadaBweSender::kMinNadaBitrateKbps); - - nada_sender_.set_original_operating_mode(false); - nada_sender_.set_bitrate_kbps(5 * NadaBweSender::kMinNadaBitrateKbps); - - 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(), NadaBweSender::kMinNadaBitrateKbps); -} - -// Sending bitrate should increase and reach its Max bound. -TEST_F(NadaSenderSideTest, VeryHighBandwith) { - const int64_t kOneWayDelayMs = 50; - const size_t kRecentReceivingRate = static_cast(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(NadaBweSender::kMinNadaBitrateKbps); - - 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) { - std::unique_ptr nada_feedback( - static_cast(nada_receiver_.GetFeedback(0))); - EXPECT_EQ(nada_feedback, nullptr); - - nada_feedback.reset( - static_cast(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(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. - std::unique_ptr nada_feedback( - static_cast(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 = arraysize(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( - 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(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); - - std::unique_ptr nada_feedback(static_cast( - 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(exp_smoothed_delays_ms[i]) / kTimeGapMs, - 0.005f); - } else { - EXPECT_NEAR(nada_feedback->derivative(), - static_cast(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( - pow((static_cast(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 = arraysize(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( - 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(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); - - std::unique_ptr nada_feedback(static_cast( - 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 = arraysize(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(exp_smoothed[i - 1] * (1.0f - kAlpha) + 0.5f)); - } -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/remb.cc b/modules/remote_bitrate_estimator/test/estimators/remb.cc deleted file mode 100644 index 3af91c4d90..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/remb.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "modules/bitrate_controller/include/bitrate_controller.h" -#include "modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" -#include "modules/remote_bitrate_estimator/test/estimators/remb.h" -#include "modules/rtp_rtcp/include/receive_statistics.h" -#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" -#include "rtc_base/strings/string_builder.h" -#include "rtc_base/system/unused.h" -#include "test/gtest.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -RembBweSender::RembBweSender(int kbps, BitrateObserver* observer, Clock* clock) - : bitrate_controller_( - BitrateController::CreateBitrateController(clock, - observer, - &event_log_)), - feedback_observer_(bitrate_controller_.get()), - clock_(clock) { - assert(kbps >= kMinBitrateKbps); - assert(kbps <= kMaxBitrateKbps); - bitrate_controller_->SetStartBitrate(1000 * kbps); - bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps, - 1000 * kMaxBitrateKbps); -} - -RembBweSender::~RembBweSender() {} - -void RembBweSender::GiveFeedback(const FeedbackPacket& feedback) { - const RembFeedback& remb_feedback = - static_cast(feedback); - feedback_observer_->OnReceivedEstimatedBitrate(remb_feedback.estimated_bps()); - ReportBlockList report_blocks; - report_blocks.push_back(remb_feedback.report_block()); - feedback_observer_->OnReceivedRtcpReceiverReport( - report_blocks, 0, clock_->TimeInMilliseconds()); - bitrate_controller_->Process(); -} - -int64_t RembBweSender::TimeUntilNextProcess() { - return bitrate_controller_->TimeUntilNextProcess(); -} - -void RembBweSender::Process() { - bitrate_controller_->Process(); -} - -int RembBweSender::GetFeedbackIntervalMs() const { - return 100; -} - -RembReceiver::RembReceiver(int flow_id, bool plot) - : BweReceiver(flow_id), - estimate_log_prefix_(), - plot_estimate_(plot), - clock_(0), - recv_stats_(ReceiveStatistics::Create(&clock_)), - latest_estimate_bps_(-1), - last_feedback_ms_(-1), - estimator_(new RemoteBitrateEstimatorAbsSendTime(this, &clock_)) { - rtc::StringBuilder ss; - ss << "Estimate_" << flow_id_ << "#1"; - estimate_log_prefix_ = ss.str(); - // Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic. - estimator_->OnRttUpdate(50, 50); - estimator_->SetMinBitrate(kRemoteBitrateEstimatorMinBitrateBps); -} - -RembReceiver::~RembReceiver() {} - -void RembReceiver::ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) { - recv_stats_->OnRtpPacket(media_packet.GetRtpPacket()); - - latest_estimate_bps_ = -1; - - int64_t step_ms = std::max(estimator_->TimeUntilNextProcess(), 0); - while ((clock_.TimeInMilliseconds() + step_ms) < arrival_time_ms) { - clock_.AdvanceTimeMilliseconds(step_ms); - estimator_->Process(); - step_ms = std::max(estimator_->TimeUntilNextProcess(), 0); - } - estimator_->IncomingPacket(arrival_time_ms, media_packet.payload_size(), - media_packet.header()); - clock_.AdvanceTimeMilliseconds(arrival_time_ms - clock_.TimeInMilliseconds()); - ASSERT_TRUE(arrival_time_ms == clock_.TimeInMilliseconds()); - - // Log received packet information. - BweReceiver::ReceivePacket(arrival_time_ms, media_packet); -} - -FeedbackPacket* RembReceiver::GetFeedback(int64_t now_ms) { - BWE_TEST_LOGGING_CONTEXT("Remb"); - uint32_t estimated_bps = 0; - RembFeedback* feedback = NULL; - if (LatestEstimate(&estimated_bps)) { - auto report_blocks = recv_stats_->RtcpReportBlocks(1); - if (!report_blocks.empty()) { - const rtcp::ReportBlock& stat = report_blocks.front(); - latest_report_block_.fraction_lost = stat.fraction_lost(); - latest_report_block_.packets_lost = stat.cumulative_lost(); - latest_report_block_.extended_highest_sequence_number = - stat.extended_high_seq_num(); - latest_report_block_.jitter = stat.jitter(); - } - - feedback = new RembFeedback(flow_id_, now_ms * 1000, last_feedback_ms_, - estimated_bps, latest_report_block_); - last_feedback_ms_ = now_ms; - - double estimated_kbps = static_cast(estimated_bps) / 1000.0; - RTC_UNUSED(estimated_kbps); - if (plot_estimate_) { - BWE_TEST_LOGGING_PLOT(0, estimate_log_prefix_, - clock_.TimeInMilliseconds(), estimated_kbps); - } - } - return feedback; -} - -void RembReceiver::OnReceiveBitrateChanged(const std::vector& ssrcs, - uint32_t bitrate) {} - -bool RembReceiver::LatestEstimate(uint32_t* estimate_bps) { - if (latest_estimate_bps_ < 0) { - std::vector ssrcs; - uint32_t bps = 0; - if (!estimator_->LatestEstimate(&ssrcs, &bps)) { - return false; - } - latest_estimate_bps_ = bps; - } - *estimate_bps = latest_estimate_bps_; - return true; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/remb.h b/modules/remote_bitrate_estimator/test/estimators/remb.h deleted file mode 100644 index df16fec848..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/remb.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_REMB_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_REMB_H_ - -#include -#include -#include - -#include "logging/rtc_event_log/mock/mock_rtc_event_log.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -class BitrateObserver; -class BitrateController; -class ReceiveStatistics; -class StreamStatistician; - -namespace testing { -namespace bwe { - -class RembBweSender : public BweSender { - public: - RembBweSender(int kbps, BitrateObserver* observer, Clock* clock); - virtual ~RembBweSender(); - - int GetFeedbackIntervalMs() const override; - void GiveFeedback(const FeedbackPacket& feedback) override; - void OnPacketsSent(const Packets& packets) override {} - int64_t TimeUntilNextProcess() override; - void Process() override; - - protected: - std::unique_ptr bitrate_controller_; - RtcpBandwidthObserver* feedback_observer_; - - private: - Clock* clock_; - ::testing::NiceMock event_log_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RembBweSender); -}; - -class RembReceiver : public BweReceiver, public RemoteBitrateObserver { - public: - static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; - - RembReceiver(int flow_id, bool plot); - ~RembReceiver() override; - - void ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) override; - FeedbackPacket* GetFeedback(int64_t now_ms) override; - // Implements RemoteBitrateObserver. - void OnReceiveBitrateChanged(const std::vector& ssrcs, - uint32_t bitrate) override; - - private: - bool LatestEstimate(uint32_t* estimate_bps); - - std::string estimate_log_prefix_; - bool plot_estimate_ = false; - SimulatedClock clock_; - std::unique_ptr recv_stats_; - int64_t latest_estimate_bps_; - int64_t last_feedback_ms_; - std::unique_ptr estimator_; - RTCPReportBlock latest_report_block_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RembReceiver); -}; - -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_REMB_H_ diff --git a/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/modules/remote_bitrate_estimator/test/estimators/send_side.cc deleted file mode 100644 index bd701cfffb..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/send_side.cc +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/estimators/send_side.h" - -#include -#include -#include - -#include "absl/memory/memory.h" -#include "api/rtp_headers.h" -#include "api/transport/network_types.h" -#include "modules/congestion_controller/goog_cc/delay_based_bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -const int kFeedbackIntervalMs = 50; - -SendSideBweSender::SendSideBweSender(int kbps, - BitrateObserver* observer, - Clock* clock) - : bitrate_controller_( - BitrateController::CreateBitrateController(clock, - observer, - &event_log_)), - acknowledged_bitrate_estimator_( - absl::make_unique( - &field_trial_config_)), - probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)), - bwe_(new DelayBasedBwe(&field_trial_config_, nullptr, nullptr)), - feedback_observer_(bitrate_controller_.get()), - clock_(clock), - send_time_history_(10000), - has_received_ack_(false), - last_acked_seq_num_(0), - last_log_time_ms_(0) { - assert(kbps >= kMinBitrateKbps); - assert(kbps <= kMaxBitrateKbps); - bitrate_controller_->SetStartBitrate(1000 * kbps); - bitrate_controller_->SetMinMaxBitrate(1000 * kMinBitrateKbps, - 1000 * kMaxBitrateKbps); - bwe_->SetMinBitrate(DataRate::kbps(kMinBitrateKbps)); -} - -SendSideBweSender::~SendSideBweSender() {} - -int SendSideBweSender::GetFeedbackIntervalMs() const { - return kFeedbackIntervalMs; -} - -void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) { - const SendSideBweFeedback& fb = - static_cast(feedback); - if (fb.packet_feedback_vector().empty()) - return; - std::vector packet_feedback_vector( - fb.packet_feedback_vector()); - for (PacketFeedback& packet_feedback : packet_feedback_vector) { - if (!send_time_history_.GetFeedback(&packet_feedback, true)) { - int64_t now_ms = clock_->TimeInMilliseconds(); - if (now_ms - last_log_time_ms_ > 5000) { - RTC_LOG(LS_WARNING) << "Ack arrived too late."; - last_log_time_ms_ = now_ms; - } - } - } - - int64_t rtt_ms = - clock_->TimeInMilliseconds() - feedback.latest_send_time_ms(); - bwe_->OnRttUpdate(TimeDelta::ms(rtt_ms)); - BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms); - - std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(), - PacketFeedbackComparator()); - acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector( - packet_feedback_vector); - for (PacketFeedback& packet : packet_feedback_vector) { - if (packet.send_time_ms != PacketFeedback::kNoSendTime && - packet.pacing_info.probe_cluster_id != PacedPacketInfo::kNotAProbe) - probe_bitrate_estimator_->HandleProbeAndEstimateBitrate(packet); - } - DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector( - packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate(), - probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), - absl::nullopt, false, Timestamp::ms(clock_->TimeInMilliseconds())); - if (result.updated) - bitrate_controller_->OnDelayBasedBweResult(result); - - if (has_received_ack_) { - int expected_packets = fb.packet_feedback_vector().back().sequence_number - - last_acked_seq_num_; - // Assuming no reordering for now. - if (expected_packets > 0) { - int lost_packets = expected_packets - - static_cast(fb.packet_feedback_vector().size()); - report_block_.fraction_lost = (lost_packets << 8) / expected_packets; - report_block_.packets_lost += lost_packets; - uint32_t unwrapped = seq_num_unwrapper_.Unwrap( - packet_feedback_vector.back().sequence_number); - report_block_.extended_highest_sequence_number = - std::max(unwrapped, report_block_.extended_highest_sequence_number); - ReportBlockList report_blocks; - report_blocks.push_back(report_block_); - feedback_observer_->OnReceivedRtcpReceiverReport( - report_blocks, rtt_ms, clock_->TimeInMilliseconds()); - } - bitrate_controller_->Process(); - - last_acked_seq_num_ = LatestSequenceNumber( - packet_feedback_vector.back().sequence_number, last_acked_seq_num_); - } else { - last_acked_seq_num_ = packet_feedback_vector.back().sequence_number; - has_received_ack_ = true; - } -} - -void SendSideBweSender::OnPacketsSent(const Packets& packets) { - for (Packet* packet : packets) { - if (packet->GetPacketType() == Packet::kMedia) { - MediaPacket* media_packet = static_cast(packet); - // TODO(philipel): Add probe_cluster_id to Packet class in order - // to create tests for probing using cluster ids. - PacketFeedback packet_feedback( - clock_->TimeInMilliseconds(), media_packet->header().sequenceNumber, - media_packet->payload_size(), 0, 0, PacedPacketInfo()); - send_time_history_.AddAndRemoveOld(packet_feedback, - clock_->TimeInMilliseconds()); - send_time_history_.OnSentPacket(media_packet->header().sequenceNumber, - media_packet->sender_timestamp_ms()); - } - } -} - -void SendSideBweSender::OnReceiveBitrateChanged( - const std::vector& ssrcs, - uint32_t bitrate) { - feedback_observer_->OnReceivedEstimatedBitrate(bitrate); -} - -int64_t SendSideBweSender::TimeUntilNextProcess() { - return bitrate_controller_->TimeUntilNextProcess(); -} - -void SendSideBweSender::Process() { - bitrate_controller_->Process(); -} - -SendSideBweReceiver::SendSideBweReceiver(int flow_id) - : BweReceiver(flow_id), last_feedback_ms_(0) {} - -SendSideBweReceiver::~SendSideBweReceiver() {} - -void SendSideBweReceiver::ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) { - packet_feedback_vector_.push_back( - PacketFeedback(-1, arrival_time_ms, media_packet.sender_timestamp_ms(), - media_packet.header().sequenceNumber, - media_packet.payload_size(), 0, 0, PacedPacketInfo())); - - // Log received packet information. - BweReceiver::ReceivePacket(arrival_time_ms, media_packet); -} - -FeedbackPacket* SendSideBweReceiver::GetFeedback(int64_t now_ms) { - if (now_ms - last_feedback_ms_ < kFeedbackIntervalMs) - return NULL; - last_feedback_ms_ = now_ms; - int64_t corrected_send_time_ms = - packet_feedback_vector_.back().send_time_ms + now_ms - - packet_feedback_vector_.back().arrival_time_ms; - FeedbackPacket* fb = new SendSideBweFeedback( - flow_id_, now_ms * 1000, corrected_send_time_ms, packet_feedback_vector_); - packet_feedback_vector_.clear(); - return fb; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/send_side.h b/modules/remote_bitrate_estimator/test/estimators/send_side.h deleted file mode 100644 index 4d7cb18759..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/send_side.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_SEND_SIDE_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_SEND_SIDE_H_ - -#include -#include -#include - -#include "api/transport/field_trial_based_config.h" -#include "logging/rtc_event_log/mock/mock_rtc_event_log.h" -#include "modules/bitrate_controller/include/bitrate_controller.h" -#include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h" -#include "modules/congestion_controller/goog_cc/delay_based_bwe.h" -#include "modules/congestion_controller/rtp/send_time_history.h" -#include "modules/include/module_common_types_public.h" -#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/packet.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "rtc_base/constructor_magic.h" -#include "system_wrappers/include/clock.h" -#include "test/gmock.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -class SendSideBweSender : public BweSender, public RemoteBitrateObserver { - public: - SendSideBweSender(int kbps, BitrateObserver* observer, Clock* clock); - virtual ~SendSideBweSender(); - - int GetFeedbackIntervalMs() const override; - void GiveFeedback(const FeedbackPacket& feedback) override; - void OnPacketsSent(const Packets& packets) override; - void OnReceiveBitrateChanged(const std::vector& ssrcs, - uint32_t bitrate) override; - int64_t TimeUntilNextProcess() override; - void Process() override; - - private: - FieldTrialBasedConfig field_trial_config_; - - protected: - std::unique_ptr bitrate_controller_; - std::unique_ptr acknowledged_bitrate_estimator_; - std::unique_ptr probe_bitrate_estimator_; - std::unique_ptr bwe_; - RtcpBandwidthObserver* feedback_observer_; - - private: - Clock* const clock_; - RTCPReportBlock report_block_; - SendTimeHistory send_time_history_; - bool has_received_ack_; - uint16_t last_acked_seq_num_; - int64_t last_log_time_ms_; - SequenceNumberUnwrapper seq_num_unwrapper_; - ::testing::NiceMock event_log_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SendSideBweSender); -}; - -class SendSideBweReceiver : public BweReceiver { - public: - explicit SendSideBweReceiver(int flow_id); - ~SendSideBweReceiver() override; - - void ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) override; - FeedbackPacket* GetFeedback(int64_t now_ms) override; - - private: - int64_t last_feedback_ms_; - std::vector packet_feedback_vector_; -}; - -} // namespace bwe -} // namespace testing -} // namespace webrtc - -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_SEND_SIDE_H_ diff --git a/modules/remote_bitrate_estimator/test/estimators/tcp.cc b/modules/remote_bitrate_estimator/test/estimators/tcp.cc deleted file mode 100644 index 96c97ed5b5..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/tcp.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 - -#include "api/rtp_headers.h" -#include "modules/remote_bitrate_estimator/test/estimators/tcp.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -TcpBweReceiver::TcpBweReceiver(int flow_id) - : BweReceiver(flow_id), last_feedback_ms_(0), latest_owd_ms_(0) {} - -TcpBweReceiver::~TcpBweReceiver() {} - -void TcpBweReceiver::ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) { - latest_owd_ms_ = arrival_time_ms - media_packet.sender_timestamp_ms() / 1000; - acks_.push_back(media_packet.header().sequenceNumber); - - // Log received packet information. - BweReceiver::ReceivePacket(arrival_time_ms, media_packet); -} - -FeedbackPacket* TcpBweReceiver::GetFeedback(int64_t now_ms) { - int64_t corrected_send_time_ms = now_ms - latest_owd_ms_; - FeedbackPacket* fb = - new TcpFeedback(flow_id_, now_ms * 1000, corrected_send_time_ms, acks_); - last_feedback_ms_ = now_ms; - acks_.clear(); - return fb; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/estimators/tcp.h b/modules/remote_bitrate_estimator/test/estimators/tcp.h deleted file mode 100644 index abdc0718cf..0000000000 --- a/modules/remote_bitrate_estimator/test/estimators/tcp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_TCP_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_TCP_H_ - -#include -#include - -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/packet.h" - -namespace webrtc { -namespace testing { -namespace bwe { -class TcpBweReceiver : public BweReceiver { - public: - explicit TcpBweReceiver(int flow_id); - ~TcpBweReceiver() override; - - void ReceivePacket(int64_t arrival_time_ms, - const MediaPacket& media_packet) override; - FeedbackPacket* GetFeedback(int64_t now_ms) override; - - private: - int64_t last_feedback_ms_; - int64_t latest_owd_ms_; - std::vector acks_; -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_TCP_H_ diff --git a/modules/remote_bitrate_estimator/test/metric_recorder.cc b/modules/remote_bitrate_estimator/test/metric_recorder.cc deleted file mode 100644 index 2346ece37e..0000000000 --- a/modules/remote_bitrate_estimator/test/metric_recorder.cc +++ /dev/null @@ -1,453 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/metric_recorder.h" - -#include - -#include - -#include "modules/remote_bitrate_estimator/test/packet_sender.h" -#include "rtc_base/strings/string_builder.h" -#include "rtc_base/system/unused.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -namespace { -// Holder mean, Manhattan distance for p=1, EuclidianNorm/sqrt(n) for p=2. -template -double NormLp(T sum, size_t size, double p) { - return pow(sum / size, 1.0 / p); -} -} // namespace - -const double kP = 1.0; // Used for Norm Lp. - -LinkShare::LinkShare(ChokeFilter* choke_filter) - : choke_filter_(choke_filter), running_flows_(choke_filter->flow_ids()) {} - -LinkShare::~LinkShare() = default; - -void LinkShare::PauseFlow(int flow_id) { - running_flows_.erase(flow_id); -} - -void LinkShare::ResumeFlow(int flow_id) { - running_flows_.insert(flow_id); -} - -uint32_t LinkShare::TotalAvailableKbps() { - return choke_filter_->capacity_kbps(); -} - -uint32_t LinkShare::AvailablePerFlowKbps(int flow_id) { - uint32_t available_capacity_per_flow_kbps = 0; - if (running_flows_.find(flow_id) != running_flows_.end()) { - available_capacity_per_flow_kbps = - TotalAvailableKbps() / static_cast(running_flows_.size()); - } - return available_capacity_per_flow_kbps; -} - -MetricRecorder::MetricRecorder(const std::string algorithm_name, - int flow_id, - PacketSender* packet_sender, - LinkShare* link_share) - : algorithm_name_(algorithm_name), - flow_id_(flow_id), - link_share_(link_share), - now_ms_(0), - sum_delays_ms_(0), - delay_histogram_ms_(), - sum_delays_square_ms2_(0), - sum_throughput_bytes_(0), - last_unweighted_estimate_error_(0), - optimal_throughput_bits_(0), - last_available_bitrate_per_flow_kbps_(0), - start_computing_metrics_ms_(0), - started_computing_metrics_(false), - num_packets_received_(0) { - std::fill_n(sum_lp_weighted_estimate_error_, 2, 0); - if (packet_sender != nullptr) - packet_sender->set_metric_recorder(this); -} - -MetricRecorder::~MetricRecorder() = default; - -void MetricRecorder::SetPlotInformation( - const std::vector& prefixes, - bool plot_delay, - bool plot_loss) { - assert(prefixes.size() == kNumMetrics); - for (size_t i = 0; i < kNumMetrics; ++i) { - plot_information_[i].prefix = prefixes[i]; - } - plot_information_[kThroughput].plot_interval_ms = 100; - plot_information_[kSendingEstimate].plot_interval_ms = 100; - plot_information_[kDelay].plot_interval_ms = 100; - plot_information_[kLoss].plot_interval_ms = 500; - plot_information_[kObjective].plot_interval_ms = 1000; - plot_information_[kTotalAvailable].plot_interval_ms = 1000; - plot_information_[kAvailablePerFlow].plot_interval_ms = 1000; - - for (int i = kThroughput; i < kNumMetrics; ++i) { - plot_information_[i].last_plot_ms = 0; - switch (i) { - case kSendingEstimate: - case kObjective: - case kAvailablePerFlow: - plot_information_[i].plot = false; - break; - case kLoss: - plot_information_[i].plot = plot_loss; - break; - case kDelay: - plot_information_[i].plot = plot_delay; - break; - default: - plot_information_[i].plot = true; - } - } -} - -void MetricRecorder::PlotAllDynamics() { - for (int i = kThroughput; i < kNumMetrics; ++i) { - if (plot_information_[i].plot && - now_ms_ - plot_information_[i].last_plot_ms >= - plot_information_[i].plot_interval_ms) { - PlotDynamics(i); - } - } -} - -void MetricRecorder::PlotDynamics(int metric) { - if (metric == kTotalAvailable) { - BWE_TEST_LOGGING_PLOT_WITH_NAME_AND_SSRC( - 0, plot_information_[kTotalAvailable].prefix, now_ms_, - GetTotalAvailableKbps(), flow_id_, "Available"); - } else if (metric == kAvailablePerFlow) { - BWE_TEST_LOGGING_PLOT_WITH_NAME_AND_SSRC( - 0, plot_information_[kAvailablePerFlow].prefix, now_ms_, - GetAvailablePerFlowKbps(), flow_id_, "Available_per_flow"); - } else { - PlotLine(metric, plot_information_[metric].prefix, - plot_information_[metric].time_ms, - plot_information_[metric].value); - } - plot_information_[metric].last_plot_ms = now_ms_; -} - -template -void MetricRecorder::PlotLine(int windows_id, - const std::string& prefix, - int64_t time_ms, - T y) { - BWE_TEST_LOGGING_PLOT_WITH_NAME_AND_SSRC(windows_id, prefix, time_ms, - static_cast(y), flow_id_, - algorithm_name_); -} - -void MetricRecorder::UpdateTimeMs(int64_t time_ms) { - now_ms_ = std::max(now_ms_, time_ms); -} - -void MetricRecorder::UpdateThroughput(int64_t bitrate_kbps, - size_t payload_size) { - // Total throughput should be computed before updating the time. - PushThroughputBytes(payload_size, now_ms_); - plot_information_[kThroughput].Update(now_ms_, bitrate_kbps); -} - -void MetricRecorder::UpdateSendingEstimateKbps(int64_t bitrate_kbps) { - plot_information_[kSendingEstimate].Update(now_ms_, bitrate_kbps); -} - -void MetricRecorder::UpdateDelayMs(int64_t delay_ms) { - PushDelayMs(delay_ms, now_ms_); - plot_information_[kDelay].Update(now_ms_, delay_ms); -} - -void MetricRecorder::UpdateLoss(float loss_ratio) { - plot_information_[kLoss].Update(now_ms_, loss_ratio); -} - -void MetricRecorder::UpdateObjective() { - plot_information_[kObjective].Update(now_ms_, ObjectiveFunction()); -} - -uint32_t MetricRecorder::GetTotalAvailableKbps() { - if (link_share_ == nullptr) - return 0; - return link_share_->TotalAvailableKbps(); -} - -uint32_t MetricRecorder::GetAvailablePerFlowKbps() { - if (link_share_ == nullptr) - return 0; - return link_share_->AvailablePerFlowKbps(flow_id_); -} - -uint32_t MetricRecorder::GetSendingEstimateKbps() { - return static_cast(plot_information_[kSendingEstimate].value); -} - -void MetricRecorder::PushDelayMs(int64_t delay_ms, int64_t arrival_time_ms) { - if (ShouldRecord(arrival_time_ms)) { - sum_delays_ms_ += delay_ms; - sum_delays_square_ms2_ += delay_ms * delay_ms; - if (delay_histogram_ms_.find(delay_ms) == delay_histogram_ms_.end()) { - delay_histogram_ms_[delay_ms] = 0; - } - ++delay_histogram_ms_[delay_ms]; - } -} - -void MetricRecorder::UpdateEstimateError(int64_t new_value) { - int64_t lp_value = pow(static_cast(std::abs(new_value)), kP); - if (new_value < 0) { - sum_lp_weighted_estimate_error_[0] += lp_value; - } else { - sum_lp_weighted_estimate_error_[1] += lp_value; - } -} - -void MetricRecorder::PushThroughputBytes(size_t payload_size, - int64_t arrival_time_ms) { - if (ShouldRecord(arrival_time_ms)) { - ++num_packets_received_; - sum_throughput_bytes_ += payload_size; - - int64_t current_available_per_flow_kbps = - static_cast(GetAvailablePerFlowKbps()); - - int64_t current_bitrate_diff_kbps = - static_cast(GetSendingEstimateKbps()) - - current_available_per_flow_kbps; - - int64_t weighted_estimate_error = - (((current_bitrate_diff_kbps + last_unweighted_estimate_error_) * - (arrival_time_ms - plot_information_[kThroughput].time_ms)) / - 2); - - UpdateEstimateError(weighted_estimate_error); - - optimal_throughput_bits_ += - ((current_available_per_flow_kbps + - last_available_bitrate_per_flow_kbps_) * - (arrival_time_ms - plot_information_[kThroughput].time_ms)) / - 2; - - last_available_bitrate_per_flow_kbps_ = current_available_per_flow_kbps; - } -} - -bool MetricRecorder::ShouldRecord(int64_t arrival_time_ms) { - 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; - } - return true; - } else { - return false; - } -} - -void MetricRecorder::PlotThroughputHistogram( - const std::string& title, - const std::string& bwe_name, - size_t num_flows, - int64_t extra_offset_ms, - const std::string optimum_id) const { - double optimal_bitrate_per_flow_kbps = static_cast( - optimal_throughput_bits_ / RunDurationMs(extra_offset_ms)); - - double neg_error = Renormalize( - NormLp(sum_lp_weighted_estimate_error_[0], num_packets_received_, kP)); - double pos_error = Renormalize( - NormLp(sum_lp_weighted_estimate_error_[1], num_packets_received_, kP)); - - double average_bitrate_kbps = AverageBitrateKbps(extra_offset_ms); - - // 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 - neg_error - extra_error, - average_bitrate_kbps + pos_error + extra_error, "estimate_error", - optimal_bitrate_per_flow_kbps, optimum_title, flow_id_); - - BWE_TEST_LOGGING_LOG1( - "RESULTS >>> " + bwe_name + " Channel utilization : ", "%lf %%", - 100.0 * static_cast(average_bitrate_kbps) / - optimal_bitrate_per_flow_kbps); - - RTC_UNUSED(pos_error); - RTC_UNUSED(neg_error); - RTC_UNUSED(extra_error); - RTC_UNUSED(optimal_bitrate_per_flow_kbps); -} - -void MetricRecorder::PlotThroughputHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows, - int64_t extra_offset_ms) const { - PlotThroughputHistogram(title, bwe_name, num_flows, extra_offset_ms, ""); -} - -void MetricRecorder::PlotDelayHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows, - int64_t one_way_path_delay_ms) const { - double average_delay_ms = - static_cast(sum_delays_ms_) / num_packets_received_; - int64_t percentile_5_ms = NthDelayPercentile(5); - int64_t percentile_95_ms = NthDelayPercentile(95); - - BWE_TEST_LOGGING_LABEL(5, title, "average_delay_(ms)", num_flows); - BWE_TEST_LOGGING_ERRORBAR(5, bwe_name, average_delay_ms, percentile_5_ms, - percentile_95_ms, "5th and 95th percentiles", - flow_id_); - - // Log added latency, disregard baseline path delay. - BWE_TEST_LOGGING_LOG1("RESULTS >>> " + bwe_name + " Delay average : ", - "%lf ms", average_delay_ms - one_way_path_delay_ms); - BWE_TEST_LOGGING_LOG1( - "RESULTS >>> " + bwe_name + " Delay 5th percentile : ", "%" PRId64 " ms", - percentile_5_ms - one_way_path_delay_ms); - BWE_TEST_LOGGING_LOG1( - "RESULTS >>> " + bwe_name + " Delay 95th percentile : ", "%" PRId64 " ms", - percentile_95_ms - one_way_path_delay_ms); - - RTC_UNUSED(average_delay_ms); - RTC_UNUSED(percentile_5_ms); - RTC_UNUSED(percentile_95_ms); -} - -void MetricRecorder::PlotLossHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows, - float global_loss_ratio) const { - BWE_TEST_LOGGING_LABEL(6, title, "packet_loss_ratio_(%)", num_flows); - BWE_TEST_LOGGING_BAR(6, bwe_name, 100.0f * global_loss_ratio, flow_id_); - - BWE_TEST_LOGGING_LOG1("RESULTS >>> " + bwe_name + " Loss Ratio : ", "%f %%", - 100.0f * global_loss_ratio); -} - -void MetricRecorder::PlotObjectiveHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows) const { - BWE_TEST_LOGGING_LABEL(7, title, "objective_function", num_flows); - BWE_TEST_LOGGING_BAR(7, bwe_name, ObjectiveFunction(), flow_id_); -} - -void MetricRecorder::PlotZero() { - for (int i = kThroughput; i <= kLoss; ++i) { - if (plot_information_[i].plot) { - rtc::StringBuilder prefix; - // TODO(terelius): Since this does not use the BWE_TEST_LOGGING macros, - // it hasn't been kept up to date with the plot format. Remove or fix? - prefix << "Receiver_" << flow_id_ << "_" + plot_information_[i].prefix; - PlotLine(i, prefix.str(), now_ms_, 0); - plot_information_[i].last_plot_ms = now_ms_; - } - } -} - -void MetricRecorder::PauseFlow() { - PlotZero(); - link_share_->PauseFlow(flow_id_); -} - -void MetricRecorder::ResumeFlow(int64_t paused_time_ms) { - UpdateTimeMs(now_ms_ + paused_time_ms); - PlotZero(); - link_share_->ResumeFlow(flow_id_); -} - -double MetricRecorder::AverageBitrateKbps(int64_t extra_offset_ms) const { - int64_t duration_ms = RunDurationMs(extra_offset_ms); - if (duration_ms == 0) - return 0.0; - return static_cast(8 * sum_throughput_bytes_ / duration_ms); -} - -int64_t MetricRecorder::RunDurationMs(int64_t extra_offset_ms) const { - return now_ms_ - start_computing_metrics_ms_ - extra_offset_ms; -} - -double MetricRecorder::DelayStdDev() const { - if (num_packets_received_ == 0) { - return 0.0; - } - double mean = static_cast(sum_delays_ms_) / num_packets_received_; - double mean2 = - static_cast(sum_delays_square_ms2_) / num_packets_received_; - return sqrt(mean2 - pow(mean, 2.0)); -} - -// Since delay values are bounded in a subset of [0, 5000] ms, -// this function's execution time is O(1), independend of num_packets_received_. -int64_t MetricRecorder::NthDelayPercentile(int n) const { - if (num_packets_received_ == 0) { - return 0; - } - size_t num_packets_remaining = (n * num_packets_received_) / 100; - for (auto hist : delay_histogram_ms_) { - if (num_packets_remaining <= hist.second) - return static_cast(hist.first); - num_packets_remaining -= hist.second; - } - - assert(false); - return -1; -} - -// The weighted_estimate_error_ was weighted based on time windows. -// This function scales back the result before plotting. -double MetricRecorder::Renormalize(double x) const { - return (x * num_packets_received_) / now_ms_; -} - -inline double U(int64_t x, double alpha) { - if (alpha == 1.0) { - return log(static_cast(x)); - } - return pow(static_cast(x), 1.0 - alpha) / (1.0 - alpha); -} - -inline double U(size_t x, double alpha) { - return U(static_cast(x), alpha); -} - -// TODO(magalhaesc): Update ObjectiveFunction. -double MetricRecorder::ObjectiveFunction() const { - 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; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/metric_recorder.h b/modules/remote_bitrate_estimator/test/metric_recorder.h deleted file mode 100644 index d0ba4e3163..0000000000 --- a/modules/remote_bitrate_estimator/test/metric_recorder.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_ - -#include -#include -#include -#include - -#include "rtc_base/gtest_prod_util.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -class ChokeFilter; -class PacketSender; - -class LinkShare { - public: - explicit LinkShare(ChokeFilter* choke_filter); - ~LinkShare(); - - void PauseFlow(int flow_id); // Increases available capacity per flow. - void ResumeFlow(int flow_id); // Decreases available capacity per flow. - - uint32_t TotalAvailableKbps(); - // If the given flow is paused, its output is zero. - uint32_t AvailablePerFlowKbps(int flow_id); - - private: - ChokeFilter* choke_filter_; - std::set running_flows_; -}; - -struct PlotInformation { - PlotInformation() - : prefix(), - last_plot_ms(0), - time_ms(0), - value(0.0), - plot_interval_ms(0) {} - template - void Update(int64_t now_ms, T new_value) { - time_ms = now_ms; - value = static_cast(new_value); - } - std::string prefix; - bool plot; - int64_t last_plot_ms; - int64_t time_ms; - double value; - int64_t plot_interval_ms; -}; - -class MetricRecorder { - public: - MetricRecorder(const std::string algorithm_name, - int flow_id, - PacketSender* packet_sender, - LinkShare* link_share); - ~MetricRecorder(); - - void SetPlotInformation(const std::vector& prefixes, - bool plot_delay, - bool plot_loss); - - template - void PlotLine(int windows_id, - const std::string& prefix, - int64_t time_ms, - T y); - - void PlotDynamics(int metric); - void PlotAllDynamics(); - - void UpdateTimeMs(int64_t time_ms); - void UpdateThroughput(int64_t bitrate_kbps, size_t payload_size); - void UpdateSendingEstimateKbps(int64_t bitrate_kbps); - void UpdateDelayMs(int64_t delay_ms); - void UpdateLoss(float loss_ratio); - void UpdateObjective(); - - void PlotThroughputHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows, - int64_t extra_offset_ms, - const std::string optimum_id) const; - - void PlotThroughputHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows, - int64_t extra_offset_ms) const; - - void PlotDelayHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows, - int64_t one_way_path_delay_ms) const; - - void PlotLossHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows, - float global_loss_ratio) const; - - void PlotObjectiveHistogram(const std::string& title, - const std::string& bwe_name, - size_t num_flows) const; - - void set_start_computing_metrics_ms(int64_t start_computing_metrics_ms) { - start_computing_metrics_ms_ = start_computing_metrics_ms; - } - - void set_plot_available_capacity(bool plot) { - plot_information_[kTotalAvailable].plot = plot; - } - - void PauseFlow(); // Plot zero. - void ResumeFlow(int64_t paused_time_ms); // Plot zero. - void PlotZero(); - - private: - FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, NoPackets); - FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, RegularPackets); - FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, VariableDelayPackets); - - uint32_t GetTotalAvailableKbps(); - uint32_t GetAvailablePerFlowKbps(); - uint32_t GetSendingEstimateKbps(); - double ObjectiveFunction() const; - - double Renormalize(double x) const; - bool ShouldRecord(int64_t arrival_time_ms); - - void PushDelayMs(int64_t delay_ms, int64_t arrival_time_ms); - void PushThroughputBytes(size_t throughput_bytes, int64_t arrival_time_ms); - - void UpdateEstimateError(int64_t new_value); - double DelayStdDev() const; - int64_t NthDelayPercentile(int n) const; - double AverageBitrateKbps(int64_t extra_offset_ms) const; - int64_t RunDurationMs(int64_t extra_offset_ms) const; - - enum Metrics { - kThroughput = 0, - kSendingEstimate, - kDelay, - kLoss, - kObjective, - kTotalAvailable, - kAvailablePerFlow, - kNumMetrics - }; - - std::string algorithm_name_; - int flow_id_; - LinkShare* link_share_; - - int64_t now_ms_; - - PlotInformation plot_information_[kNumMetrics]; - - int64_t sum_delays_ms_; - // delay_histogram_ms_[i] counts how many packets have delay = i ms. - std::map delay_histogram_ms_; - int64_t sum_delays_square_ms2_; // Used to compute standard deviation. - size_t sum_throughput_bytes_; - // ((Receiving rate - available bitrate per flow) * time window)^p. - // 0 for negative values, 1 for positive values. - int64_t sum_lp_weighted_estimate_error_[2]; - int64_t last_unweighted_estimate_error_; - int64_t optimal_throughput_bits_; - int64_t last_available_bitrate_per_flow_kbps_; - int64_t start_computing_metrics_ms_; - bool started_computing_metrics_; - size_t num_packets_received_; -}; - -} // namespace bwe -} // namespace testing -} // namespace webrtc -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_ diff --git a/modules/remote_bitrate_estimator/test/metric_recorder_unittest.cc b/modules/remote_bitrate_estimator/test/metric_recorder_unittest.cc deleted file mode 100644 index 670b9bc00b..0000000000 --- a/modules/remote_bitrate_estimator/test/metric_recorder_unittest.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/metric_recorder.h" - -#include -#include -#include -#include -#include - -#include "test/gtest.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -class MetricRecorderTest : public ::testing::Test { - public: - MetricRecorderTest() : metric_recorder_("Test", 0, nullptr, nullptr) {} - - ~MetricRecorderTest() {} - - protected: - MetricRecorder metric_recorder_; -}; - -TEST_F(MetricRecorderTest, NoPackets) { - EXPECT_EQ(metric_recorder_.AverageBitrateKbps(0), 0); - EXPECT_EQ(metric_recorder_.DelayStdDev(), 0.0); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(0), 0); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(5), 0); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(95), 0); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(100), 0); -} - -TEST_F(MetricRecorderTest, RegularPackets) { - const size_t kPayloadSizeBytes = 1200; - const int64_t kDelayMs = 20; - const int64_t kInterpacketGapMs = 5; - const int kNumPackets = 1000; - - for (int i = 0; i < kNumPackets; ++i) { - int64_t arrival_time_ms = kInterpacketGapMs * i + kDelayMs; - metric_recorder_.UpdateTimeMs(arrival_time_ms); - metric_recorder_.PushDelayMs(kDelayMs, arrival_time_ms); - metric_recorder_.PushThroughputBytes(kPayloadSizeBytes, arrival_time_ms); - } - - EXPECT_NEAR( - metric_recorder_.AverageBitrateKbps(0), - static_cast(kPayloadSizeBytes * 8) / (kInterpacketGapMs), 10); - - EXPECT_EQ(metric_recorder_.DelayStdDev(), 0.0); - - EXPECT_EQ(metric_recorder_.NthDelayPercentile(0), kDelayMs); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(5), kDelayMs); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(95), kDelayMs); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(100), kDelayMs); -} - -TEST_F(MetricRecorderTest, VariableDelayPackets) { - const size_t kPayloadSizeBytes = 1200; - const int64_t kInterpacketGapMs = 2000; - const int kNumPackets = 1000; - - std::vector delays_ms; - delays_ms.reserve(kNumPackets); - for (int i = 0; i < kNumPackets; ++i) { - delays_ms.push_back(static_cast(i + 1)); - } - // Order of packets should not matter here. - std::shuffle(delays_ms.begin(), delays_ms.end(), - std::mt19937(std::random_device()())); - - int first_received_ms = delays_ms[0]; - int64_t last_received_ms = 0; - for (int i = 0; i < kNumPackets; ++i) { - int64_t arrival_time_ms = kInterpacketGapMs * i + delays_ms[i]; - last_received_ms = std::max(last_received_ms, arrival_time_ms); - metric_recorder_.UpdateTimeMs(arrival_time_ms); - metric_recorder_.PushDelayMs(delays_ms[i], arrival_time_ms); - metric_recorder_.PushThroughputBytes(kPayloadSizeBytes, arrival_time_ms); - } - - size_t received_bits = kPayloadSizeBytes * 8 * kNumPackets; - EXPECT_NEAR(metric_recorder_.AverageBitrateKbps(0), - static_cast(received_bits) / - ((last_received_ms - first_received_ms)), - 10); - - double expected_x = (kNumPackets + 1) / 2.0; - double expected_x2 = ((kNumPackets + 1) * (2 * kNumPackets + 1)) / 6.0; - double var = expected_x2 - pow(expected_x, 2.0); - EXPECT_NEAR(metric_recorder_.DelayStdDev(), sqrt(var), kNumPackets / 1000.0); - - EXPECT_EQ(metric_recorder_.NthDelayPercentile(0), 1); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(5), (5 * kNumPackets) / 100); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(95), (95 * kNumPackets) / 100); - EXPECT_EQ(metric_recorder_.NthDelayPercentile(100), kNumPackets); -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/packet.cc b/modules/remote_bitrate_estimator/test/packet.cc deleted file mode 100644 index d318f09b45..0000000000 --- a/modules/remote_bitrate_estimator/test/packet.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 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/remote_bitrate_estimator/test/packet.h" - -#include -#include - -namespace webrtc { -namespace testing { -namespace bwe { - -Packet::Packet() - : flow_id_(0), - creation_time_us_(-1), - send_time_us_(-1), - sender_timestamp_us_(-1), - payload_size_(0) {} - -Packet::Packet(int flow_id, int64_t send_time_us, size_t payload_size) - : flow_id_(flow_id), - creation_time_us_(send_time_us), - send_time_us_(send_time_us), - sender_timestamp_us_(send_time_us), - payload_size_(payload_size) {} - -Packet::~Packet() {} - -bool Packet::operator<(const Packet& rhs) const { - return send_time_us_ < rhs.send_time_us_; -} - -void Packet::set_send_time_us(int64_t send_time_us) { - assert(send_time_us >= 0); - send_time_us_ = send_time_us; -} - -int Packet::flow_id() const { - return flow_id_; -} - -int64_t Packet::send_time_us() const { - return send_time_us_; -} - -int64_t Packet::sender_timestamp_us() const { - return sender_timestamp_us_; -} - -size_t Packet::payload_size() const { - return payload_size_; -} - -void Packet::set_sender_timestamp_us(int64_t sender_timestamp_us) { - sender_timestamp_us_ = sender_timestamp_us; -} - -int64_t Packet::creation_time_ms() const { - return (creation_time_us_ + 500) / 1000; -} - -int64_t Packet::sender_timestamp_ms() const { - return (sender_timestamp_us_ + 500) / 1000; -} - -int64_t Packet::send_time_ms() const { - return (send_time_us_ + 500) / 1000; -} - -Packet::Type MediaPacket::GetPacketType() const { - return kMedia; -} - -Packet::Type FeedbackPacket::GetPacketType() const { - return kFeedback; -} - -BbrBweFeedback::~BbrBweFeedback() = default; - -SendSideBweFeedback::~SendSideBweFeedback() = default; - -TcpFeedback::TcpFeedback(int flow_id, - int64_t send_time_us, - int64_t latest_send_time_ms, - const std::vector& acked_packets) - : FeedbackPacket(flow_id, send_time_us, latest_send_time_ms), - acked_packets_(acked_packets) {} - -TcpFeedback::~TcpFeedback() = default; - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/packet.h b/modules/remote_bitrate_estimator/test/packet.h deleted file mode 100644 index 5a8c6467f3..0000000000 --- a/modules/remote_bitrate_estimator/test/packet.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_H_ - -#include -#include -#include -#include -#include - -#include "api/rtp_headers.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "modules/rtp_rtcp/source/rtp_packet_received.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -class Packet { - public: - enum Type { kMedia, kFeedback }; - - Packet(); - Packet(int flow_id, int64_t send_time_us, size_t payload_size); - virtual ~Packet(); - - virtual bool operator<(const Packet& rhs) const; - - virtual int flow_id() const; - virtual void set_send_time_us(int64_t send_time_us); - virtual int64_t send_time_us() const; - virtual int64_t sender_timestamp_us() const; - virtual size_t payload_size() const; - virtual Packet::Type GetPacketType() const = 0; - virtual void set_sender_timestamp_us(int64_t sender_timestamp_us); - virtual int64_t creation_time_ms() const; - virtual int64_t sender_timestamp_ms() const; - virtual int64_t send_time_ms() const; - - protected: - int flow_id_; - int64_t creation_time_us_; // Time when the packet was created. - int64_t send_time_us_; // Time the packet left last processor touching it. - int64_t sender_timestamp_us_; // Time the packet left the Sender. - size_t payload_size_; // Size of the (non-existent, simulated) payload. -}; - -class MediaPacket : public Packet { - public: - MediaPacket(); - MediaPacket(int flow_id, - int64_t send_time_us, - size_t payload_size, - uint16_t sequence_number); - MediaPacket(int flow_id, - int64_t send_time_us, - size_t payload_size, - const RTPHeader& header); - MediaPacket(int64_t send_time_us, uint16_t sequence_number); - - ~MediaPacket() override {} - - int64_t GetAbsSendTimeInMs() const { - int64_t timestamp = header_.extension.absoluteSendTime - << kAbsSendTimeInterArrivalUpshift; - return 1000.0 * timestamp / static_cast(1 << kInterArrivalShift); - } - void SetAbsSendTimeMs(int64_t abs_send_time_ms); - const RTPHeader& header() const { return header_; } - Packet::Type GetPacketType() const override; - uint16_t sequence_number() const { return header_.sequenceNumber; } - RtpPacketReceived GetRtpPacket() const; - - private: - static const int kAbsSendTimeFraction = 18; - static const int kAbsSendTimeInterArrivalUpshift = 8; - static const int kInterArrivalShift = - kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; - - RTPHeader header_; -}; - -class FeedbackPacket : public Packet { - public: - FeedbackPacket(int flow_id, - int64_t this_send_time_us, - int64_t latest_send_time_ms) - : Packet(flow_id, this_send_time_us, 0), - latest_send_time_ms_(latest_send_time_ms) {} - ~FeedbackPacket() override {} - - Packet::Type GetPacketType() const override; - int64_t latest_send_time_ms() const { return latest_send_time_ms_; } - - private: - int64_t latest_send_time_ms_; // Time stamp for the latest sent FbPacket. -}; - -class BbrBweFeedback : public FeedbackPacket { - public: - BbrBweFeedback(int flow_id, - int64_t send_time_us, - int64_t latest_send_time_ms, - const std::vector& packet_feedback_vector); - ~BbrBweFeedback() override; - - const std::vector& packet_feedback_vector() const { - return packet_feedback_vector_; - } - - private: - const std::vector packet_feedback_vector_; -}; - -class RembFeedback : public FeedbackPacket { - public: - RembFeedback(int flow_id, - int64_t send_time_us, - int64_t latest_send_time_ms, - uint32_t estimated_bps, - RTCPReportBlock report_block); - ~RembFeedback() override {} - - uint32_t estimated_bps() const { return estimated_bps_; } - RTCPReportBlock report_block() const { return report_block_; } - - private: - const uint32_t estimated_bps_; - const RTCPReportBlock report_block_; -}; - -class SendSideBweFeedback : public FeedbackPacket { - public: - typedef std::map ArrivalTimesMap; - SendSideBweFeedback( - int flow_id, - int64_t send_time_us, - int64_t latest_send_time_ms, - const std::vector& packet_feedback_vector); - ~SendSideBweFeedback() override; - - const std::vector& packet_feedback_vector() const { - return packet_feedback_vector_; - } - - private: - const std::vector packet_feedback_vector_; -}; - -class NadaFeedback : public FeedbackPacket { - public: - NadaFeedback(int flow_id, - int64_t this_send_time_us, - int64_t exp_smoothed_delay_ms, - int64_t est_queuing_delay_signal_ms, - int64_t congestion_signal, - float derivative, - float receiving_rate, - int64_t latest_send_time_ms) - : FeedbackPacket(flow_id, this_send_time_us, latest_send_time_ms), - exp_smoothed_delay_ms_(exp_smoothed_delay_ms), - est_queuing_delay_signal_ms_(est_queuing_delay_signal_ms), - congestion_signal_(congestion_signal), - derivative_(derivative), - receiving_rate_(receiving_rate) {} - ~NadaFeedback() override {} - - int64_t exp_smoothed_delay_ms() const { return exp_smoothed_delay_ms_; } - int64_t est_queuing_delay_signal_ms() const { - return est_queuing_delay_signal_ms_; - } - int64_t congestion_signal() const { return congestion_signal_; } - float derivative() const { return derivative_; } - float receiving_rate() const { return receiving_rate_; } - - private: - int64_t exp_smoothed_delay_ms_; // Referred as d_hat_n. - int64_t est_queuing_delay_signal_ms_; // Referred as d_tilde_n. - int64_t congestion_signal_; // Referred as x_n. - float derivative_; // Referred as x'_n. - float receiving_rate_; // Referred as R_r. -}; - -class TcpFeedback : public FeedbackPacket { - public: - TcpFeedback(int flow_id, - int64_t send_time_us, - int64_t latest_send_time_ms, - const std::vector& acked_packets); - ~TcpFeedback() override; - - const std::vector& acked_packets() const { return acked_packets_; } - - private: - const std::vector acked_packets_; -}; - -typedef std::list Packets; -typedef std::list::iterator PacketsIt; -typedef std::list::const_iterator PacketsConstIt; - -} // namespace bwe -} // namespace testing -} // namespace webrtc -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_H_ diff --git a/modules/remote_bitrate_estimator/test/packet_receiver.cc b/modules/remote_bitrate_estimator/test/packet_receiver.cc deleted file mode 100644 index abd1b5f78a..0000000000 --- a/modules/remote_bitrate_estimator/test/packet_receiver.cc +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/packet_receiver.h" - -#include -#include - -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -PacketReceiver::PacketReceiver(PacketProcessorListener* listener, - int flow_id, - BandwidthEstimatorType bwe_type, - bool plot_delay, - bool plot_bwe, - MetricRecorder* metric_recorder) - : PacketProcessor(listener, flow_id, kReceiver), - bwe_receiver_(CreateBweReceiver(bwe_type, flow_id, plot_bwe)), - metric_recorder_(metric_recorder), - plot_delay_(plot_delay), - last_delay_plot_ms_(0), - // #2 aligns the plot with the right axis. - delay_prefix_("Delay_ms#2"), - bwe_type_(bwe_type) { - if (metric_recorder_ != nullptr) { - // Setup the prefix std::strings used when logging. - std::vector prefixes; - - // Metric recorder plots them in separated figures, - // alignment will take place with the #1 left axis. - prefixes.push_back("MetricRecorderThroughput_kbps#1"); - prefixes.push_back("Sending_Estimate_kbps#1"); - prefixes.push_back("Delay_ms_#1"); - prefixes.push_back("Packet_Loss_#1"); - prefixes.push_back("Objective_function_#1"); - - // Plot Total/PerFlow Available capacity together with throughputs. - prefixes.push_back("Capacity_kbps#1"); // Total Available. - prefixes.push_back("PerFlowCapacity_kbps#1"); // Available per flow. - - bool plot_loss = plot_delay; // Plot loss if delay is plotted. - metric_recorder_->SetPlotInformation(prefixes, plot_delay, plot_loss); - } -} - -PacketReceiver::PacketReceiver(PacketProcessorListener* listener, - int flow_id, - BandwidthEstimatorType bwe_type, - bool plot_delay, - bool plot_bwe) - : PacketReceiver(listener, - flow_id, - bwe_type, - plot_delay, - plot_bwe, - nullptr) {} - -PacketReceiver::~PacketReceiver() {} - -void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) { - Packets feedback; - for (auto it = in_out->begin(); it != in_out->end();) { - // PacketReceivers are only associated with a single stream, and therefore - // should only process a single flow id. - // TODO(holmer): Break this out into a Demuxer which implements both - // PacketProcessorListener and PacketProcessor. - BWE_TEST_LOGGING_CONTEXT("Receiver"); - if ((*it)->GetPacketType() == Packet::kMedia && - (*it)->flow_id() == *flow_ids().begin()) { - BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin()); - const MediaPacket* media_packet = static_cast(*it); - // We're treating the send time (from previous filter) as the arrival - // time once packet reaches the estimator. - int64_t arrival_time_ms = media_packet->send_time_ms(); - int64_t send_time_ms = media_packet->creation_time_ms(); - delay_stats_.Push(arrival_time_ms - send_time_ms); - - if (metric_recorder_ != nullptr) { - metric_recorder_->UpdateTimeMs(arrival_time_ms); - UpdateMetrics(arrival_time_ms, send_time_ms, - media_packet->payload_size()); - metric_recorder_->PlotAllDynamics(); - } else if (plot_delay_) { - PlotDelay(arrival_time_ms, send_time_ms); - } - - bwe_receiver_->ReceivePacket(arrival_time_ms, *media_packet); - FeedbackPacket* fb = bwe_receiver_->GetFeedback(arrival_time_ms); - if (fb) - feedback.push_back(fb); - delete media_packet; - it = in_out->erase(it); - } else { - ++it; - } - } - // Insert feedback packets to be sent back to the sender. - in_out->merge(feedback, DereferencingComparator); -} - -void PacketReceiver::UpdateMetrics(int64_t arrival_time_ms, - int64_t send_time_ms, - size_t payload_size) { - metric_recorder_->UpdateThroughput(bwe_receiver_->RecentKbps(), payload_size); - metric_recorder_->UpdateDelayMs(arrival_time_ms - send_time_ms); - metric_recorder_->UpdateLoss(bwe_receiver_->RecentPacketLossRatio()); - metric_recorder_->UpdateObjective(); -} - -void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) { - const int64_t kDelayPlotIntervalMs = 100; - if (arrival_time_ms >= last_delay_plot_ms_ + kDelayPlotIntervalMs) { - BWE_TEST_LOGGING_PLOT_WITH_NAME(0, delay_prefix_, arrival_time_ms, - arrival_time_ms - send_time_ms, - bwe_names[bwe_type_]); - last_delay_plot_ms_ = arrival_time_ms; - } -} - -float PacketReceiver::GlobalPacketLoss() { - return bwe_receiver_->GlobalReceiverPacketLossRatio(); -} - -Stats PacketReceiver::GetDelayStats() const { - return delay_stats_; -} -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/packet_receiver.h b/modules/remote_bitrate_estimator/test/packet_receiver.h deleted file mode 100644 index 848119e6d5..0000000000 --- a/modules/remote_bitrate_estimator/test/packet_receiver.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_RECEIVER_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_RECEIVER_H_ - -#include -#include -#include -#include - -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "modules/remote_bitrate_estimator/test/metric_recorder.h" -#include "modules/remote_bitrate_estimator/test/packet.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -class PacketReceiver : public PacketProcessor { - public: - PacketReceiver(PacketProcessorListener* listener, - int flow_id, - BandwidthEstimatorType bwe_type, - bool plot_delay, - bool plot_bwe); - PacketReceiver(PacketProcessorListener* listener, - int flow_id, - BandwidthEstimatorType bwe_type, - bool plot_delay, - bool plot_bwe, - MetricRecorder* metric_recorder); - ~PacketReceiver() override; - - // Implements PacketProcessor. - void RunFor(int64_t time_ms, Packets* in_out) override; - - void LogStats(); - - Stats GetDelayStats() const; - - float GlobalPacketLoss(); - - protected: - void UpdateMetrics(int64_t arrival_time_ms, - int64_t send_time_ms, - size_t payload_size); - - Stats delay_stats_; - std::unique_ptr bwe_receiver_; - - private: - void PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms); - MetricRecorder* metric_recorder_; - bool plot_delay_; // Used in case there isn't a metric recorder. - int64_t last_delay_plot_ms_; - std::string delay_prefix_; - BandwidthEstimatorType bwe_type_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PacketReceiver); -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_RECEIVER_H_ diff --git a/modules/remote_bitrate_estimator/test/packet_sender.cc b/modules/remote_bitrate_estimator/test/packet_sender.cc deleted file mode 100644 index f7cb716cd6..0000000000 --- a/modules/remote_bitrate_estimator/test/packet_sender.cc +++ /dev/null @@ -1,533 +0,0 @@ -/* - * 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 "modules/remote_bitrate_estimator/test/packet_sender.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "modules/include/module_common_types_public.h" -#include "modules/pacing/pacer.h" -#include "modules/remote_bitrate_estimator/test/bbr_paced_sender.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" -#include "modules/remote_bitrate_estimator/test/metric_recorder.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "rtc_base/checks.h" - -namespace webrtc { -namespace testing { -namespace bwe { -namespace { -const float kPaceMultiplier = 2.5f; -} - -uint32_t PacketSender::TargetBitrateKbps() { - return 0; -} - -void PacketSender::Pause() { - running_ = false; - if (metric_recorder_ != nullptr) { - metric_recorder_->PauseFlow(); - } -} - -void PacketSender::Resume(int64_t paused_time_ms) { - running_ = true; - if (metric_recorder_ != nullptr) { - metric_recorder_->ResumeFlow(paused_time_ms); - } -} - -void PacketSender::set_metric_recorder(MetricRecorder* metric_recorder) { - metric_recorder_ = metric_recorder; -} - -void PacketSender::RecordBitrate() { - if (metric_recorder_ != nullptr) { - BWE_TEST_LOGGING_CONTEXT("Sender"); - BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin()); - metric_recorder_->UpdateTimeMs(clock_.TimeInMilliseconds()); - metric_recorder_->UpdateSendingEstimateKbps(TargetBitrateKbps()); - } -} - -std::list GetFeedbackPackets(Packets* in_out, - int64_t end_time_ms, - int flow_id) { - std::list fb_packets; - for (auto it = in_out->begin(); it != in_out->end();) { - if ((*it)->send_time_us() > 1000 * end_time_ms) - break; - if ((*it)->GetPacketType() == Packet::kFeedback && - flow_id == (*it)->flow_id()) { - fb_packets.push_back(static_cast(*it)); - it = in_out->erase(it); - } else { - ++it; - } - } - return fb_packets; -} - -VideoSender::VideoSender(PacketProcessorListener* listener, - VideoSource* source, - BandwidthEstimatorType estimator_type) - : PacketSender(listener, source->flow_id()), - source_(source), - bwe_(CreateBweSender(estimator_type, - source_->bits_per_second() / 1000, - this, - &clock_)), - previous_sending_bitrate_(0) { - modules_.push_back(bwe_.get()); -} - -VideoSender::~VideoSender() {} - -void VideoSender::Pause() { - previous_sending_bitrate_ = TargetBitrateKbps(); - PacketSender::Pause(); -} - -void VideoSender::Resume(int64_t paused_time_ms) { - source_->SetBitrateBps(previous_sending_bitrate_); - PacketSender::Resume(paused_time_ms); -} - -void VideoSender::RunFor(int64_t time_ms, Packets* in_out) { - std::list feedbacks = GetFeedbackPackets( - in_out, clock_.TimeInMilliseconds() + time_ms, source_->flow_id()); - ProcessFeedbackAndGeneratePackets(time_ms, &feedbacks, in_out); -} - -VideoSource* VideoSender::source() const { - return source_; -} - -void VideoSender::ProcessFeedbackAndGeneratePackets( - int64_t time_ms, - std::list* feedbacks, - Packets* packets) { - do { - // Make sure to at least run Process() below every 100 ms. - int64_t time_to_run_ms = std::min(time_ms, 100); - if (!feedbacks->empty()) { - int64_t time_until_feedback_ms = - feedbacks->front()->send_time_ms() - clock_.TimeInMilliseconds(); - time_to_run_ms = - std::max(std::min(time_ms, time_until_feedback_ms), 0); - } - - if (!running_) { - source_->SetBitrateBps(0); - } - - Packets generated; - source_->RunFor(time_to_run_ms, &generated); - bwe_->OnPacketsSent(generated); - packets->merge(generated, DereferencingComparator); - - clock_.AdvanceTimeMilliseconds(time_to_run_ms); - - if (!feedbacks->empty()) { - bwe_->GiveFeedback(*feedbacks->front()); - delete feedbacks->front(); - feedbacks->pop_front(); - } - - bwe_->Process(); - - time_ms -= time_to_run_ms; - } while (time_ms > 0); - assert(feedbacks->empty()); -} - -int VideoSender::GetFeedbackIntervalMs() const { - return bwe_->GetFeedbackIntervalMs(); -} - -void VideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, - uint8_t fraction_lost, - int64_t rtt) { - source_->SetBitrateBps(target_bitrate_bps); - RecordBitrate(); -} - -uint32_t VideoSender::TargetBitrateKbps() { - return (source_->bits_per_second() + 500) / 1000; -} - -PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener, - VideoSource* source, - BandwidthEstimatorType estimator) - : VideoSender(listener, source, estimator), - pacer_( - estimator == kBbrEstimator - ? static_cast(new BbrPacedSender(&clock_, this, nullptr)) - : static_cast(new PacedSender(&clock_, this, nullptr))) { - modules_.push_back(pacer_.get()); - pacer_->SetPacingRates(source->bits_per_second() * kPaceMultiplier, 0); -} - -PacedVideoSender::~PacedVideoSender() { - for (Packet* packet : pacer_queue_) - delete packet; - for (Packet* packet : queue_) - delete packet; -} - -void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) { - int64_t end_time_ms = clock_.TimeInMilliseconds() + time_ms; - // Run process periodically to allow the packets to be paced out. - std::list feedbacks = - GetFeedbackPackets(in_out, end_time_ms, source_->flow_id()); - int64_t last_run_time_ms = -1; - BWE_TEST_LOGGING_CONTEXT("Sender"); - BWE_TEST_LOGGING_CONTEXT(source_->flow_id()); - do { - int64_t time_until_process_ms = TimeUntilNextProcess(modules_); - int64_t time_until_feedback_ms = time_ms; - if (!feedbacks.empty()) - time_until_feedback_ms = std::max( - feedbacks.front()->send_time_ms() - clock_.TimeInMilliseconds(), 0); - - int64_t time_until_next_event_ms = - std::min(time_until_feedback_ms, time_until_process_ms); - - time_until_next_event_ms = - std::min(source_->GetTimeUntilNextFrameMs(), time_until_next_event_ms); - - // Never run for longer than we have been asked for. - if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms) - time_until_next_event_ms = end_time_ms - clock_.TimeInMilliseconds(); - - // Make sure we don't get stuck if an event doesn't trigger. This typically - // happens if the prober wants to probe, but there's no packet to send. - if (time_until_next_event_ms == 0 && last_run_time_ms == 0) - time_until_next_event_ms = 1; - last_run_time_ms = time_until_next_event_ms; - - Packets generated_packets; - source_->RunFor(time_until_next_event_ms, &generated_packets); - if (!generated_packets.empty()) { - for (Packet* packet : generated_packets) { - MediaPacket* media_packet = static_cast(packet); - pacer_->InsertPacket( - PacedSender::kNormalPriority, media_packet->header().ssrc, - media_packet->header().sequenceNumber, media_packet->send_time_ms(), - media_packet->payload_size(), false); - pacer_queue_size_in_bytes_ += media_packet->payload_size(); - pacer_queue_.push_back(packet); - assert(pacer_queue_.size() < 10000); - } - } - - clock_.AdvanceTimeMilliseconds(time_until_next_event_ms); - - if (time_until_next_event_ms == time_until_feedback_ms) { - if (!feedbacks.empty()) { - bwe_->GiveFeedback(*feedbacks.front()); - delete feedbacks.front(); - feedbacks.pop_front(); - } - bwe_->Process(); - } - - if (time_until_next_event_ms == time_until_process_ms) { - CallProcess(modules_); - } - } while (clock_.TimeInMilliseconds() < end_time_ms); - QueuePackets(in_out, end_time_ms * 1000); -} - -int64_t PacedVideoSender::TimeUntilNextProcess( - const std::list& modules) { - int64_t time_until_next_process_ms = 10; - for (Module* module : modules) { - int64_t next_process_ms = module->TimeUntilNextProcess(); - if (next_process_ms < time_until_next_process_ms) - time_until_next_process_ms = next_process_ms; - } - if (time_until_next_process_ms < 0) - time_until_next_process_ms = 0; - return time_until_next_process_ms; -} - -void PacedVideoSender::CallProcess(const std::list& modules) { - for (Module* module : modules) { - if (module->TimeUntilNextProcess() <= 0) { - module->Process(); - } - } -} - -void PacedVideoSender::QueuePackets(Packets* batch, - int64_t end_of_batch_time_us) { - queue_.merge(*batch, DereferencingComparator); - if (queue_.empty()) { - return; - } - Packets::iterator it = queue_.begin(); - for (; it != queue_.end(); ++it) { - if ((*it)->send_time_us() > end_of_batch_time_us) { - break; - } - } - Packets to_transfer; - to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it); - bwe_->OnPacketsSent(to_transfer); - batch->merge(to_transfer, DereferencingComparator); -} - -RtpPacketSendResult PacedVideoSender::TimeToSendPacket( - uint32_t ssrc, - uint16_t sequence_number, - int64_t capture_time_ms, - bool retransmission, - const PacedPacketInfo& pacing_info) { - for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end(); - ++it) { - MediaPacket* media_packet = static_cast(*it); - if (media_packet->header().sequenceNumber == sequence_number) { - int64_t pace_out_time_ms = clock_.TimeInMilliseconds(); - - // Make sure a packet is never paced out earlier than when it was put into - // the pacer. - RTC_CHECK_GE(pace_out_time_ms, media_packet->send_time_ms()); - media_packet->SetAbsSendTimeMs(pace_out_time_ms); - media_packet->set_send_time_us(1000 * pace_out_time_ms); - media_packet->set_sender_timestamp_us(1000 * pace_out_time_ms); - queue_.push_back(media_packet); - pacer_queue_size_in_bytes_ -= media_packet->payload_size(); - pacer_queue_.erase(it); - return RtpPacketSendResult::kSuccess; - } - } - return RtpPacketSendResult::kTransportUnavailable; -} - -size_t PacedVideoSender::TimeToSendPadding(size_t bytes, - const PacedPacketInfo& pacing_info) { - return 0; -} - -void PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, - uint8_t fraction_lost, - int64_t rtt) { - VideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt); - pacer_->SetPacingRates(target_bitrate_bps * kPaceMultiplier, 0); -} - -void PacedVideoSender::OnNetworkChanged(uint32_t bitrate_for_encoder_bps, - uint32_t bitrate_for_pacer_bps, - bool in_probe_rtt, - int64_t target_set_time, - uint64_t congestion_window) { - VideoSender::OnNetworkChanged(bitrate_for_encoder_bps, 0u, 0u); - pacer_->SetEstimatedBitrateAndCongestionWindow( - bitrate_for_pacer_bps, in_probe_rtt, congestion_window); -} - -size_t PacedVideoSender::pacer_queue_size_in_bytes() { - return pacer_queue_size_in_bytes_; -} - -void PacedVideoSender::OnBytesAcked(size_t bytes) { - pacer_->OnBytesAcked(bytes); -} - -const int kNoLimit = std::numeric_limits::max(); -const int kPacketSizeBytes = 1200; - -TcpSender::TcpSender(PacketProcessorListener* listener, - int flow_id, - int64_t offset_ms) - : TcpSender(listener, flow_id, offset_ms, kNoLimit) {} - -TcpSender::TcpSender(PacketProcessorListener* listener, - int flow_id, - int64_t offset_ms, - int send_limit_bytes) - : PacketSender(listener, flow_id), - cwnd_(10), - ssthresh_(kNoLimit), - ack_received_(false), - last_acked_seq_num_(0), - next_sequence_number_(0), - offset_ms_(offset_ms), - last_reduction_time_ms_(-1), - last_rtt_ms_(0), - total_sent_bytes_(0), - send_limit_bytes_(send_limit_bytes), - last_generated_packets_ms_(0), - num_recent_sent_packets_(0), - bitrate_kbps_(0) {} - -TcpSender::~TcpSender() = default; - -void TcpSender::RunFor(int64_t time_ms, Packets* in_out) { - if (clock_.TimeInMilliseconds() + time_ms < offset_ms_) { - clock_.AdvanceTimeMilliseconds(time_ms); - if (running_) { - Pause(); - } - return; - } - - if (!running_ && total_sent_bytes_ == 0) { - Resume(offset_ms_); - } - - int64_t start_time_ms = clock_.TimeInMilliseconds(); - - std::list feedbacks = GetFeedbackPackets( - in_out, clock_.TimeInMilliseconds() + time_ms, *flow_ids().begin()); - // The number of packets which are sent in during time_ms depends on the - // number of packets in_flight_ and the max number of packets in flight - // (cwnd_). Therefore SendPackets() isn't directly dependent on time_ms. - for (FeedbackPacket* fb : feedbacks) { - clock_.AdvanceTimeMilliseconds(fb->send_time_ms() - - clock_.TimeInMilliseconds()); - last_rtt_ms_ = fb->send_time_ms() - fb->latest_send_time_ms(); - UpdateCongestionControl(fb); - SendPackets(in_out); - } - - for (auto it = in_flight_.begin(); it != in_flight_.end();) { - if (it->time_ms < clock_.TimeInMilliseconds() - 1000) - in_flight_.erase(it++); - else - ++it; - } - - clock_.AdvanceTimeMilliseconds(time_ms - - (clock_.TimeInMilliseconds() - start_time_ms)); - SendPackets(in_out); -} - -int TcpSender::GetFeedbackIntervalMs() const { - return 10; -} - -void TcpSender::SendPackets(Packets* in_out) { - int cwnd = std::ceil(cwnd_); - int packets_to_send = std::max(cwnd - static_cast(in_flight_.size()), 0); - int timed_out = TriggerTimeouts(); - if (timed_out > 0) { - HandleLoss(); - } - if (packets_to_send > 0) { - Packets generated = GeneratePackets(packets_to_send); - for (Packet* packet : generated) - in_flight_.insert(InFlight(*static_cast(packet))); - - in_out->merge(generated, DereferencingComparator); - } -} - -void TcpSender::UpdateCongestionControl(const FeedbackPacket* fb) { - const TcpFeedback* tcp_fb = static_cast(fb); - RTC_DCHECK(!tcp_fb->acked_packets().empty()); - ack_received_ = true; - - uint16_t expected = tcp_fb->acked_packets().back() - last_acked_seq_num_; - uint16_t missing = - expected - static_cast(tcp_fb->acked_packets().size()); - - for (uint16_t ack_seq_num : tcp_fb->acked_packets()) - in_flight_.erase(InFlight(ack_seq_num, clock_.TimeInMilliseconds())); - - if (missing > 0) { - HandleLoss(); - } else if (cwnd_ <= ssthresh_) { - cwnd_ += tcp_fb->acked_packets().size(); - } else { - cwnd_ += 1.0f / cwnd_; - } - - last_acked_seq_num_ = - LatestSequenceNumber(tcp_fb->acked_packets().back(), last_acked_seq_num_); -} - -int TcpSender::TriggerTimeouts() { - int timed_out = 0; - for (auto it = in_flight_.begin(); it != in_flight_.end();) { - if (it->time_ms < clock_.TimeInMilliseconds() - 1000) { - in_flight_.erase(it++); - ++timed_out; - } else { - ++it; - } - } - return timed_out; -} - -void TcpSender::HandleLoss() { - if (clock_.TimeInMilliseconds() - last_reduction_time_ms_ < last_rtt_ms_) - return; - last_reduction_time_ms_ = clock_.TimeInMilliseconds(); - ssthresh_ = std::max(static_cast(in_flight_.size() / 2), 2); - cwnd_ = ssthresh_; -} - -Packets TcpSender::GeneratePackets(size_t num_packets) { - Packets generated; - - UpdateSendBitrateEstimate(num_packets); - - for (size_t i = 0; i < num_packets; ++i) { - if ((total_sent_bytes_ + kPacketSizeBytes) > send_limit_bytes_) { - if (running_) { - Pause(); - } - break; - } - generated.push_back( - new MediaPacket(*flow_ids().begin(), 1000 * clock_.TimeInMilliseconds(), - kPacketSizeBytes, next_sequence_number_++)); - generated.back()->set_sender_timestamp_us(1000 * - clock_.TimeInMilliseconds()); - - total_sent_bytes_ += kPacketSizeBytes; - } - - return generated; -} - -void TcpSender::UpdateSendBitrateEstimate(size_t num_packets) { - const int kTimeWindowMs = 500; - num_recent_sent_packets_ += num_packets; - - int64_t delta_ms = clock_.TimeInMilliseconds() - last_generated_packets_ms_; - if (delta_ms >= kTimeWindowMs) { - bitrate_kbps_ = - static_cast(8 * num_recent_sent_packets_ * kPacketSizeBytes) / - delta_ms; - last_generated_packets_ms_ = clock_.TimeInMilliseconds(); - num_recent_sent_packets_ = 0; - } - - RecordBitrate(); -} - -uint32_t TcpSender::TargetBitrateKbps() { - return bitrate_kbps_; -} - -} // namespace bwe -} // namespace testing -} // namespace webrtc diff --git a/modules/remote_bitrate_estimator/test/packet_sender.h b/modules/remote_bitrate_estimator/test/packet_sender.h deleted file mode 100644 index 085ceab381..0000000000 --- a/modules/remote_bitrate_estimator/test/packet_sender.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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. - */ - -#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_SENDER_H_ -#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_SENDER_H_ - -#include -#include -#include -#include -#include - -#include "modules/include/module.h" -#include "modules/remote_bitrate_estimator/test/bwe.h" -#include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" -#include "rtc_base/constructor_magic.h" - -namespace webrtc { -namespace testing { -namespace bwe { - -class MetricRecorder; - -class PacketSender : public PacketProcessor { - public: - PacketSender(PacketProcessorListener* listener, int flow_id) - : PacketProcessor(listener, flow_id, kSender), - running_(true), - // For Packet::send_time_us() to be comparable with timestamps from - // clock_, the clock of the PacketSender and the Source must be aligned. - // We assume that both start at time 0. - clock_(0), - metric_recorder_(nullptr) {} - ~PacketSender() override {} - // Call GiveFeedback() with the returned interval in milliseconds, provided - // there is a new estimate available. - // Note that changing the feedback interval affects the timing of when the - // output of the estimators is sampled and therefore the baseline files may - // have to be regenerated. - virtual int GetFeedbackIntervalMs() const = 0; - void SetSenderTimestamps(Packets* in_out); - - virtual uint32_t TargetBitrateKbps(); - - virtual void Pause(); - virtual void Resume(int64_t paused_time_ms); - - void set_metric_recorder(MetricRecorder* metric_recorder); - virtual void RecordBitrate(); - - protected: - bool running_; // Initialized by default as true. - SimulatedClock clock_; - - private: - MetricRecorder* metric_recorder_; -}; - -class VideoSender : public PacketSender, public BitrateObserver { - public: - VideoSender(PacketProcessorListener* listener, - VideoSource* source, - BandwidthEstimatorType estimator); - ~VideoSender() override; - - int GetFeedbackIntervalMs() const override; - void RunFor(int64_t time_ms, Packets* in_out) override; - - virtual VideoSource* source() const; - - uint32_t TargetBitrateKbps() override; - - // Implements BitrateObserver. - void OnNetworkChanged(uint32_t target_bitrate_bps, - uint8_t fraction_lost, - int64_t rtt) override; - void Pause() override; - void Resume(int64_t paused_time_ms) override; - - protected: - void ProcessFeedbackAndGeneratePackets(int64_t time_ms, - std::list* feedbacks, - Packets* generated); - - VideoSource* source_; - std::unique_ptr bwe_; - int64_t start_of_run_ms_; - std::list modules_; - - private: - uint32_t previous_sending_bitrate_; - RTC_DISALLOW_COPY_AND_ASSIGN(VideoSender); -}; - -class PacedVideoSender : public VideoSender, public PacedSender::PacketSender { - public: - PacedVideoSender(PacketProcessorListener* listener, - VideoSource* source, - BandwidthEstimatorType estimator); - ~PacedVideoSender() override; - - void RunFor(int64_t time_ms, Packets* in_out) override; - - // Implements PacedSender::Callback. - RtpPacketSendResult TimeToSendPacket( - uint32_t ssrc, - uint16_t sequence_number, - int64_t capture_time_ms, - bool retransmission, - const PacedPacketInfo& pacing_info) override; - size_t TimeToSendPadding(size_t bytes, - const PacedPacketInfo& pacing_info) override; - - // Implements BitrateObserver. - void OnNetworkChanged(uint32_t target_bitrate_bps, - uint8_t fraction_lost, - int64_t rtt) override; - - void OnNetworkChanged(uint32_t bitrate_for_encoder_bps, - uint32_t bitrate_for_pacer_bps, - bool in_probe_rtt, - int64_t rtt, - uint64_t congestion_window) override; - size_t pacer_queue_size_in_bytes() override; - void OnBytesAcked(size_t bytes) override; - - private: - int64_t TimeUntilNextProcess(const std::list& modules); - void CallProcess(const std::list& modules); - void QueuePackets(Packets* batch, int64_t end_of_batch_time_us); - - size_t pacer_queue_size_in_bytes_ = 0; - std::unique_ptr pacer_; - Packets queue_; - Packets pacer_queue_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PacedVideoSender); -}; - -class TcpSender : public PacketSender { - public: - TcpSender(PacketProcessorListener* listener, int flow_id, int64_t offset_ms); - TcpSender(PacketProcessorListener* listener, - int flow_id, - int64_t offset_ms, - int send_limit_bytes); - ~TcpSender() override; - - void RunFor(int64_t time_ms, Packets* in_out) override; - int GetFeedbackIntervalMs() const override; - - uint32_t TargetBitrateKbps() override; - - private: - struct InFlight { - public: - explicit InFlight(const MediaPacket& packet) - : sequence_number(packet.header().sequenceNumber), - time_ms(packet.send_time_ms()) {} - - InFlight(uint16_t seq_num, int64_t now_ms) - : sequence_number(seq_num), time_ms(now_ms) {} - - bool operator<(const InFlight& rhs) const { - return sequence_number < rhs.sequence_number; - } - - uint16_t sequence_number; // Sequence number of a packet in flight, or a - // packet which has just been acked. - int64_t time_ms; // Time of when the packet left the sender, or when the - // ack was received. - }; - - void SendPackets(Packets* in_out); - void UpdateCongestionControl(const FeedbackPacket* fb); - int TriggerTimeouts(); - void HandleLoss(); - Packets GeneratePackets(size_t num_packets); - void UpdateSendBitrateEstimate(size_t num_packets); - - float cwnd_; - int ssthresh_; - std::set in_flight_; - bool ack_received_; - uint16_t last_acked_seq_num_; - uint16_t next_sequence_number_; - int64_t offset_ms_; - int64_t last_reduction_time_ms_; - int64_t last_rtt_ms_; - int total_sent_bytes_; - int send_limit_bytes_; // Initialized by default as kNoLimit. - int64_t last_generated_packets_ms_; - size_t num_recent_sent_packets_; - uint32_t bitrate_kbps_; -}; -} // namespace bwe -} // namespace testing -} // namespace webrtc -#endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_SENDER_H_ diff --git a/modules/remote_bitrate_estimator/test/plot_bars.sh b/modules/remote_bitrate_estimator/test/plot_bars.sh deleted file mode 100755 index 9f7fb16203..0000000000 --- a/modules/remote_bitrate_estimator/test/plot_bars.sh +++ /dev/null @@ -1,286 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2013 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. - -# To set up in e.g. Eclipse, run a separate shell and pipe the output from the -# test into this script. -# -# In Eclipse, that amounts to creating a Run Configuration which starts -# "/bin/bash" with the arguments "-c [trunk_path]/out/Debug/modules_unittests -# --gtest_filter=*BweTest* | [trunk_path]/webrtc/modules/ -# remote_bitrate_estimator/test/plot_bars.sh - -# This script supports multiple figures (windows), the figure is specified as an -# identifier at the first argument after the PLOT command. Each figure has a -# single y axis and a dual y axis mode. If any line specifies an axis by ending -# with "#" two y axis will be used, the first will be -# assumed to represent bitrate (in kbps) and the second will be assumed to -# represent time deltas (in ms). - -log=$( "1" )); then - tcp_flow=true - box_width=$(echo "(1.0-$tcp_space/2)/$num_flows" | bc -l) - echo "set xtics font 'Verdana,16'" - x_labels="(" - delimiter="" - abscissa=$(echo $x_start + 0.5 + 0.5*$box_width | bc) - for label in "${split_label_1[@]}" ; do - x_labels+="$delimiter'$label' $abscissa" - abscissa=$(echo $abscissa + $box_width | bc) - delimiter=", " - done - abscissa=$(echo $abscissa + $tcp_space | bc) - IFS='x' read -ra split_label_2 <<< "$x_label_2" - for label in "${split_label_2[@]}" ; do - x_labels+="$delimiter'$label' $abscissa" - abscissa=$(echo $abscissa + $box_width | bc) - done - x_labels="$x_labels)" - else - box_width=$(echo 1.0/$num_flows | bc -l) - fi - - echo "set boxwidth $box_width" - - # Plots can be directly exported to image files. - file_name=$(echo "$labels" | grep "^LABEL.$figure" | cut -f 5 | head -n 1) - - y_max=0 # Used to scale the plot properly. - - # Scale all latency plots with the same vertical scale. - delay_figure=5 - if (( $figure==$delay_figure )) ; then - y_max=400 - else # Take y_max = 1.1 * highest plot value. - - # Since only the optimal bitrate for the first flow is being ploted, - # consider only this one for scalling purposes. - data_sets=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | cut -f 3 | \ - sed 's/_/\t/g' | cut -f 1 | sort | uniq) - - if (( ${#data_sets[@]} > "0" )); then - for set in $data_sets ; do - y=$(echo "$bars" | grep "LIMITERRORBAR.$figure.$set" | cut -f 8 | \ - head -n 1) - if (( $(bc <<< "$y > $y_max") == 1 )); then - y_max=$y - fi - done - fi - - data_sets=$(echo "$bars" | grep "ERRORBAR.$figure" | cut -f 3 | \ - sort | uniq) - if (( ${#data_sets[@]} > "0" )); then - for set in $data_sets ; do - y=$(echo "$bars" | grep "ERRORBAR.$figure.$set" | cut -f 6 | \ - head -n 1) - if (( $(bc <<< "$y > $y_max") == 1 )) ; then - y_max=$y - fi - done - fi - - data_sets=$(echo "$bars" | grep "BAR.$figure" | cut -f 3 | sort | uniq) - - for set in $data_sets ; do - y=$(echo "$bars" | grep "BAR.$figure.$set" | cut -f 4 | head -n 1) - if (( $(bc <<< "$y > $y_max") == 1 )) ; then - y_max=$y - fi - done - - y_max=$(echo $y_max*1.1 | bc) - fi - - - echo "set ylabel \"$y_label\"" - echo "set yrange[0:$y_max]" - - echo "set multiplot" - - # Plot bars. - data_sets=$(echo "$bars" | grep "BAR.$figure" | cut -f 3 | sort | uniq) - - echo "set xtics $x_labels" - echo "plot '-' using 1:4:2 with boxes lc variable notitle" - - echo - - color=11 # Green. - x_bar=$(echo $x_start + 0.5 + 0.5*$box_width | bc) - for set in $data_sets ; do - echo -n "$x_bar $color " - echo "$bars" | grep "BAR.$figure.$set" | cut -f 3,4 - - # Add extra space if TCP flows are being plotted. - if $tcp_flow && \ - (( $(bc <<< "$x_bar < $x_start + 1.5 - 0.5*$tcp_space") == 1 )) && \ - (( $(bc <<< "$x_bar + $box_width > $x_start + 1.5 + 0.5*$tcp_space") \ - == 1 )); then - x_bar=$(echo $x_bar + $tcp_space | bc) - fi - - x_bar=$(echo $x_bar + $box_width | bc) - - if (( $(bc <<< "$x_bar > 2.5") == 1 )) ; then - color=12 # Blue. - fi - # Different bar color for TCP flows: - if $tcp_flow && \ - (( $(bc <<< "(100*$x_bar)%100 < 50") == 1 )) - then - color=18 # Gray. - fi - done - echo "e" - - # Plot Baseline bars, e.g. one-way path delay on latency plots. - data_sets=$(echo "$log" | grep "BASELINE.$figure" | cut -f 3 | sort | uniq) - - if (( ${#data_sets} > "0" )); then - echo "set xtics $x_labels" - echo "plot '-' using 1:4:2 with boxes lc variable notitle" - - echo - - color=18 # Gray. - x_bar=$(echo $x_start + 0.5 + 0.5*$box_width | bc) - for set in $data_sets ; do - echo -n "$x_bar $color " - echo "$log" | grep "BASELINE.$figure.$set" | cut -f 3,4 - - # Add extra space if TCP flows are being plotted. - if $tcp_flow && \ - (( $(bc <<< "$x_bar < $x_start + 1.5 - 0.5*$tcp_space") == 1 )) && \ - (( $(bc <<< "$x_bar + $box_width > $x_start + 1.5 \ - + 0.5*$tcp_space") == 1 )); then - x_bar=$(echo $x_bar + $tcp_space | bc) - fi - - x_bar=$(echo $x_bar + $box_width | bc) - - done - echo "e" - fi - - # Plot vertical error lines, e.g. y +- sigma. - data_sets=$(echo "$bars" | grep "ERRORBAR.$figure" | cut -f 3 | sort | uniq) - - if (( ${#data_sets} > "0" )); then - - echo "set key left" - error_title=$(echo "$bars" | grep "ERRORBAR.$figure" | cut -f 7 | \ - head -n 1 | sed 's/_/ /g') - - echo "set xtics $x_labels" - echo "plot '-' using 1:3:4:5 title '$error_title' with yerr" - - x_error_line=$(echo $x_start + 0.5 + 0.5*$box_width | bc) - for set in $data_sets ; do - echo -n "$x_error_line " - echo "$bars" | grep "ERRORBAR.$figure.$set" | cut -f 3,4,5,6 - - # Add extra space if TCP flows are being plotted. - if $tcp_flow && \ - (( $(bc <<< "$x_error_line < $x_start + 1.5 - 0.5*$tcp_space") == 1 \ - )) && (( $(bc <<< "$x_error_line + $box_width > $x_start + 1.5 \ - + 0.5*$tcp_space") == 1 )); then - x_error_line=$(echo $x_error_line + $tcp_space | bc) - fi - - x_error_line=$(echo $x_error_line + $box_width | bc) - done - echo "e" - fi - - # Plot horizontal dashed lines, e.g. y = optimal bitrate. - data_sets=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | cut -f 3 \ - | sort | uniq) - if (( ${#data_sets} > "0" )); then - - echo "set style line 1 lt 1 lw 3 pt 3 ps 0 linecolor rgb 'black'" - - limit_titles=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | cut -f 9 \ - | sort | uniq) - - for title in $limit_titles ; do - y_max=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | grep "$title" \ - | cut -f 8 | head -n 1) - - retouched_title=$(echo "$title" | sed 's/#/\t/g' | cut -f 1 \ - | sed 's/_/ /g') - - echo "set key right top" - echo "set xtics $x_labels" - echo "plot $y_max lt 7 lw 1 linecolor rgb 'black' \ - title '$retouched_title'" - done - - fi - - echo "unset multiplot" - done -} - -gen_gnuplot_bar_input | gnuplot -persist diff --git a/modules/remote_bitrate_estimator/test/plot_dynamics.py b/modules/remote_bitrate_estimator/test/plot_dynamics.py deleted file mode 100755 index e5180634cb..0000000000 --- a/modules/remote_bitrate_estimator/test/plot_dynamics.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python -# 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. - -# This script is used to plot simulation dynamics. The expected format is -# PLOT :@