| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CAST_STREAMING_RTP_PACKET_PARSER_H_ |
| #define CAST_STREAMING_RTP_PACKET_PARSER_H_ |
| |
| #include <chrono> |
| |
| #include "absl/types/optional.h" |
| #include "absl/types/span.h" |
| #include "cast/streaming/frame_id.h" |
| #include "cast/streaming/rtp_defines.h" |
| #include "cast/streaming/rtp_time.h" |
| #include "cast/streaming/ssrc.h" |
| |
| namespace openscreen { |
| namespace cast { |
| |
| // Parses RTP packets for all frames in the same Cast RTP stream. One |
| // RtpPacketParser instance should be used for all RTP packets having the same |
| // SSRC. |
| // |
| // Note that the parser is not stateless: One of its responsibilities is to |
| // bit-expand values that exist in a truncated form within the packets. It |
| // tracks the progression of those values in a live system to re-constitute such |
| // values. |
| class RtpPacketParser { |
| public: |
| struct ParseResult { |
| // Elements from RTP packet header. |
| // https://tools.ietf.org/html/rfc3550#section-5 |
| RtpPayloadType payload_type; |
| uint16_t sequence_number; // Wrap-around packet transmission counter. |
| RtpTimeTicks rtp_timestamp; // The media timestamp. |
| |
| // Elements from Cast header (at beginning of RTP payload). |
| bool is_key_frame; |
| FrameId frame_id; |
| FramePacketId packet_id; // Always in the range [0,max_packet_id]. |
| FramePacketId max_packet_id; |
| FrameId referenced_frame_id; // ID of frame required to decode this one. |
| std::chrono::milliseconds new_playout_delay{}; // Ignore if non-positive. |
| |
| // Portion of the |packet| that was passed into Parse() that contains the |
| // payload. WARNING: This memory region is only valid while the original |
| // |packet| memory remains valid. |
| absl::Span<const uint8_t> payload; |
| |
| ParseResult(); |
| ~ParseResult(); |
| }; |
| |
| explicit RtpPacketParser(Ssrc sender_ssrc); |
| ~RtpPacketParser(); |
| |
| // Parses the packet. The caller should use InspectPacketForRouting() |
| // beforehand to ensure that the packet is meant to be parsed by this |
| // instance. Returns absl::nullopt if the |packet| was corrupt. |
| absl::optional<ParseResult> Parse(absl::Span<const uint8_t> packet); |
| |
| private: |
| const Ssrc sender_ssrc_; |
| |
| // Tracks recently-parsed RTP timestamps so that the truncated values can be |
| // re-expanded into full-form. |
| RtpTimeTicks last_parsed_rtp_timestamp_; |
| |
| // The highest frame ID seen in any RTP packets so far. This is tracked so |
| // that the truncated frame ID fields in RTP packets can be re-expanded into |
| // full-form. |
| FrameId highest_rtp_frame_id_; |
| }; |
| |
| } // namespace cast |
| } // namespace openscreen |
| |
| #endif // CAST_STREAMING_RTP_PACKET_PARSER_H_ |