2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
11 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.h"
13 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h"
14 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
15 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
16 #include "webrtc/system_wrappers/interface/clock.h"
17 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
26 namespace stl_helpers {
27 template<typename T> void DeleteElements(T* container) {
28 if (!container) return;
29 for (typename T::iterator it = container->begin(); it != container->end();
35 } // namespace stl_helpers
37 class BweTest::TestedEstimator : public RemoteBitrateObserver {
39 static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
41 TestedEstimator(const string& test_name,
42 const BweTestConfig::EstimatorConfig& config)
43 : debug_name_(config.debug_name),
46 relative_estimator_stats_(),
47 latest_estimate_bps_(-1),
48 estimator_(config.estimator_factory->Create(
49 this, &clock_, kRemoteBitrateEstimatorMinBitrateBps)),
50 relative_estimator_(NULL),
51 baseline_(BaseLineFileInterface::Create(test_name + "_" + debug_name_,
52 config.update_baseline)) {
53 assert(estimator_.get());
54 assert(baseline_.get());
55 // Default RTT in RemoteRateControl is 200 ms ; 50 ms is more realistic.
56 estimator_->OnRttUpdate(50);
59 void SetRelativeEstimator(TestedEstimator* relative_estimator) {
60 relative_estimator_ = relative_estimator;
63 void EatPacket(const Packet& packet) {
64 BWE_TEST_LOGGING_CONTEXT(debug_name_);
66 latest_estimate_bps_ = -1;
68 // We're treating the send time (from previous filter) as the arrival
69 // time once packet reaches the estimator.
70 int64_t packet_time_ms = (packet.send_time_us() + 500) / 1000;
71 BWE_TEST_LOGGING_TIME(packet_time_ms);
72 BWE_TEST_LOGGING_PLOT("Delay_#2", clock_.TimeInMilliseconds(),
74 (packet.creation_time_us() + 500) / 1000);
76 int64_t step_ms = estimator_->TimeUntilNextProcess();
77 while ((clock_.TimeInMilliseconds() + step_ms) < packet_time_ms) {
78 clock_.AdvanceTimeMilliseconds(step_ms);
79 estimator_->Process();
80 step_ms = estimator_->TimeUntilNextProcess();
82 estimator_->IncomingPacket(packet_time_ms, packet.payload_size(),
84 clock_.AdvanceTimeMilliseconds(packet_time_ms -
85 clock_.TimeInMilliseconds());
86 ASSERT_TRUE(packet_time_ms == clock_.TimeInMilliseconds());
89 bool CheckEstimate(PacketSender::Feedback* feedback) {
91 BWE_TEST_LOGGING_CONTEXT(debug_name_);
92 uint32_t estimated_bps = 0;
93 if (LatestEstimate(&estimated_bps)) {
94 feedback->estimated_bps = estimated_bps;
95 baseline_->Estimate(clock_.TimeInMilliseconds(), estimated_bps);
97 double estimated_kbps = static_cast<double>(estimated_bps) / 1000.0;
98 stats_.Push(estimated_kbps);
99 BWE_TEST_LOGGING_PLOT("Estimate_#1", clock_.TimeInMilliseconds(),
101 uint32_t relative_estimate_bps = 0;
102 if (relative_estimator_ &&
103 relative_estimator_->LatestEstimate(&relative_estimate_bps)) {
104 double relative_estimate_kbps =
105 static_cast<double>(relative_estimate_bps) / 1000.0;
106 relative_estimator_stats_.Push(estimated_kbps - relative_estimate_kbps);
114 BWE_TEST_LOGGING_CONTEXT(debug_name_);
115 BWE_TEST_LOGGING_CONTEXT("Mean");
117 if (relative_estimator_) {
118 BWE_TEST_LOGGING_CONTEXT("Diff");
119 relative_estimator_stats_.Log("kbps");
123 void VerifyOrWriteBaseline() {
124 EXPECT_TRUE(baseline_->VerifyOrWrite());
127 virtual void OnReceiveBitrateChanged(const vector<unsigned int>& ssrcs,
128 unsigned int bitrate) {
132 bool LatestEstimate(uint32_t* estimate_bps) {
133 if (latest_estimate_bps_ < 0) {
134 vector<unsigned int> ssrcs;
135 unsigned int bps = 0;
136 if (!estimator_->LatestEstimate(&ssrcs, &bps)) {
139 latest_estimate_bps_ = bps;
141 *estimate_bps = latest_estimate_bps_;
146 SimulatedClock clock_;
147 Stats<double> stats_;
148 Stats<double> relative_estimator_stats_;
149 int64_t latest_estimate_bps_;
150 scoped_ptr<RemoteBitrateEstimator> estimator_;
151 TestedEstimator* relative_estimator_;
152 scoped_ptr<BaseLineFileInterface> baseline_;
154 DISALLOW_IMPLICIT_CONSTRUCTORS(TestedEstimator);
159 simulation_interval_ms_(-1),
166 BweTest::~BweTest() {
167 stl_helpers::DeleteElements(&estimators_);
168 stl_helpers::DeleteElements(&packet_senders_);
171 void BweTest::SetUp() {
172 const ::testing::TestInfo* const test_info =
173 ::testing::UnitTest::GetInstance()->current_test_info();
175 string(test_info->test_case_name()) + "_" + string(test_info->name());
176 BWE_TEST_LOGGING_GLOBAL_CONTEXT(test_name);
178 const BweTestConfig& config = GetParam();
180 uint32_t total_capacity = 0;
181 for (vector<const PacketSenderFactory*>::const_iterator it =
182 config.sender_factories.begin(); it != config.sender_factories.end();
184 PacketSender* sender = (*it)->Create();
186 total_capacity += sender->GetCapacityKbps();
187 packet_senders_.push_back(sender);
188 processors_.push_back(sender);
190 BWE_TEST_LOGGING_LOG1("RequiredLinkCapacity", "%d kbps", total_capacity)
192 // Set simulation interval from first packet sender.
193 if (packet_senders_.size() > 0) {
194 simulation_interval_ms_ = packet_senders_[0]->GetFeedbackIntervalMs();
197 for (vector<BweTestConfig::EstimatorConfig>:: const_iterator it =
198 config.estimator_configs.begin(); it != config.estimator_configs.end();
200 estimators_.push_back(new TestedEstimator(test_name, *it));
202 if (estimators_.size() > 1) {
203 // Set all estimators as relative to the first one.
204 for (uint32_t i = 1; i < estimators_.size(); ++i) {
205 estimators_[i]->SetRelativeEstimator(estimators_[0]);
209 BWE_TEST_LOGGING_GLOBAL_ENABLE(false);
212 void BweTest::TearDown() {
213 BWE_TEST_LOGGING_GLOBAL_ENABLE(true);
215 for (vector<TestedEstimator*>::iterator eit = estimators_.begin();
216 eit != estimators_.end(); ++eit) {
217 (*eit)->VerifyOrWriteBaseline();
221 BWE_TEST_LOGGING_GLOBAL_CONTEXT("");
224 void BweTest::AddPacketProcessor(
225 PacketProcessor* processor) {
227 processors_.push_back(processor);
230 void BweTest::RemovePacketProcessor(
231 PacketProcessor* processor) {
232 vector<PacketProcessor*>::iterator it =
233 std::find(processors_.begin(), processors_.end(), processor);
234 assert(it != processors_.end());
235 processors_.erase(it);
238 void BweTest::VerboseLogging(bool enable) {
239 BWE_TEST_LOGGING_GLOBAL_ENABLE(enable);
242 void BweTest::RunFor(int64_t time_ms) {
243 for (run_time_ms_ += time_ms; run_time_ms_ >= simulation_interval_ms_;
244 run_time_ms_ -= simulation_interval_ms_) {
246 for (vector<PacketProcessor*>::const_iterator it =
247 processors_.begin(); it != processors_.end(); ++it) {
248 (*it)->RunFor(simulation_interval_ms_, &packets);
249 (*it)->Plot((packets.back().send_time_us() + 500) / 1000);
252 // Verify packets are in order between batches.
253 if (!packets.empty() && !previous_packets_.empty()) {
254 packets.splice(packets.begin(), previous_packets_,
255 --previous_packets_.end());
256 ASSERT_TRUE(IsTimeSorted(packets));
257 packets.erase(packets.begin());
259 ASSERT_TRUE(IsTimeSorted(packets));
262 for (PacketsConstIt pit = packets.begin(); pit != packets.end(); ++pit) {
263 for (vector<TestedEstimator*>::iterator eit = estimators_.begin();
264 eit != estimators_.end(); ++eit) {
265 (*eit)->EatPacket(*pit);
269 previous_packets_.swap(packets);
271 for (vector<TestedEstimator*>::iterator eit = estimators_.begin();
272 eit != estimators_.end(); ++eit) {
273 PacketSender::Feedback feedback = {0};
274 if ((*eit)->CheckEstimate(&feedback)) {
275 for (vector<PacketSender*>::iterator psit = packet_senders_.begin();
276 psit != packet_senders_.end(); ++psit) {
277 (*psit)->GiveFeedback(feedback);
284 } // namespace testing
285 } // namespace webrtc