blob: 7bc7e0f06040b969bd6787c7bc0cff874eff6c99 [file] [log] [blame]
Erik Språng09708512018-03-14 14:16:501/*
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 12:49:3918#include <set>
Erik Språng09708512018-03-14 14:16:5019#include <string>
Sebastian Jansson7ee2e252018-05-07 12:49:3920#include <vector>
Erik Språng09708512018-03-14 14:16:5021
22#include "api/call/transport.h"
Patrik Höglundb6b29e02018-06-21 14:58:0123#include "api/test/simulated_network.h"
Artem Titov46c4e602018-08-17 12:26:5424#include "call/simulated_packet_receiver.h"
Per Kbc319022023-01-09 20:44:5625#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Markus Handell8fe932a2020-07-06 15:41:3526#include "rtc_base/synchronization/mutex.h"
Erik Språng09708512018-03-14 14:16:5027#include "rtc_base/thread_annotations.h"
Erik Språng09708512018-03-14 14:16:5028
29namespace webrtc {
30
31class Clock;
32class PacketReceiver;
33enum class MediaType;
34
35class NetworkPacket {
36 public:
37 NetworkPacket(rtc::CopyOnWriteBuffer packet,
38 int64_t send_time,
39 int64_t arrival_time,
Danil Chapovalovb9b146c2018-06-15 10:28:0740 absl::optional<PacketOptions> packet_options,
Erik Språng09708512018-03-14 14:16:5041 bool is_rtcp,
Niels Möller70082872018-08-07 09:03:1242 MediaType media_type,
Erik Språngeea605d2019-08-12 13:56:5143 absl::optional<int64_t> packet_time_us,
44 Transport* transport);
Niels Möller70082872018-08-07 09:03:1245
Per Kbc319022023-01-09 20:44:5646 NetworkPacket(RtpPacketReceived packet,
47 MediaType media_type,
48 int64_t send_time,
49 int64_t arrival_time);
50
Artem Titovea240272021-07-26 10:40:2151 // Disallow copy constructor and copy assignment (no deep copies of `data_`).
Erik Språng09708512018-03-14 14:16:5052 NetworkPacket(const NetworkPacket&) = delete;
Mirko Bonadeied1dcf92018-07-26 07:15:1153 ~NetworkPacket();
Christoffer Rodbro8ef59a42018-03-20 13:34:0154 NetworkPacket& operator=(const NetworkPacket&) = delete;
Erik Språng09708512018-03-14 14:16:5055 // Allow move constructor/assignment, so that we can use in stl containers.
56 NetworkPacket(NetworkPacket&&);
57 NetworkPacket& operator=(NetworkPacket&&);
58
59 const uint8_t* data() const { return packet_.data(); }
60 size_t data_length() const { return packet_.size(); }
61 rtc::CopyOnWriteBuffer* raw_packet() { return &packet_; }
62 int64_t send_time() const { return send_time_; }
63 int64_t arrival_time() const { return arrival_time_; }
64 void IncrementArrivalTime(int64_t extra_delay) {
65 arrival_time_ += extra_delay;
66 }
67 PacketOptions packet_options() const {
68 return packet_options_.value_or(PacketOptions());
69 }
70 bool is_rtcp() const { return is_rtcp_; }
71 MediaType media_type() const { return media_type_; }
Niels Möller70082872018-08-07 09:03:1272 absl::optional<int64_t> packet_time_us() const { return packet_time_us_; }
Per K4abca662023-01-19 14:11:0773 RtpPacketReceived* packet_received() {
74 return packet_received_ ? &packet_received_.value() : nullptr;
75 }
Per Kbc319022023-01-09 20:44:5676 absl::optional<RtpPacketReceived> packet_received() const {
77 return packet_received_;
78 }
Erik Språngeea605d2019-08-12 13:56:5179 Transport* transport() const { return transport_; }
Erik Språng09708512018-03-14 14:16:5080
81 private:
82 rtc::CopyOnWriteBuffer packet_;
83 // The time the packet was sent out on the network.
84 int64_t send_time_;
85 // The time the packet should arrive at the receiver.
86 int64_t arrival_time_;
87 // If using a Transport for outgoing degradation, populate with
88 // PacketOptions (transport-wide sequence number) for RTP.
Danil Chapovalovb9b146c2018-06-15 10:28:0789 absl::optional<PacketOptions> packet_options_;
Erik Språng09708512018-03-14 14:16:5090 bool is_rtcp_;
91 // If using a PacketReceiver for incoming degradation, populate with
Niels Möller29e13fd2018-12-17 11:35:3092 // appropriate MediaType and packet time. This type/timing will be kept and
93 // forwarded. The packet time might be altered to reflect time spent in fake
Erik Språng09708512018-03-14 14:16:5094 // network pipe.
95 MediaType media_type_;
Niels Möller70082872018-08-07 09:03:1296 absl::optional<int64_t> packet_time_us_;
Per Kbc319022023-01-09 20:44:5697 absl::optional<RtpPacketReceived> packet_received_;
Erik Språngeea605d2019-08-12 13:56:5198 Transport* transport_;
Erik Språng09708512018-03-14 14:16:5099};
100
Sebastian Jansson7ee2e252018-05-07 12:49:39101// Class faking a network link, internally is uses an implementation of a
102// SimulatedNetworkInterface to simulate network behavior.
Sebastian Jansson836fee12019-02-08 15:08:10103class FakeNetworkPipe : public SimulatedPacketReceiverInterface {
Sebastian Jansson7ee2e252018-05-07 12:49:39104 public:
Artem Titovea240272021-07-26 10:40:21105 // Will keep `network_behavior` alive while pipe is alive itself.
Artem Titov8ea1e9d2018-10-04 12:46:31106 FakeNetworkPipe(Clock* clock,
107 std::unique_ptr<NetworkBehaviorInterface> network_behavior);
108 FakeNetworkPipe(Clock* clock,
109 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
110 PacketReceiver* receiver);
111 FakeNetworkPipe(Clock* clock,
112 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
113 PacketReceiver* receiver,
114 uint64_t seed);
Erik Språng09708512018-03-14 14:16:50115
Mirko Bonadeied1dcf92018-07-26 07:15:11116 ~FakeNetworkPipe() override;
Erik Språng09708512018-03-14 14:16:50117
Byoungchan Leec065e732022-01-18 00:35:48118 FakeNetworkPipe(const FakeNetworkPipe&) = delete;
119 FakeNetworkPipe& operator=(const FakeNetworkPipe&) = delete;
120
Artem Titovc02df812018-08-20 08:03:22121 void SetClockOffset(int64_t offset_ms);
Sebastian Jansson7e85d672018-04-06 07:56:21122
Sebastian Jansson09408112018-04-24 12:41:22123 // Must not be called in parallel with DeliverPacket or Process.
Artem Titov46c4e602018-08-17 12:26:54124 void SetReceiver(PacketReceiver* receiver) override;
Erik Språng09708512018-03-14 14:16:50125
Erik Språngeea605d2019-08-12 13:56:51126 // Adds/subtracts references to Transport instances. If a Transport is
127 // destroyed we cannot use to forward a potential delayed packet, these
128 // methods are used to maintain a map of which instances are live.
129 void AddActiveTransport(Transport* transport);
130 void RemoveActiveTransport(Transport* transport);
131
Erik Språngeea605d2019-08-12 13:56:51132 // Methods for use with Transport interface. When/if packets are delivered,
Artem Titovea240272021-07-26 10:40:21133 // they will be passed to the instance specified by the `transport` parameter.
Erik Språngeea605d2019-08-12 13:56:51134 // Note that that instance must be in the map of active transports.
Harald Alvestrandd43af912023-08-15 11:41:45135 bool SendRtp(rtc::ArrayView<const uint8_t> packet,
Erik Språngeea605d2019-08-12 13:56:51136 const PacketOptions& options,
137 Transport* transport);
Harald Alvestrandd43af912023-08-15 11:41:45138 bool SendRtcp(rtc::ArrayView<const uint8_t> packet, Transport* transport);
Erik Språngeea605d2019-08-12 13:56:51139
Erik Språng09708512018-03-14 14:16:50140 // Implements the PacketReceiver interface. When/if packets are delivered,
141 // they will be passed directly to the receiver instance given in
Per Kbc319022023-01-09 20:44:56142 // SetReceiver(). The receive time will be increased by the amount of time the
143 // packet spent in the fake network pipe.
144 void DeliverRtpPacket(
145 MediaType media_type,
146 RtpPacketReceived packet,
147 OnUndemuxablePacketHandler undemuxable_packet_handler) override;
148 void DeliverRtcpPacket(rtc::CopyOnWriteBuffer packet) override;
149
Erik Språng09708512018-03-14 14:16:50150 // Processes the network queues and trigger PacketReceiver::IncomingPacket for
151 // packets ready to be delivered.
152 void Process() override;
Sebastian Jansson836fee12019-02-08 15:08:10153 absl::optional<int64_t> TimeUntilNextProcess() override;
Erik Språng09708512018-03-14 14:16:50154
155 // Get statistics.
156 float PercentageLoss();
Artem Titov46c4e602018-08-17 12:26:54157 int AverageDelay() override;
Erik Språng09708512018-03-14 14:16:50158 size_t DroppedPackets();
159 size_t SentPackets();
Christoffer Rodbro8ef59a42018-03-20 13:34:01160 void ResetStats();
161
162 protected:
163 void DeliverPacketWithLock(NetworkPacket* packet);
Sebastian Jansson512bdce2018-04-23 11:15:04164 int64_t GetTimeInMicroseconds() const;
Sebastian Jansson512bdce2018-04-23 11:15:04165 bool ShouldProcess(int64_t time_now_us) const;
166 void SetTimeToNextProcess(int64_t skip_us);
Erik Språng09708512018-03-14 14:16:50167
168 private:
Sebastian Jansson7ee2e252018-05-07 12:49:39169 struct StoredPacket {
170 NetworkPacket packet;
171 bool removed = false;
172 explicit StoredPacket(NetworkPacket&& packet);
173 StoredPacket(StoredPacket&&) = default;
174 StoredPacket(const StoredPacket&) = delete;
175 StoredPacket& operator=(const StoredPacket&) = delete;
176 StoredPacket() = delete;
177 };
178
Erik Språngeea605d2019-08-12 13:56:51179 // Returns true if enqueued, or false if packet was dropped. Use this method
180 // when enqueueing packets that should be received by PacketReceiver instance.
Niels Möller70082872018-08-07 09:03:12181 bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
182 absl::optional<PacketOptions> options,
183 bool is_rtcp,
Erik Språngeea605d2019-08-12 13:56:51184 MediaType media_type,
185 absl::optional<int64_t> packet_time_us);
186
187 // Returns true if enqueued, or false if packet was dropped. Use this method
188 // when enqueueing packets that should be received by Transport instance.
189 bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
190 absl::optional<PacketOptions> options,
191 bool is_rtcp,
192 Transport* transport);
193
194 bool EnqueuePacket(NetworkPacket&& net_packet)
195 RTC_EXCLUSIVE_LOCKS_REQUIRED(process_lock_);
196
Niels Möller70082872018-08-07 09:03:12197 void DeliverNetworkPacket(NetworkPacket* packet)
Erik Språng09708512018-03-14 14:16:50198 RTC_EXCLUSIVE_LOCKS_REQUIRED(config_lock_);
Sebastian Jansson09408112018-04-24 12:41:22199 bool HasReceiver() const;
Erik Språng09708512018-03-14 14:16:50200
201 Clock* const clock_;
Artem Titovea240272021-07-26 10:40:21202 // `config_lock` guards the mostly constant things like the callbacks.
Markus Handell8fe932a2020-07-06 15:41:35203 mutable Mutex config_lock_;
Artem Titov8ea1e9d2018-10-04 12:46:31204 const std::unique_ptr<NetworkBehaviorInterface> network_behavior_;
Erik Språng09708512018-03-14 14:16:50205 PacketReceiver* receiver_ RTC_GUARDED_BY(config_lock_);
Erik Språng09708512018-03-14 14:16:50206
Artem Titovea240272021-07-26 10:40:21207 // `process_lock` guards the data structures involved in delay and loss
Erik Språng09708512018-03-14 14:16:50208 // processes, such as the packet queues.
Markus Handell8fe932a2020-07-06 15:41:35209 Mutex process_lock_;
Sebastian Jansson7ee2e252018-05-07 12:49:39210 // Packets are added at the back of the deque, this makes the deque ordered
211 // by increasing send time. The common case when removing packets from the
212 // deque is removing early packets, which will be close to the front of the
213 // deque. This makes finding the packets in the deque efficient in the common
214 // case.
215 std::deque<StoredPacket> packets_in_flight_ RTC_GUARDED_BY(process_lock_);
Erik Språng09708512018-03-14 14:16:50216
Sebastian Jansson7e85d672018-04-06 07:56:21217 int64_t clock_offset_ms_ RTC_GUARDED_BY(config_lock_);
218
Erik Språng09708512018-03-14 14:16:50219 // Statistics.
220 size_t dropped_packets_ RTC_GUARDED_BY(process_lock_);
221 size_t sent_packets_ RTC_GUARDED_BY(process_lock_);
Sebastian Jansson512bdce2018-04-23 11:15:04222 int64_t total_packet_delay_us_ RTC_GUARDED_BY(process_lock_);
Sebastian Jansson512bdce2018-04-23 11:15:04223 int64_t last_log_time_us_;
Erik Språng09708512018-03-14 14:16:50224
Erik Språngeea605d2019-08-12 13:56:51225 std::map<Transport*, size_t> active_transports_ RTC_GUARDED_BY(config_lock_);
Erik Språng09708512018-03-14 14:16:50226};
227
228} // namespace webrtc
229
230#endif // CALL_FAKE_NETWORK_PIPE_H_