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