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