14b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org/*
24b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
34b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org *
44b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org *  Use of this source code is governed by a BSD-style license
54b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org *  that can be found in the LICENSE file in the root of the source
64b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org *  tree. An additional intellectual property rights grant can be found
74b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org *  in the file PATENTS.  All contributing project authors may
84b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
94b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org */
104b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org
11c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
124b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org
13bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org#include <stdio.h>
14bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org
15ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org#include <sstream>
16ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org
174b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.orgnamespace webrtc {
184b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.orgnamespace testing {
194b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.orgnamespace bwe {
20b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.orgclass DelayCapHelper {
21b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org public:
22b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  DelayCapHelper() : max_delay_us_(0), delay_stats_() {}
23b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
24b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  void SetMaxDelay(int max_delay_ms) {
25b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    BWE_TEST_LOGGING_ENABLE(false);
26b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    BWE_TEST_LOGGING_LOG1("Max Delay", "%d ms", static_cast<int>(max_delay_ms));
27b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    assert(max_delay_ms >= 0);
28b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    max_delay_us_ = max_delay_ms * 1000;
29b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  }
30b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
31b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  bool ShouldSendPacket(int64_t send_time_us, int64_t arrival_time_us) {
32b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    int64_t packet_delay_us = send_time_us - arrival_time_us;
33b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    delay_stats_.Push(std::min(packet_delay_us, max_delay_us_) / 1000);
34b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    return (max_delay_us_ == 0 || max_delay_us_ >= packet_delay_us);
35b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  }
36b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
37b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  const Stats<double>& delay_stats() const {
38b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    return delay_stats_;
39b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  }
40b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
41b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org private:
42b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  int64_t max_delay_us_;
43b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  Stats<double> delay_stats_;
44b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
45b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  DISALLOW_COPY_AND_ASSIGN(DelayCapHelper);
46b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org};
474b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org
4851ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgconst FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids) {
4951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  FlowIds flow_ids(&flow_ids_array[0], flow_ids_array + num_flow_ids);
5051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  return flow_ids;
5151ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org}
5251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org
53de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.orgclass RateCounter {
54de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org public:
55de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  RateCounter()
56de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      : kWindowSizeUs(1000000),
57de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org        packets_per_second_(0),
58de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org        bytes_per_second_(0),
59de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org        last_accumulated_us_(0),
60de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org        window_() {}
61de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
62de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  void UpdateRates(int64_t send_time_us, uint32_t payload_size) {
63de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    packets_per_second_++;
64de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    bytes_per_second_ += payload_size;
65de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    last_accumulated_us_ = send_time_us;
66de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    window_.push_back(std::make_pair(send_time_us, payload_size));
67de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    while (!window_.empty()) {
68de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      const TimeSizePair& packet = window_.front();
69de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      if (packet.first > (last_accumulated_us_ - kWindowSizeUs)) {
70de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org        break;
71de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      }
72de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      assert(packets_per_second_ >= 1);
73de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      assert(bytes_per_second_ >= packet.second);
74de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      packets_per_second_--;
75de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      bytes_per_second_ -= packet.second;
76de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      window_.pop_front();
77de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    }
78de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  }
79de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
80de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  uint32_t bits_per_second() const {
81de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    return bytes_per_second_ * 8;
82de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  }
83de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  uint32_t packets_per_second() const { return packets_per_second_; }
84de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
85de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org private:
86de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  typedef std::pair<int64_t, uint32_t> TimeSizePair;
87de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
88de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  const int64_t kWindowSizeUs;
89de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  uint32_t packets_per_second_;
90de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  uint32_t bytes_per_second_;
91de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  int64_t last_accumulated_us_;
92de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  std::list<TimeSizePair> window_;
93de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org};
94de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
95cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgRandom::Random(uint32_t seed)
96cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    : a_(0x531FDB97 ^ seed),
97cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      b_(0x6420ECA8 + seed) {
98cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
99cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
100cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgfloat Random::Rand() {
101cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  const float kScale = 1.0f / 0xffffffff;
102cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  float result = kScale * b_;
103cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  a_ ^= b_;
104cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  b_ += a_;
105cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  return result;
106cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
107cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
108cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgint Random::Gaussian(int mean, int standard_deviation) {
109cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  // Creating a Normal distribution variable from two independent uniform
110cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  // variables based on the Box-Muller transform, which is defined on the
111cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  // interval (0, 1], hence the mask+add below.
112cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  const double kPi = 3.14159265358979323846;
113cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  const double kScale = 1.0 / 0x80000000ul;
114cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  double u1 = kScale * ((a_ & 0x7ffffffful) + 1);
115cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  double u2 = kScale * ((b_ & 0x7ffffffful) + 1);
116cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  a_ ^= b_;
117cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  b_ += a_;
118cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  return static_cast<int>(mean + standard_deviation *
119bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org      sqrt(-2 * log(u1)) * cos(2 * kPi * u2));
120cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
121cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
122cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgPacket::Packet()
12351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : flow_id_(0),
12451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      creation_time_us_(-1),
125df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org      send_time_us_(-1),
126cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      payload_size_(0) {
12751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  memset(&header_, 0, sizeof(header_));
128cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
129cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
13051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgPacket::Packet(int flow_id, int64_t send_time_us, uint32_t payload_size,
131df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org               const RTPHeader& header)
13251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : flow_id_(flow_id),
13351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      creation_time_us_(send_time_us),
13451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      send_time_us_(send_time_us),
13551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      payload_size_(payload_size),
13651ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      header_(header) {
137cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
138cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
139cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgPacket::Packet(int64_t send_time_us, uint32_t sequence_number)
14051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : flow_id_(0),
14151ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      creation_time_us_(send_time_us),
142df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org      send_time_us_(send_time_us),
143cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      payload_size_(0) {
14451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  memset(&header_, 0, sizeof(header_));
14551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  header_.sequenceNumber = sequence_number;
146cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
147cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
148cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgbool Packet::operator<(const Packet& rhs) const {
149cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  return send_time_us_ < rhs.send_time_us_;
150cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
151cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
152cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid Packet::set_send_time_us(int64_t send_time_us) {
153cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(send_time_us >= 0);
154cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  send_time_us_ = send_time_us;
155cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
156cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
157c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.orgvoid Packet::SetAbsSendTimeMs(int64_t abs_send_time_ms) {
158c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  header_.extension.absoluteSendTime = ((static_cast<int64_t>(abs_send_time_ms *
159c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    (1 << 18)) + 500) / 1000) & 0x00fffffful;
160c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org}
161c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org
1624b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.orgbool IsTimeSorted(const Packets& packets) {
1634b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org  PacketsConstIt last_it = packets.begin();
1644b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org  for (PacketsConstIt it = last_it; it != packets.end(); ++it) {
1654b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org    if (it != last_it && *it < *last_it) {
1664b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org      return false;
1674b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org    }
1684b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org    last_it = it;
1694b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org  }
1704b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org  return true;
1714b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org}
172cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
17351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgPacketProcessor::PacketProcessor(PacketProcessorListener* listener,
17451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                                 bool is_sender)
17551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : listener_(listener), flow_ids_(1, 0) {
176cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  if (listener_) {
17751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    listener_->AddPacketProcessor(this, is_sender);
17851ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  }
17951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org}
18051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org
18151ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgPacketProcessor::PacketProcessor(PacketProcessorListener* listener,
18251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                                 const FlowIds& flow_ids,
18351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                                 bool is_sender)
18451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : listener_(listener), flow_ids_(flow_ids) {
18551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  if (listener_) {
18651ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    listener_->AddPacketProcessor(this, is_sender);
187cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
188cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
189cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
190cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgPacketProcessor::~PacketProcessor() {
191cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  if (listener_) {
192cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    listener_->RemovePacketProcessor(this);
193cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
194cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
195cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
196cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgRateCounterFilter::RateCounterFilter(PacketProcessorListener* listener)
19751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
198de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      rate_counter_(new RateCounter()),
199caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      packets_per_second_stats_(),
200df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org      kbps_stats_(),
201de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      name_("") {}
202df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org
203df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.orgRateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
204df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org                                     const std::string& name)
20551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
206de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      rate_counter_(new RateCounter()),
207caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      packets_per_second_stats_(),
208df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org      kbps_stats_(),
209de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      name_(name) {}
210cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
21151ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgRateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
21251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                                     const FlowIds& flow_ids,
21351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                                     const std::string& name)
21451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, flow_ids, false),
21551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      rate_counter_(new RateCounter()),
216caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      packets_per_second_stats_(),
21751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      kbps_stats_(),
21851ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      name_(name) {
21951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  std::stringstream ss;
22051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  ss << name_ << "_";
22151ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  for (size_t i = 0; i < flow_ids.size(); ++i) {
22251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    ss << flow_ids[i] << ",";
22351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  }
22451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  name_ = ss.str();
22551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org}
22651ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org
227cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgRateCounterFilter::~RateCounterFilter() {
228cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  LogStats();
229cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
230cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
231de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.orguint32_t RateCounterFilter::packets_per_second() const {
232de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  return rate_counter_->packets_per_second();
233de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org}
234de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
235de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.orguint32_t RateCounterFilter::bits_per_second() const {
236de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  return rate_counter_->bits_per_second();
237de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org}
238de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
239cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid RateCounterFilter::LogStats() {
240cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_CONTEXT("RateCounterFilter");
241caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org  packets_per_second_stats_.Log("pps");
242cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  kbps_stats_.Log("kbps");
243cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
244cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
245e823012b65d4260205a91a9381fd9cdf2057d6ddstefan@webrtc.orgStats<double> RateCounterFilter::GetBitrateStats() const {
246e823012b65d4260205a91a9381fd9cdf2057d6ddstefan@webrtc.org  return kbps_stats_;
247e823012b65d4260205a91a9381fd9cdf2057d6ddstefan@webrtc.org}
248e823012b65d4260205a91a9381fd9cdf2057d6ddstefan@webrtc.org
249df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.orgvoid RateCounterFilter::Plot(int64_t timestamp_ms) {
250df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org  BWE_TEST_LOGGING_CONTEXT(name_.c_str());
251df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org  BWE_TEST_LOGGING_PLOT("Throughput_#1", timestamp_ms,
252de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org                        rate_counter_->bits_per_second() / 1000.0);
253df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org}
254df1f99ff019b1c666a15bf65e222cb2518d4e62cstefan@webrtc.org
255cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
256cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(in_out);
257cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  for (PacketsConstIt it = in_out->begin(); it != in_out->end(); ++it) {
258de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    rate_counter_->UpdateRates(it->send_time_us(), it->payload_size());
259cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
260caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org  packets_per_second_stats_.Push(rate_counter_->packets_per_second());
261de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
262cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
263cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
264cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgLossFilter::LossFilter(PacketProcessorListener* listener)
26551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
266cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      random_(0x12345678),
267cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      loss_fraction_(0.0f) {
268cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
269cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
270cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid LossFilter::SetLoss(float loss_percent) {
271cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_ENABLE(false);
272cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_LOG1("Loss", "%f%%", loss_percent);
273cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(loss_percent >= 0.0f);
274cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(loss_percent <= 100.0f);
275cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  loss_fraction_ = loss_percent * 0.01f;
276cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
277cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
278cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid LossFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
279cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(in_out);
280cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  for (PacketsIt it = in_out->begin(); it != in_out->end(); ) {
281cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    if (random_.Rand() < loss_fraction_) {
282cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      it = in_out->erase(it);
283cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    } else {
284cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      ++it;
285cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    }
286cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
287cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
288cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
289cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgDelayFilter::DelayFilter(PacketProcessorListener* listener)
29051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
291cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      delay_us_(0),
292cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      last_send_time_us_(0) {
293cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
294cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
295cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid DelayFilter::SetDelay(int64_t delay_ms) {
296cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_ENABLE(false);
297cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_LOG1("Delay", "%d ms", static_cast<int>(delay_ms));
298cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(delay_ms >= 0);
299cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  delay_us_ = delay_ms * 1000;
300cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
301cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
302cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
303cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(in_out);
304cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
305cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    int64_t new_send_time_us = it->send_time_us() + delay_us_;
306cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
307cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    it->set_send_time_us(last_send_time_us_);
308cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
309cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
310cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
311cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgJitterFilter::JitterFilter(PacketProcessorListener* listener)
31251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
313cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      random_(0x89674523),
314cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      stddev_jitter_us_(0),
315cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      last_send_time_us_(0) {
316cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
317cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
318cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid JitterFilter::SetJitter(int64_t stddev_jitter_ms) {
319cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_ENABLE(false);
320cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_LOG1("Jitter", "%d ms",
321cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org                        static_cast<int>(stddev_jitter_ms));
322cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(stddev_jitter_ms >= 0);
323cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  stddev_jitter_us_ = stddev_jitter_ms * 1000;
324cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
325cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
326cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
327cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(in_out);
328cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
329cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    int64_t new_send_time_us = it->send_time_us();
330cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    new_send_time_us += random_.Gaussian(0, stddev_jitter_us_);
331cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
332cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    it->set_send_time_us(last_send_time_us_);
333cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
334cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
335cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
336cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgReorderFilter::ReorderFilter(PacketProcessorListener* listener)
33751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
338cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      random_(0x27452389),
339cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      reorder_fraction_(0.0f) {
340cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
341cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
342cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid ReorderFilter::SetReorder(float reorder_percent) {
343cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_ENABLE(false);
344cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_LOG1("Reordering", "%f%%", reorder_percent);
345cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(reorder_percent >= 0.0f);
346cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(reorder_percent <= 100.0f);
347cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  reorder_fraction_ = reorder_percent * 0.01f;
348cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
349cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
350cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid ReorderFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
351cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(in_out);
352cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  if (in_out->size() >= 2) {
353cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    PacketsIt last_it = in_out->begin();
354cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    PacketsIt it = last_it;
355cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    while (++it != in_out->end()) {
356cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      if (random_.Rand() < reorder_fraction_) {
357cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org        int64_t t1 = last_it->send_time_us();
358cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org        int64_t t2 = it->send_time_us();
359cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org        std::swap(*last_it, *it);
360cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org        last_it->set_send_time_us(t1);
361cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org        it->set_send_time_us(t2);
362cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      }
363cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      last_it = it;
364cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    }
365cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
366cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
367cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
368cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgChokeFilter::ChokeFilter(PacketProcessorListener* listener)
36951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
37051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      kbps_(1200),
37151ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      last_send_time_us_(0),
37251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      delay_cap_helper_(new DelayCapHelper()) {
37351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org}
37451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org
37551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgChokeFilter::ChokeFilter(PacketProcessorListener* listener,
37651ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                         const FlowIds& flow_ids)
37751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, flow_ids, false),
378cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      kbps_(1200),
379b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      last_send_time_us_(0),
380b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      delay_cap_helper_(new DelayCapHelper()) {
381cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
382cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
383b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.orgChokeFilter::~ChokeFilter() {}
384b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
385cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid ChokeFilter::SetCapacity(uint32_t kbps) {
386cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_ENABLE(false);
387cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  BWE_TEST_LOGGING_LOG1("BitrateChoke", "%d kbps", kbps);
388cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  kbps_ = kbps;
389cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
390cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
391cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid ChokeFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
392cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(in_out);
393cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  for (PacketsIt it = in_out->begin(); it != in_out->end(); ) {
394cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    int64_t earliest_send_time_us = last_send_time_us_ +
395cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org        (it->payload_size() * 8 * 1000 + kbps_ / 2) / kbps_;
396cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    int64_t new_send_time_us = std::max(it->send_time_us(),
397cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org                                        earliest_send_time_us);
398b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    if (delay_cap_helper_->ShouldSendPacket(new_send_time_us,
399b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org                                            it->send_time_us())) {
400cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      it->set_send_time_us(new_send_time_us);
401cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      last_send_time_us_ = new_send_time_us;
402cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      ++it;
403cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    } else {
404cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      it = in_out->erase(it);
405cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    }
406cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
407cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
408cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
409b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.orgvoid ChokeFilter::SetMaxDelay(int max_delay_ms) {
410b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  delay_cap_helper_->SetMaxDelay(max_delay_ms);
411b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org}
412b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
413b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.orgStats<double> ChokeFilter::GetDelayStats() const {
414b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  return delay_cap_helper_->delay_stats();
415b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org}
416b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
417ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.orgTraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
418ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    PacketProcessorListener* listener)
41951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
4207a560797ddeafa0472a0bd85aa9ad62b2530ffbastefan@webrtc.org      current_offset_us_(0),
421ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      delivery_times_us_(),
422ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      next_delivery_it_(),
423de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      local_time_us_(-1),
424de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      rate_counter_(new RateCounter),
425b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      name_(""),
426caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      delay_cap_helper_(new DelayCapHelper()),
427caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      packets_per_second_stats_(),
428caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      kbps_stats_() {}
429de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
430de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.orgTraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
431de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    PacketProcessorListener* listener,
432de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org    const std::string& name)
43351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, false),
4347a560797ddeafa0472a0bd85aa9ad62b2530ffbastefan@webrtc.org      current_offset_us_(0),
435de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      delivery_times_us_(),
436de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      next_delivery_it_(),
437de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      local_time_us_(-1),
438de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org      rate_counter_(new RateCounter),
439b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      name_(name),
440caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      delay_cap_helper_(new DelayCapHelper()),
441caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      packets_per_second_stats_(),
442caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org      kbps_stats_() {}
443de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
444de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.orgTraceBasedDeliveryFilter::~TraceBasedDeliveryFilter() {
445de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org}
446ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org
447ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.orgbool TraceBasedDeliveryFilter::Init(const std::string& filename) {
448ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  FILE* trace_file = fopen(filename.c_str(), "r");
449ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  if (!trace_file) {
450ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    return false;
451ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  }
452ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  int64_t first_timestamp = -1;
453ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  while(!feof(trace_file)) {
454ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    const size_t kMaxLineLength = 100;
455ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    char line[kMaxLineLength];
456ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    if (fgets(line, kMaxLineLength, trace_file)) {
457ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      std::string line_string(line);
458ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      std::istringstream buffer(line_string);
459ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      int64_t timestamp;
460ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      buffer >> timestamp;
461ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      timestamp /= 1000;  // Convert to microseconds.
462ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      if (first_timestamp == -1)
463ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org        first_timestamp = timestamp;
464ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      assert(delivery_times_us_.empty() ||
465ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org             timestamp - first_timestamp - delivery_times_us_.back() >= 0);
466ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      delivery_times_us_.push_back(timestamp - first_timestamp);
467ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    }
468ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  }
469ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  assert(!delivery_times_us_.empty());
470ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  next_delivery_it_ = delivery_times_us_.begin();
471ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  fclose(trace_file);
472ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  return true;
473ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org}
474ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org
475de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.orgvoid TraceBasedDeliveryFilter::Plot(int64_t timestamp_ms) {
476de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  BWE_TEST_LOGGING_CONTEXT(name_.c_str());
477de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  // This plots the max possible throughput of the trace-based delivery filter,
478de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  // which will be reached if a packet sent on every packet slot of the trace.
479de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org  BWE_TEST_LOGGING_PLOT("MaxThroughput_#1", timestamp_ms,
480de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org                        rate_counter_->bits_per_second() / 1000.0);
481de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org}
482de93ce079f7ee5a42592e670d9f30d880e760a25stefan@webrtc.org
483ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.orgvoid TraceBasedDeliveryFilter::RunFor(int64_t time_ms, Packets* in_out) {
484ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  assert(in_out);
485b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  for (PacketsIt it = in_out->begin(); it != in_out->end();) {
486b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    while (local_time_us_ < it->send_time_us()) {
487b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      ProceedToNextSlot();
488b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    }
489b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    // Drop any packets that have been queued for too long.
490b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    while (!delay_cap_helper_->ShouldSendPacket(local_time_us_,
491b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org                                                it->send_time_us())) {
492b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      it = in_out->erase(it);
493b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      if (it == in_out->end()) {
494b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org        return;
495b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      }
496b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    }
497b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    if (local_time_us_ >= it->send_time_us()) {
498b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org      it->set_send_time_us(local_time_us_);
499ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      ProceedToNextSlot();
500b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    }
501b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org    ++it;
502ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  }
503caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org  packets_per_second_stats_.Push(rate_counter_->packets_per_second());
504caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org  kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
505ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org}
506ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org
507b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.orgvoid TraceBasedDeliveryFilter::SetMaxDelay(int max_delay_ms) {
508b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  delay_cap_helper_->SetMaxDelay(max_delay_ms);
509b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org}
510b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
511b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.orgStats<double> TraceBasedDeliveryFilter::GetDelayStats() const {
512b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  return delay_cap_helper_->delay_stats();
513b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org}
514b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org
515caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.orgStats<double> TraceBasedDeliveryFilter::GetBitrateStats() const {
516caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org  return kbps_stats_;
517caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org}
518caa56eb9a5ef6074f59a321bdf60f2a43503f805stefan@webrtc.org
519ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.orgvoid TraceBasedDeliveryFilter::ProceedToNextSlot() {
520ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  if (*next_delivery_it_ <= local_time_us_) {
521ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    ++next_delivery_it_;
522ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    if (next_delivery_it_ == delivery_times_us_.end()) {
523ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      // When the trace wraps we allow two packets to be sent back-to-back.
524ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      for (TimeList::iterator it = delivery_times_us_.begin();
525ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org           it != delivery_times_us_.end(); ++it) {
5267a560797ddeafa0472a0bd85aa9ad62b2530ffbastefan@webrtc.org        *it += local_time_us_ - current_offset_us_;
527ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      }
5287a560797ddeafa0472a0bd85aa9ad62b2530ffbastefan@webrtc.org      current_offset_us_ += local_time_us_ - current_offset_us_;
529ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org      next_delivery_it_ = delivery_times_us_.begin();
530ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org    }
531ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  }
532ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org  local_time_us_ = *next_delivery_it_;
533e823012b65d4260205a91a9381fd9cdf2057d6ddstefan@webrtc.org  const int kPayloadSize = 1200;
534b67e9b7527bc6b4a4d189f50de6f051985ac954estefan@webrtc.org  rate_counter_->UpdateRates(local_time_us_, kPayloadSize);
535ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org}
536ef6a602db36bf9d4fc7c2f1d69b2f04a56349edfstefan@webrtc.org
537cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgPacketSender::PacketSender(PacketProcessorListener* listener)
53851ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, true) {}
53951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org
54051ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgPacketSender::PacketSender(PacketProcessorListener* listener,
54151ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                           const FlowIds& flow_ids)
54251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketProcessor(listener, flow_ids, true) {
54351ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org
544cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
545cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
54651ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgVideoSender::VideoSender(int flow_id, PacketProcessorListener* listener,
54751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                         float fps, uint32_t kbps, uint32_t ssrc,
54851ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                         float first_frame_offset)
54951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : PacketSender(listener, FlowIds(1, flow_id)),
550e823012b65d4260205a91a9381fd9cdf2057d6ddstefan@webrtc.org      kMaxPayloadSizeBytes(1200),
551cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      kTimestampBase(0xff80ff00ul),
552cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      frame_period_ms_(1000.0 / fps),
553cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      bytes_per_second_((1000 * kbps) / 8),
554cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      frame_size_bytes_(bytes_per_second_ / fps),
55576dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org      next_frame_ms_(frame_period_ms_ * first_frame_offset),
55676dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org      now_ms_(0.0),
557cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      prototype_header_() {
558cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(first_frame_offset >= 0.0f);
559cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(first_frame_offset < 1.0f);
560cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  memset(&prototype_header_, 0, sizeof(prototype_header_));
561cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  prototype_header_.ssrc = ssrc;
562cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  prototype_header_.sequenceNumber = 0xf000u;
563cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
564cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
565cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orguint32_t VideoSender::GetCapacityKbps() const {
566cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  return (bytes_per_second_ * 8) / 1000;
567cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
568cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
569cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
570cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  assert(in_out);
571cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  now_ms_ += time_ms;
57251ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  Packets new_packets;
573cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  while (now_ms_ >= next_frame_ms_) {
574cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    prototype_header_.timestamp = kTimestampBase +
575cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org        static_cast<uint32_t>(next_frame_ms_ * 90.0);
576cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    prototype_header_.extension.transmissionTimeOffset = 0;
577cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
578cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    // Generate new packets for this frame, all with the same timestamp,
579cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    // but the payload size is capped, so if the whole frame doesn't fit in
580cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    // one packet, we will see a number of equally sized packets followed by
581cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    // one smaller at the tail.
582cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    int64_t send_time_us = next_frame_ms_ * 1000.0;
583cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    uint32_t payload_size = frame_size_bytes_;
584cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    while (payload_size > 0) {
585c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      ++prototype_header_.sequenceNumber;
586cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      uint32_t size = std::min(kMaxPayloadSizeBytes, payload_size);
58751ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org      new_packets.push_back(Packet(flow_ids()[0], send_time_us, size,
58851ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                                   prototype_header_));
589c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      new_packets.back().SetAbsSendTimeMs(next_frame_ms_);
590cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      payload_size -= size;
591cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    }
592cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
593cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    next_frame_ms_ += frame_period_ms_;
594cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
59551ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org  in_out->merge(new_packets);
596cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
59776dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org
59851ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.orgAdaptiveVideoSender::AdaptiveVideoSender(int flow_id,
59951ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org                                         PacketProcessorListener* listener,
60076dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org                                         float fps,
60176dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org                                         uint32_t kbps,
60276dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org                                         uint32_t ssrc,
60376dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org                                         float first_frame_offset)
60451ef6b0a9d93b12a6a2d31a8ecb3b5e5dcc0cbe3stefan@webrtc.org    : VideoSender(flow_id, listener, fps, kbps, ssrc, first_frame_offset) {}
60576dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org
60676dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.orgvoid AdaptiveVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
60776dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org  bytes_per_second_ = feedback.estimated_bps / 8;
60876dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org  frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
60976dcaae0f350051ae2a9364ee92f65f9683c5b24stefan@webrtc.org}
610c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org
611c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.orgPacedVideoSender::PacedVideoSender(PacketProcessorListener* listener,
612c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                                   uint32_t kbps,
613c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                                   AdaptiveVideoSender* source)
614c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    // It is important that the first_frame_offset and the initial time of
615c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    // clock_ are both zero, otherwise we can't have absolute time in this
616c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    // class.
617c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    : PacketSender(listener, source->flow_ids()),
618c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      clock_(0),
619c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      start_of_run_ms_(0),
620c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      pacer_(&clock_, this, PacedSender::kDefaultPaceMultiplier * kbps, 0),
621c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      source_(source) {}
622c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org
623c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.orgvoid PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
624c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  start_of_run_ms_ = clock_.TimeInMilliseconds();
625c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  Packets generated_packets;
626c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  source_->RunFor(time_ms, &generated_packets);
627c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  Packets::iterator it = generated_packets.begin();
628c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  // Run process periodically to allow the packets to be paced out.
629c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  const int kProcessIntervalMs = 10;
630c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  for (int64_t current_time = 0; current_time < time_ms;
631c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org       current_time += kProcessIntervalMs) {
632c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    int64_t end_of_interval_us =
633c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org        1000 * (clock_.TimeInMilliseconds() + kProcessIntervalMs);
634c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    while (it != generated_packets.end() &&
635c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org           end_of_interval_us >= it->send_time_us()) {
636c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      // Time to send next packet to pacer.
637c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      pacer_.SendPacket(PacedSender::kNormalPriority,
638c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                        it->header().ssrc,
639c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                        it->header().sequenceNumber,
640c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                        (it->send_time_us() + 500) / 1000,
641c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                        it->payload_size(),
642c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                        false);
643c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      pacer_queue_.push_back(*it);
644c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      const size_t kMaxPacerQueueSize = 1000;
645c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      if (pacer_queue_.size() > kMaxPacerQueueSize) {
646c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org        pacer_queue_.pop_front();
647c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      }
648c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      ++it;
649c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    }
650c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
651c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    pacer_.Process();
652c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  }
653c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  QueuePackets(in_out, (start_of_run_ms_ + time_ms) * 1000);
654c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org}
655c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org
656c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.orgvoid PacedVideoSender::QueuePackets(Packets* batch,
657c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                                    int64_t end_of_batch_time_us) {
658c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  queue_.merge(*batch);
659c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  if (queue_.empty()) {
660c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    return;
661c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  }
662c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  Packets::iterator it = queue_.begin();
663c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  for (; it != queue_.end(); ++it) {
664c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    if (it->send_time_us() > end_of_batch_time_us) {
665c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      break;
666c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    }
667c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  }
668c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  Packets to_transfer;
669c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it);
670c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  batch->merge(to_transfer);
671c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org}
672c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org
673c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.orgvoid PacedVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
674c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  source_->GiveFeedback(feedback);
675c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  pacer_.UpdateBitrate(
676c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      PacedSender::kDefaultPaceMultiplier * feedback.estimated_bps / 1000, 0);
677c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org}
678c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org
679c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.orgbool PacedVideoSender::TimeToSendPacket(uint32_t ssrc,
680c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                                        uint16_t sequence_number,
681c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                                        int64_t capture_time_ms,
682c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org                                        bool retransmission) {
683c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end();
684c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org       ++it) {
685c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    if (it->header().sequenceNumber == sequence_number) {
686c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      int64_t pace_out_time_ms = clock_.TimeInMilliseconds();
687c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      // Make sure a packet is never paced out earlier than when it was put into
688c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      // the pacer.
689c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      assert(1000 * pace_out_time_ms >= it->send_time_us());
690c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      it->SetAbsSendTimeMs(pace_out_time_ms);
691c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      it->set_send_time_us(1000 * pace_out_time_ms);
692c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      queue_.push_back(*it);
693c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org      return true;
694c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org    }
695c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  }
696c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  return false;
697c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org}
698c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org
699c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.orgint PacedVideoSender::TimeToSendPadding(int bytes) {
700c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org  return 0;
701c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org}
7024b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org}  // namespace bwe
7034b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org}  // namespace testing
7044b3ff2d418644bf4ce29763db9a406fd1e16cbf5solenberg@webrtc.org}  // namespace webrtc
705