xref: /aosp_15_r20/external/openscreen/cast/streaming/rtp_packet_parser.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "cast/streaming/rtp_packet_parser.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include <algorithm>
8*3f982cf4SFabien Sanglard #include <utility>
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard #include "cast/streaming/packet_util.h"
11*3f982cf4SFabien Sanglard #include "util/osp_logging.h"
12*3f982cf4SFabien Sanglard 
13*3f982cf4SFabien Sanglard namespace openscreen {
14*3f982cf4SFabien Sanglard namespace cast {
15*3f982cf4SFabien Sanglard 
RtpPacketParser(Ssrc sender_ssrc)16*3f982cf4SFabien Sanglard RtpPacketParser::RtpPacketParser(Ssrc sender_ssrc)
17*3f982cf4SFabien Sanglard     : sender_ssrc_(sender_ssrc), highest_rtp_frame_id_(FrameId::first()) {}
18*3f982cf4SFabien Sanglard 
19*3f982cf4SFabien Sanglard RtpPacketParser::~RtpPacketParser() = default;
20*3f982cf4SFabien Sanglard 
Parse(absl::Span<const uint8_t> buffer)21*3f982cf4SFabien Sanglard absl::optional<RtpPacketParser::ParseResult> RtpPacketParser::Parse(
22*3f982cf4SFabien Sanglard     absl::Span<const uint8_t> buffer) {
23*3f982cf4SFabien Sanglard   if (buffer.size() < kRtpPacketMinValidSize ||
24*3f982cf4SFabien Sanglard       ConsumeField<uint8_t>(&buffer) != kRtpRequiredFirstByte) {
25*3f982cf4SFabien Sanglard     return absl::nullopt;
26*3f982cf4SFabien Sanglard   }
27*3f982cf4SFabien Sanglard 
28*3f982cf4SFabien Sanglard   // RTP header elements.
29*3f982cf4SFabien Sanglard   //
30*3f982cf4SFabien Sanglard   // Note: M (marker bit) is ignored here. Technically, according to the Cast
31*3f982cf4SFabien Sanglard   // Streaming spec, it should only be set when PID == Max PID; but, let's be
32*3f982cf4SFabien Sanglard   // lenient just in case some sender implementations don't adhere to this tiny,
33*3f982cf4SFabien Sanglard   // subtle detail.
34*3f982cf4SFabien Sanglard   const uint8_t payload_type =
35*3f982cf4SFabien Sanglard       ConsumeField<uint8_t>(&buffer) & kRtpPayloadTypeMask;
36*3f982cf4SFabien Sanglard   if (!IsRtpPayloadType(payload_type)) {
37*3f982cf4SFabien Sanglard     return absl::nullopt;
38*3f982cf4SFabien Sanglard   }
39*3f982cf4SFabien Sanglard   ParseResult result;
40*3f982cf4SFabien Sanglard   result.payload_type = static_cast<RtpPayloadType>(payload_type);
41*3f982cf4SFabien Sanglard   result.sequence_number = ConsumeField<uint16_t>(&buffer);
42*3f982cf4SFabien Sanglard   result.rtp_timestamp =
43*3f982cf4SFabien Sanglard       last_parsed_rtp_timestamp_.Expand(ConsumeField<uint32_t>(&buffer));
44*3f982cf4SFabien Sanglard   if (ConsumeField<uint32_t>(&buffer) != sender_ssrc_) {
45*3f982cf4SFabien Sanglard     return absl::nullopt;
46*3f982cf4SFabien Sanglard   }
47*3f982cf4SFabien Sanglard 
48*3f982cf4SFabien Sanglard   // Cast-specific header elements.
49*3f982cf4SFabien Sanglard   const uint8_t byte12 = ConsumeField<uint8_t>(&buffer);
50*3f982cf4SFabien Sanglard   result.is_key_frame = !!(byte12 & kRtpKeyFrameBitMask);
51*3f982cf4SFabien Sanglard   const bool has_referenced_frame_id =
52*3f982cf4SFabien Sanglard       !!(byte12 & kRtpHasReferenceFrameIdBitMask);
53*3f982cf4SFabien Sanglard   const size_t num_cast_extensions = byte12 & kRtpExtensionCountMask;
54*3f982cf4SFabien Sanglard   result.frame_id =
55*3f982cf4SFabien Sanglard       highest_rtp_frame_id_.Expand(ConsumeField<uint8_t>(&buffer));
56*3f982cf4SFabien Sanglard   result.packet_id = ConsumeField<uint16_t>(&buffer);
57*3f982cf4SFabien Sanglard   result.max_packet_id = ConsumeField<uint16_t>(&buffer);
58*3f982cf4SFabien Sanglard   if (result.max_packet_id == kAllPacketsLost) {
59*3f982cf4SFabien Sanglard     return absl::nullopt;  // Packet ID cannot be the special value.
60*3f982cf4SFabien Sanglard   }
61*3f982cf4SFabien Sanglard   if (result.packet_id > result.max_packet_id) {
62*3f982cf4SFabien Sanglard     return absl::nullopt;
63*3f982cf4SFabien Sanglard   }
64*3f982cf4SFabien Sanglard   if (has_referenced_frame_id) {
65*3f982cf4SFabien Sanglard     if (buffer.empty()) {
66*3f982cf4SFabien Sanglard       return absl::nullopt;
67*3f982cf4SFabien Sanglard     }
68*3f982cf4SFabien Sanglard     result.referenced_frame_id =
69*3f982cf4SFabien Sanglard         result.frame_id.Expand(ConsumeField<uint8_t>(&buffer));
70*3f982cf4SFabien Sanglard   } else {
71*3f982cf4SFabien Sanglard     // By default, if no reference frame ID was provided, the assumption is that
72*3f982cf4SFabien Sanglard     // a key frame only references itself, while non-key frames reference only
73*3f982cf4SFabien Sanglard     // their immediate predecessor.
74*3f982cf4SFabien Sanglard     result.referenced_frame_id =
75*3f982cf4SFabien Sanglard         result.is_key_frame ? result.frame_id : (result.frame_id - 1);
76*3f982cf4SFabien Sanglard   }
77*3f982cf4SFabien Sanglard 
78*3f982cf4SFabien Sanglard   // Zero or more Cast extensions.
79*3f982cf4SFabien Sanglard   for (size_t i = 0; i < num_cast_extensions; ++i) {
80*3f982cf4SFabien Sanglard     if (buffer.size() < sizeof(uint16_t)) {
81*3f982cf4SFabien Sanglard       return absl::nullopt;
82*3f982cf4SFabien Sanglard     }
83*3f982cf4SFabien Sanglard     const uint16_t type_and_size = ConsumeField<uint16_t>(&buffer);
84*3f982cf4SFabien Sanglard     const uint8_t type = type_and_size >> kNumExtensionDataSizeFieldBits;
85*3f982cf4SFabien Sanglard     const size_t size =
86*3f982cf4SFabien Sanglard         type_and_size & FieldBitmask<uint16_t>(kNumExtensionDataSizeFieldBits);
87*3f982cf4SFabien Sanglard     if (buffer.size() < size) {
88*3f982cf4SFabien Sanglard       return absl::nullopt;
89*3f982cf4SFabien Sanglard     }
90*3f982cf4SFabien Sanglard     if (type == kAdaptiveLatencyRtpExtensionType) {
91*3f982cf4SFabien Sanglard       if (size != sizeof(uint16_t)) {
92*3f982cf4SFabien Sanglard         return absl::nullopt;
93*3f982cf4SFabien Sanglard       }
94*3f982cf4SFabien Sanglard       result.new_playout_delay =
95*3f982cf4SFabien Sanglard           std::chrono::milliseconds(ReadBigEndian<uint16_t>(buffer.data()));
96*3f982cf4SFabien Sanglard     }
97*3f982cf4SFabien Sanglard     buffer.remove_prefix(size);
98*3f982cf4SFabien Sanglard   }
99*3f982cf4SFabien Sanglard 
100*3f982cf4SFabien Sanglard   // All remaining data in the packet is the payload.
101*3f982cf4SFabien Sanglard   result.payload = buffer;
102*3f982cf4SFabien Sanglard 
103*3f982cf4SFabien Sanglard   // At this point, the packet is known to be well-formed. Track recent field
104*3f982cf4SFabien Sanglard   // values for later parses, to bit-extend the truncated values found in future
105*3f982cf4SFabien Sanglard   // packets.
106*3f982cf4SFabien Sanglard   last_parsed_rtp_timestamp_ = result.rtp_timestamp;
107*3f982cf4SFabien Sanglard   highest_rtp_frame_id_ = std::max(highest_rtp_frame_id_, result.frame_id);
108*3f982cf4SFabien Sanglard 
109*3f982cf4SFabien Sanglard   return result;
110*3f982cf4SFabien Sanglard }
111*3f982cf4SFabien Sanglard 
112*3f982cf4SFabien Sanglard RtpPacketParser::ParseResult::ParseResult() = default;
113*3f982cf4SFabien Sanglard RtpPacketParser::ParseResult::~ParseResult() = default;
114*3f982cf4SFabien Sanglard 
115*3f982cf4SFabien Sanglard }  // namespace cast
116*3f982cf4SFabien Sanglard }  // namespace openscreen
117