Optimize adding many consecutive missing packets to rtcp TransportFeedback

Bug: chromium:1342840
Change-Id: I894157af2ed4f8b9dc97ccb8613cbf18db09f95a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/269100
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37583}
This commit is contained in:
Danil Chapovalov 2022-07-21 10:05:58 +02:00 committed by WebRTC LUCI CQ
parent 054ea47379
commit be5258e61d
2 changed files with 57 additions and 7 deletions

View File

@ -116,6 +116,15 @@ void TransportFeedback::LastChunk::Add(DeltaSize delta_size) {
has_large_delta_ = has_large_delta_ || delta_size == kLarge;
}
void TransportFeedback::LastChunk::AddMissingPackets(size_t num_missing) {
RTC_DCHECK_EQ(size_, 0);
RTC_DCHECK(all_same_);
RTC_DCHECK(!has_large_delta_);
RTC_DCHECK_LT(num_missing, kMaxRunLengthCapacity);
absl::c_fill(delta_sizes_, DeltaSize(0));
size_ = num_missing;
}
uint16_t TransportFeedback::LastChunk::Emit() {
RTC_DCHECK(!CanAdd(0) || !CanAdd(1) || !CanAdd(2));
if (all_same_) {
@ -160,7 +169,8 @@ void TransportFeedback::LastChunk::AppendTo(
if (all_same_) {
deltas->insert(deltas->end(), size_, delta_sizes_[0]);
} else {
deltas->insert(deltas->end(), delta_sizes_, delta_sizes_ + size_);
deltas->insert(deltas->end(), delta_sizes_.begin(),
delta_sizes_.begin() + size_);
}
}
@ -342,11 +352,13 @@ bool TransportFeedback::AddReceivedPacket(uint16_t sequence_number,
uint16_t last_seq_no = next_seq_no - 1;
if (!IsNewerSequenceNumber(sequence_number, last_seq_no))
return false;
for (; next_seq_no != sequence_number; ++next_seq_no) {
if (!AddDeltaSize(0))
return false;
if (include_lost_)
uint16_t num_missing_packets = sequence_number - next_seq_no;
if (!AddMissingPackets(num_missing_packets))
return false;
if (include_lost_) {
for (; next_seq_no != sequence_number; ++next_seq_no) {
all_packets_.emplace_back(next_seq_no);
}
}
}
@ -698,5 +710,38 @@ bool TransportFeedback::AddDeltaSize(DeltaSize delta_size) {
return true;
}
bool TransportFeedback::AddMissingPackets(size_t num_missing_packets) {
size_t new_num_seq_no = num_seq_no_ + num_missing_packets;
if (new_num_seq_no > kMaxReportedPackets) {
return false;
}
if (!last_chunk_.Empty()) {
while (num_missing_packets > 0 && last_chunk_.CanAdd(0)) {
last_chunk_.Add(0);
--num_missing_packets;
}
if (num_missing_packets == 0) {
num_seq_no_ = new_num_seq_no;
return true;
}
encoded_chunks_.push_back(last_chunk_.Emit());
}
RTC_DCHECK(last_chunk_.Empty());
size_t full_chunks = num_missing_packets / LastChunk::kMaxRunLengthCapacity;
size_t partial_chunk = num_missing_packets % LastChunk::kMaxRunLengthCapacity;
size_t num_chunks = full_chunks + (partial_chunk > 0 ? 1 : 0);
if (size_bytes_ + kChunkSizeBytes * num_chunks > kMaxSizeBytes) {
num_seq_no_ = (new_num_seq_no - num_missing_packets);
return false;
}
size_bytes_ += kChunkSizeBytes * num_chunks;
// T = 0, S = 0, run length = kMaxRunLengthCapacity, see EncodeRunLength().
encoded_chunks_.insert(encoded_chunks_.end(), full_chunks,
LastChunk::kMaxRunLengthCapacity);
last_chunk_.AddMissingPackets(partial_chunk);
num_seq_no_ = new_num_seq_no;
return true;
}
} // namespace rtcp
} // namespace webrtc

View File

@ -11,6 +11,7 @@
#ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
#define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_TRANSPORT_FEEDBACK_H_
#include <array>
#include <memory>
#include <vector>
@ -110,6 +111,7 @@ class TransportFeedback : public Rtpfb {
class LastChunk {
public:
using DeltaSize = TransportFeedback::DeltaSize;
static constexpr size_t kMaxRunLengthCapacity = 0x1fff;
LastChunk();
@ -120,6 +122,8 @@ class TransportFeedback : public Rtpfb {
bool CanAdd(DeltaSize delta_size) const;
// Add `delta_size`, assumes `CanAdd(delta_size)`,
void Add(DeltaSize delta_size);
// Equivalent to calling Add(0) `num_missing` times. Assumes `Empty()`.
void AddMissingPackets(size_t num_missing);
// Encode chunk as large as possible removing encoded delta sizes.
// Assume CanAdd() == false for some valid delta_size.
@ -133,7 +137,6 @@ class TransportFeedback : public Rtpfb {
void AppendTo(std::vector<DeltaSize>* deltas) const;
private:
static constexpr size_t kMaxRunLengthCapacity = 0x1fff;
static constexpr size_t kMaxOneBitCapacity = 14;
static constexpr size_t kMaxTwoBitCapacity = 7;
static constexpr size_t kMaxVectorCapacity = kMaxOneBitCapacity;
@ -148,7 +151,7 @@ class TransportFeedback : public Rtpfb {
uint16_t EncodeRunLength() const;
void DecodeRunLength(uint16_t chunk, size_t max_size);
DeltaSize delta_sizes_[kMaxVectorCapacity];
std::array<DeltaSize, kMaxVectorCapacity> delta_sizes_;
size_t size_;
bool all_same_;
bool has_large_delta_;
@ -158,6 +161,8 @@ class TransportFeedback : public Rtpfb {
void Clear();
bool AddDeltaSize(DeltaSize delta_size);
// Adds `num_missing_packets` deltas of size 0.
bool AddMissingPackets(size_t num_missing_packets);
const bool include_lost_;
uint16_t base_seq_no_;