xref: /aosp_15_r20/external/openscreen/cast/streaming/rtp_packetizer.h (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 #ifndef CAST_STREAMING_RTP_PACKETIZER_H_
6*3f982cf4SFabien Sanglard #define CAST_STREAMING_RTP_PACKETIZER_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <stdint.h>
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard #include "absl/types/span.h"
11*3f982cf4SFabien Sanglard #include "cast/streaming/frame_crypto.h"
12*3f982cf4SFabien Sanglard #include "cast/streaming/rtp_defines.h"
13*3f982cf4SFabien Sanglard #include "cast/streaming/ssrc.h"
14*3f982cf4SFabien Sanglard 
15*3f982cf4SFabien Sanglard namespace openscreen {
16*3f982cf4SFabien Sanglard namespace cast {
17*3f982cf4SFabien Sanglard 
18*3f982cf4SFabien Sanglard // Transforms a logical sequence of EncryptedFrames into RTP packets for
19*3f982cf4SFabien Sanglard // transmission. A single instance of RtpPacketizer should be used for all the
20*3f982cf4SFabien Sanglard // frames in a Cast RTP stream having the same SSRC.
21*3f982cf4SFabien Sanglard class RtpPacketizer {
22*3f982cf4SFabien Sanglard  public:
23*3f982cf4SFabien Sanglard   // |payload_type| describes the type of the media content for the RTP stream
24*3f982cf4SFabien Sanglard   // from the sender having the given |sender_ssrc|.
25*3f982cf4SFabien Sanglard   //
26*3f982cf4SFabien Sanglard   // The |max_packet_size| argument depends on the optimal over-the-wire size of
27*3f982cf4SFabien Sanglard   // packets for the network medium being used. See discussion in rtp_defines.h
28*3f982cf4SFabien Sanglard   // for further info.
29*3f982cf4SFabien Sanglard   RtpPacketizer(RtpPayloadType payload_type,
30*3f982cf4SFabien Sanglard                 Ssrc sender_ssrc,
31*3f982cf4SFabien Sanglard                 int max_packet_size);
32*3f982cf4SFabien Sanglard 
33*3f982cf4SFabien Sanglard   ~RtpPacketizer();
34*3f982cf4SFabien Sanglard 
35*3f982cf4SFabien Sanglard   // Wire-format one of the RTP packets for the given frame, which must only be
36*3f982cf4SFabien Sanglard   // transmitted once. This method should be called in the same sequence that
37*3f982cf4SFabien Sanglard   // packets will be transmitted. This also means that, if a packet needs to be
38*3f982cf4SFabien Sanglard   // re-transmitted, this method should be called to generate it again. Returns
39*3f982cf4SFabien Sanglard   // the subspan of |buffer| that contains the packet. |buffer| must be at least
40*3f982cf4SFabien Sanglard   // as large as the |max_packet_size| passed to the constructor.
41*3f982cf4SFabien Sanglard   absl::Span<uint8_t> GeneratePacket(const EncryptedFrame& frame,
42*3f982cf4SFabien Sanglard                                      FramePacketId packet_id,
43*3f982cf4SFabien Sanglard                                      absl::Span<uint8_t> buffer);
44*3f982cf4SFabien Sanglard 
45*3f982cf4SFabien Sanglard   // Given |frame|, compute the total number of packets over which the whole
46*3f982cf4SFabien Sanglard   // frame will be split-up. Returns -1 if the frame is too large and cannot be
47*3f982cf4SFabien Sanglard   // packetized.
48*3f982cf4SFabien Sanglard   int ComputeNumberOfPackets(const EncryptedFrame& frame) const;
49*3f982cf4SFabien Sanglard 
50*3f982cf4SFabien Sanglard   // See rtp_defines.h for wire-format diagram.
51*3f982cf4SFabien Sanglard   static constexpr int kBaseRtpHeaderSize =
52*3f982cf4SFabien Sanglard       // Plus one byte, because this implementation always includes the 8-bit
53*3f982cf4SFabien Sanglard       // Reference Frame ID field.
54*3f982cf4SFabien Sanglard       kRtpPacketMinValidSize + 1;
55*3f982cf4SFabien Sanglard   static constexpr int kAdaptiveLatencyHeaderSize = 4;
56*3f982cf4SFabien Sanglard   static constexpr int kMaxRtpHeaderSize =
57*3f982cf4SFabien Sanglard       kBaseRtpHeaderSize + kAdaptiveLatencyHeaderSize;
58*3f982cf4SFabien Sanglard 
59*3f982cf4SFabien Sanglard  private:
max_payload_size()60*3f982cf4SFabien Sanglard   int max_payload_size() const {
61*3f982cf4SFabien Sanglard     // Start with the configured max packet size, then subtract reserved space
62*3f982cf4SFabien Sanglard     // for packet header fields. The rest can be allocated to the payload.
63*3f982cf4SFabien Sanglard     return max_packet_size_ - kMaxRtpHeaderSize;
64*3f982cf4SFabien Sanglard   }
65*3f982cf4SFabien Sanglard 
66*3f982cf4SFabien Sanglard   // The validated ctor RtpPayloadType arg, in wire-format form.
67*3f982cf4SFabien Sanglard   const uint8_t payload_type_7bits_;
68*3f982cf4SFabien Sanglard 
69*3f982cf4SFabien Sanglard   const Ssrc sender_ssrc_;
70*3f982cf4SFabien Sanglard   const int max_packet_size_;
71*3f982cf4SFabien Sanglard 
72*3f982cf4SFabien Sanglard   // Incremented each time GeneratePacket() is called. Every packet, even those
73*3f982cf4SFabien Sanglard   // re-transmitted, must have different sequence numbers (within wrap-around
74*3f982cf4SFabien Sanglard   // concerns) per the RTP spec.
75*3f982cf4SFabien Sanglard   uint16_t sequence_number_;
76*3f982cf4SFabien Sanglard };
77*3f982cf4SFabien Sanglard 
78*3f982cf4SFabien Sanglard }  // namespace cast
79*3f982cf4SFabien Sanglard }  // namespace openscreen
80*3f982cf4SFabien Sanglard 
81*3f982cf4SFabien Sanglard #endif  // CAST_STREAMING_RTP_PACKETIZER_H_
82