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_RTP_PACKET_PARSER_H_ 6 #define CAST_STREAMING_RTP_PACKET_PARSER_H_ 7 8 #include <chrono> 9 10 #include "absl/types/optional.h" 11 #include "absl/types/span.h" 12 #include "cast/streaming/frame_id.h" 13 #include "cast/streaming/rtp_defines.h" 14 #include "cast/streaming/rtp_time.h" 15 #include "cast/streaming/ssrc.h" 16 17 namespace openscreen { 18 namespace cast { 19 20 // Parses RTP packets for all frames in the same Cast RTP stream. One 21 // RtpPacketParser instance should be used for all RTP packets having the same 22 // SSRC. 23 // 24 // Note that the parser is not stateless: One of its responsibilities is to 25 // bit-expand values that exist in a truncated form within the packets. It 26 // tracks the progression of those values in a live system to re-constitute such 27 // values. 28 class RtpPacketParser { 29 public: 30 struct ParseResult { 31 // Elements from RTP packet header. 32 // https://tools.ietf.org/html/rfc3550#section-5 33 RtpPayloadType payload_type; 34 uint16_t sequence_number; // Wrap-around packet transmission counter. 35 RtpTimeTicks rtp_timestamp; // The media timestamp. 36 37 // Elements from Cast header (at beginning of RTP payload). 38 bool is_key_frame; 39 FrameId frame_id; 40 FramePacketId packet_id; // Always in the range [0,max_packet_id]. 41 FramePacketId max_packet_id; 42 FrameId referenced_frame_id; // ID of frame required to decode this one. 43 std::chrono::milliseconds new_playout_delay{}; // Ignore if non-positive. 44 45 // Portion of the |packet| that was passed into Parse() that contains the 46 // payload. WARNING: This memory region is only valid while the original 47 // |packet| memory remains valid. 48 absl::Span<const uint8_t> payload; 49 50 ParseResult(); 51 ~ParseResult(); 52 }; 53 54 explicit RtpPacketParser(Ssrc sender_ssrc); 55 ~RtpPacketParser(); 56 57 // Parses the packet. The caller should use InspectPacketForRouting() 58 // beforehand to ensure that the packet is meant to be parsed by this 59 // instance. Returns absl::nullopt if the |packet| was corrupt. 60 absl::optional<ParseResult> Parse(absl::Span<const uint8_t> packet); 61 62 private: 63 const Ssrc sender_ssrc_; 64 65 // Tracks recently-parsed RTP timestamps so that the truncated values can be 66 // re-expanded into full-form. 67 RtpTimeTicks last_parsed_rtp_timestamp_; 68 69 // The highest frame ID seen in any RTP packets so far. This is tracked so 70 // that the truncated frame ID fields in RTP packets can be re-expanded into 71 // full-form. 72 FrameId highest_rtp_frame_id_; 73 }; 74 75 } // namespace cast 76 } // namespace openscreen 77 78 #endif // CAST_STREAMING_RTP_PACKET_PARSER_H_ 79