xref: /aosp_15_r20/external/openscreen/cast/streaming/sender_packet_router.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #ifndef CAST_STREAMING_SENDER_PACKET_ROUTER_H_
6*3f982cf4SFabien Sanglard #define CAST_STREAMING_SENDER_PACKET_ROUTER_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <stdint.h>
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard #include <chrono>
11*3f982cf4SFabien Sanglard #include <memory>
12*3f982cf4SFabien Sanglard #include <vector>
13*3f982cf4SFabien Sanglard 
14*3f982cf4SFabien Sanglard #include "absl/types/span.h"
15*3f982cf4SFabien Sanglard #include "cast/streaming/bandwidth_estimator.h"
16*3f982cf4SFabien Sanglard #include "cast/streaming/environment.h"
17*3f982cf4SFabien Sanglard #include "cast/streaming/ssrc.h"
18*3f982cf4SFabien Sanglard #include "platform/api/time.h"
19*3f982cf4SFabien Sanglard #include "util/alarm.h"
20*3f982cf4SFabien Sanglard 
21*3f982cf4SFabien Sanglard namespace openscreen {
22*3f982cf4SFabien Sanglard namespace cast {
23*3f982cf4SFabien Sanglard 
24*3f982cf4SFabien Sanglard // Manages network packet transmission for one or more Senders, directing each
25*3f982cf4SFabien Sanglard // inbound packet to a specific Sender instance, pacing the transmission of
26*3f982cf4SFabien Sanglard // outbound packets, and employing network bandwidth/availability monitoring and
27*3f982cf4SFabien Sanglard // congestion control.
28*3f982cf4SFabien Sanglard //
29*3f982cf4SFabien Sanglard // Instead of just sending packets whenever they want, Senders must request
30*3f982cf4SFabien Sanglard // transmission from the SenderPacketRouter. The router then calls-back to each
31*3f982cf4SFabien Sanglard // Sender, in the near future, when it has allocated an available time slice for
32*3f982cf4SFabien Sanglard // transmission. The Sender is allowed to decide, at that exact moment, which
33*3f982cf4SFabien Sanglard // packet most needs to be sent.
34*3f982cf4SFabien Sanglard //
35*3f982cf4SFabien Sanglard // Pacing strategy: Packets are sent in bursts. This allows the platform
36*3f982cf4SFabien Sanglard // (operating system) to collect many small packets into a short-term buffer,
37*3f982cf4SFabien Sanglard // which allows for optimizations at the link layer. For example, multiple
38*3f982cf4SFabien Sanglard // packets can be sent together as one larger transmission unit, and this can be
39*3f982cf4SFabien Sanglard // critical for good performance over shared-medium networks (such as 802.11
40*3f982cf4SFabien Sanglard // WiFi). https://en.wikipedia.org/wiki/Frame-bursting
41*3f982cf4SFabien Sanglard class SenderPacketRouter : public BandwidthEstimator,
42*3f982cf4SFabien Sanglard                            public Environment::PacketConsumer {
43*3f982cf4SFabien Sanglard  public:
44*3f982cf4SFabien Sanglard   class Sender {
45*3f982cf4SFabien Sanglard    public:
46*3f982cf4SFabien Sanglard     // Called to provide the Sender with what looks like a RTCP packet meant for
47*3f982cf4SFabien Sanglard     // it specifically (among other Senders) to process. |arrival_time|
48*3f982cf4SFabien Sanglard     // indicates when the packet arrived (i.e., when it was received from the
49*3f982cf4SFabien Sanglard     // platform).
50*3f982cf4SFabien Sanglard     virtual void OnReceivedRtcpPacket(Clock::time_point arrival_time,
51*3f982cf4SFabien Sanglard                                       absl::Span<const uint8_t> packet) = 0;
52*3f982cf4SFabien Sanglard 
53*3f982cf4SFabien Sanglard     // Populates the given |buffer| with a RTCP/RTP packet that will be sent
54*3f982cf4SFabien Sanglard     // immediately. Returns the portion of |buffer| contaning the packet, or an
55*3f982cf4SFabien Sanglard     // empty Span if nothing is ready to send.
56*3f982cf4SFabien Sanglard     virtual absl::Span<uint8_t> GetRtcpPacketForImmediateSend(
57*3f982cf4SFabien Sanglard         Clock::time_point send_time,
58*3f982cf4SFabien Sanglard         absl::Span<uint8_t> buffer) = 0;
59*3f982cf4SFabien Sanglard     virtual absl::Span<uint8_t> GetRtpPacketForImmediateSend(
60*3f982cf4SFabien Sanglard         Clock::time_point send_time,
61*3f982cf4SFabien Sanglard         absl::Span<uint8_t> buffer) = 0;
62*3f982cf4SFabien Sanglard 
63*3f982cf4SFabien Sanglard     // Returns the point-in-time at which RTP sending should resume, or kNever
64*3f982cf4SFabien Sanglard     // if it should be suspended until an explicit call to RequestRtpSend(). The
65*3f982cf4SFabien Sanglard     // implementation may return a value on or before "now" to indicate an
66*3f982cf4SFabien Sanglard     // immediate resume is desired.
67*3f982cf4SFabien Sanglard     virtual Clock::time_point GetRtpResumeTime() = 0;
68*3f982cf4SFabien Sanglard 
69*3f982cf4SFabien Sanglard    protected:
70*3f982cf4SFabien Sanglard     virtual ~Sender();
71*3f982cf4SFabien Sanglard   };
72*3f982cf4SFabien Sanglard 
73*3f982cf4SFabien Sanglard   // Constructs an instance with default burst parameters appropriate for the
74*3f982cf4SFabien Sanglard   // given |max_burst_bitrate|.
75*3f982cf4SFabien Sanglard   explicit SenderPacketRouter(Environment* environment,
76*3f982cf4SFabien Sanglard                               int max_burst_bitrate = kDefaultMaxBurstBitrate);
77*3f982cf4SFabien Sanglard 
78*3f982cf4SFabien Sanglard   // Constructs an instance with specific burst parameters. The maximum bitrate
79*3f982cf4SFabien Sanglard   // will be computed based on these (and Environment::GetMaxPacketSize()).
80*3f982cf4SFabien Sanglard   SenderPacketRouter(Environment* environment,
81*3f982cf4SFabien Sanglard                      int max_packets_per_burst,
82*3f982cf4SFabien Sanglard                      std::chrono::milliseconds burst_interval);
83*3f982cf4SFabien Sanglard 
84*3f982cf4SFabien Sanglard   ~SenderPacketRouter();
85*3f982cf4SFabien Sanglard 
max_packet_size()86*3f982cf4SFabien Sanglard   int max_packet_size() const { return packet_buffer_size_; }
max_burst_bitrate()87*3f982cf4SFabien Sanglard   int max_burst_bitrate() const { return max_burst_bitrate_; }
88*3f982cf4SFabien Sanglard 
89*3f982cf4SFabien Sanglard   // Called from a Sender constructor/destructor to register/deregister a Sender
90*3f982cf4SFabien Sanglard   // instance that processes RTP/RTCP packets from a Receiver having the given
91*3f982cf4SFabien Sanglard   // SSRC.
92*3f982cf4SFabien Sanglard   void OnSenderCreated(Ssrc receiver_ssrc, Sender* client);
93*3f982cf4SFabien Sanglard   void OnSenderDestroyed(Ssrc receiver_ssrc);
94*3f982cf4SFabien Sanglard 
95*3f982cf4SFabien Sanglard   // Requests an immediate send of a RTCP packet, and then RTCP sending will
96*3f982cf4SFabien Sanglard   // repeat at regular intervals (see kRtcpSendInterval) until the Sender is
97*3f982cf4SFabien Sanglard   // de-registered.
98*3f982cf4SFabien Sanglard   void RequestRtcpSend(Ssrc receiver_ssrc);
99*3f982cf4SFabien Sanglard 
100*3f982cf4SFabien Sanglard   // Requests an immediate send of a RTP packet. RTP sending will continue until
101*3f982cf4SFabien Sanglard   // the Sender stops providing packet data.
102*3f982cf4SFabien Sanglard   //
103*3f982cf4SFabien Sanglard   // See also: Sender::GetRtpResumeTime().
104*3f982cf4SFabien Sanglard   void RequestRtpSend(Ssrc receiver_ssrc);
105*3f982cf4SFabien Sanglard 
106*3f982cf4SFabien Sanglard   // A reasonable default maximum bitrate for bursting. Congestion control
107*3f982cf4SFabien Sanglard   // should always be employed to limit the Senders' sustained/average outbound
108*3f982cf4SFabien Sanglard   // data volume for "fair" use of the network.
109*3f982cf4SFabien Sanglard   static constexpr int kDefaultMaxBurstBitrate = 24 << 20;  // 24 megabits/sec
110*3f982cf4SFabien Sanglard 
111*3f982cf4SFabien Sanglard   // The minimum amount of time between burst-sends. The methodology by which
112*3f982cf4SFabien Sanglard   // this value was determined is lost knowledge, but is likely the result of
113*3f982cf4SFabien Sanglard   // experimentation with various network and operating system configurations.
114*3f982cf4SFabien Sanglard   // This value came from the original Chrome Cast Streaming implementation.
115*3f982cf4SFabien Sanglard   static constexpr std::chrono::milliseconds kDefaultBurstInterval{10};
116*3f982cf4SFabien Sanglard 
117*3f982cf4SFabien Sanglard   // A special time_point value representing "never."
118*3f982cf4SFabien Sanglard   static constexpr Clock::time_point kNever = Clock::time_point::max();
119*3f982cf4SFabien Sanglard 
120*3f982cf4SFabien Sanglard  private:
121*3f982cf4SFabien Sanglard   struct SenderEntry {
122*3f982cf4SFabien Sanglard     Ssrc receiver_ssrc;
123*3f982cf4SFabien Sanglard     Sender* sender;
124*3f982cf4SFabien Sanglard     Clock::time_point next_rtcp_send_time;
125*3f982cf4SFabien Sanglard     Clock::time_point next_rtp_send_time;
126*3f982cf4SFabien Sanglard 
127*3f982cf4SFabien Sanglard     // Entries are ordered by the transmission priority (high→low), as implied
128*3f982cf4SFabien Sanglard     // by their SSRC. See ssrc.h for details.
129*3f982cf4SFabien Sanglard     bool operator<(const SenderEntry& other) const {
130*3f982cf4SFabien Sanglard       return ComparePriority(receiver_ssrc, other.receiver_ssrc) < 0;
131*3f982cf4SFabien Sanglard     }
132*3f982cf4SFabien Sanglard   };
133*3f982cf4SFabien Sanglard 
134*3f982cf4SFabien Sanglard   using SenderEntries = std::vector<SenderEntry>;
135*3f982cf4SFabien Sanglard 
136*3f982cf4SFabien Sanglard   // Environment::PacketConsumer implementation.
137*3f982cf4SFabien Sanglard   void OnReceivedPacket(const IPEndpoint& source,
138*3f982cf4SFabien Sanglard                         Clock::time_point arrival_time,
139*3f982cf4SFabien Sanglard                         std::vector<uint8_t> packet) final;
140*3f982cf4SFabien Sanglard 
141*3f982cf4SFabien Sanglard   // Helper to return an iterator pointing to the entry corresponding to the
142*3f982cf4SFabien Sanglard   // given |receiver_ssrc|, or "end" if not found.
143*3f982cf4SFabien Sanglard   SenderEntries::iterator FindEntry(Ssrc receiver_ssrc);
144*3f982cf4SFabien Sanglard 
145*3f982cf4SFabien Sanglard   // Examine the next send time for all Senders, and decide whether to schedule
146*3f982cf4SFabien Sanglard   // a burst-send.
147*3f982cf4SFabien Sanglard   void ScheduleNextBurst();
148*3f982cf4SFabien Sanglard 
149*3f982cf4SFabien Sanglard   // Performs a burst-send of packets. This is called whenever the Alarm fires.
150*3f982cf4SFabien Sanglard   void SendBurstOfPackets();
151*3f982cf4SFabien Sanglard 
152*3f982cf4SFabien Sanglard   // Send an RTCP packet from each Sender that has one ready, and return the
153*3f982cf4SFabien Sanglard   // number of packets sent.
154*3f982cf4SFabien Sanglard   int SendJustTheRtcpPackets(Clock::time_point send_time);
155*3f982cf4SFabien Sanglard 
156*3f982cf4SFabien Sanglard   // Send zero or more RTP packets from each Sender, up to a maximum of
157*3f982cf4SFabien Sanglard   // |num_packets_to_send|, and return the number of packets sent.
158*3f982cf4SFabien Sanglard   int SendJustTheRtpPackets(Clock::time_point send_time,
159*3f982cf4SFabien Sanglard                             int num_packets_to_send);
160*3f982cf4SFabien Sanglard 
161*3f982cf4SFabien Sanglard   // Returns the maximum number of packets to send in one burst, based on the
162*3f982cf4SFabien Sanglard   // given parameters.
163*3f982cf4SFabien Sanglard   static int ComputeMaxPacketsPerBurst(
164*3f982cf4SFabien Sanglard       int max_burst_bitrate,
165*3f982cf4SFabien Sanglard       int packet_size,
166*3f982cf4SFabien Sanglard       std::chrono::milliseconds burst_interval);
167*3f982cf4SFabien Sanglard 
168*3f982cf4SFabien Sanglard   // Returns the maximum bitrate inferred by the given parameters.
169*3f982cf4SFabien Sanglard   static int ComputeMaxBurstBitrate(int packet_size,
170*3f982cf4SFabien Sanglard                                     int max_packets_per_burst,
171*3f982cf4SFabien Sanglard                                     std::chrono::milliseconds burst_interval);
172*3f982cf4SFabien Sanglard 
173*3f982cf4SFabien Sanglard   Environment* const environment_;
174*3f982cf4SFabien Sanglard   const int packet_buffer_size_;
175*3f982cf4SFabien Sanglard   const std::unique_ptr<uint8_t[]> packet_buffer_;
176*3f982cf4SFabien Sanglard   const int max_packets_per_burst_;
177*3f982cf4SFabien Sanglard   const std::chrono::milliseconds burst_interval_;
178*3f982cf4SFabien Sanglard   const int max_burst_bitrate_;
179*3f982cf4SFabien Sanglard 
180*3f982cf4SFabien Sanglard   // Schedules the task that calls back into this SenderPacketRouter at a later
181*3f982cf4SFabien Sanglard   // time to send the next burst of packets.
182*3f982cf4SFabien Sanglard   Alarm alarm_;
183*3f982cf4SFabien Sanglard 
184*3f982cf4SFabien Sanglard   // The current list of Senders and their timing information. This is
185*3f982cf4SFabien Sanglard   // maintained in order of the priority implied by the Sender SSRC's.
186*3f982cf4SFabien Sanglard   SenderEntries senders_;
187*3f982cf4SFabien Sanglard 
188*3f982cf4SFabien Sanglard   // The last time a burst of packets was sent. This is used to determine the
189*3f982cf4SFabien Sanglard   // next burst time.
190*3f982cf4SFabien Sanglard   Clock::time_point last_burst_time_ = Clock::time_point::min();
191*3f982cf4SFabien Sanglard };
192*3f982cf4SFabien Sanglard 
193*3f982cf4SFabien Sanglard }  // namespace cast
194*3f982cf4SFabien Sanglard }  // namespace openscreen
195*3f982cf4SFabien Sanglard 
196*3f982cf4SFabien Sanglard #endif  // CAST_STREAMING_SENDER_PACKET_ROUTER_H_
197