blob: fd540fb9b6916beb1c0c4671333e9ba6fae4673f [file] [log] [blame]
Erik Språng09708512018-03-14 15:16:50 +01001/*
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
11#ifndef CALL_FAKE_NETWORK_PIPE_H_
12#define CALL_FAKE_NETWORK_PIPE_H_
13
14#include <deque>
15#include <map>
16#include <memory>
17#include <queue>
Sebastian Jansson7ee2e252018-05-07 14:49:39 +020018#include <set>
Erik Språng09708512018-03-14 15:16:50 +010019#include <string>
Sebastian Jansson7ee2e252018-05-07 14:49:39 +020020#include <vector>
Erik Språng09708512018-03-14 15:16:50 +010021
22#include "api/call/transport.h"
Patrik Höglundb6b29e02018-06-21 16:58:01 +020023#include "api/test/simulated_network.h"
Erik Språng09708512018-03-14 15:16:50 +010024#include "call/call.h"
Artem Titov46c4e602018-08-17 14:26:54 +020025#include "call/simulated_packet_receiver.h"
Erik Språng09708512018-03-14 15:16:50 +010026#include "common_types.h" // NOLINT(build/include)
Erik Språng09708512018-03-14 15:16:50 +010027#include "rtc_base/constructormagic.h"
28#include "rtc_base/criticalsection.h"
Erik Språng09708512018-03-14 15:16:50 +010029#include "rtc_base/thread_annotations.h"
Erik Språng09708512018-03-14 15:16:50 +010030
31namespace webrtc {
32
33class Clock;
34class PacketReceiver;
35enum class MediaType;
36
37class NetworkPacket {
38 public:
39 NetworkPacket(rtc::CopyOnWriteBuffer packet,
40 int64_t send_time,
41 int64_t arrival_time,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020042 absl::optional<PacketOptions> packet_options,
Erik Språng09708512018-03-14 15:16:50 +010043 bool is_rtcp,
Niels Möller70082872018-08-07 11:03:12 +020044 MediaType media_type,
45 absl::optional<int64_t> packet_time_us);
Niels Möller70082872018-08-07 11:03:12 +020046
Christoffer Rodbro8ef59a42018-03-20 14:34:01 +010047 // Disallow copy constructor and copy assignment (no deep copies of |data_|).
Erik Språng09708512018-03-14 15:16:50 +010048 NetworkPacket(const NetworkPacket&) = delete;
Mirko Bonadeied1dcf92018-07-26 09:15:11 +020049 ~NetworkPacket();
Christoffer Rodbro8ef59a42018-03-20 14:34:01 +010050 NetworkPacket& operator=(const NetworkPacket&) = delete;
Erik Språng09708512018-03-14 15:16:50 +010051 // Allow move constructor/assignment, so that we can use in stl containers.
52 NetworkPacket(NetworkPacket&&);
53 NetworkPacket& operator=(NetworkPacket&&);
54
55 const uint8_t* data() const { return packet_.data(); }
56 size_t data_length() const { return packet_.size(); }
57 rtc::CopyOnWriteBuffer* raw_packet() { return &packet_; }
58 int64_t send_time() const { return send_time_; }
59 int64_t arrival_time() const { return arrival_time_; }
60 void IncrementArrivalTime(int64_t extra_delay) {
61 arrival_time_ += extra_delay;
62 }
63 PacketOptions packet_options() const {
64 return packet_options_.value_or(PacketOptions());
65 }
66 bool is_rtcp() const { return is_rtcp_; }
67 MediaType media_type() const { return media_type_; }
Niels Möller70082872018-08-07 11:03:12 +020068 absl::optional<int64_t> packet_time_us() const { return packet_time_us_; }
Erik Språng09708512018-03-14 15:16:50 +010069
70 private:
71 rtc::CopyOnWriteBuffer packet_;
72 // The time the packet was sent out on the network.
73 int64_t send_time_;
74 // The time the packet should arrive at the receiver.
75 int64_t arrival_time_;
76 // If using a Transport for outgoing degradation, populate with
77 // PacketOptions (transport-wide sequence number) for RTP.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020078 absl::optional<PacketOptions> packet_options_;
Erik Språng09708512018-03-14 15:16:50 +010079 bool is_rtcp_;
80 // If using a PacketReceiver for incoming degradation, populate with
81 // appropriate MediaType and PacketTime. This type/timing will be kept and
82 // forwarded. The PacketTime might be altered to reflect time spent in fake
83 // network pipe.
84 MediaType media_type_;
Niels Möller70082872018-08-07 11:03:12 +020085 absl::optional<int64_t> packet_time_us_;
Erik Språng09708512018-03-14 15:16:50 +010086};
87
Sebastian Jansson7ee2e252018-05-07 14:49:39 +020088// Class faking a network link, internally is uses an implementation of a
89// SimulatedNetworkInterface to simulate network behavior.
Artem Titov46c4e602018-08-17 14:26:54 +020090class FakeNetworkPipe : public webrtc::SimulatedPacketReceiverInterface,
91 public Transport {
Sebastian Jansson7ee2e252018-05-07 14:49:39 +020092 public:
Artem Titov847a9c72018-08-14 15:44:31 +020093 using Config = NetworkSimulationInterface::SimulatedNetworkConfig;
Erik Språng09708512018-03-14 15:16:50 +010094
Artem Titovb0050872018-08-16 17:02:20 +020095 // Deprecated. DO NOT USE. To be removed. Use corresponding version with
96 // NetworkSimulationInterface instance instead.
Sebastian Jansson09408112018-04-24 14:41:22 +020097 // Use these constructors if you plan to insert packets using DeliverPacket().
Erik Språng09708512018-03-14 15:16:50 +010098 FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config);
Artem Titov537b7fe2018-08-16 11:20:45 +020099 // Will keep |network_simulation| alive while pipe is alive itself.
Artem Titovb0050872018-08-16 17:02:20 +0200100 // Use these constructors if you plan to insert packets using DeliverPacket().
Artem Titov537b7fe2018-08-16 11:20:45 +0200101 FakeNetworkPipe(
102 Clock* clock,
103 std::unique_ptr<NetworkSimulationInterface> network_simulation);
Artem Titovb0050872018-08-16 17:02:20 +0200104 // Deprecated. DO NOT USE. To be removed. Use corresponding version with
105 // NetworkSimulationInterface instance instead.
Erik Språng09708512018-03-14 15:16:50 +0100106 FakeNetworkPipe(Clock* clock,
107 const FakeNetworkPipe::Config& config,
Sebastian Jansson09408112018-04-24 14:41:22 +0200108 PacketReceiver* receiver);
Artem Titovb0050872018-08-16 17:02:20 +0200109 FakeNetworkPipe(
110 Clock* clock,
111 std::unique_ptr<NetworkSimulationInterface> network_simulation,
112 PacketReceiver* receiver);
113 // Deprecated. DO NOT USE. To be removed. Use corresponding version with
114 // NetworkSimulationInterface instance instead.
Erik Språng09708512018-03-14 15:16:50 +0100115 FakeNetworkPipe(Clock* clock,
116 const FakeNetworkPipe::Config& config,
Sebastian Jansson09408112018-04-24 14:41:22 +0200117 PacketReceiver* receiver,
Erik Språng09708512018-03-14 15:16:50 +0100118 uint64_t seed);
Artem Titovb0050872018-08-16 17:02:20 +0200119 FakeNetworkPipe(
120 Clock* clock,
121 std::unique_ptr<NetworkSimulationInterface> network_simulation,
122 PacketReceiver* receiver,
123 uint64_t seed);
Erik Språng09708512018-03-14 15:16:50 +0100124
Artem Titovb0050872018-08-16 17:02:20 +0200125 // Deprecated. DO NOT USE. To be removed. Use corresponding version with
126 // NetworkSimulationInterface instance instead.
Erik Språng09708512018-03-14 15:16:50 +0100127 // Use this constructor if you plan to insert packets using SendRt[c?]p().
128 FakeNetworkPipe(Clock* clock,
129 const FakeNetworkPipe::Config& config,
130 Transport* transport);
Artem Titovb0050872018-08-16 17:02:20 +0200131 // Use this constructor if you plan to insert packets using SendRt[c?]p().
132 FakeNetworkPipe(
133 Clock* clock,
134 std::unique_ptr<NetworkSimulationInterface> network_simulation,
135 Transport* transport);
Erik Språng09708512018-03-14 15:16:50 +0100136
Mirko Bonadeied1dcf92018-07-26 09:15:11 +0200137 ~FakeNetworkPipe() override;
Erik Språng09708512018-03-14 15:16:50 +0100138
Artem Titovc02df812018-08-20 10:03:22 +0200139 void SetClockOffset(int64_t offset_ms);
Sebastian Jansson7e85d672018-04-06 09:56:21 +0200140
Artem Titovb0050872018-08-16 17:02:20 +0200141 // Deprecated. DO NOT USE. Hold direct reference on NetworkSimulationInterface
142 // instead and call SetConfig on that object directly. Will be removed soon.
Erik Språng09708512018-03-14 15:16:50 +0100143 // Sets a new configuration. This won't affect packets already in the pipe.
Artem Titov46c4e602018-08-17 14:26:54 +0200144 void SetConfig(const DefaultNetworkSimulationConfig& config) override;
Erik Språng09708512018-03-14 15:16:50 +0100145
Sebastian Jansson09408112018-04-24 14:41:22 +0200146 // Must not be called in parallel with DeliverPacket or Process.
Artem Titov46c4e602018-08-17 14:26:54 +0200147 void SetReceiver(PacketReceiver* receiver) override;
Erik Språng09708512018-03-14 15:16:50 +0100148
149 // Implements Transport interface. When/if packets are delivered, they will
150 // be passed to the transport instance given in SetReceiverTransport(). These
151 // methods should only be called if a Transport instance was provided in the
152 // constructor.
153 bool SendRtp(const uint8_t* packet,
154 size_t length,
155 const PacketOptions& options) override;
156 bool SendRtcp(const uint8_t* packet, size_t length) override;
157
158 // Implements the PacketReceiver interface. When/if packets are delivered,
159 // they will be passed directly to the receiver instance given in
160 // SetReceiver(), without passing through a Demuxer. The receive time in
161 // PacketTime will be increased by the amount of time the packet spent in the
162 // fake network pipe.
Niels Möller70082872018-08-07 11:03:12 +0200163 PacketReceiver::DeliveryStatus DeliverPacket(MediaType media_type,
164 rtc::CopyOnWriteBuffer packet,
165 int64_t packet_time_us) override;
166
167 // TODO(bugs.webrtc.org/9584): Needed to inherit the alternative signature for
168 // this method.
169 using PacketReceiver::DeliverPacket;
Erik Språng09708512018-03-14 15:16:50 +0100170
171 // Processes the network queues and trigger PacketReceiver::IncomingPacket for
172 // packets ready to be delivered.
173 void Process() override;
174 int64_t TimeUntilNextProcess() override;
175
176 // Get statistics.
177 float PercentageLoss();
Artem Titov46c4e602018-08-17 14:26:54 +0200178 int AverageDelay() override;
Erik Språng09708512018-03-14 15:16:50 +0100179 size_t DroppedPackets();
180 size_t SentPackets();
Christoffer Rodbro8ef59a42018-03-20 14:34:01 +0100181 void ResetStats();
182
183 protected:
184 void DeliverPacketWithLock(NetworkPacket* packet);
Christoffer Rodbro8ef59a42018-03-20 14:34:01 +0100185 void AddToPacketDropCount();
186 void AddToPacketSentCount(int count);
Sebastian Jansson512bdce2018-04-23 13:15:04 +0200187 void AddToTotalDelay(int delay_us);
188 int64_t GetTimeInMicroseconds() const;
Sebastian Jansson512bdce2018-04-23 13:15:04 +0200189 bool ShouldProcess(int64_t time_now_us) const;
190 void SetTimeToNextProcess(int64_t skip_us);
Erik Språng09708512018-03-14 15:16:50 +0100191
192 private:
Sebastian Jansson7ee2e252018-05-07 14:49:39 +0200193 struct StoredPacket {
194 NetworkPacket packet;
195 bool removed = false;
196 explicit StoredPacket(NetworkPacket&& packet);
197 StoredPacket(StoredPacket&&) = default;
198 StoredPacket(const StoredPacket&) = delete;
199 StoredPacket& operator=(const StoredPacket&) = delete;
200 StoredPacket() = delete;
201 };
202
Erik Språng09708512018-03-14 15:16:50 +0100203 // Returns true if enqueued, or false if packet was dropped.
Christoffer Rodbro8ef59a42018-03-20 14:34:01 +0100204 virtual bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200205 absl::optional<PacketOptions> options,
206 bool is_rtcp,
207 MediaType media_type,
Niels Möller70082872018-08-07 11:03:12 +0200208 absl::optional<int64_t> packet_time_us);
209
Niels Möller70082872018-08-07 11:03:12 +0200210 bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
211 absl::optional<PacketOptions> options,
212 bool is_rtcp,
213 MediaType media_type) {
Niels Möllerf189c482018-08-17 09:49:20 +0200214 return EnqueuePacket(packet, options, is_rtcp, media_type, absl::nullopt);
Niels Möller70082872018-08-07 11:03:12 +0200215 }
216 void DeliverNetworkPacket(NetworkPacket* packet)
Erik Språng09708512018-03-14 15:16:50 +0100217 RTC_EXCLUSIVE_LOCKS_REQUIRED(config_lock_);
218 bool HasTransport() const;
Sebastian Jansson09408112018-04-24 14:41:22 +0200219 bool HasReceiver() const;
Erik Språng09708512018-03-14 15:16:50 +0100220
221 Clock* const clock_;
222 // |config_lock| guards the mostly constant things like the callbacks.
223 rtc::CriticalSection config_lock_;
Artem Titov847a9c72018-08-14 15:44:31 +0200224 const std::unique_ptr<NetworkSimulationInterface> network_simulation_;
Erik Språng09708512018-03-14 15:16:50 +0100225 PacketReceiver* receiver_ RTC_GUARDED_BY(config_lock_);
226 Transport* const transport_ RTC_GUARDED_BY(config_lock_);
227
228 // |process_lock| guards the data structures involved in delay and loss
229 // processes, such as the packet queues.
230 rtc::CriticalSection process_lock_;
Erik Språng09708512018-03-14 15:16:50 +0100231
Sebastian Jansson7ee2e252018-05-07 14:49:39 +0200232 // Packets are added at the back of the deque, this makes the deque ordered
233 // by increasing send time. The common case when removing packets from the
234 // deque is removing early packets, which will be close to the front of the
235 // deque. This makes finding the packets in the deque efficient in the common
236 // case.
237 std::deque<StoredPacket> packets_in_flight_ RTC_GUARDED_BY(process_lock_);
Erik Språng09708512018-03-14 15:16:50 +0100238
Sebastian Jansson7e85d672018-04-06 09:56:21 +0200239 int64_t clock_offset_ms_ RTC_GUARDED_BY(config_lock_);
240
Erik Språng09708512018-03-14 15:16:50 +0100241 // Statistics.
242 size_t dropped_packets_ RTC_GUARDED_BY(process_lock_);
243 size_t sent_packets_ RTC_GUARDED_BY(process_lock_);
Sebastian Jansson512bdce2018-04-23 13:15:04 +0200244 int64_t total_packet_delay_us_ RTC_GUARDED_BY(process_lock_);
Erik Språng09708512018-03-14 15:16:50 +0100245
Sebastian Jansson512bdce2018-04-23 13:15:04 +0200246 int64_t next_process_time_us_;
Erik Språng09708512018-03-14 15:16:50 +0100247
Sebastian Jansson512bdce2018-04-23 13:15:04 +0200248 int64_t last_log_time_us_;
Erik Språng09708512018-03-14 15:16:50 +0100249
Erik Språng09708512018-03-14 15:16:50 +0100250 RTC_DISALLOW_COPY_AND_ASSIGN(FakeNetworkPipe);
251};
252
253} // namespace webrtc
254
255#endif // CALL_FAKE_NETWORK_PIPE_H_