// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CAST_STREAMING_IMPL_RTP_PACKETIZER_H_ #define CAST_STREAMING_IMPL_RTP_PACKETIZER_H_ #include #include "cast/streaming/impl/frame_crypto.h" #include "cast/streaming/impl/rtp_defines.h" #include "cast/streaming/ssrc.h" #include "platform/base/span.h" namespace openscreen::cast { // Transforms a logical sequence of EncryptedFrames into RTP packets for // transmission. A single instance of RtpPacketizer should be used for all the // frames in a Cast RTP stream having the same SSRC. class RtpPacketizer { public: // `payload_type` describes the type of the media content for the RTP stream // from the sender having the given `sender_ssrc`. // // The `max_packet_size` argument depends on the optimal over-the-wire size of // packets for the network medium being used. See discussion in rtp_defines.h // for further info. RtpPacketizer(RtpPayloadType payload_type, Ssrc sender_ssrc, int max_packet_size); ~RtpPacketizer(); // Wire-format one of the RTP packets for the given frame, which must only be // transmitted once. This method should be called in the same sequence that // packets will be transmitted. This also means that, if a packet needs to be // re-transmitted, this method should be called to generate it again. Returns // the subspan of `buffer` that contains the packet. `buffer` must be at least // as large as the `max_packet_size` passed to the constructor. ByteBuffer GeneratePacket(const EncryptedFrame& frame, FramePacketId packet_id, ByteBuffer buffer); // Given `frame`, compute the total number of packets over which the whole // frame will be split-up. Returns -1 if the frame is too large and cannot be // packetized. int ComputeNumberOfPackets(const EncryptedFrame& frame) const; // See rtp_defines.h for wire-format diagram. static constexpr int kBaseRtpHeaderSize = // Plus one byte, because this implementation always includes the 8-bit // Reference Frame ID field. kRtpPacketMinValidSize + 1; static constexpr int kAdaptiveLatencyHeaderSize = 4; static constexpr int kMaxRtpHeaderSize = kBaseRtpHeaderSize + kAdaptiveLatencyHeaderSize; private: int max_payload_size() const { // Start with the configured max packet size, then subtract reserved space // for packet header fields. The rest can be allocated to the payload. return max_packet_size_ - kMaxRtpHeaderSize; } // The validated ctor RtpPayloadType arg, in wire-format form. const uint8_t payload_type_7bits_; const Ssrc sender_ssrc_; const int max_packet_size_; // Incremented each time GeneratePacket() is called. Every packet, even those // re-transmitted, must have different sequence numbers (within wrap-around // concerns) per the RTP spec. uint16_t sequence_number_; }; } // namespace openscreen::cast #endif // CAST_STREAMING_IMPL_RTP_PACKETIZER_H_