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