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