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 virtual ~Client(); 41 42 // Called when a Receiver Reference Time Report has been parsed. 43 virtual void OnReceiverReferenceTimeAdvanced( 44 Clock::time_point reference_time); 45 46 // Called when a Receiver Report with a Report Block has been parsed. 47 virtual void OnReceiverReport(const RtcpReportBlock& receiver_report); 48 49 // Called when the Receiver has encountered an unrecoverable error in 50 // decoding the data. The Sender should provide a key frame as soon as 51 // possible. 52 virtual void OnReceiverIndicatesPictureLoss(); 53 54 // Called when the Receiver indicates that all of the packets for all frames 55 // up to and including |frame_id| have been successfully received (or 56 // otherwise do not need to be re-transmitted). The |playout_delay| is the 57 // Receiver's current end-to-end target playout delay setting, which should 58 // reflect any changes the Sender has made by using the "Cast Adaptive 59 // Latency Extension" in RTP packets. 60 virtual void OnReceiverCheckpoint(FrameId frame_id, 61 std::chrono::milliseconds playout_delay); 62 63 // Called to indicate the Receiver has successfully received all of the 64 // packets for each of the given |acks|. The argument's elements are in 65 // monotonically increasing order. 66 virtual void OnReceiverHasFrames(std::vector<FrameId> acks); 67 68 // Called to indicate the Receiver is missing certain specific packets for 69 // certain specific frames. Any elements where the packet_id is 70 // kAllPacketsLost indicates that all the packets are missing for a frame. 71 // The argument's elements are in monotonically increasing order. 72 virtual void OnReceiverIsMissingPackets(std::vector<PacketNack> nacks); 73 }; 74 75 // |session| and |client| must be non-null and must outlive the 76 // CompoundRtcpParser instance. 77 CompoundRtcpParser(RtcpSession* session, Client* client); 78 ~CompoundRtcpParser(); 79 80 // Parses the packet, invoking the Client callback methods when appropriate. 81 // Returns true if the |packet| was well-formed, or false if it was corrupt. 82 // Note that none of the Client callback methods will be invoked until a 83 // packet is known to be well-formed. 84 // 85 // |max_feedback_frame_id| is the maximum-valued FrameId that could possibly 86 // be ACKnowledged by the Receiver, if there is Cast Feedback in the |packet|. 87 // This is needed for expanding truncated frame IDs correctly. 88 bool Parse(absl::Span<const uint8_t> packet, FrameId max_feedback_frame_id); 89 90 private: 91 // These return true if the input was well-formed, and false if it was 92 // invalid/corrupt. The true/false value does NOT indicate whether the data 93 // contained within was ignored. Output arguments are only modified if the 94 // input contained the relevant field(s). 95 bool ParseReceiverReport(absl::Span<const uint8_t> in, 96 int num_report_blocks, 97 absl::optional<RtcpReportBlock>* receiver_report); 98 bool ParseFeedback(absl::Span<const uint8_t> in, 99 FrameId max_feedback_frame_id, 100 FrameId* checkpoint_frame_id, 101 std::chrono::milliseconds* target_playout_delay, 102 std::vector<FrameId>* received_frames, 103 std::vector<PacketNack>* packet_nacks); 104 bool ParseExtendedReports(absl::Span<const uint8_t> in, 105 Clock::time_point* receiver_reference_time); 106 bool ParsePictureLossIndicator(absl::Span<const uint8_t> in, 107 bool* picture_loss_indicator); 108 109 RtcpSession* const session_; 110 Client* const client_; 111 112 // Tracks the latest timestamp seen from any Receiver Reference Time Report, 113 // and uses this to ignore stale RTCP packets that arrived out-of-order and/or 114 // late from the network. 115 Clock::time_point latest_receiver_timestamp_; 116 }; 117 118 } // namespace cast 119 } // namespace openscreen 120 121 #endif // CAST_STREAMING_COMPOUND_RTCP_PARSER_H_ 122