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 |
deleted file mode 100644 |
index f96437698ba4d4085d85fd5656b131105466bee6..0000000000000000000000000000000000000000 |
--- a/webrtc/modules/rtp_rtcp/source/producer_fec.cc |
+++ /dev/null |
@@ -1,251 +0,0 @@ |
-/* |
- * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include "webrtc/modules/rtp_rtcp/source/producer_fec.h" |
- |
-#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 { |
- |
-namespace { |
- |
-constexpr size_t kRedForFecHeaderLength = 1; |
- |
-// This controls the maximum amount of excess overhead (actual - target) |
-// allowed in order to trigger EncodeFec(), before |params_.max_fec_frames| |
-// is reached. Overhead here is defined as relative to number of media packets. |
-constexpr int kMaxExcessOverhead = 50; // Q8. |
- |
-// This is the minimum number of media packets required (above some protection |
-// level) in order to trigger EncodeFec(), before |params_.max_fec_frames| is |
-// reached. |
-constexpr size_t kMinMediaPackets = 4; |
- |
-// Threshold on the received FEC protection level, above which we enforce at |
-// 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; |
- |
-} // namespace |
- |
-RedPacket::RedPacket(size_t length) |
- : data_(new uint8_t[length]), |
- length_(length), |
- header_length_(0) { |
-} |
- |
-void RedPacket::CreateHeader(const uint8_t* rtp_header, |
- size_t header_length, |
- int red_payload_type, |
- int payload_type) { |
- RTC_DCHECK_LE(header_length + kRedForFecHeaderLength, length_); |
- memcpy(data_.get(), rtp_header, header_length); |
- // Replace payload type. |
- data_[1] &= 0x80; |
- data_[1] += red_payload_type; |
- // Add RED header |
- // f-bit always 0 |
- data_[header_length] = static_cast<uint8_t>(payload_type); |
- header_length_ = header_length + kRedForFecHeaderLength; |
-} |
- |
-void RedPacket::SetSeqNum(int seq_num) { |
- 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) { |
- RTC_DCHECK_LE(header_length_ + length, length_); |
- memcpy(data_.get() + header_length_, payload, length); |
-} |
- |
-void RedPacket::ClearMarkerBit() { |
- data_[1] &= 0x7F; |
-} |
- |
-uint8_t* RedPacket::data() const { |
- return data_.get(); |
-} |
- |
-size_t RedPacket::length() const { |
- return length_; |
-} |
- |
-ProducerFec::ProducerFec() |
- : fec_(ForwardErrorCorrection::CreateUlpfec()), |
- num_protected_frames_(0), |
- min_num_media_packets_(1) { |
- memset(¶ms_, 0, sizeof(params_)); |
- memset(&new_params_, 0, sizeof(new_params_)); |
-} |
- |
-ProducerFec::~ProducerFec() = default; |
- |
-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) { |
- RTC_DCHECK_GE(params->fec_rate, 0); |
- RTC_DCHECK_LE(params->fec_rate, 255); |
- // Store the new params and apply them for the next set of FEC packets being |
- // produced. |
- new_params_ = *params; |
- if (params->fec_rate > kHighProtectionThreshold) { |
- min_num_media_packets_ = kMinMediaPackets; |
- } else { |
- min_num_media_packets_ = 1; |
- } |
-} |
- |
-int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer, |
- size_t payload_length, |
- size_t rtp_header_length) { |
- 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_.size() < kUlpfecMaxMediaPackets) { |
- // Generic FEC can only protect up to |kUlpfecMaxMediaPackets| 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_.push_back(std::move(packet)); |
- } |
- if (marker_bit) { |
- ++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 |min_num_media_packets_| media packets is reached. |
- if (complete_frame && |
- (num_protected_frames_ == params_.max_fec_frames || |
- (ExcessOverheadBelowMax() && MinimumMediaPacketsReached()))) { |
- // We are not using Unequal Protection feature of the parity erasure code. |
- constexpr int kNumImportantPackets = 0; |
- constexpr bool kUseUnequalProtection = false; |
- int ret = fec_->EncodeFec(media_packets_, params_.fec_rate, |
- kNumImportantPackets, kUseUnequalProtection, |
- params_.fec_mask_type, &generated_fec_packets_); |
- if (generated_fec_packets_.empty()) { |
- ResetState(); |
- } |
- return ret; |
- } |
- return 0; |
-} |
- |
-bool ProducerFec::ExcessOverheadBelowMax() const { |
- return ((Overhead() - params_.fec_rate) < kMaxExcessOverhead); |
-} |
- |
-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. |
- // TODO(brandtr): Investigate what impact this adaptation has. |
- return num_media_packets >= min_num_media_packets_ + 1; |
- } |
-} |
- |
-bool ProducerFec::FecAvailable() const { |
- return !generated_fec_packets_.empty(); |
-} |
- |
-size_t ProducerFec::NumAvailableFecPackets() const { |
- return generated_fec_packets_.size(); |
-} |
- |
-size_t ProducerFec::MaxPacketOverhead() const { |
- return fec_->MaxPacketOverhead(); |
-} |
- |
-std::vector<std::unique_ptr<RedPacket>> ProducerFec::GetUlpfecPacketsAsRed( |
- 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_payload_type, ulpfec_payload_type); |
- red_packet->SetSeqNum(seq_num++); |
- red_packet->ClearMarkerBit(); |
- red_packet->AssignPayload(fec_packet->data, fec_packet->length); |
- red_packets.push_back(std::move(red_packet)); |
- } |
- |
- ResetState(); |
- |
- return red_packets; |
-} |
- |
-int ProducerFec::Overhead() const { |
- RTC_DCHECK(!media_packets_.empty()); |
- int num_fec_packets = |
- fec_->NumFecPackets(media_packets_.size(), params_.fec_rate); |
- // Return the overhead in Q8. |
- return (num_fec_packets << 8) / media_packets_.size(); |
-} |
- |
-void ProducerFec::ResetState() { |
- media_packets_.clear(); |
- generated_fec_packets_.clear(); |
- num_protected_frames_ = 0; |
-} |
- |
-} // namespace webrtc |