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_COMPOUND_RTCP_PARSER_H_ 6 #define CAST_STREAMING_COMPOUND_RTCP_PARSER_H_ 7 8 #include <chrono> 9 #include <vector> 10 11 #include "absl/types/optional.h" 12 #include "absl/types/span.h" 13 #include "cast/streaming/frame_id.h" 14 #include "cast/streaming/rtcp_common.h" 15 #include "cast/streaming/rtp_defines.h" 16 17 namespace openscreen { 18 namespace cast { 19 20 class RtcpSession; 21 22 // Parses compound RTCP packets from a Receiver, invoking client callbacks when 23 // information of interest to a Sender (in the current process) is encountered. 24 class CompoundRtcpParser { 25 public: 26 // Callback interface used while parsing RTCP packets of interest to a Sender. 27 // The implementation must take into account: 28 // 29 // 1. Some/All of the data could be stale, as it only reflects the state of 30 // the Receiver at the time the packet was generated. A significant 31 // amount of time may have passed, depending on how long it took the 32 // packet to reach this local instance over the network. 33 // 2. The data shouldn't necessarily be trusted blindly: Some may be 34 // inconsistent (e.g., the same frame being ACKed and NACKed; or a frame 35 // that has not been sent yet is being NACKed). While that would indicate 36 // a badly-behaving Receiver, the Sender should be robust to such things. 37 class Client { 38 public: 39 Client(); 40 41 // Called when a Receiver Reference Time Report has been parsed. 42 virtual void OnReceiverReferenceTimeAdvanced( 43 Clock::time_point reference_time); 44 45 // Called when a Receiver Report with a Report Block has been parsed. 46 virtual void OnReceiverReport(const RtcpReportBlock& receiver_report); 47 48 // Called when the Receiver has encountered an unrecoverable error in 49 // decoding the data. The Sender should provide a key frame as soon as 50 // possible. 51 virtual void OnReceiverIndicatesPictureLoss(); 52 53 // Called when the Receiver indicates that all of the packets for all frames 54 // up to and including |frame_id| have been successfully received (or 55 // otherwise do not need to be re-transmitted). The |playout_delay| is the 56 // Receiver's current end-to-end target playout delay setting, which should 57 // reflect any changes the Sender has made by using the "Cast Adaptive 58 // Latency Extension" in RTP packets. 59 virtual void OnReceiverCheckpoint(FrameId frame_id, 60 std::chrono::milliseconds playout_delay); 61 62 // Called to indicate the Receiver has successfully received all of the 63 // packets for each of the given |acks|. The argument's elements are in 64 // monotonically increasing order. 65 virtual void OnReceiverHasFrames(std::vector<FrameId> acks); 66 67 // Called to indicate the Receiver is missing certain specific packets for 68 // certain specific frames. Any elements where the packet_id is 69 // kAllPacketsLost indicates that all the packets are missing for a frame. 70 // The argument's elements are in monotonically increasing order. 71 virtual void OnReceiverIsMissingPackets(std::vector<PacketNack> nacks); 72 73 protected: 74 virtual ~Client(); 75 }; 76 77 // |session| and |client| must be non-null and must outlive the 78 // CompoundRtcpParser instance. 79 CompoundRtcpParser(RtcpSession* session, Client* client); 80 ~CompoundRtcpParser(); 81 82 // Parses the packet, invoking the Client callback methods when appropriate. 83 // Returns true if the |packet| was well-formed, or false if it was corrupt. 84 // Note that none of the Client callback methods will be invoked until a 85 // packet is known to be well-formed. 86 // 87 // |max_feedback_frame_id| is the maximum-valued FrameId that could possibly 88 // be ACKnowledged by the Receiver, if there is Cast Feedback in the |packet|. 89 // This is needed for expanding truncated frame IDs correctly. 90 bool Parse(absl::Span<const uint8_t> packet, FrameId max_feedback_frame_id); 91 92 private: 93 // These return true if the input was well-formed, and false if it was 94 // invalid/corrupt. The true/false value does NOT indicate whether the data 95 // contained within was ignored. Output arguments are only modified if the 96 // input contained the relevant field(s). 97 bool ParseReceiverReport(absl::Span<const uint8_t> in, 98 int num_report_blocks, 99 absl::optional<RtcpReportBlock>* receiver_report); 100 bool ParseFeedback(absl::Span<const uint8_t> in, 101 FrameId max_feedback_frame_id, 102 FrameId* checkpoint_frame_id, 103 std::chrono::milliseconds* target_playout_delay, 104 std::vector<FrameId>* received_frames, 105 std::vector<PacketNack>* packet_nacks); 106 bool ParseExtendedReports(absl::Span<const uint8_t> in, 107 Clock::time_point* receiver_reference_time); 108 bool ParsePictureLossIndicator(absl::Span<const uint8_t> in, 109 bool* picture_loss_indicator); 110 111 RtcpSession* const session_; 112 Client* const client_; 113 114 // Tracks the latest timestamp seen from any Receiver Reference Time Report, 115 // and uses this to ignore stale RTCP packets that arrived out-of-order and/or 116 // late from the network. 117 Clock::time_point latest_receiver_timestamp_; 118 }; 119 120 } // namespace cast 121 } // namespace openscreen 122 123 #endif // CAST_STREAMING_COMPOUND_RTCP_PARSER_H_ 124