blob: 198615cb793da6df9400e784704a622ff0c4a69c [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 Kbc319022023-01-09 20:44:5673 absl::optional<RtpPacketReceived> packet_received() const {
74 return packet_received_;
75 }
Erik Språngeea605d2019-08-12 13:56:5176 Transport* transport() const { return transport_; }
Erik Språng09708512018-03-14 14:16:5077
78 private:
79 rtc::CopyOnWriteBuffer packet_;
80 // The time the packet was sent out on the network.
81 int64_t send_time_;
82 // The time the packet should arrive at the receiver.
83 int64_t arrival_time_;
84 // If using a Transport for outgoing degradation, populate with
85 // PacketOptions (transport-wide sequence number) for RTP.
Danil Chapovalovb9b146c2018-06-15 10:28:0786 absl::optional<PacketOptions> packet_options_;
Erik Språng09708512018-03-14 14:16:5087 bool is_rtcp_;
88 // If using a PacketReceiver for incoming degradation, populate with
Niels Möller29e13fd2018-12-17 11:35:3089 // appropriate MediaType and packet time. This type/timing will be kept and
90 // forwarded. The packet time might be altered to reflect time spent in fake
Erik Språng09708512018-03-14 14:16:5091 // network pipe.
92 MediaType media_type_;
Niels Möller70082872018-08-07 09:03:1293 absl::optional<int64_t> packet_time_us_;
Per Kbc319022023-01-09 20:44:5694 absl::optional<RtpPacketReceived> packet_received_;
Erik Språngeea605d2019-08-12 13:56:5195 Transport* transport_;
Erik Språng09708512018-03-14 14:16:5096};
97
Sebastian Jansson7ee2e252018-05-07 12:49:3998// Class faking a network link, internally is uses an implementation of a
99// SimulatedNetworkInterface to simulate network behavior.
Sebastian Jansson836fee12019-02-08 15:08:10100class FakeNetworkPipe : public SimulatedPacketReceiverInterface {
Sebastian Jansson7ee2e252018-05-07 12:49:39101 public:
Artem Titovea240272021-07-26 10:40:21102 // Will keep `network_behavior` alive while pipe is alive itself.
Artem Titov8ea1e9d2018-10-04 12:46:31103 FakeNetworkPipe(Clock* clock,
104 std::unique_ptr<NetworkBehaviorInterface> network_behavior);
105 FakeNetworkPipe(Clock* clock,
106 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
107 PacketReceiver* receiver);
108 FakeNetworkPipe(Clock* clock,
109 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
110 PacketReceiver* receiver,
111 uint64_t seed);
Erik Språng09708512018-03-14 14:16:50112
Artem Titovb0050872018-08-16 15:02:20113 // Use this constructor if you plan to insert packets using SendRt[c?]p().
Artem Titov8ea1e9d2018-10-04 12:46:31114 FakeNetworkPipe(Clock* clock,
115 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
116 Transport* transport);
Erik Språng09708512018-03-14 14:16:50117
Mirko Bonadeied1dcf92018-07-26 07:15:11118 ~FakeNetworkPipe() override;
Erik Språng09708512018-03-14 14:16:50119
Byoungchan Leec065e732022-01-18 00:35:48120 FakeNetworkPipe(const FakeNetworkPipe&) = delete;
121 FakeNetworkPipe& operator=(const FakeNetworkPipe&) = delete;
122
Artem Titovc02df812018-08-20 08:03:22123 void SetClockOffset(int64_t offset_ms);
Sebastian Jansson7e85d672018-04-06 07:56:21124
Sebastian Jansson09408112018-04-24 12:41:22125 // Must not be called in parallel with DeliverPacket or Process.
Artem Titov46c4e602018-08-17 12:26:54126 void SetReceiver(PacketReceiver* receiver) override;
Erik Språng09708512018-03-14 14:16:50127
Erik Språngeea605d2019-08-12 13:56:51128 // Adds/subtracts references to Transport instances. If a Transport is
129 // destroyed we cannot use to forward a potential delayed packet, these
130 // methods are used to maintain a map of which instances are live.
131 void AddActiveTransport(Transport* transport);
132 void RemoveActiveTransport(Transport* transport);
133
Erik Språng09708512018-03-14 14:16:50134 // Implements Transport interface. When/if packets are delivered, they will
135 // be passed to the transport instance given in SetReceiverTransport(). These
136 // methods should only be called if a Transport instance was provided in the
137 // constructor.
138 bool SendRtp(const uint8_t* packet,
139 size_t length,
Sebastian Jansson836fee12019-02-08 15:08:10140 const PacketOptions& options);
141 bool SendRtcp(const uint8_t* packet, size_t length);
Erik Språng09708512018-03-14 14:16:50142
Erik Språngeea605d2019-08-12 13:56:51143 // Methods for use with Transport interface. When/if packets are delivered,
Artem Titovea240272021-07-26 10:40:21144 // they will be passed to the instance specified by the `transport` parameter.
Erik Språngeea605d2019-08-12 13:56:51145 // Note that that instance must be in the map of active transports.
146 bool SendRtp(const uint8_t* packet,
147 size_t length,
148 const PacketOptions& options,
149 Transport* transport);
150 bool SendRtcp(const uint8_t* packet, size_t length, Transport* transport);
151
Erik Språng09708512018-03-14 14:16:50152 // Implements the PacketReceiver interface. When/if packets are delivered,
153 // they will be passed directly to the receiver instance given in
Per Kbc319022023-01-09 20:44:56154 // SetReceiver(). The receive time will be increased by the amount of time the
155 // packet spent in the fake network pipe.
156 void DeliverRtpPacket(
157 MediaType media_type,
158 RtpPacketReceived packet,
159 OnUndemuxablePacketHandler undemuxable_packet_handler) override;
160 void DeliverRtcpPacket(rtc::CopyOnWriteBuffer packet) override;
161
162 // TODO(perkj, https://bugs.webrtc.org/7135): Remove once implementations
163 // dont use it.
Niels Möller70082872018-08-07 09:03:12164 PacketReceiver::DeliveryStatus DeliverPacket(MediaType media_type,
165 rtc::CopyOnWriteBuffer packet,
166 int64_t packet_time_us) override;
167
Erik Språng09708512018-03-14 14:16:50168 // Processes the network queues and trigger PacketReceiver::IncomingPacket for
169 // packets ready to be delivered.
170 void Process() override;
Sebastian Jansson836fee12019-02-08 15:08:10171 absl::optional<int64_t> TimeUntilNextProcess() override;
Erik Språng09708512018-03-14 14:16:50172
173 // Get statistics.
174 float PercentageLoss();
Artem Titov46c4e602018-08-17 12:26:54175 int AverageDelay() override;
Erik Språng09708512018-03-14 14:16:50176 size_t DroppedPackets();
177 size_t SentPackets();
Christoffer Rodbro8ef59a42018-03-20 13:34:01178 void ResetStats();
179
180 protected:
181 void DeliverPacketWithLock(NetworkPacket* packet);
Sebastian Jansson512bdce2018-04-23 11:15:04182 int64_t GetTimeInMicroseconds() const;
Sebastian Jansson512bdce2018-04-23 11:15:04183 bool ShouldProcess(int64_t time_now_us) const;
184 void SetTimeToNextProcess(int64_t skip_us);
Erik Språng09708512018-03-14 14:16:50185
186 private:
Sebastian Jansson7ee2e252018-05-07 12:49:39187 struct StoredPacket {
188 NetworkPacket packet;
189 bool removed = false;
190 explicit StoredPacket(NetworkPacket&& packet);
191 StoredPacket(StoredPacket&&) = default;
192 StoredPacket(const StoredPacket&) = delete;
193 StoredPacket& operator=(const StoredPacket&) = delete;
194 StoredPacket() = delete;
195 };
196
Erik Språngeea605d2019-08-12 13:56:51197 // Returns true if enqueued, or false if packet was dropped. Use this method
198 // when enqueueing packets that should be received by PacketReceiver instance.
Niels Möller70082872018-08-07 09:03:12199 bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
200 absl::optional<PacketOptions> options,
201 bool is_rtcp,
Erik Språngeea605d2019-08-12 13:56:51202 MediaType media_type,
203 absl::optional<int64_t> packet_time_us);
204
205 // Returns true if enqueued, or false if packet was dropped. Use this method
206 // when enqueueing packets that should be received by Transport instance.
207 bool EnqueuePacket(rtc::CopyOnWriteBuffer packet,
208 absl::optional<PacketOptions> options,
209 bool is_rtcp,
210 Transport* transport);
211
212 bool EnqueuePacket(NetworkPacket&& net_packet)
213 RTC_EXCLUSIVE_LOCKS_REQUIRED(process_lock_);
214
Niels Möller70082872018-08-07 09:03:12215 void DeliverNetworkPacket(NetworkPacket* packet)
Erik Språng09708512018-03-14 14:16:50216 RTC_EXCLUSIVE_LOCKS_REQUIRED(config_lock_);
Sebastian Jansson09408112018-04-24 12:41:22217 bool HasReceiver() const;
Erik Språng09708512018-03-14 14:16:50218
219 Clock* const clock_;
Artem Titovea240272021-07-26 10:40:21220 // `config_lock` guards the mostly constant things like the callbacks.
Markus Handell8fe932a2020-07-06 15:41:35221 mutable Mutex config_lock_;
Artem Titov8ea1e9d2018-10-04 12:46:31222 const std::unique_ptr<NetworkBehaviorInterface> network_behavior_;
Erik Språng09708512018-03-14 14:16:50223 PacketReceiver* receiver_ RTC_GUARDED_BY(config_lock_);
Erik Språngeea605d2019-08-12 13:56:51224 Transport* const global_transport_;
Erik Språng09708512018-03-14 14:16:50225
Artem Titovea240272021-07-26 10:40:21226 // `process_lock` guards the data structures involved in delay and loss
Erik Språng09708512018-03-14 14:16:50227 // processes, such as the packet queues.
Markus Handell8fe932a2020-07-06 15:41:35228 Mutex process_lock_;
Sebastian Jansson7ee2e252018-05-07 12:49:39229 // Packets are added at the back of the deque, this makes the deque ordered
230 // by increasing send time. The common case when removing packets from the
231 // deque is removing early packets, which will be close to the front of the
232 // deque. This makes finding the packets in the deque efficient in the common
233 // case.
234 std::deque<StoredPacket> packets_in_flight_ RTC_GUARDED_BY(process_lock_);
Erik Språng09708512018-03-14 14:16:50235
Sebastian Jansson7e85d672018-04-06 07:56:21236 int64_t clock_offset_ms_ RTC_GUARDED_BY(config_lock_);
237
Erik Språng09708512018-03-14 14:16:50238 // Statistics.
239 size_t dropped_packets_ RTC_GUARDED_BY(process_lock_);
240 size_t sent_packets_ RTC_GUARDED_BY(process_lock_);
Sebastian Jansson512bdce2018-04-23 11:15:04241 int64_t total_packet_delay_us_ RTC_GUARDED_BY(process_lock_);
Sebastian Jansson512bdce2018-04-23 11:15:04242 int64_t last_log_time_us_;
Erik Språng09708512018-03-14 14:16:50243
Erik Språngeea605d2019-08-12 13:56:51244 std::map<Transport*, size_t> active_transports_ RTC_GUARDED_BY(config_lock_);
Erik Språng09708512018-03-14 14:16:50245};
246
247} // namespace webrtc
248
249#endif // CALL_FAKE_NETWORK_PIPE_H_