Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1309)

Unified Diff: webrtc/modules/rtp_rtcp/source/producer_fec.cc

Issue 2110763002: Style updates to ProducerFec/FecReceiver. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase + 'git cl format'. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/rtp_rtcp/source/producer_fec.cc
diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec.cc b/webrtc/modules/rtp_rtcp/source/producer_fec.cc
index c27472bfaf264532352041b25762328ea38ef418..b928020df3211d33c7a9be5c838b39f49708faa9 100644
--- a/webrtc/modules/rtp_rtcp/source/producer_fec.cc
+++ b/webrtc/modules/rtp_rtcp/source/producer_fec.cc
@@ -13,27 +13,39 @@
#include <memory>
#include <utility>
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/checks.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
namespace webrtc {
-enum { kREDForFECHeaderLength = 1 };
+constexpr size_t kRedForFecHeaderLength = 1;
+
// This controls the maximum amount of excess overhead (actual - target)
// allowed in order to trigger GenerateFec(), before |params_.max_fec_frames|
// is reached. Overhead here is defined as relative to number of media packets.
-enum { kMaxExcessOverhead = 50 }; // Q8.
+constexpr int kMaxExcessOverhead = 50; // Q8.
+
// This is the minimum number of media packets required (above some protection
// level) in order to trigger GenerateFec(), before |params_.max_fec_frames| is
// reached.
-enum { kMinimumMediaPackets = 4 };
+constexpr size_t kMinMediaPackets = 4;
+
// Threshold on the received FEC protection level, above which we enforce at
-// least |kMinimumMediaPackets| packets for the FEC code. Below this
-// threshold |kMinimumMediaPackets| is set to default value of 1.
-enum { kHighProtectionThreshold = 80 }; // Corresponds to ~30 overhead, range
-// is 0 to 255, where 255 corresponds to 100% overhead (relative to number of
-// media packets).
+// least |kMinMediaPackets| packets for the FEC code. Below this
+// threshold |kMinMediaPackets| is set to default value of 1.
+//
+// The range is between 0 and 255, where 255 corresponds to 100% overhead
+// (relative to the number of protected media packets).
+constexpr uint8_t kHighProtectionThreshold = 80;
+
+// This threshold is used to adapt the |kMinMediaPackets| threshold, based
+// on the average number of packets per frame seen so far. When there are few
+// packets per frame (as given by this threshold), at least
+// |kMinMediaPackets| + 1 packets are sent to the FEC code.
+constexpr float kMinMediaPacketsAdaptationThreshold = 2.0f;
RedPacket::RedPacket(size_t length)
: data_(new uint8_t[length]),
@@ -41,32 +53,31 @@ RedPacket::RedPacket(size_t length)
header_length_(0) {
}
-RedPacket::~RedPacket() {
- delete [] data_;
-}
-
-void RedPacket::CreateHeader(const uint8_t* rtp_header, size_t header_length,
- int red_pl_type, int pl_type) {
- assert(header_length + kREDForFECHeaderLength <= length_);
- memcpy(data_, rtp_header, header_length);
+void RedPacket::CreateHeader(const uint8_t* rtp_header,
+ size_t header_length,
+ int red_payload_type,
+ int payload_type) {
+ RTC_DCHECK_LT(header_length + kRedForFecHeaderLength, length_);
+ memcpy(data_.get(), rtp_header, header_length);
// Replace payload type.
data_[1] &= 0x80;
- data_[1] += red_pl_type;
+ data_[1] += red_payload_type;
// Add RED header
// f-bit always 0
- data_[header_length] = static_cast<uint8_t>(pl_type);
- header_length_ = header_length + kREDForFECHeaderLength;
+ data_[header_length] = static_cast<uint8_t>(payload_type);
+ header_length_ = header_length + kRedForFecHeaderLength;
}
void RedPacket::SetSeqNum(int seq_num) {
- assert(seq_num >= 0 && seq_num < (1<<16));
+ RTC_DCHECK_GE(seq_num, 0);
+ RTC_DCHECK_LT(seq_num, 1 << 16);
ByteWriter<uint16_t>::WriteBigEndian(&data_[2], seq_num);
}
void RedPacket::AssignPayload(const uint8_t* payload, size_t length) {
- assert(header_length_ + length <= length_);
- memcpy(data_ + header_length_, payload, length);
+ RTC_DCHECK_LE(header_length_ + length, length_);
+ memcpy(data_.get() + header_length_, payload, length);
}
void RedPacket::ClearMarkerBit() {
@@ -74,7 +85,7 @@ void RedPacket::ClearMarkerBit() {
}
uint8_t* RedPacket::data() const {
- return data_;
+ return data_.get();
}
size_t RedPacket::length() const {
@@ -83,11 +94,11 @@ size_t RedPacket::length() const {
ProducerFec::ProducerFec(ForwardErrorCorrection* fec)
: fec_(fec),
- media_packets_fec_(),
- fec_packets_(),
- num_frames_(0),
- num_first_partition_(0),
- minimum_media_packets_fec_(1),
+ media_packets_(),
+ generated_fec_packets_(),
+ num_protected_frames_(0),
+ num_important_packets_(0),
+ min_num_media_packets_(1),
params_(),
new_params_() {
memset(&params_, 0, sizeof(params_));
@@ -95,166 +106,165 @@ ProducerFec::ProducerFec(ForwardErrorCorrection* fec)
}
ProducerFec::~ProducerFec() {
- DeletePackets();
+ DeleteMediaPackets();
+}
+
+std::unique_ptr<RedPacket> ProducerFec::BuildRedPacket(
+ const uint8_t* data_buffer,
+ size_t payload_length,
+ size_t rtp_header_length,
+ int red_payload_type) {
+ std::unique_ptr<RedPacket> red_packet(new RedPacket(
+ payload_length + kRedForFecHeaderLength + rtp_header_length));
+ int payload_type = data_buffer[1] & 0x7f;
+ red_packet->CreateHeader(data_buffer, rtp_header_length, red_payload_type,
+ payload_type);
+ red_packet->AssignPayload(data_buffer + rtp_header_length, payload_length);
+ return red_packet;
}
void ProducerFec::SetFecParameters(const FecProtectionParams* params,
- int num_first_partition) {
- // Number of first partition packets cannot exceed kMaxMediaPackets
- assert(params->fec_rate >= 0 && params->fec_rate < 256);
- if (num_first_partition >
+ int num_important_packets) {
+ // Number of important packets (i.e. number of packets receiving additional
+ // protection in 'unequal protection mode') cannot exceed kMaxMediaPackets.
+ RTC_DCHECK_GE(params->fec_rate, 0);
+ RTC_DCHECK_LE(params->fec_rate, 255);
+ if (num_important_packets >
static_cast<int>(ForwardErrorCorrection::kMaxMediaPackets)) {
- num_first_partition =
- ForwardErrorCorrection::kMaxMediaPackets;
+ num_important_packets = ForwardErrorCorrection::kMaxMediaPackets;
}
// Store the new params and apply them for the next set of FEC packets being
// produced.
new_params_ = *params;
- num_first_partition_ = num_first_partition;
+ num_important_packets_ = num_important_packets;
if (params->fec_rate > kHighProtectionThreshold) {
- minimum_media_packets_fec_ = kMinimumMediaPackets;
+ min_num_media_packets_ = kMinMediaPackets;
} else {
- minimum_media_packets_fec_ = 1;
+ min_num_media_packets_ = 1;
}
}
-RedPacket* ProducerFec::BuildRedPacket(const uint8_t* data_buffer,
- size_t payload_length,
- size_t rtp_header_length,
- int red_pl_type) {
- RedPacket* red_packet = new RedPacket(
- payload_length + kREDForFECHeaderLength + rtp_header_length);
- int pl_type = data_buffer[1] & 0x7f;
- red_packet->CreateHeader(data_buffer, rtp_header_length,
- red_pl_type, pl_type);
- red_packet->AssignPayload(data_buffer + rtp_header_length, payload_length);
- return red_packet;
-}
-
int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer,
size_t payload_length,
size_t rtp_header_length) {
- assert(fec_packets_.empty());
- if (media_packets_fec_.empty()) {
+ RTC_DCHECK(generated_fec_packets_.empty());
+ if (media_packets_.empty()) {
params_ = new_params_;
}
bool complete_frame = false;
const bool marker_bit = (data_buffer[1] & kRtpMarkerBitMask) ? true : false;
- if (media_packets_fec_.size() < ForwardErrorCorrection::kMaxMediaPackets) {
- // Generic FEC can only protect up to kMaxMediaPackets packets.
+ if (media_packets_.size() < ForwardErrorCorrection::kMaxMediaPackets) {
+ // Generic FEC can only protect up to |kMaxMediaPackets| packets.
std::unique_ptr<ForwardErrorCorrection::Packet> packet(
new ForwardErrorCorrection::Packet());
packet->length = payload_length + rtp_header_length;
memcpy(packet->data, data_buffer, packet->length);
- media_packets_fec_.push_back(std::move(packet));
+ media_packets_.push_back(std::move(packet));
}
if (marker_bit) {
- ++num_frames_;
+ ++num_protected_frames_;
complete_frame = true;
}
// Produce FEC over at most |params_.max_fec_frames| frames, or as soon as:
// (1) the excess overhead (actual overhead - requested/target overhead) is
// less than |kMaxExcessOverhead|, and
- // (2) at least |minimum_media_packets_fec_| media packets is reached.
+ // (2) at least |min_num_media_packets_| media packets is reached.
if (complete_frame &&
- (num_frames_ == params_.max_fec_frames ||
- (ExcessOverheadBelowMax() && MinimumMediaPacketsReached()))) {
- assert(num_first_partition_ <=
- static_cast<int>(ForwardErrorCorrection::kMaxMediaPackets));
+ (num_protected_frames_ == params_.max_fec_frames ||
+ (ExcessOverheadBelowMax() && MinimumMediaPacketsReached()))) {
+ RTC_DCHECK_LE(num_important_packets_,
+ static_cast<int>(ForwardErrorCorrection::kMaxMediaPackets));
// TODO(pbos): Consider whether unequal protection should be enabled or not,
// it is currently always disabled.
- int ret = fec_->GenerateFec(media_packets_fec_, params_.fec_rate,
- num_first_partition_, false,
- params_.fec_mask_type, &fec_packets_);
- if (fec_packets_.empty()) {
- num_frames_ = 0;
- DeletePackets();
+ //
+ // Since unequal protection is disabled, the value of
+ // |num_important_packets_| has no importance when calling GenerateFec().
+ constexpr bool kUseUnequalProtection = false;
+ int ret = fec_->GenerateFec(media_packets_, params_.fec_rate,
+ num_important_packets_, kUseUnequalProtection,
+ params_.fec_mask_type, &generated_fec_packets_);
+ if (generated_fec_packets_.empty()) {
+ num_protected_frames_ = 0;
+ DeleteMediaPackets();
}
return ret;
}
return 0;
}
-// Returns true if the excess overhead (actual - target) for the FEC is below
-// the amount |kMaxExcessOverhead|. This effects the lower protection level
-// cases and low number of media packets/frame. The target overhead is given by
-// |params_.fec_rate|, and is only achievable in the limit of large number of
-// media packets.
-bool ProducerFec::ExcessOverheadBelowMax() {
+bool ProducerFec::ExcessOverheadBelowMax() const {
return ((Overhead() - params_.fec_rate) < kMaxExcessOverhead);
}
-// Returns true if the media packet list for the FEC is at least
-// |minimum_media_packets_fec_|. This condition tries to capture the effect
-// that, for the same amount of protection/overhead, longer codes
-// (e.g. (2k,2m) vs (k,m)) are generally more effective at recovering losses.
-bool ProducerFec::MinimumMediaPacketsReached() {
- float avg_num_packets_frame = static_cast<float>(media_packets_fec_.size()) /
- num_frames_;
- if (avg_num_packets_frame < 2.0f) {
- return (static_cast<int>(media_packets_fec_.size()) >=
- minimum_media_packets_fec_);
+bool ProducerFec::MinimumMediaPacketsReached() const {
+ float average_num_packets_per_frame =
+ static_cast<float>(media_packets_.size()) / num_protected_frames_;
+ int num_media_packets = static_cast<int>(media_packets_.size());
+ if (average_num_packets_per_frame < kMinMediaPacketsAdaptationThreshold) {
+ return num_media_packets >= min_num_media_packets_;
} else {
// For larger rates (more packets/frame), increase the threshold.
- return (static_cast<int>(media_packets_fec_.size()) >=
- minimum_media_packets_fec_ + 1);
+ // TODO(brandtr): Investigate what impact this adaptation has.
+ return num_media_packets >= min_num_media_packets_ + 1;
}
}
bool ProducerFec::FecAvailable() const {
- return !fec_packets_.empty();
+ return !generated_fec_packets_.empty();
}
size_t ProducerFec::NumAvailableFecPackets() const {
- return fec_packets_.size();
+ return generated_fec_packets_.size();
}
-std::vector<RedPacket*> ProducerFec::GetFecPackets(int red_pl_type,
- int fec_pl_type,
- uint16_t first_seq_num,
- size_t rtp_header_length) {
- std::vector<RedPacket*> fec_packets;
- fec_packets.reserve(fec_packets_.size());
- uint16_t sequence_number = first_seq_num;
- while (!fec_packets_.empty()) {
- // Build FEC packet. The FEC packets in |fec_packets_| doesn't
- // have RTP headers, so we're reusing the header from the last
- // media packet.
- ForwardErrorCorrection::Packet* packet_to_send = fec_packets_.front();
- ForwardErrorCorrection::Packet* last_media_packet =
- media_packets_fec_.back().get();
-
- RedPacket* red_packet = new RedPacket(
- packet_to_send->length + kREDForFECHeaderLength + rtp_header_length);
+std::vector<std::unique_ptr<RedPacket>> ProducerFec::GetFecPacketsAsRed(
+ int red_payload_type,
+ int ulpfec_payload_type,
+ uint16_t first_seq_num,
+ size_t rtp_header_length) {
+ std::vector<std::unique_ptr<RedPacket>> red_packets;
+ red_packets.reserve(generated_fec_packets_.size());
+ RTC_DCHECK(!media_packets_.empty());
+ ForwardErrorCorrection::Packet* last_media_packet =
+ media_packets_.back().get();
+ uint16_t seq_num = first_seq_num;
+ for (const auto& fec_packet : generated_fec_packets_) {
+ // Wrap FEC packet (including FEC headers) in a RED packet. Since the
+ // FEC packets in |generated_fec_packets_| don't have RTP headers, we
+ // reuse the header from the last media packet.
+ std::unique_ptr<RedPacket> red_packet(new RedPacket(
+ fec_packet->length + kRedForFecHeaderLength + rtp_header_length));
red_packet->CreateHeader(last_media_packet->data, rtp_header_length,
- red_pl_type, fec_pl_type);
- red_packet->SetSeqNum(sequence_number++);
+ red_payload_type, ulpfec_payload_type);
+ red_packet->SetSeqNum(seq_num++);
red_packet->ClearMarkerBit();
- red_packet->AssignPayload(packet_to_send->data, packet_to_send->length);
-
- fec_packets.push_back(red_packet);
+ red_packet->AssignPayload(fec_packet->data, fec_packet->length);
- fec_packets_.pop_front();
+ red_packets.push_back(std::move(red_packet));
}
- DeletePackets();
- num_frames_ = 0;
- return fec_packets;
+
+ // Reset state.
+ DeleteMediaPackets();
+ generated_fec_packets_.clear();
+ num_protected_frames_ = 0;
+
+ return red_packets;
}
int ProducerFec::Overhead() const {
// Overhead is defined as relative to the number of media packets, and not
- // relative to total number of packets. This definition is inhereted from the
+ // relative to total number of packets. This definition is inherited from the
// protection factor produced by video_coding module and how the FEC
// generation is implemented.
- assert(!media_packets_fec_.empty());
- int num_fec_packets = fec_->GetNumberOfFecPackets(media_packets_fec_.size(),
- params_.fec_rate);
+ RTC_DCHECK(!media_packets_.empty());
+ int num_fec_packets =
+ fec_->GetNumberOfFecPackets(media_packets_.size(), params_.fec_rate);
// Return the overhead in Q8.
- return (num_fec_packets << 8) / media_packets_fec_.size();
+ return (num_fec_packets << 8) / media_packets_.size();
}
-void ProducerFec::DeletePackets() {
- media_packets_fec_.clear();
+void ProducerFec::DeleteMediaPackets() {
+ media_packets_.clear();
}
} // namespace webrtc
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/producer_fec.h ('k') | webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698