1 // Copyright 2019 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_RECEIVER_H_ 6 #define CAST_STREAMING_RECEIVER_H_ 7 8 #include <stdint.h> 9 10 #include <array> 11 #include <chrono> 12 #include <memory> 13 #include <utility> 14 #include <vector> 15 16 #include "absl/types/optional.h" 17 #include "absl/types/span.h" 18 #include "cast/streaming/clock_drift_smoother.h" 19 #include "cast/streaming/compound_rtcp_builder.h" 20 #include "cast/streaming/environment.h" 21 #include "cast/streaming/frame_collector.h" 22 #include "cast/streaming/frame_id.h" 23 #include "cast/streaming/packet_receive_stats_tracker.h" 24 #include "cast/streaming/receiver_base.h" 25 #include "cast/streaming/rtcp_common.h" 26 #include "cast/streaming/rtcp_session.h" 27 #include "cast/streaming/rtp_packet_parser.h" 28 #include "cast/streaming/sender_report_parser.h" 29 #include "cast/streaming/session_config.h" 30 #include "cast/streaming/ssrc.h" 31 #include "platform/api/time.h" 32 #include "util/alarm.h" 33 34 namespace openscreen { 35 namespace cast { 36 37 struct EncodedFrame; 38 class ReceiverPacketRouter; 39 40 // The Cast Streaming Receiver, a peer corresponding to some Cast Streaming 41 // Sender at the other end of a network link. 42 // 43 // Cast Streaming is a transport protocol which divides up the frames for one 44 // media stream (e.g., audio or video) into multiple RTP packets containing an 45 // encrypted payload. The Receiver is the peer responsible for collecting the 46 // RTP packets, decrypting the payload, and re-assembling a frame that can be 47 // passed to a decoder and played out. 48 // 49 // A Sender ↔ Receiver pair is used to transport each media stream. Typically, 50 // there are two pairs in a normal system, one for the audio stream and one for 51 // video stream. A local player is responsible for synchronizing the playout of 52 // the frames of each stream to achieve lip-sync. See the discussion in 53 // encoded_frame.h for how the |reference_time| and |rtp_timestamp| of the 54 // EncodedFrames are used to achieve this. 55 // 56 // See the Receiver Demo app for a reference implementation that both shows and 57 // explains how Receivers are properly configured and started, integrated with a 58 // decoder, and the resulting decoded media is played out. Also, here is a 59 // general usage example: 60 // 61 // class MyPlayer : public openscreen::cast::Receiver::Consumer { 62 // public: 63 // explicit MyPlayer(Receiver* receiver) : receiver_(receiver) { 64 // recevier_->SetPlayerProcessingTime(std::chrono::milliseconds(10)); 65 // receiver_->SetConsumer(this); 66 // } 67 // 68 // ~MyPlayer() override { 69 // receiver_->SetConsumer(nullptr); 70 // } 71 // 72 // private: 73 // // Receiver::Consumer implementation. 74 // void OnFramesReady(int next_frame_buffer_size) override { 75 // std::vector<uint8_t> buffer; 76 // buffer.resize(next_frame_buffer_size); 77 // openscreen::cast::EncodedFrame encoded_frame = 78 // receiver_->ConsumeNextFrame(absl::Span<uint8_t>(buffer)); 79 // 80 // display_.RenderFrame(decoder_.DecodeFrame(encoded_frame.data)); 81 // 82 // // Note: An implementation could call receiver_->AdvanceToNextFrame() 83 // // and receiver_->ConsumeNextFrame() in a loop here, to consume all the 84 // // remaining frames that are ready. 85 // } 86 // 87 // Receiver* const receiver_; 88 // MyDecoder decoder_; 89 // MyDisplay display_; 90 // }; 91 // 92 // Internally, a queue of complete and partially-received frames is maintained. 93 // The queue is a circular queue of FrameCollectors that each maintain the 94 // individual receive state of each in-flight frame. There are three conceptual 95 // "pointers" that indicate what assumptions and operations are made on certain 96 // ranges of frames in the queue: 97 // 98 // 1. Latest Frame Expected: The FrameId of the latest frame whose existence 99 // is known to this Receiver. This is the highest FrameId seen in any 100 // successfully-parsed RTP packet. 101 // 2. Checkpoint Frame: Indicates that all of the RTP packets for all frames 102 // up to and including the one having this FrameId have been successfully 103 // received and processed. 104 // 3. Last Frame Consumed: The FrameId of last frame consumed (see 105 // ConsumeNextFrame()). Once a frame is consumed, all internal resources 106 // related to the frame can be freed and/or re-used for later frames. 107 class Receiver : public ReceiverBase { 108 public: 109 using ReceiverBase::Consumer; 110 111 // Constructs a Receiver that attaches to the given |environment| and 112 // |packet_router|. The config contains the settings that were 113 // agreed-upon by both sides from the OFFER/ANSWER exchange (i.e., the part of 114 // the overall end-to-end connection process that occurs before Cast Streaming 115 // is started). 116 Receiver(Environment* environment, 117 ReceiverPacketRouter* packet_router, 118 SessionConfig config); 119 ~Receiver() override; 120 121 // ReceiverBase overrides. 122 const SessionConfig& config() const override; 123 int rtp_timebase() const override; 124 Ssrc ssrc() const override; 125 void SetConsumer(Consumer* consumer) override; 126 void SetPlayerProcessingTime(Clock::duration needed_time) override; 127 void RequestKeyFrame() override; 128 int AdvanceToNextFrame() override; 129 EncodedFrame ConsumeNextFrame(absl::Span<uint8_t> buffer) override; 130 131 // Allows setting picture loss indication for testing. In production, this 132 // should be done using the config. SetPliEnabledForTesting(bool is_pli_enabled)133 void SetPliEnabledForTesting(bool is_pli_enabled) { 134 is_pli_enabled_ = is_pli_enabled; 135 } 136 137 // The default "player processing time" amount. See SetPlayerProcessingTime(). 138 static constexpr std::chrono::milliseconds kDefaultPlayerProcessingTime = 139 ReceiverBase::kDefaultPlayerProcessingTime; 140 141 // Returned by AdvanceToNextFrame() when there are no frames currently ready 142 // for consumption. 143 static constexpr int kNoFramesReady = ReceiverBase::kNoFramesReady; 144 145 protected: 146 friend class ReceiverPacketRouter; 147 148 // Called by ReceiverPacketRouter to provide this Receiver with what looks 149 // like a RTP/RTCP packet meant for it specifically (among other Receivers). 150 void OnReceivedRtpPacket(Clock::time_point arrival_time, 151 std::vector<uint8_t> packet); 152 void OnReceivedRtcpPacket(Clock::time_point arrival_time, 153 std::vector<uint8_t> packet); 154 155 private: 156 // An entry in the circular queue (see |pending_frames_|). 157 struct PendingFrame { 158 FrameCollector collector; 159 160 // The Receiver's [local] Clock time when this frame was originally captured 161 // at the Sender. This is computed and assigned when the RTP packet with ID 162 // 0 is processed. Add the target playout delay to this to get the target 163 // playout time. 164 absl::optional<Clock::time_point> estimated_capture_time; 165 166 PendingFrame(); 167 ~PendingFrame(); 168 169 // Reset this entry to its initial state, freeing resources. 170 void Reset(); 171 }; 172 173 // Get/Set the checkpoint FrameId. This indicates that all of the packets for 174 // all frames up to and including this FrameId have been successfully received 175 // (or otherwise do not need to be re-transmitted). checkpoint_frame()176 FrameId checkpoint_frame() const { return rtcp_builder_.checkpoint_frame(); } set_checkpoint_frame(FrameId frame_id)177 void set_checkpoint_frame(FrameId frame_id) { 178 rtcp_builder_.SetCheckpointFrame(frame_id); 179 } 180 181 // Send an RTCP packet to the Sender immediately, to acknowledge the complete 182 // reception of one or more additional frames, to reply to a Sender Report, or 183 // to request re-transmits. Calling this also schedules additional RTCP 184 // packets to be sent periodically for the life of this Receiver. 185 void SendRtcp(); 186 187 // Helpers to map the given |frame_id| to the element in the |pending_frames_| 188 // circular queue. There are both const and non-const versions, but neither 189 // mutate any state (i.e., they are just look-ups). 190 const PendingFrame& GetQueueEntry(FrameId frame_id) const; 191 PendingFrame& GetQueueEntry(FrameId frame_id); 192 193 // Record that the target playout delay has changed starting with the given 194 // FrameId. 195 void RecordNewTargetPlayoutDelay(FrameId as_of_frame, 196 std::chrono::milliseconds delay); 197 198 // Examine the known target playout delay changes to determine what setting is 199 // in-effect for the given frame. 200 std::chrono::milliseconds ResolveTargetPlayoutDelay(FrameId frame_id) const; 201 202 // Called to move the checkpoint forward. This scans the queue, starting from 203 // |new_checkpoint|, to find the latest in a contiguous sequence of completed 204 // frames. Then, it records that frame as the new checkpoint, and immediately 205 // sends a feedback RTCP packet to the Sender. 206 void AdvanceCheckpoint(FrameId new_checkpoint); 207 208 // Helper to force-drop all frames before |first_kept_frame|, even if they 209 // were never consumed. This will also auto-cancel frames that were never 210 // completely received, artificially moving the checkpoint forward, and 211 // notifying the Sender of that. The caller of this method is responsible for 212 // making sure that frame data dependencies will not be broken by dropping the 213 // frames. 214 void DropAllFramesBefore(FrameId first_kept_frame); 215 216 // Sets the |consumption_alarm_| to check whether any frames are ready, 217 // including possibly skipping over late frames in order to make not-yet-late 218 // frames become ready. The default argument value means "without delay." 219 void ScheduleFrameReadyCheck(Clock::time_point when = Alarm::kImmediately); 220 221 const ClockNowFunctionPtr now_; 222 ReceiverPacketRouter* const packet_router_; 223 const SessionConfig config_; 224 RtcpSession rtcp_session_; 225 SenderReportParser rtcp_parser_; 226 CompoundRtcpBuilder rtcp_builder_; 227 PacketReceiveStatsTracker stats_tracker_; // Tracks transmission stats. 228 RtpPacketParser rtp_parser_; 229 const int rtp_timebase_; // RTP timestamp ticks per second. 230 const FrameCrypto crypto_; // Decrypts assembled frames. 231 bool is_pli_enabled_; // Whether picture loss indication is enabled. 232 233 // Buffer for serializing/sending RTCP packets. 234 const int rtcp_buffer_capacity_; 235 const std::unique_ptr<uint8_t[]> rtcp_buffer_; 236 237 // Schedules tasks to ensure RTCP reports are sent within a bounded interval. 238 // Not scheduled until after this Receiver has processed the first packet from 239 // the Sender. 240 Alarm rtcp_alarm_; 241 Clock::time_point last_rtcp_send_time_ = Clock::time_point::min(); 242 243 // The last Sender Report received and when the packet containing it had 244 // arrived. This contains lip-sync timestamps used as part of the calculation 245 // of playout times for the received frames, as well as ping-pong data bounced 246 // back to the Sender in the Receiver Reports. It is nullopt until the first 247 // parseable Sender Report is received. 248 absl::optional<SenderReportParser::SenderReportWithId> last_sender_report_; 249 Clock::time_point last_sender_report_arrival_time_; 250 251 // Tracks the offset between the Receiver's [local] clock and the Sender's 252 // clock. This is invalid until the first Sender Report has been successfully 253 // processed (i.e., |last_sender_report_| is not nullopt). 254 ClockDriftSmoother smoothed_clock_offset_; 255 256 // The ID of the latest frame whose existence is known to this Receiver. This 257 // value must always be greater than or equal to |checkpoint_frame()|. 258 FrameId latest_frame_expected_ = FrameId::leader(); 259 260 // The ID of the last frame consumed. This value must always be less than or 261 // equal to |checkpoint_frame()|, since it's impossible to consume incomplete 262 // frames! 263 FrameId last_frame_consumed_ = FrameId::leader(); 264 265 // The ID of the latest key frame known to be in-flight. This is used by 266 // RequestKeyFrame() to ensure the PLI condition doesn't get set again until 267 // after the consumer has seen a key frame that would clear the condition. 268 FrameId last_key_frame_received_; 269 270 // The frame queue (circular), which tracks which frames are in-flight, stores 271 // data for partially-received frames, and holds onto completed frames until 272 // the consumer consumes them. 273 // 274 // Use GetQueueEntry() to access a slot. The currently-active slots are those 275 // for the frames after |last_frame_consumed_| and up-to/including 276 // |latest_frame_expected_|. 277 std::array<PendingFrame, kMaxUnackedFrames> pending_frames_{}; 278 279 // Tracks the recent changes to the target playout delay, which is controlled 280 // by the Sender. The FrameId indicates the first frame where a new delay 281 // setting takes effect. This vector is never empty, is kept sorted, and is 282 // pruned to remain as small as possible. 283 // 284 // The target playout delay is the amount of time between a frame's 285 // capture/recording on the Sender and when it should be played-out at the 286 // Receiver. 287 std::vector<std::pair<FrameId, std::chrono::milliseconds>> 288 playout_delay_changes_; 289 290 // The consumer to notify when there are one or more frames completed and 291 // ready to be consumed. 292 Consumer* consumer_ = nullptr; 293 294 // The additional time needed to decode/play-out each frame after being 295 // consumed from this Receiver. 296 Clock::duration player_processing_time_ = kDefaultPlayerProcessingTime; 297 298 // Scheduled to check whether there are frames ready and, if there are, to 299 // notify the Consumer via OnFramesReady(). 300 Alarm consumption_alarm_; 301 302 // The interval between sending ACK/NACK feedback RTCP messages while 303 // incomplete frames exist in the queue. 304 // 305 // TODO(jophba): This should be a function of the current target playout 306 // delay, similar to the Sender's kickstart interval logic. 307 static constexpr std::chrono::milliseconds kNackFeedbackInterval{30}; 308 }; 309 310 } // namespace cast 311 } // namespace openscreen 312 313 #endif // CAST_STREAMING_RECEIVER_H_ 314