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