| // 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 <stdint.h> |
| |
| #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_ |