xref: /aosp_15_r20/external/openscreen/cast/streaming/rtp_packetizer.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_packetizer.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include <algorithm>
8*3f982cf4SFabien Sanglard #include <limits>
9*3f982cf4SFabien Sanglard #include <random>
10*3f982cf4SFabien Sanglard 
11*3f982cf4SFabien Sanglard #include "cast/streaming/packet_util.h"
12*3f982cf4SFabien Sanglard #include "platform/api/time.h"
13*3f982cf4SFabien Sanglard #include "util/big_endian.h"
14*3f982cf4SFabien Sanglard #include "util/integer_division.h"
15*3f982cf4SFabien Sanglard #include "util/osp_logging.h"
16*3f982cf4SFabien Sanglard 
17*3f982cf4SFabien Sanglard namespace openscreen {
18*3f982cf4SFabien Sanglard namespace cast {
19*3f982cf4SFabien Sanglard 
20*3f982cf4SFabien Sanglard namespace {
21*3f982cf4SFabien Sanglard 
22*3f982cf4SFabien Sanglard // Returns a random sequence number to start with. The reason for using a random
23*3f982cf4SFabien Sanglard // number instead of zero is unclear, but this has existed both in several
24*3f982cf4SFabien Sanglard // versions of the Cast Streaming spec and in other implementations for many
25*3f982cf4SFabien Sanglard // years.
GenerateRandomSequenceNumberStart()26*3f982cf4SFabien Sanglard uint16_t GenerateRandomSequenceNumberStart() {
27*3f982cf4SFabien Sanglard   // Use a statically-allocated generator, instantiated upon first use, and
28*3f982cf4SFabien Sanglard   // seeded with the current time tick count. This generator was chosen because
29*3f982cf4SFabien Sanglard   // it is light-weight and does not need to produce unguessable (nor
30*3f982cf4SFabien Sanglard   // crypto-secure) values.
31*3f982cf4SFabien Sanglard   static std::minstd_rand generator(static_cast<std::minstd_rand::result_type>(
32*3f982cf4SFabien Sanglard       Clock::now().time_since_epoch().count()));
33*3f982cf4SFabien Sanglard 
34*3f982cf4SFabien Sanglard   return std::uniform_int_distribution<uint16_t>()(generator);
35*3f982cf4SFabien Sanglard }
36*3f982cf4SFabien Sanglard 
37*3f982cf4SFabien Sanglard }  // namespace
38*3f982cf4SFabien Sanglard 
RtpPacketizer(RtpPayloadType payload_type,Ssrc sender_ssrc,int max_packet_size)39*3f982cf4SFabien Sanglard RtpPacketizer::RtpPacketizer(RtpPayloadType payload_type,
40*3f982cf4SFabien Sanglard                              Ssrc sender_ssrc,
41*3f982cf4SFabien Sanglard                              int max_packet_size)
42*3f982cf4SFabien Sanglard     : payload_type_7bits_(static_cast<uint8_t>(payload_type)),
43*3f982cf4SFabien Sanglard       sender_ssrc_(sender_ssrc),
44*3f982cf4SFabien Sanglard       max_packet_size_(max_packet_size),
45*3f982cf4SFabien Sanglard       sequence_number_(GenerateRandomSequenceNumberStart()) {
46*3f982cf4SFabien Sanglard   OSP_DCHECK(IsRtpPayloadType(payload_type_7bits_));
47*3f982cf4SFabien Sanglard   OSP_DCHECK_GT(max_packet_size_, kMaxRtpHeaderSize);
48*3f982cf4SFabien Sanglard }
49*3f982cf4SFabien Sanglard 
50*3f982cf4SFabien Sanglard RtpPacketizer::~RtpPacketizer() = default;
51*3f982cf4SFabien Sanglard 
GeneratePacket(const EncryptedFrame & frame,FramePacketId packet_id,absl::Span<uint8_t> buffer)52*3f982cf4SFabien Sanglard absl::Span<uint8_t> RtpPacketizer::GeneratePacket(const EncryptedFrame& frame,
53*3f982cf4SFabien Sanglard                                                   FramePacketId packet_id,
54*3f982cf4SFabien Sanglard                                                   absl::Span<uint8_t> buffer) {
55*3f982cf4SFabien Sanglard   OSP_CHECK_GE(static_cast<int>(buffer.size()), max_packet_size_);
56*3f982cf4SFabien Sanglard 
57*3f982cf4SFabien Sanglard   const int num_packets = ComputeNumberOfPackets(frame);
58*3f982cf4SFabien Sanglard   OSP_DCHECK_GT(num_packets, 0);
59*3f982cf4SFabien Sanglard   OSP_DCHECK_LT(int{packet_id}, num_packets);
60*3f982cf4SFabien Sanglard   const bool is_last_packet = int{packet_id} == (num_packets - 1);
61*3f982cf4SFabien Sanglard 
62*3f982cf4SFabien Sanglard   // Compute the size of this packet, which is the number of bytes of header
63*3f982cf4SFabien Sanglard   // plus the number of bytes of payload. Note that the optional Adaptive
64*3f982cf4SFabien Sanglard   // Latency information is only added to the first packet.
65*3f982cf4SFabien Sanglard   int packet_size = kBaseRtpHeaderSize;
66*3f982cf4SFabien Sanglard   const bool include_adaptive_latency_change =
67*3f982cf4SFabien Sanglard       (packet_id == 0 &&
68*3f982cf4SFabien Sanglard        frame.new_playout_delay > std::chrono::milliseconds(0));
69*3f982cf4SFabien Sanglard   if (include_adaptive_latency_change) {
70*3f982cf4SFabien Sanglard     OSP_DCHECK_LE(frame.new_playout_delay.count(),
71*3f982cf4SFabien Sanglard                   int{std::numeric_limits<uint16_t>::max()});
72*3f982cf4SFabien Sanglard     packet_size += kAdaptiveLatencyHeaderSize;
73*3f982cf4SFabien Sanglard   }
74*3f982cf4SFabien Sanglard   int data_chunk_size = max_payload_size();
75*3f982cf4SFabien Sanglard   const int data_chunk_start = data_chunk_size * int{packet_id};
76*3f982cf4SFabien Sanglard   if (is_last_packet) {
77*3f982cf4SFabien Sanglard     data_chunk_size = static_cast<int>(frame.data.size()) - data_chunk_start;
78*3f982cf4SFabien Sanglard   }
79*3f982cf4SFabien Sanglard   packet_size += data_chunk_size;
80*3f982cf4SFabien Sanglard   OSP_DCHECK_LE(packet_size, max_packet_size_);
81*3f982cf4SFabien Sanglard   const absl::Span<uint8_t> packet(buffer.data(), packet_size);
82*3f982cf4SFabien Sanglard 
83*3f982cf4SFabien Sanglard   // RTP Header.
84*3f982cf4SFabien Sanglard   AppendField<uint8_t>(kRtpRequiredFirstByte, &buffer);
85*3f982cf4SFabien Sanglard   AppendField<uint8_t>(
86*3f982cf4SFabien Sanglard       (is_last_packet ? kRtpMarkerBitMask : 0) | payload_type_7bits_, &buffer);
87*3f982cf4SFabien Sanglard   AppendField<uint16_t>(sequence_number_++, &buffer);
88*3f982cf4SFabien Sanglard   AppendField<uint32_t>(frame.rtp_timestamp.lower_32_bits(), &buffer);
89*3f982cf4SFabien Sanglard   AppendField<uint32_t>(sender_ssrc_, &buffer);
90*3f982cf4SFabien Sanglard 
91*3f982cf4SFabien Sanglard   // Cast Header.
92*3f982cf4SFabien Sanglard   AppendField<uint8_t>(
93*3f982cf4SFabien Sanglard       ((frame.dependency == EncodedFrame::KEY_FRAME) ? kRtpKeyFrameBitMask
94*3f982cf4SFabien Sanglard                                                      : 0) |
95*3f982cf4SFabien Sanglard           kRtpHasReferenceFrameIdBitMask |
96*3f982cf4SFabien Sanglard           (include_adaptive_latency_change ? 1 : 0),
97*3f982cf4SFabien Sanglard       &buffer);
98*3f982cf4SFabien Sanglard   AppendField<uint8_t>(frame.frame_id.lower_8_bits(), &buffer);
99*3f982cf4SFabien Sanglard   AppendField<uint16_t>(packet_id, &buffer);
100*3f982cf4SFabien Sanglard   AppendField<uint16_t>(num_packets - 1, &buffer);
101*3f982cf4SFabien Sanglard   AppendField<uint8_t>(frame.referenced_frame_id.lower_8_bits(), &buffer);
102*3f982cf4SFabien Sanglard 
103*3f982cf4SFabien Sanglard   // Extension of Cast Header for Adaptive Latency change.
104*3f982cf4SFabien Sanglard   if (include_adaptive_latency_change) {
105*3f982cf4SFabien Sanglard     AppendField<uint16_t>(
106*3f982cf4SFabien Sanglard         (kAdaptiveLatencyRtpExtensionType << kNumExtensionDataSizeFieldBits) |
107*3f982cf4SFabien Sanglard             sizeof(uint16_t),
108*3f982cf4SFabien Sanglard         &buffer);
109*3f982cf4SFabien Sanglard     AppendField<uint16_t>(frame.new_playout_delay.count(), &buffer);
110*3f982cf4SFabien Sanglard   }
111*3f982cf4SFabien Sanglard 
112*3f982cf4SFabien Sanglard   // Sanity-check the pointer math, to ensure the packet is being entirely
113*3f982cf4SFabien Sanglard   // populated, with no underrun or overrun.
114*3f982cf4SFabien Sanglard   OSP_DCHECK_EQ(buffer.data() + data_chunk_size, packet.end());
115*3f982cf4SFabien Sanglard 
116*3f982cf4SFabien Sanglard   // Copy the encrypted payload data into the packet.
117*3f982cf4SFabien Sanglard   memcpy(buffer.data(), frame.data.data() + data_chunk_start, data_chunk_size);
118*3f982cf4SFabien Sanglard 
119*3f982cf4SFabien Sanglard   return packet;
120*3f982cf4SFabien Sanglard }
121*3f982cf4SFabien Sanglard 
ComputeNumberOfPackets(const EncryptedFrame & frame) const122*3f982cf4SFabien Sanglard int RtpPacketizer::ComputeNumberOfPackets(const EncryptedFrame& frame) const {
123*3f982cf4SFabien Sanglard   // The total number of packets is computed by assuming the payload will be
124*3f982cf4SFabien Sanglard   // split-up across as few packets as possible.
125*3f982cf4SFabien Sanglard   int num_packets = DividePositivesRoundingUp(
126*3f982cf4SFabien Sanglard       static_cast<int>(frame.data.size()), max_payload_size());
127*3f982cf4SFabien Sanglard   // Edge case: There must always be at least one packet, even when there are no
128*3f982cf4SFabien Sanglard   // payload bytes. Some audio codecs, for example, use zero bytes to represent
129*3f982cf4SFabien Sanglard   // a period of silence.
130*3f982cf4SFabien Sanglard   num_packets = std::max(1, num_packets);
131*3f982cf4SFabien Sanglard 
132*3f982cf4SFabien Sanglard   // Ensure that the entire range of FramePacketIds can be represented.
133*3f982cf4SFabien Sanglard   return num_packets <= int{kMaxAllowedFramePacketId} ? num_packets : -1;
134*3f982cf4SFabien Sanglard }
135*3f982cf4SFabien Sanglard 
136*3f982cf4SFabien Sanglard }  // namespace cast
137*3f982cf4SFabien Sanglard }  // namespace openscreen
138