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