Replace RtpPacketizerH264::Fragment struct with rtc::ArrayView

Bug: None
Change-Id: Ifd1c8555eeddf8e95fb8ed56b39bbffb916aa292
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/157103
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29494}
This commit is contained in:
Danil Chapovalov
2019-10-15 15:12:35 +02:00
committed by Commit Bot
parent 8038541a4f
commit 82ed5d17dd
2 changed files with 34 additions and 53 deletions

View File

@ -82,10 +82,8 @@ RtpPacketizerH264::RtpPacketizerH264(
packetization_mode == H264PacketizationMode::SingleNalUnit); packetization_mode == H264PacketizationMode::SingleNalUnit);
for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) { for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) {
const uint8_t* fragment = input_fragments_.push_back(
payload.data() + fragmentation.fragmentationOffset[i]; payload.subview(fragmentation.Offset(i), fragmentation.Length(i)));
const size_t fragment_length = fragmentation.fragmentationLength[i];
input_fragments_.push_back(Fragment(fragment, fragment_length));
} }
if (!GeneratePackets(packetization_mode)) { if (!GeneratePackets(packetization_mode)) {
@ -101,13 +99,6 @@ RtpPacketizerH264::RtpPacketizerH264(
RtpPacketizerH264::~RtpPacketizerH264() = default; RtpPacketizerH264::~RtpPacketizerH264() = default;
RtpPacketizerH264::Fragment::~Fragment() = default;
RtpPacketizerH264::Fragment::Fragment(const uint8_t* buffer, size_t length)
: buffer(buffer), length(length) {}
RtpPacketizerH264::Fragment::Fragment(const Fragment& fragment)
: buffer(fragment.buffer), length(fragment.length) {}
size_t RtpPacketizerH264::NumPackets() const { size_t RtpPacketizerH264::NumPackets() const {
return num_packets_left_; return num_packets_left_;
} }
@ -122,7 +113,7 @@ bool RtpPacketizerH264::GeneratePackets(
++i; ++i;
break; break;
case H264PacketizationMode::NonInterleaved: case H264PacketizationMode::NonInterleaved:
int fragment_len = input_fragments_[i].length; int fragment_len = input_fragments_[i].size();
int single_packet_capacity = limits_.max_payload_len; int single_packet_capacity = limits_.max_payload_len;
if (input_fragments_.size() == 1) if (input_fragments_.size() == 1)
single_packet_capacity -= limits_.single_packet_reduction_len; single_packet_capacity -= limits_.single_packet_reduction_len;
@ -146,7 +137,7 @@ bool RtpPacketizerH264::GeneratePackets(
bool RtpPacketizerH264::PacketizeFuA(size_t fragment_index) { bool RtpPacketizerH264::PacketizeFuA(size_t fragment_index) {
// Fragment payload into packets (FU-A). // Fragment payload into packets (FU-A).
const Fragment& fragment = input_fragments_[fragment_index]; rtc::ArrayView<const uint8_t> fragment = input_fragments_[fragment_index];
PayloadSizeLimits limits = limits_; PayloadSizeLimits limits = limits_;
// Leave room for the FU-A header. // Leave room for the FU-A header.
@ -170,7 +161,7 @@ bool RtpPacketizerH264::PacketizeFuA(size_t fragment_index) {
limits.last_packet_reduction_len = 0; limits.last_packet_reduction_len = 0;
// Strip out the original header. // Strip out the original header.
size_t payload_left = fragment.length - kNalHeaderSize; size_t payload_left = fragment.size() - kNalHeaderSize;
int offset = kNalHeaderSize; int offset = kNalHeaderSize;
std::vector<int> payload_sizes = SplitAboutEqually(payload_left, limits); std::vector<int> payload_sizes = SplitAboutEqually(payload_left, limits);
@ -180,10 +171,10 @@ bool RtpPacketizerH264::PacketizeFuA(size_t fragment_index) {
for (size_t i = 0; i < payload_sizes.size(); ++i) { for (size_t i = 0; i < payload_sizes.size(); ++i) {
int packet_length = payload_sizes[i]; int packet_length = payload_sizes[i];
RTC_CHECK_GT(packet_length, 0); RTC_CHECK_GT(packet_length, 0);
packets_.push(PacketUnit(Fragment(fragment.buffer + offset, packet_length), packets_.push(PacketUnit(fragment.subview(offset, packet_length),
/*first_fragment=*/i == 0, /*first_fragment=*/i == 0,
/*last_fragment=*/i == payload_sizes.size() - 1, /*last_fragment=*/i == payload_sizes.size() - 1,
false, fragment.buffer[0])); false, fragment[0]));
offset += packet_length; offset += packet_length;
payload_left -= packet_length; payload_left -= packet_length;
} }
@ -201,12 +192,12 @@ size_t RtpPacketizerH264::PacketizeStapA(size_t fragment_index) {
payload_size_left -= limits_.first_packet_reduction_len; payload_size_left -= limits_.first_packet_reduction_len;
int aggregated_fragments = 0; int aggregated_fragments = 0;
size_t fragment_headers_length = 0; size_t fragment_headers_length = 0;
const Fragment* fragment = &input_fragments_[fragment_index]; rtc::ArrayView<const uint8_t> fragment = input_fragments_[fragment_index];
RTC_CHECK_GE(payload_size_left, fragment->length); RTC_CHECK_GE(payload_size_left, fragment.size());
++num_packets_left_; ++num_packets_left_;
auto payload_size_needed = [&] { auto payload_size_needed = [&] {
size_t fragment_size = fragment->length + fragment_headers_length; size_t fragment_size = fragment.size() + fragment_headers_length;
if (input_fragments_.size() == 1) { if (input_fragments_.size() == 1) {
// Single fragment, single packet, payload_size_left already adjusted // Single fragment, single packet, payload_size_left already adjusted
// with limits_.single_packet_reduction_len. // with limits_.single_packet_reduction_len.
@ -220,10 +211,10 @@ size_t RtpPacketizerH264::PacketizeStapA(size_t fragment_index) {
}; };
while (payload_size_left >= payload_size_needed()) { while (payload_size_left >= payload_size_needed()) {
RTC_CHECK_GT(fragment->length, 0); RTC_CHECK_GT(fragment.size(), 0);
packets_.push(PacketUnit(*fragment, aggregated_fragments == 0, false, true, packets_.push(PacketUnit(fragment, aggregated_fragments == 0, false, true,
fragment->buffer[0])); fragment[0]));
payload_size_left -= fragment->length; payload_size_left -= fragment.size();
payload_size_left -= fragment_headers_length; payload_size_left -= fragment_headers_length;
fragment_headers_length = kLengthFieldSize; fragment_headers_length = kLengthFieldSize;
@ -238,7 +229,7 @@ size_t RtpPacketizerH264::PacketizeStapA(size_t fragment_index) {
++fragment_index; ++fragment_index;
if (fragment_index == input_fragments_.size()) if (fragment_index == input_fragments_.size())
break; break;
fragment = &input_fragments_[fragment_index]; fragment = input_fragments_[fragment_index];
} }
RTC_CHECK_GT(aggregated_fragments, 0); RTC_CHECK_GT(aggregated_fragments, 0);
packets_.back().last_fragment = true; packets_.back().last_fragment = true;
@ -254,18 +245,18 @@ bool RtpPacketizerH264::PacketizeSingleNalu(size_t fragment_index) {
payload_size_left -= limits_.first_packet_reduction_len; payload_size_left -= limits_.first_packet_reduction_len;
else if (fragment_index + 1 == input_fragments_.size()) else if (fragment_index + 1 == input_fragments_.size())
payload_size_left -= limits_.last_packet_reduction_len; payload_size_left -= limits_.last_packet_reduction_len;
const Fragment* fragment = &input_fragments_[fragment_index]; rtc::ArrayView<const uint8_t> fragment = input_fragments_[fragment_index];
if (payload_size_left < fragment->length) { if (payload_size_left < fragment.size()) {
RTC_LOG(LS_ERROR) << "Failed to fit a fragment to packet in SingleNalu " RTC_LOG(LS_ERROR) << "Failed to fit a fragment to packet in SingleNalu "
"packetization mode. Payload size left " "packetization mode. Payload size left "
<< payload_size_left << ", fragment length " << payload_size_left << ", fragment length "
<< fragment->length << ", packet capacity " << fragment.size() << ", packet capacity "
<< limits_.max_payload_len; << limits_.max_payload_len;
return false; return false;
} }
RTC_CHECK_GT(fragment->length, 0u); RTC_CHECK_GT(fragment.size(), 0u);
packets_.push(PacketUnit(*fragment, true /* first */, true /* last */, packets_.push(PacketUnit(fragment, true /* first */, true /* last */,
false /* aggregated */, fragment->buffer[0])); false /* aggregated */, fragment[0]));
++num_packets_left_; ++num_packets_left_;
return true; return true;
} }
@ -279,9 +270,9 @@ bool RtpPacketizerH264::NextPacket(RtpPacketToSend* rtp_packet) {
PacketUnit packet = packets_.front(); PacketUnit packet = packets_.front();
if (packet.first_fragment && packet.last_fragment) { if (packet.first_fragment && packet.last_fragment) {
// Single NAL unit packet. // Single NAL unit packet.
size_t bytes_to_send = packet.source_fragment.length; size_t bytes_to_send = packet.source_fragment.size();
uint8_t* buffer = rtp_packet->AllocatePayload(bytes_to_send); uint8_t* buffer = rtp_packet->AllocatePayload(bytes_to_send);
memcpy(buffer, packet.source_fragment.buffer, bytes_to_send); memcpy(buffer, packet.source_fragment.data(), bytes_to_send);
packets_.pop(); packets_.pop();
input_fragments_.pop_front(); input_fragments_.pop_front();
} else if (packet.aggregated) { } else if (packet.aggregated) {
@ -307,14 +298,14 @@ void RtpPacketizerH264::NextAggregatePacket(RtpPacketToSend* rtp_packet) {
size_t index = kNalHeaderSize; size_t index = kNalHeaderSize;
bool is_last_fragment = packet->last_fragment; bool is_last_fragment = packet->last_fragment;
while (packet->aggregated) { while (packet->aggregated) {
const Fragment& fragment = packet->source_fragment; rtc::ArrayView<const uint8_t> fragment = packet->source_fragment;
RTC_CHECK_LE(index + kLengthFieldSize + fragment.length, payload_capacity); RTC_CHECK_LE(index + kLengthFieldSize + fragment.size(), payload_capacity);
// Add NAL unit length field. // Add NAL unit length field.
ByteWriter<uint16_t>::WriteBigEndian(&buffer[index], fragment.length); ByteWriter<uint16_t>::WriteBigEndian(&buffer[index], fragment.size());
index += kLengthFieldSize; index += kLengthFieldSize;
// Add NAL unit. // Add NAL unit.
memcpy(&buffer[index], fragment.buffer, fragment.length); memcpy(&buffer[index], fragment.data(), fragment.size());
index += fragment.length; index += fragment.size();
packets_.pop(); packets_.pop();
input_fragments_.pop_front(); input_fragments_.pop_front();
if (is_last_fragment) if (is_last_fragment)
@ -340,12 +331,12 @@ void RtpPacketizerH264::NextFragmentPacket(RtpPacketToSend* rtp_packet) {
fu_header |= (packet->last_fragment ? kEBit : 0); fu_header |= (packet->last_fragment ? kEBit : 0);
uint8_t type = packet->header & kTypeMask; uint8_t type = packet->header & kTypeMask;
fu_header |= type; fu_header |= type;
const Fragment& fragment = packet->source_fragment; rtc::ArrayView<const uint8_t> fragment = packet->source_fragment;
uint8_t* buffer = uint8_t* buffer =
rtp_packet->AllocatePayload(kFuAHeaderSize + fragment.length); rtp_packet->AllocatePayload(kFuAHeaderSize + fragment.size());
buffer[0] = fu_indicator; buffer[0] = fu_indicator;
buffer[1] = fu_header; buffer[1] = fu_header;
memcpy(buffer + kFuAHeaderSize, fragment.buffer, fragment.length); memcpy(buffer + kFuAHeaderSize, fragment.data(), fragment.size());
if (packet->last_fragment) if (packet->last_fragment)
input_fragments_.pop_front(); input_fragments_.pop_front();
packets_.pop(); packets_.pop();

View File

@ -47,16 +47,6 @@ class RtpPacketizerH264 : public RtpPacketizer {
bool NextPacket(RtpPacketToSend* rtp_packet) override; bool NextPacket(RtpPacketToSend* rtp_packet) override;
private: private:
// Input fragments (NAL units), with an optionally owned temporary buffer,
// used in case the fragment gets modified.
struct Fragment {
Fragment(const uint8_t* buffer, size_t length);
explicit Fragment(const Fragment& fragment);
~Fragment();
const uint8_t* buffer = nullptr;
size_t length = 0;
};
// A packet unit (H264 packet), to be put into an RTP packet: // A packet unit (H264 packet), to be put into an RTP packet:
// If a NAL unit is too large for an RTP packet, this packet unit will // If a NAL unit is too large for an RTP packet, this packet unit will
// represent a FU-A packet of a single fragment of the NAL unit. // represent a FU-A packet of a single fragment of the NAL unit.
@ -64,7 +54,7 @@ class RtpPacketizerH264 : public RtpPacketizer {
// packet unit may represent a single NAL unit or a STAP-A packet, of which // packet unit may represent a single NAL unit or a STAP-A packet, of which
// there may be multiple in a single RTP packet (if so, aggregated = true). // there may be multiple in a single RTP packet (if so, aggregated = true).
struct PacketUnit { struct PacketUnit {
PacketUnit(const Fragment& source_fragment, PacketUnit(rtc::ArrayView<const uint8_t> source_fragment,
bool first_fragment, bool first_fragment,
bool last_fragment, bool last_fragment,
bool aggregated, bool aggregated,
@ -75,7 +65,7 @@ class RtpPacketizerH264 : public RtpPacketizer {
aggregated(aggregated), aggregated(aggregated),
header(header) {} header(header) {}
const Fragment source_fragment; rtc::ArrayView<const uint8_t> source_fragment;
bool first_fragment; bool first_fragment;
bool last_fragment; bool last_fragment;
bool aggregated; bool aggregated;
@ -92,7 +82,7 @@ class RtpPacketizerH264 : public RtpPacketizer {
const PayloadSizeLimits limits_; const PayloadSizeLimits limits_;
size_t num_packets_left_; size_t num_packets_left_;
std::deque<Fragment> input_fragments_; std::deque<rtc::ArrayView<const uint8_t>> input_fragments_;
std::queue<PacketUnit> packets_; std::queue<PacketUnit> packets_;
RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerH264); RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerH264);