Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / remote_bitrate_estimator / test / bwe_test_framework.cc
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
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.
9  */
10
11 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
12
13 #include <cstdio>
14 #include <sstream>
15
16 namespace webrtc {
17 namespace testing {
18 namespace bwe {
19
20 class RateCounter {
21  public:
22   RateCounter()
23       : kWindowSizeUs(1000000),
24         packets_per_second_(0),
25         bytes_per_second_(0),
26         last_accumulated_us_(0),
27         window_() {}
28
29   void UpdateRates(int64_t send_time_us, uint32_t payload_size) {
30     packets_per_second_++;
31     bytes_per_second_ += payload_size;
32     last_accumulated_us_ = send_time_us;
33     window_.push_back(std::make_pair(send_time_us, payload_size));
34     while (!window_.empty()) {
35       const TimeSizePair& packet = window_.front();
36       if (packet.first > (last_accumulated_us_ - kWindowSizeUs)) {
37         break;
38       }
39       assert(packets_per_second_ >= 1);
40       assert(bytes_per_second_ >= packet.second);
41       packets_per_second_--;
42       bytes_per_second_ -= packet.second;
43       window_.pop_front();
44     }
45   }
46
47   uint32_t bits_per_second() const {
48     return bytes_per_second_ * 8;
49   }
50   uint32_t packets_per_second() const { return packets_per_second_; }
51
52  private:
53   typedef std::pair<int64_t, uint32_t> TimeSizePair;
54
55   const int64_t kWindowSizeUs;
56   uint32_t packets_per_second_;
57   uint32_t bytes_per_second_;
58   int64_t last_accumulated_us_;
59   std::list<TimeSizePair> window_;
60 };
61
62 Random::Random(uint32_t seed)
63     : a_(0x531FDB97 ^ seed),
64       b_(0x6420ECA8 + seed) {
65 }
66
67 float Random::Rand() {
68   const float kScale = 1.0f / 0xffffffff;
69   float result = kScale * b_;
70   a_ ^= b_;
71   b_ += a_;
72   return result;
73 }
74
75 int Random::Gaussian(int mean, int standard_deviation) {
76   // Creating a Normal distribution variable from two independent uniform
77   // variables based on the Box-Muller transform, which is defined on the
78   // interval (0, 1], hence the mask+add below.
79   const double kPi = 3.14159265358979323846;
80   const double kScale = 1.0 / 0x80000000ul;
81   double u1 = kScale * ((a_ & 0x7ffffffful) + 1);
82   double u2 = kScale * ((b_ & 0x7ffffffful) + 1);
83   a_ ^= b_;
84   b_ += a_;
85   return static_cast<int>(mean + standard_deviation *
86       std::sqrt(-2 * std::log(u1)) * std::cos(2 * kPi * u2));
87 }
88
89 Packet::Packet()
90     : creation_time_us_(-1),
91       send_time_us_(-1),
92       payload_size_(0) {
93    memset(&header_, 0, sizeof(header_));
94 }
95
96 Packet::Packet(int64_t send_time_us, uint32_t payload_size,
97                const RTPHeader& header)
98   : creation_time_us_(send_time_us),
99     send_time_us_(send_time_us),
100     payload_size_(payload_size),
101     header_(header) {
102 }
103
104 Packet::Packet(int64_t send_time_us, uint32_t sequence_number)
105     : creation_time_us_(send_time_us),
106       send_time_us_(send_time_us),
107       payload_size_(0) {
108    memset(&header_, 0, sizeof(header_));
109    header_.sequenceNumber = sequence_number;
110 }
111
112 bool Packet::operator<(const Packet& rhs) const {
113   return send_time_us_ < rhs.send_time_us_;
114 }
115
116 void Packet::set_send_time_us(int64_t send_time_us) {
117   assert(send_time_us >= 0);
118   send_time_us_ = send_time_us;
119 }
120
121 bool IsTimeSorted(const Packets& packets) {
122   PacketsConstIt last_it = packets.begin();
123   for (PacketsConstIt it = last_it; it != packets.end(); ++it) {
124     if (it != last_it && *it < *last_it) {
125       return false;
126     }
127     last_it = it;
128   }
129   return true;
130 }
131
132 PacketProcessor::PacketProcessor(PacketProcessorListener* listener)
133     : listener_(listener) {
134   if (listener_) {
135     listener_->AddPacketProcessor(this);
136   }
137 }
138
139 PacketProcessor::~PacketProcessor() {
140   if (listener_) {
141     listener_->RemovePacketProcessor(this);
142   }
143 }
144
145 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener)
146     : PacketProcessor(listener),
147       rate_counter_(new RateCounter()),
148       pps_stats_(),
149       kbps_stats_(),
150       name_("") {}
151
152 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
153                                      const std::string& name)
154     : PacketProcessor(listener),
155       rate_counter_(new RateCounter()),
156       pps_stats_(),
157       kbps_stats_(),
158       name_(name) {}
159
160 RateCounterFilter::~RateCounterFilter() {
161   LogStats();
162 }
163
164 uint32_t RateCounterFilter::packets_per_second() const {
165   return rate_counter_->packets_per_second();
166 }
167
168 uint32_t RateCounterFilter::bits_per_second() const {
169   return rate_counter_->bits_per_second();
170 }
171
172 void RateCounterFilter::LogStats() {
173   BWE_TEST_LOGGING_CONTEXT("RateCounterFilter");
174   pps_stats_.Log("pps");
175   kbps_stats_.Log("kbps");
176 }
177
178 void RateCounterFilter::Plot(int64_t timestamp_ms) {
179   BWE_TEST_LOGGING_CONTEXT(name_.c_str());
180   BWE_TEST_LOGGING_PLOT("Throughput_#1", timestamp_ms,
181                         rate_counter_->bits_per_second() / 1000.0);
182 }
183
184 void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
185   assert(in_out);
186   for (PacketsConstIt it = in_out->begin(); it != in_out->end(); ++it) {
187     rate_counter_->UpdateRates(it->send_time_us(), it->payload_size());
188   }
189   pps_stats_.Push(rate_counter_->packets_per_second());
190   kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
191 }
192
193 LossFilter::LossFilter(PacketProcessorListener* listener)
194     : PacketProcessor(listener),
195       random_(0x12345678),
196       loss_fraction_(0.0f) {
197 }
198
199 void LossFilter::SetLoss(float loss_percent) {
200   BWE_TEST_LOGGING_ENABLE(false);
201   BWE_TEST_LOGGING_LOG1("Loss", "%f%%", loss_percent);
202   assert(loss_percent >= 0.0f);
203   assert(loss_percent <= 100.0f);
204   loss_fraction_ = loss_percent * 0.01f;
205 }
206
207 void LossFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
208   assert(in_out);
209   for (PacketsIt it = in_out->begin(); it != in_out->end(); ) {
210     if (random_.Rand() < loss_fraction_) {
211       it = in_out->erase(it);
212     } else {
213       ++it;
214     }
215   }
216 }
217
218 DelayFilter::DelayFilter(PacketProcessorListener* listener)
219     : PacketProcessor(listener),
220       delay_us_(0),
221       last_send_time_us_(0) {
222 }
223
224 void DelayFilter::SetDelay(int64_t delay_ms) {
225   BWE_TEST_LOGGING_ENABLE(false);
226   BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(delay_ms));
227   assert(delay_ms >= 0);
228   delay_us_ = delay_ms * 1000;
229 }
230
231 void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
232   assert(in_out);
233   for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
234     int64_t new_send_time_us = it->send_time_us() + delay_us_;
235     last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
236     it->set_send_time_us(last_send_time_us_);
237   }
238 }
239
240 JitterFilter::JitterFilter(PacketProcessorListener* listener)
241     : PacketProcessor(listener),
242       random_(0x89674523),
243       stddev_jitter_us_(0),
244       last_send_time_us_(0) {
245 }
246
247 void JitterFilter::SetJitter(int64_t stddev_jitter_ms) {
248   BWE_TEST_LOGGING_ENABLE(false);
249   BWE_TEST_LOGGING_LOG1("Jitter", "%d ms",
250                         static_cast<int>(stddev_jitter_ms));
251   assert(stddev_jitter_ms >= 0);
252   stddev_jitter_us_ = stddev_jitter_ms * 1000;
253 }
254
255 void JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
256   assert(in_out);
257   for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
258     int64_t new_send_time_us = it->send_time_us();
259     new_send_time_us += random_.Gaussian(0, stddev_jitter_us_);
260     last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
261     it->set_send_time_us(last_send_time_us_);
262   }
263 }
264
265 ReorderFilter::ReorderFilter(PacketProcessorListener* listener)
266     : PacketProcessor(listener),
267       random_(0x27452389),
268       reorder_fraction_(0.0f) {
269 }
270
271 void ReorderFilter::SetReorder(float reorder_percent) {
272   BWE_TEST_LOGGING_ENABLE(false);
273   BWE_TEST_LOGGING_LOG1("Reordering", "%f%%", reorder_percent);
274   assert(reorder_percent >= 0.0f);
275   assert(reorder_percent <= 100.0f);
276   reorder_fraction_ = reorder_percent * 0.01f;
277 }
278
279 void ReorderFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
280   assert(in_out);
281   if (in_out->size() >= 2) {
282     PacketsIt last_it = in_out->begin();
283     PacketsIt it = last_it;
284     while (++it != in_out->end()) {
285       if (random_.Rand() < reorder_fraction_) {
286         int64_t t1 = last_it->send_time_us();
287         int64_t t2 = it->send_time_us();
288         std::swap(*last_it, *it);
289         last_it->set_send_time_us(t1);
290         it->set_send_time_us(t2);
291       }
292       last_it = it;
293     }
294   }
295 }
296
297 ChokeFilter::ChokeFilter(PacketProcessorListener* listener)
298     : PacketProcessor(listener),
299       kbps_(1200),
300       max_delay_us_(0),
301       last_send_time_us_(0) {
302 }
303
304 void ChokeFilter::SetCapacity(uint32_t kbps) {
305   BWE_TEST_LOGGING_ENABLE(false);
306   BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps);
307   kbps_ = kbps;
308 }
309
310 void ChokeFilter::SetMaxDelay(int64_t max_delay_ms) {
311   BWE_TEST_LOGGING_ENABLE(false);
312   BWE_TEST_LOGGING_LOG1("Max Delay", "%d ms", static_cast<int>(max_delay_ms));
313   assert(max_delay_ms >= 0);
314   max_delay_us_ = max_delay_ms * 1000;
315 }
316
317 void ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
318   assert(in_out);
319   for (PacketsIt it = in_out->begin(); it != in_out->end(); ) {
320     int64_t earliest_send_time_us = last_send_time_us_ +
321         (it->payload_size() * 8 * 1000 + kbps_ / 2) / kbps_;
322     int64_t new_send_time_us = std::max(it->send_time_us(),
323                                         earliest_send_time_us);
324     if (max_delay_us_ == 0 ||
325         max_delay_us_ >= (new_send_time_us - it->send_time_us())) {
326       it->set_send_time_us(new_send_time_us);
327       last_send_time_us_ = new_send_time_us;
328       ++it;
329     } else {
330       it = in_out->erase(it);
331     }
332   }
333 }
334
335 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
336     PacketProcessorListener* listener)
337     : PacketProcessor(listener),
338       delivery_times_us_(),
339       next_delivery_it_(),
340       local_time_us_(-1),
341       rate_counter_(new RateCounter),
342       name_("") {}
343
344 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
345     PacketProcessorListener* listener,
346     const std::string& name)
347     : PacketProcessor(listener),
348       delivery_times_us_(),
349       next_delivery_it_(),
350       local_time_us_(-1),
351       rate_counter_(new RateCounter),
352       name_(name) {}
353
354 TraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() {
355 }
356
357 bool TraceBasedDeliveryFilter::Init(const std::string& filename) {
358   FILE* trace_file = fopen(filename.c_str(), "r");
359   if (!trace_file) {
360     return false;
361   }
362   int64_t first_timestamp = -1;
363   while(!feof(trace_file)) {
364     const size_t kMaxLineLength = 100;
365     char line[kMaxLineLength];
366     if (fgets(line, kMaxLineLength, trace_file)) {
367       std::string line_string(line);
368       std::istringstream buffer(line_string);
369       int64_t timestamp;
370       buffer >> timestamp;
371       timestamp /= 1000;  // Convert to microseconds.
372       if (first_timestamp == -1)
373         first_timestamp = timestamp;
374       assert(delivery_times_us_.empty() ||
375              timestamp - first_timestamp - delivery_times_us_.back() >= 0);
376       delivery_times_us_.push_back(timestamp - first_timestamp);
377     }
378   }
379   assert(!delivery_times_us_.empty());
380   next_delivery_it_ = delivery_times_us_.begin();
381   fclose(trace_file);
382   return true;
383 }
384
385 void TraceBasedDeliveryFilter::Plot(int64_t timestamp_ms) {
386   BWE_TEST_LOGGING_CONTEXT(name_.c_str());
387   // This plots the max possible throughput of the trace-based delivery filter,
388   // which will be reached if a packet sent on every packet slot of the trace.
389   BWE_TEST_LOGGING_PLOT("MaxThroughput_#1", timestamp_ms,
390                         rate_counter_->bits_per_second() / 1000.0);
391 }
392
393 void TraceBasedDeliveryFilter::RunFor(int64_t time_ms, Packets* in_out) {
394   assert(in_out);
395   for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
396     do {
397       ProceedToNextSlot();
398       const int kPayloadSize = 1240;
399       rate_counter_->UpdateRates(local_time_us_, kPayloadSize);
400     } while (local_time_us_ < it->send_time_us());
401     it->set_send_time_us(local_time_us_);
402   }
403 }
404
405 void TraceBasedDeliveryFilter::ProceedToNextSlot() {
406   if (*next_delivery_it_ <= local_time_us_) {
407     ++next_delivery_it_;
408     if (next_delivery_it_ == delivery_times_us_.end()) {
409       // When the trace wraps we allow two packets to be sent back-to-back.
410       for (TimeList::iterator it = delivery_times_us_.begin();
411            it != delivery_times_us_.end(); ++it) {
412         *it += local_time_us_;
413       }
414       next_delivery_it_ = delivery_times_us_.begin();
415     }
416   }
417   local_time_us_ = *next_delivery_it_;
418 }
419
420 PacketSender::PacketSender(PacketProcessorListener* listener)
421     : PacketProcessor(listener) {
422 }
423
424 VideoSender::VideoSender(PacketProcessorListener* listener, float fps,
425                          uint32_t kbps, uint32_t ssrc, float first_frame_offset)
426     : PacketSender(listener),
427       kMaxPayloadSizeBytes(1000),
428       kTimestampBase(0xff80ff00ul),
429       frame_period_ms_(1000.0 / fps),
430       bytes_per_second_((1000 * kbps) / 8),
431       frame_size_bytes_(bytes_per_second_ / fps),
432       next_frame_ms_(frame_period_ms_ * first_frame_offset),
433       now_ms_(0.0),
434       prototype_header_() {
435   assert(first_frame_offset >= 0.0f);
436   assert(first_frame_offset < 1.0f);
437   memset(&prototype_header_, 0, sizeof(prototype_header_));
438   prototype_header_.ssrc = ssrc;
439   prototype_header_.sequenceNumber = 0xf000u;
440 }
441
442 uint32_t VideoSender::GetCapacityKbps() const {
443   return (bytes_per_second_ * 8) / 1000;
444 }
445
446 void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
447   assert(in_out);
448   now_ms_ += time_ms;
449   Packets newPackets;
450   while (now_ms_ >= next_frame_ms_) {
451     prototype_header_.sequenceNumber++;
452     prototype_header_.timestamp = kTimestampBase +
453         static_cast<uint32_t>(next_frame_ms_ * 90.0);
454     prototype_header_.extension.absoluteSendTime = (kTimestampBase +
455         ((static_cast<int64_t>(next_frame_ms_ * (1 << 18)) + 500) / 1000)) &
456             0x00fffffful;
457     prototype_header_.extension.transmissionTimeOffset = 0;
458
459     // Generate new packets for this frame, all with the same timestamp,
460     // but the payload size is capped, so if the whole frame doesn't fit in
461     // one packet, we will see a number of equally sized packets followed by
462     // one smaller at the tail.
463     int64_t send_time_us = next_frame_ms_ * 1000.0;
464     uint32_t payload_size = frame_size_bytes_;
465     while (payload_size > 0) {
466       uint32_t size = std::min(kMaxPayloadSizeBytes, payload_size);
467       newPackets.push_back(Packet(send_time_us, size, prototype_header_));
468       payload_size -= size;
469     }
470
471     next_frame_ms_ += frame_period_ms_;
472   }
473   in_out->merge(newPackets);
474 }
475
476 AdaptiveVideoSender::AdaptiveVideoSender(PacketProcessorListener* listener,
477                                          float fps,
478                                          uint32_t kbps,
479                                          uint32_t ssrc,
480                                          float first_frame_offset)
481     : VideoSender(listener, fps, kbps, ssrc, first_frame_offset) {}
482
483 void AdaptiveVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
484   bytes_per_second_ = feedback.estimated_bps / 8;
485   frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
486 }
487 }  // namespace bwe
488 }  // namespace testing
489 }  // namespace webrtc