blob: 7e4f59b77bc882f6f2923ce047f8cd7fca51bdff [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CAST_STREAMING_RTP_PACKETIZER_H_
#define CAST_STREAMING_RTP_PACKETIZER_H_
#include <stdint.h>
#include "absl/types/span.h"
#include "cast/streaming/frame_crypto.h"
#include "cast/streaming/rtp_defines.h"
#include "cast/streaming/ssrc.h"
namespace openscreen {
namespace 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.
absl::Span<uint8_t> GeneratePacket(const EncryptedFrame& frame,
FramePacketId packet_id,
absl::Span<uint8_t> 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 cast
} // namespace openscreen
#endif // CAST_STREAMING_RTP_PACKETIZER_H_