stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 11 | #ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_H_ |
| 12 | #define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_H_ |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 13 | |
terelius | 8f09f17 | 2015-12-15 00:51:54 -0800 | [diff] [blame] | 14 | #include <list> |
| 15 | #include <map> |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 16 | #include <sstream> |
terelius | 8f09f17 | 2015-12-15 00:51:54 -0800 | [diff] [blame] | 17 | #include <string> |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 18 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 19 | #include "modules/bitrate_controller/include/bitrate_controller.h" |
| 20 | #include "modules/remote_bitrate_estimator/test/bwe_test_framework.h" |
| 21 | #include "modules/remote_bitrate_estimator/test/packet.h" |
| 22 | #include "rtc_base/constructormagic.h" |
| 23 | #include "rtc_base/gtest_prod_util.h" |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 24 | |
| 25 | namespace webrtc { |
| 26 | namespace testing { |
| 27 | namespace bwe { |
| 28 | |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 29 | // Overload map comparator. |
| 30 | class SequenceNumberOlderThan { |
| 31 | public: |
| 32 | bool operator()(uint16_t seq_num_1, uint16_t seq_num_2) const { |
| 33 | return IsNewerSequenceNumber(seq_num_2, seq_num_1); |
| 34 | } |
| 35 | }; |
| 36 | |
| 37 | // Holds information for computing global packet loss. |
| 38 | struct LossAccount { |
| 39 | LossAccount() : num_total(0), num_lost(0) {} |
| 40 | LossAccount(size_t num_total, size_t num_lost) |
| 41 | : num_total(num_total), num_lost(num_lost) {} |
| 42 | void Add(LossAccount rhs); |
| 43 | void Subtract(LossAccount rhs); |
| 44 | float LossRatio(); |
| 45 | size_t num_total; |
| 46 | size_t num_lost; |
| 47 | }; |
| 48 | |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 49 | // Holds only essential information about packets to be saved for |
| 50 | // further use, e.g. for calculating packet loss and receiving rate. |
| 51 | struct PacketIdentifierNode { |
| 52 | PacketIdentifierNode(uint16_t sequence_number, |
| 53 | int64_t send_time_ms, |
| 54 | int64_t arrival_time_ms, |
| 55 | size_t payload_size) |
| 56 | : sequence_number(sequence_number), |
| 57 | send_time_ms(send_time_ms), |
| 58 | arrival_time_ms(arrival_time_ms), |
| 59 | payload_size(payload_size) {} |
| 60 | |
| 61 | uint16_t sequence_number; |
| 62 | int64_t send_time_ms; |
| 63 | int64_t arrival_time_ms; |
| 64 | size_t payload_size; |
| 65 | }; |
| 66 | |
| 67 | typedef std::list<PacketIdentifierNode*>::iterator PacketNodeIt; |
| 68 | |
| 69 | // FIFO implementation for a limited capacity set. |
| 70 | // Used for keeping the latest arrived packets while avoiding duplicates. |
| 71 | // Allows efficient insertion, deletion and search. |
| 72 | class LinkedSet { |
| 73 | public: |
| 74 | explicit LinkedSet(int capacity) : capacity_(capacity) {} |
stefan | 870eee4 | 2015-07-14 03:53:57 -0700 | [diff] [blame] | 75 | ~LinkedSet(); |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 76 | |
| 77 | // If the arriving packet (identified by its sequence number) is already |
| 78 | // in the LinkedSet, move its Node to the head of the list. Else, create |
| 79 | // a PacketIdentifierNode n_ and then UpdateHead(n_), calling RemoveTail() |
| 80 | // if the LinkedSet reached its maximum capacity. |
| 81 | void Insert(uint16_t sequence_number, |
| 82 | int64_t send_time_ms, |
| 83 | int64_t arrival_time_ms, |
| 84 | size_t payload_size); |
| 85 | |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 86 | void Insert(PacketIdentifierNode packet_identifier); |
| 87 | |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 88 | PacketNodeIt begin() { return list_.begin(); } |
| 89 | PacketNodeIt end() { return list_.end(); } |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 90 | |
| 91 | bool empty() const { return list_.empty(); } |
| 92 | size_t size() const { return list_.size(); } |
| 93 | size_t capacity() const { return capacity_; } |
| 94 | |
| 95 | uint16_t OldestSeqNumber() const { return empty() ? 0 : map_.begin()->first; } |
| 96 | uint16_t NewestSeqNumber() const { |
| 97 | return empty() ? 0 : map_.rbegin()->first; |
| 98 | } |
| 99 | |
| 100 | void Erase(PacketNodeIt node_it); |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 101 | |
| 102 | private: |
| 103 | // Pop oldest element from the back of the list and remove it from the map. |
| 104 | void RemoveTail(); |
| 105 | // Add new element to the front of the list and insert it in the map. |
| 106 | void UpdateHead(PacketIdentifierNode* new_head); |
| 107 | size_t capacity_; |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 108 | std::map<uint16_t, PacketNodeIt, SequenceNumberOlderThan> map_; |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 109 | std::list<PacketIdentifierNode*> list_; |
| 110 | }; |
| 111 | |
stefan | db75438 | 2016-08-04 06:42:07 -0700 | [diff] [blame] | 112 | const int kMinBitrateKbps = 10; |
terelius | 182e4a4 | 2016-12-01 07:29:09 -0800 | [diff] [blame] | 113 | const int kMaxBitrateKbps = 25000; |
sprang@webrtc.org | db8e605 | 2015-02-24 13:24:19 +0000 | [diff] [blame] | 114 | |
stefan@webrtc.org | 7663684 | 2015-02-17 16:03:45 +0000 | [diff] [blame] | 115 | class BweSender : public Module { |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 116 | public: |
stefan@webrtc.org | 7663684 | 2015-02-17 16:03:45 +0000 | [diff] [blame] | 117 | BweSender() {} |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 118 | explicit BweSender(int bitrate_kbps) : bitrate_kbps_(bitrate_kbps) {} |
stefan@webrtc.org | 7663684 | 2015-02-17 16:03:45 +0000 | [diff] [blame] | 119 | virtual ~BweSender() {} |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 120 | |
| 121 | virtual int GetFeedbackIntervalMs() const = 0; |
| 122 | virtual void GiveFeedback(const FeedbackPacket& feedback) = 0; |
stefan@webrtc.org | 4346d92 | 2015-03-18 13:40:54 +0000 | [diff] [blame] | 123 | virtual void OnPacketsSent(const Packets& packets) = 0; |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 124 | |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 125 | protected: |
| 126 | int bitrate_kbps_; |
| 127 | |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 128 | private: |
henrikg | 3c089d7 | 2015-09-16 05:37:44 -0700 | [diff] [blame] | 129 | RTC_DISALLOW_COPY_AND_ASSIGN(BweSender); |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 130 | }; |
| 131 | |
| 132 | class BweReceiver { |
| 133 | public: |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 134 | explicit BweReceiver(int flow_id); |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 135 | BweReceiver(int flow_id, int64_t window_size_ms); |
| 136 | |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 137 | virtual ~BweReceiver() {} |
| 138 | |
| 139 | virtual void ReceivePacket(int64_t arrival_time_ms, |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 140 | const MediaPacket& media_packet); |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 141 | virtual FeedbackPacket* GetFeedback(int64_t now_ms) { return NULL; } |
| 142 | |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 143 | size_t GetSetCapacity() { return received_packets_.capacity(); } |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 144 | double BitrateWindowS() const { return rate_counter_.BitrateWindowS(); } |
| 145 | uint32_t RecentKbps() const; // Receiving Rate. |
| 146 | |
| 147 | // Computes packet loss during an entire simulation, up to 4 billion packets. |
| 148 | float GlobalReceiverPacketLossRatio(); // Plot histogram. |
| 149 | float RecentPacketLossRatio(); // Plot dynamics. |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 150 | |
| 151 | static const int64_t kPacketLossTimeWindowMs = 500; |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 152 | static const int64_t kReceivingRateTimeWindowMs = 1000; |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 153 | |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 154 | protected: |
| 155 | int flow_id_; |
Cesar Magalhaes | 77cabab | 2015-06-08 11:29:08 +0200 | [diff] [blame] | 156 | // Deals with packets sent more than once. |
| 157 | LinkedSet received_packets_; |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 158 | // Used for calculating recent receiving rate. |
| 159 | RateCounter rate_counter_; |
| 160 | |
| 161 | private: |
| 162 | FRIEND_TEST_ALL_PREFIXES(BweReceiverTest, RecentKbps); |
| 163 | FRIEND_TEST_ALL_PREFIXES(BweReceiverTest, Loss); |
| 164 | |
| 165 | void UpdateLoss(); |
| 166 | void RelieveSetAndUpdateLoss(); |
| 167 | // Packet loss for packets stored in the LinkedSet, up to 1000 packets. |
| 168 | // Used to update global loss account whenever the set is filled and cleared. |
| 169 | LossAccount LinkedSetPacketLossRatio(); |
| 170 | |
| 171 | // Used for calculating global packet loss ratio. |
| 172 | LossAccount loss_account_; |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 173 | }; |
| 174 | |
| 175 | enum BandwidthEstimatorType { |
| 176 | kNullEstimator, |
stefan@webrtc.org | 7663684 | 2015-02-17 16:03:45 +0000 | [diff] [blame] | 177 | kNadaEstimator, |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 178 | kRembEstimator, |
terelius | 2d81eb3 | 2016-10-25 07:04:37 -0700 | [diff] [blame] | 179 | kSendSideEstimator, |
gnish | 6dcdf10 | 2017-06-05 06:01:26 -0700 | [diff] [blame] | 180 | kTcpEstimator, |
| 181 | kBbrEstimator |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 182 | }; |
| 183 | |
gnish | 6dcdf10 | 2017-06-05 06:01:26 -0700 | [diff] [blame] | 184 | const char* const bwe_names[] = {"Null", "NADA", "REMB", "GCC", "TCP", "BBR"}; |
Cesar Magalhaes | 9c261f2 | 2015-07-15 16:31:18 +0200 | [diff] [blame] | 185 | |
sprang@webrtc.org | db8e605 | 2015-02-24 13:24:19 +0000 | [diff] [blame] | 186 | int64_t GetAbsSendTimeInMs(uint32_t abs_send_time); |
| 187 | |
stefan@webrtc.org | 7663684 | 2015-02-17 16:03:45 +0000 | [diff] [blame] | 188 | BweSender* CreateBweSender(BandwidthEstimatorType estimator, |
| 189 | int kbps, |
| 190 | BitrateObserver* observer, |
| 191 | Clock* clock); |
stefan@webrtc.org | 14b0279 | 2015-02-16 12:02:20 +0000 | [diff] [blame] | 192 | |
| 193 | BweReceiver* CreateBweReceiver(BandwidthEstimatorType type, |
| 194 | int flow_id, |
| 195 | bool plot); |
| 196 | } // namespace bwe |
| 197 | } // namespace testing |
| 198 | } // namespace webrtc |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 199 | #endif // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_H_ |