blob: 1cfaa382f49e9d91f7afb8968adff733a15d064a [file] [log] [blame]
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +00001/*
2 * Copyright (c) 2012 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 Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef TEST_FAKE_NETWORK_PIPE_H_
12#define TEST_FAKE_NETWORK_PIPE_H_
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000013
philipela2c55232016-01-26 08:41:53 -080014#include <string.h>
minyue20c84cc2017-04-10 16:57:57 -070015#include <map>
16#include <memory>
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000017#include <queue>
minyue20c84cc2017-04-10 16:57:57 -070018#include <set>
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000019
Mirko Bonadei71207422017-09-15 13:58:09 +020020#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/constructormagic.h"
22#include "rtc_base/criticalsection.h"
23#include "rtc_base/random.h"
Mirko Bonadei71207422017-09-15 13:58:09 +020024#include "typedefs.h" // NOLINT(build/include)
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000025
26namespace webrtc {
27
Peter Boströmd3c94472015-12-09 11:20:58 +010028class Clock;
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000029class PacketReceiver;
nissee5ad5ca2017-03-29 23:57:43 -070030enum class MediaType;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000031
philipela2c55232016-01-26 08:41:53 -080032class NetworkPacket {
33 public:
34 NetworkPacket(const uint8_t* data,
35 size_t length,
36 int64_t send_time,
37 int64_t arrival_time)
38 : data_(new uint8_t[length]),
39 data_length_(length),
40 send_time_(send_time),
41 arrival_time_(arrival_time) {
42 memcpy(data_.get(), data, length);
43 }
44
45 uint8_t* data() const { return data_.get(); }
46 size_t data_length() const { return data_length_; }
47 int64_t send_time() const { return send_time_; }
48 int64_t arrival_time() const { return arrival_time_; }
49 void IncrementArrivalTime(int64_t extra_delay) {
50 arrival_time_ += extra_delay;
51 }
52
53 private:
54 // The packet data.
kwibergbfefb032016-05-01 14:53:46 -070055 std::unique_ptr<uint8_t[]> data_;
philipela2c55232016-01-26 08:41:53 -080056 // Length of data_.
57 size_t data_length_;
58 // The time the packet was sent out on the network.
59 const int64_t send_time_;
60 // The time the packet should arrive at the receiver.
61 int64_t arrival_time_;
62};
63
minyue20c84cc2017-04-10 16:57:57 -070064class Demuxer {
65 public:
66 virtual ~Demuxer() = default;
67 virtual void SetReceiver(PacketReceiver* receiver) = 0;
68 virtual void DeliverPacket(const NetworkPacket* packet,
69 const PacketTime& packet_time) = 0;
70};
71
72class DemuxerImpl final : public Demuxer {
73 public:
74 explicit DemuxerImpl(const std::map<uint8_t, MediaType>& payload_type_map);
75
76 void SetReceiver(PacketReceiver* receiver) override;
77 void DeliverPacket(const NetworkPacket* packet,
78 const PacketTime& packet_time) override;
79
80 private:
81 PacketReceiver* packet_receiver_;
82 const std::map<uint8_t, MediaType> payload_type_map_;
83 RTC_DISALLOW_COPY_AND_ASSIGN(DemuxerImpl);
84};
85
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000086// Class faking a network link. This is a simple and naive solution just faking
87// capacity and adding an extra transport delay in addition to the capacity
88// introduced delay.
89
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000090class FakeNetworkPipe {
91 public:
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000092 struct Config {
Peter Boströmd3c94472015-12-09 11:20:58 +010093 Config() {}
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000094 // Queue length in number of packets.
Peter Boströmd3c94472015-12-09 11:20:58 +010095 size_t queue_length_packets = 0;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000096 // Delay in addition to capacity induced delay.
Peter Boströmd3c94472015-12-09 11:20:58 +010097 int queue_delay_ms = 0;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000098 // Standard deviation of the extra delay.
Peter Boströmd3c94472015-12-09 11:20:58 +010099 int delay_standard_deviation_ms = 0;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000100 // Link capacity in kbps.
Peter Boströmd3c94472015-12-09 11:20:58 +0100101 int link_capacity_kbps = 0;
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +0000102 // Random packet loss.
Peter Boströmd3c94472015-12-09 11:20:58 +0100103 int loss_percent = 0;
philipela2c55232016-01-26 08:41:53 -0800104 // If packets are allowed to be reordered.
105 bool allow_reordering = false;
philipel536378b2016-05-31 03:20:23 -0700106 // The average length of a burst of lost packets.
107 int avg_burst_loss_length = -1;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000108 };
109
philipela2c55232016-01-26 08:41:53 -0800110 FakeNetworkPipe(Clock* clock,
minyue20c84cc2017-04-10 16:57:57 -0700111 const FakeNetworkPipe::Config& config,
112 std::unique_ptr<Demuxer> demuxer);
113 FakeNetworkPipe(Clock* clock,
114 const FakeNetworkPipe::Config& config,
115 std::unique_ptr<Demuxer> demuxer,
philipela2c55232016-01-26 08:41:53 -0800116 uint64_t seed);
Christoffer Rodbrod2817d82017-10-24 16:26:49 +0200117 virtual ~FakeNetworkPipe();
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000118
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52 +0000119 // Sets a new configuration. This won't affect packets already in the pipe.
120 void SetConfig(const FakeNetworkPipe::Config& config);
121
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000122 // Sends a new packet to the link.
Christoffer Rodbrod2817d82017-10-24 16:26:49 +0200123 virtual void SendPacket(const uint8_t* packet, size_t packet_length);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000124
minyue20c84cc2017-04-10 16:57:57 -0700125 // Must not be called in parallel with SendPacket or Process.
126 void SetReceiver(PacketReceiver* receiver);
127
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000128 // Processes the network queues and trigger PacketReceiver::IncomingPacket for
129 // packets ready to be delivered.
Christoffer Rodbrod2817d82017-10-24 16:26:49 +0200130 virtual void Process();
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000131 int64_t TimeUntilNextProcess() const;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000132
133 // Get statistics.
134 float PercentageLoss();
135 int AverageDelay();
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000136 size_t dropped_packets() { return dropped_packets_; }
137 size_t sent_packets() { return sent_packets_; }
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000138
Christoffer Rodbrod2817d82017-10-24 16:26:49 +0200139 protected:
Peter Boströmd3c94472015-12-09 11:20:58 +0100140 Clock* const clock_;
pbos5ad935c2016-01-25 03:52:44 -0800141 rtc::CriticalSection lock_;
minyue20c84cc2017-04-10 16:57:57 -0700142 const std::unique_ptr<Demuxer> demuxer_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000143 std::queue<NetworkPacket*> capacity_link_;
philipela2c55232016-01-26 08:41:53 -0800144 Random random_;
145
146 // Since we need to access both the packet with the earliest and latest
147 // arrival time we need to use a multiset to keep all packets sorted,
148 // hence, we cannot use a priority queue.
149 struct PacketArrivalTimeComparator {
150 bool operator()(const NetworkPacket* p1, const NetworkPacket* p2) {
151 return p1->arrival_time() < p2->arrival_time();
152 }
153 };
154 std::multiset<NetworkPacket*, PacketArrivalTimeComparator> delay_link_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000155
156 // Link configuration.
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000157 Config config_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000158
159 // Statistics.
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000160 size_t dropped_packets_;
161 size_t sent_packets_;
Stefan Holmerff2a6352016-01-14 10:00:21 +0100162 int64_t total_packet_delay_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000163
philipel536378b2016-05-31 03:20:23 -0700164 // Are we currently dropping a burst of packets?
165 bool bursting_;
166
167 // The probability to drop the packet if we are currently dropping a
168 // burst of packet
169 double prob_loss_bursting_;
170
171 // The probability to drop a burst of packets.
172 double prob_start_bursting_;
173
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000174 int64_t next_process_time_;
175
stefane9ad2712017-02-10 06:09:28 -0800176 int64_t last_log_time_;
177
philipel19f51432017-09-07 09:08:50 -0700178 int64_t capacity_delay_error_bytes_ = 0;
179
henrikg3c089d72015-09-16 05:37:44 -0700180 RTC_DISALLOW_COPY_AND_ASSIGN(FakeNetworkPipe);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000181};
182
183} // namespace webrtc
184
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200185#endif // TEST_FAKE_NETWORK_PIPE_H_