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