| Index: webrtc/modules/video_coding/media_opt_util.cc
|
| diff --git a/webrtc/modules/video_coding/media_opt_util.cc b/webrtc/modules/video_coding/media_opt_util.cc
|
| index 9bd722696ac0d8aa2a7613ed0f4c4d1d61979f66..d57e9c8dd28120e1d1765a31163440efa3d6bf93 100644
|
| --- a/webrtc/modules/video_coding/media_opt_util.cc
|
| +++ b/webrtc/modules/video_coding/media_opt_util.cc
|
| @@ -10,11 +10,12 @@
|
|
|
| #include "webrtc/modules/video_coding/media_opt_util.h"
|
|
|
| -#include <algorithm>
|
| #include <float.h>
|
| #include <limits.h>
|
| #include <math.h>
|
|
|
| +#include <algorithm>
|
| +
|
| #include "webrtc/modules/include/module_common_types.h"
|
| #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
|
| #include "webrtc/modules/video_coding/include/video_coding_defines.h"
|
| @@ -37,18 +38,14 @@ VCMProtectionMethod::VCMProtectionMethod()
|
| _useUepProtectionK(false),
|
| _useUepProtectionD(true),
|
| _corrFecCost(1.0),
|
| - _type(kNone) {
|
| -}
|
| + _type(kNone) {}
|
|
|
| -VCMProtectionMethod::~VCMProtectionMethod()
|
| -{
|
| - delete _qmRobustness;
|
| +VCMProtectionMethod::~VCMProtectionMethod() {
|
| + delete _qmRobustness;
|
| }
|
| -void
|
| -VCMProtectionMethod::UpdateContentMetrics(const
|
| - VideoContentMetrics* contentMetrics)
|
| -{
|
| - _qmRobustness->UpdateContent(contentMetrics);
|
| +void VCMProtectionMethod::UpdateContentMetrics(
|
| + const VideoContentMetrics* contentMetrics) {
|
| + _qmRobustness->UpdateContent(contentMetrics);
|
| }
|
|
|
| VCMNackFecMethod::VCMNackFecMethod(int64_t lowRttNackThresholdMs,
|
| @@ -64,51 +61,45 @@ VCMNackFecMethod::VCMNackFecMethod(int64_t lowRttNackThresholdMs,
|
| _type = kNackFec;
|
| }
|
|
|
| -VCMNackFecMethod::~VCMNackFecMethod()
|
| -{
|
| - //
|
| -}
|
| -bool
|
| -VCMNackFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
|
| -{
|
| - // Hybrid Nack FEC has three operational modes:
|
| - // 1. Low RTT (below kLowRttNackMs) - Nack only: Set FEC rate
|
| - // (_protectionFactorD) to zero. -1 means no FEC.
|
| - // 2. High RTT (above _highRttNackMs) - FEC Only: Keep FEC factors.
|
| - // -1 means always allow NACK.
|
| - // 3. Medium RTT values - Hybrid mode: We will only nack the
|
| - // residual following the decoding of the FEC (refer to JB logic). FEC
|
| - // delta protection factor will be adjusted based on the RTT.
|
| -
|
| - // Otherwise: we count on FEC; if the RTT is below a threshold, then we
|
| - // nack the residual, based on a decision made in the JB.
|
| -
|
| - // Compute the protection factors
|
| - VCMFecMethod::ProtectionFactor(parameters);
|
| - if (_lowRttNackMs == -1 || parameters->rtt < _lowRttNackMs)
|
| - {
|
| - _protectionFactorD = 0;
|
| - VCMFecMethod::UpdateProtectionFactorD(_protectionFactorD);
|
| - }
|
| +VCMNackFecMethod::~VCMNackFecMethod() {
|
| + //
|
| +}
|
| +bool VCMNackFecMethod::ProtectionFactor(
|
| + const VCMProtectionParameters* parameters) {
|
| + // Hybrid Nack FEC has three operational modes:
|
| + // 1. Low RTT (below kLowRttNackMs) - Nack only: Set FEC rate
|
| + // (_protectionFactorD) to zero. -1 means no FEC.
|
| + // 2. High RTT (above _highRttNackMs) - FEC Only: Keep FEC factors.
|
| + // -1 means always allow NACK.
|
| + // 3. Medium RTT values - Hybrid mode: We will only nack the
|
| + // residual following the decoding of the FEC (refer to JB logic). FEC
|
| + // delta protection factor will be adjusted based on the RTT.
|
| +
|
| + // Otherwise: we count on FEC; if the RTT is below a threshold, then we
|
| + // nack the residual, based on a decision made in the JB.
|
| +
|
| + // Compute the protection factors
|
| + VCMFecMethod::ProtectionFactor(parameters);
|
| + if (_lowRttNackMs == -1 || parameters->rtt < _lowRttNackMs) {
|
| + _protectionFactorD = 0;
|
| + VCMFecMethod::UpdateProtectionFactorD(_protectionFactorD);
|
|
|
| // When in Hybrid mode (RTT range), adjust FEC rates based on the
|
| // RTT (NACK effectiveness) - adjustment factor is in the range [0,1].
|
| - else if (_highRttNackMs == -1 || parameters->rtt < _highRttNackMs)
|
| - {
|
| - // TODO(mikhal): Disabling adjustment temporarily.
|
| - // uint16_t rttIndex = (uint16_t) parameters->rtt;
|
| - float adjustRtt = 1.0f;// (float)VCMNackFecTable[rttIndex] / 100.0f;
|
| -
|
| - // Adjust FEC with NACK on (for delta frame only)
|
| - // table depends on RTT relative to rttMax (NACK Threshold)
|
| - _protectionFactorD = static_cast<uint8_t>
|
| - (adjustRtt *
|
| - static_cast<float>(_protectionFactorD));
|
| - // update FEC rates after applying adjustment
|
| - VCMFecMethod::UpdateProtectionFactorD(_protectionFactorD);
|
| - }
|
| + } else if (_highRttNackMs == -1 || parameters->rtt < _highRttNackMs) {
|
| + // TODO(mikhal): Disabling adjustment temporarily.
|
| + // uint16_t rttIndex = (uint16_t) parameters->rtt;
|
| + float adjustRtt = 1.0f; // (float)VCMNackFecTable[rttIndex] / 100.0f;
|
| +
|
| + // Adjust FEC with NACK on (for delta frame only)
|
| + // table depends on RTT relative to rttMax (NACK Threshold)
|
| + _protectionFactorD = static_cast<uint8_t>(
|
| + adjustRtt * static_cast<float>(_protectionFactorD));
|
| + // update FEC rates after applying adjustment
|
| + VCMFecMethod::UpdateProtectionFactorD(_protectionFactorD);
|
| + }
|
|
|
| - return true;
|
| + return true;
|
| }
|
|
|
| int VCMNackFecMethod::ComputeMaxFramesFec(
|
| @@ -123,11 +114,13 @@ int VCMNackFecMethod::ComputeMaxFramesFec(
|
| // we will have complete frames in one RTT. Note that this is an upper
|
| // bound, and that the actual number of frames used for FEC is decided by the
|
| // RTP module based on the actual number of packets and the protection factor.
|
| - float base_layer_framerate = parameters->frameRate /
|
| + float base_layer_framerate =
|
| + parameters->frameRate /
|
| static_cast<float>(1 << (parameters->numLayers - 1));
|
| - int max_frames_fec = std::max(static_cast<int>(
|
| - 2.0f * base_layer_framerate * parameters->rtt /
|
| - 1000.0f + 0.5f), 1);
|
| + int max_frames_fec = std::max(
|
| + static_cast<int>(2.0f * base_layer_framerate * parameters->rtt / 1000.0f +
|
| + 0.5f),
|
| + 1);
|
| // |kUpperLimitFramesFec| is the upper limit on how many frames we
|
| // allow any FEC to be based on.
|
| if (max_frames_fec > kUpperLimitFramesFec) {
|
| @@ -155,325 +148,285 @@ bool VCMNackFecMethod::BitRateTooLowForFec(
|
| } else if (num_pixels > 640 * 480) {
|
| max_bytes_per_frame = kMaxBytesPerFrameForFecHigh;
|
| }
|
| - // TODO (marpan): add condition based on maximum frames used for FEC,
|
| + // TODO(marpan): add condition based on maximum frames used for FEC,
|
| // and expand condition based on frame size.
|
| // Max round trip time threshold in ms.
|
| const int64_t kMaxRttTurnOffFec = 200;
|
| if (estimate_bytes_per_frame < max_bytes_per_frame &&
|
| - parameters->numLayers < 3 &&
|
| - parameters->rtt < kMaxRttTurnOffFec) {
|
| + parameters->numLayers < 3 && parameters->rtt < kMaxRttTurnOffFec) {
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| -bool
|
| -VCMNackFecMethod::EffectivePacketLoss(const VCMProtectionParameters* parameters)
|
| -{
|
| - // Set the effective packet loss for encoder (based on FEC code).
|
| - // Compute the effective packet loss and residual packet loss due to FEC.
|
| - VCMFecMethod::EffectivePacketLoss(parameters);
|
| - return true;
|
| +bool VCMNackFecMethod::EffectivePacketLoss(
|
| + const VCMProtectionParameters* parameters) {
|
| + // Set the effective packet loss for encoder (based on FEC code).
|
| + // Compute the effective packet loss and residual packet loss due to FEC.
|
| + VCMFecMethod::EffectivePacketLoss(parameters);
|
| + return true;
|
| }
|
|
|
| -bool
|
| -VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameters)
|
| -{
|
| - ProtectionFactor(parameters);
|
| - EffectivePacketLoss(parameters);
|
| - _maxFramesFec = ComputeMaxFramesFec(parameters);
|
| - if (BitRateTooLowForFec(parameters)) {
|
| - _protectionFactorK = 0;
|
| - _protectionFactorD = 0;
|
| - }
|
| +bool VCMNackFecMethod::UpdateParameters(
|
| + const VCMProtectionParameters* parameters) {
|
| + ProtectionFactor(parameters);
|
| + EffectivePacketLoss(parameters);
|
| + _maxFramesFec = ComputeMaxFramesFec(parameters);
|
| + if (BitRateTooLowForFec(parameters)) {
|
| + _protectionFactorK = 0;
|
| + _protectionFactorD = 0;
|
| + }
|
|
|
| - // Protection/fec rates obtained above are defined relative to total number
|
| - // of packets (total rate: source + fec) FEC in RTP module assumes
|
| - // protection factor is defined relative to source number of packets so we
|
| - // should convert the factor to reduce mismatch between mediaOpt's rate and
|
| - // the actual one
|
| - _protectionFactorK = VCMFecMethod::ConvertFECRate(_protectionFactorK);
|
| - _protectionFactorD = VCMFecMethod::ConvertFECRate(_protectionFactorD);
|
| + // Protection/fec rates obtained above are defined relative to total number
|
| + // of packets (total rate: source + fec) FEC in RTP module assumes
|
| + // protection factor is defined relative to source number of packets so we
|
| + // should convert the factor to reduce mismatch between mediaOpt's rate and
|
| + // the actual one
|
| + _protectionFactorK = VCMFecMethod::ConvertFECRate(_protectionFactorK);
|
| + _protectionFactorD = VCMFecMethod::ConvertFECRate(_protectionFactorD);
|
|
|
| - return true;
|
| + return true;
|
| }
|
|
|
| -VCMNackMethod::VCMNackMethod():
|
| -VCMProtectionMethod()
|
| -{
|
| - _type = kNack;
|
| +VCMNackMethod::VCMNackMethod() : VCMProtectionMethod() {
|
| + _type = kNack;
|
| }
|
|
|
| -VCMNackMethod::~VCMNackMethod()
|
| -{
|
| - //
|
| +VCMNackMethod::~VCMNackMethod() {
|
| + //
|
| }
|
|
|
| -bool
|
| -VCMNackMethod::EffectivePacketLoss(const VCMProtectionParameters* parameter)
|
| -{
|
| - // Effective Packet Loss, NA in current version.
|
| - _effectivePacketLoss = 0;
|
| - return true;
|
| +bool VCMNackMethod::EffectivePacketLoss(
|
| + const VCMProtectionParameters* parameter) {
|
| + // Effective Packet Loss, NA in current version.
|
| + _effectivePacketLoss = 0;
|
| + return true;
|
| }
|
|
|
| -bool
|
| -VCMNackMethod::UpdateParameters(const VCMProtectionParameters* parameters)
|
| -{
|
| - // Compute the effective packet loss
|
| - EffectivePacketLoss(parameters);
|
| +bool VCMNackMethod::UpdateParameters(
|
| + const VCMProtectionParameters* parameters) {
|
| + // Compute the effective packet loss
|
| + EffectivePacketLoss(parameters);
|
|
|
| - // nackCost = (bitRate - nackCost) * (lossPr)
|
| - return true;
|
| + // nackCost = (bitRate - nackCost) * (lossPr)
|
| + return true;
|
| }
|
|
|
| -VCMFecMethod::VCMFecMethod():
|
| -VCMProtectionMethod()
|
| -{
|
| - _type = kFec;
|
| +VCMFecMethod::VCMFecMethod() : VCMProtectionMethod() {
|
| + _type = kFec;
|
| }
|
| -VCMFecMethod::~VCMFecMethod()
|
| -{
|
| - //
|
| +VCMFecMethod::~VCMFecMethod() {
|
| + //
|
| }
|
|
|
| -uint8_t
|
| -VCMFecMethod::BoostCodeRateKey(uint8_t packetFrameDelta,
|
| - uint8_t packetFrameKey) const
|
| -{
|
| - uint8_t boostRateKey = 2;
|
| - // Default: ratio scales the FEC protection up for I frames
|
| - uint8_t ratio = 1;
|
| +uint8_t VCMFecMethod::BoostCodeRateKey(uint8_t packetFrameDelta,
|
| + uint8_t packetFrameKey) const {
|
| + uint8_t boostRateKey = 2;
|
| + // Default: ratio scales the FEC protection up for I frames
|
| + uint8_t ratio = 1;
|
|
|
| - if (packetFrameDelta > 0)
|
| - {
|
| - ratio = (int8_t) (packetFrameKey / packetFrameDelta);
|
| - }
|
| - ratio = VCM_MAX(boostRateKey, ratio);
|
| + if (packetFrameDelta > 0) {
|
| + ratio = (int8_t)(packetFrameKey / packetFrameDelta);
|
| + }
|
| + ratio = VCM_MAX(boostRateKey, ratio);
|
|
|
| - return ratio;
|
| + return ratio;
|
| }
|
|
|
| -uint8_t
|
| -VCMFecMethod::ConvertFECRate(uint8_t codeRateRTP) const
|
| -{
|
| - return static_cast<uint8_t> (VCM_MIN(255,(0.5 + 255.0 * codeRateRTP /
|
| - (float)(255 - codeRateRTP))));
|
| +uint8_t VCMFecMethod::ConvertFECRate(uint8_t codeRateRTP) const {
|
| + return static_cast<uint8_t>(VCM_MIN(
|
| + 255,
|
| + (0.5 + 255.0 * codeRateRTP / static_cast<float>(255 - codeRateRTP))));
|
| }
|
|
|
| // Update FEC with protectionFactorD
|
| -void
|
| -VCMFecMethod::UpdateProtectionFactorD(uint8_t protectionFactorD)
|
| -{
|
| - _protectionFactorD = protectionFactorD;
|
| +void VCMFecMethod::UpdateProtectionFactorD(uint8_t protectionFactorD) {
|
| + _protectionFactorD = protectionFactorD;
|
| }
|
|
|
| // Update FEC with protectionFactorK
|
| -void
|
| -VCMFecMethod::UpdateProtectionFactorK(uint8_t protectionFactorK)
|
| -{
|
| - _protectionFactorK = protectionFactorK;
|
| -}
|
| -
|
| -bool
|
| -VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
|
| -{
|
| - // FEC PROTECTION SETTINGS: varies with packet loss and bitrate
|
| -
|
| - // No protection if (filtered) packetLoss is 0
|
| - uint8_t packetLoss = (uint8_t) (255 * parameters->lossPr);
|
| - if (packetLoss == 0)
|
| - {
|
| - _protectionFactorK = 0;
|
| - _protectionFactorD = 0;
|
| - return true;
|
| - }
|
| +void VCMFecMethod::UpdateProtectionFactorK(uint8_t protectionFactorK) {
|
| + _protectionFactorK = protectionFactorK;
|
| +}
|
|
|
| - // Parameters for FEC setting:
|
| - // first partition size, thresholds, table pars, spatial resoln fac.
|
| -
|
| - // First partition protection: ~ 20%
|
| - uint8_t firstPartitionProt = (uint8_t) (255 * 0.20);
|
| -
|
| - // Minimum protection level needed to generate one FEC packet for one
|
| - // source packet/frame (in RTP sender)
|
| - uint8_t minProtLevelFec = 85;
|
| -
|
| - // Threshold on packetLoss and bitRrate/frameRate (=average #packets),
|
| - // above which we allocate protection to cover at least first partition.
|
| - uint8_t lossThr = 0;
|
| - uint8_t packetNumThr = 1;
|
| -
|
| - // Parameters for range of rate index of table.
|
| - const uint8_t ratePar1 = 5;
|
| - const uint8_t ratePar2 = 49;
|
| -
|
| - // Spatial resolution size, relative to a reference size.
|
| - float spatialSizeToRef = static_cast<float>
|
| - (parameters->codecWidth * parameters->codecHeight) /
|
| - (static_cast<float>(704 * 576));
|
| - // resolnFac: This parameter will generally increase/decrease the FEC rate
|
| - // (for fixed bitRate and packetLoss) based on system size.
|
| - // Use a smaller exponent (< 1) to control/soften system size effect.
|
| - const float resolnFac = 1.0 / powf(spatialSizeToRef, 0.3f);
|
| -
|
| - const int bitRatePerFrame = BitsPerFrame(parameters);
|
| -
|
| -
|
| - // Average number of packets per frame (source and fec):
|
| - const uint8_t avgTotPackets = 1 + (uint8_t)
|
| - ((float) bitRatePerFrame * 1000.0
|
| - / (float) (8.0 * _maxPayloadSize) + 0.5);
|
| -
|
| - // FEC rate parameters: for P and I frame
|
| - uint8_t codeRateDelta = 0;
|
| - uint8_t codeRateKey = 0;
|
| -
|
| - // Get index for table: the FEC protection depends on an effective rate.
|
| - // The range on the rate index corresponds to rates (bps)
|
| - // from ~200k to ~8000k, for 30fps
|
| - const uint16_t effRateFecTable = static_cast<uint16_t>
|
| - (resolnFac * bitRatePerFrame);
|
| - uint8_t rateIndexTable =
|
| - (uint8_t) VCM_MAX(VCM_MIN((effRateFecTable - ratePar1) /
|
| - ratePar1, ratePar2), 0);
|
| -
|
| - // Restrict packet loss range to 50:
|
| - // current tables defined only up to 50%
|
| - if (packetLoss >= kPacketLossMax)
|
| - {
|
| - packetLoss = kPacketLossMax - 1;
|
| - }
|
| - uint16_t indexTable = rateIndexTable * kPacketLossMax + packetLoss;
|
| +bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) {
|
| + // FEC PROTECTION SETTINGS: varies with packet loss and bitrate
|
|
|
| - // Check on table index
|
| - assert(indexTable < kSizeCodeRateXORTable);
|
| + // No protection if (filtered) packetLoss is 0
|
| + uint8_t packetLoss = (uint8_t)(255 * parameters->lossPr);
|
| + if (packetLoss == 0) {
|
| + _protectionFactorK = 0;
|
| + _protectionFactorD = 0;
|
| + return true;
|
| + }
|
|
|
| - // Protection factor for P frame
|
| - codeRateDelta = kCodeRateXORTable[indexTable];
|
| + // Parameters for FEC setting:
|
| + // first partition size, thresholds, table pars, spatial resoln fac.
|
| +
|
| + // First partition protection: ~ 20%
|
| + uint8_t firstPartitionProt = (uint8_t)(255 * 0.20);
|
| +
|
| + // Minimum protection level needed to generate one FEC packet for one
|
| + // source packet/frame (in RTP sender)
|
| + uint8_t minProtLevelFec = 85;
|
| +
|
| + // Threshold on packetLoss and bitRrate/frameRate (=average #packets),
|
| + // above which we allocate protection to cover at least first partition.
|
| + uint8_t lossThr = 0;
|
| + uint8_t packetNumThr = 1;
|
| +
|
| + // Parameters for range of rate index of table.
|
| + const uint8_t ratePar1 = 5;
|
| + const uint8_t ratePar2 = 49;
|
| +
|
| + // Spatial resolution size, relative to a reference size.
|
| + float spatialSizeToRef =
|
| + static_cast<float>(parameters->codecWidth * parameters->codecHeight) /
|
| + (static_cast<float>(704 * 576));
|
| + // resolnFac: This parameter will generally increase/decrease the FEC rate
|
| + // (for fixed bitRate and packetLoss) based on system size.
|
| + // Use a smaller exponent (< 1) to control/soften system size effect.
|
| + const float resolnFac = 1.0 / powf(spatialSizeToRef, 0.3f);
|
| +
|
| + const int bitRatePerFrame = BitsPerFrame(parameters);
|
| +
|
| + // Average number of packets per frame (source and fec):
|
| + const uint8_t avgTotPackets =
|
| + 1 + (uint8_t)(static_cast<float>(bitRatePerFrame) * 1000.0 /
|
| + static_cast<float>(8.0 * _maxPayloadSize) +
|
| + 0.5);
|
| +
|
| + // FEC rate parameters: for P and I frame
|
| + uint8_t codeRateDelta = 0;
|
| + uint8_t codeRateKey = 0;
|
| +
|
| + // Get index for table: the FEC protection depends on an effective rate.
|
| + // The range on the rate index corresponds to rates (bps)
|
| + // from ~200k to ~8000k, for 30fps
|
| + const uint16_t effRateFecTable =
|
| + static_cast<uint16_t>(resolnFac * bitRatePerFrame);
|
| + uint8_t rateIndexTable = (uint8_t)VCM_MAX(
|
| + VCM_MIN((effRateFecTable - ratePar1) / ratePar1, ratePar2), 0);
|
| +
|
| + // Restrict packet loss range to 50:
|
| + // current tables defined only up to 50%
|
| + if (packetLoss >= kPacketLossMax) {
|
| + packetLoss = kPacketLossMax - 1;
|
| + }
|
| + uint16_t indexTable = rateIndexTable * kPacketLossMax + packetLoss;
|
|
|
| - if (packetLoss > lossThr && avgTotPackets > packetNumThr)
|
| - {
|
| - // Set a minimum based on first partition size.
|
| - if (codeRateDelta < firstPartitionProt)
|
| - {
|
| - codeRateDelta = firstPartitionProt;
|
| - }
|
| - }
|
| + // Check on table index
|
| + assert(indexTable < kSizeCodeRateXORTable);
|
|
|
| - // Check limit on amount of protection for P frame; 50% is max.
|
| - if (codeRateDelta >= kPacketLossMax)
|
| - {
|
| - codeRateDelta = kPacketLossMax - 1;
|
| - }
|
| + // Protection factor for P frame
|
| + codeRateDelta = kCodeRateXORTable[indexTable];
|
|
|
| - float adjustFec = 1.0f;
|
| - // Avoid additional adjustments when layers are active.
|
| - // TODO(mikhal/marco): Update adjusmtent based on layer info.
|
| - if (parameters->numLayers == 1)
|
| - {
|
| - adjustFec = _qmRobustness->AdjustFecFactor(codeRateDelta,
|
| - parameters->bitRate,
|
| - parameters->frameRate,
|
| - parameters->rtt,
|
| - packetLoss);
|
| + if (packetLoss > lossThr && avgTotPackets > packetNumThr) {
|
| + // Set a minimum based on first partition size.
|
| + if (codeRateDelta < firstPartitionProt) {
|
| + codeRateDelta = firstPartitionProt;
|
| }
|
| + }
|
|
|
| - codeRateDelta = static_cast<uint8_t>(codeRateDelta * adjustFec);
|
| -
|
| - // For Key frame:
|
| - // Effectively at a higher rate, so we scale/boost the rate
|
| - // The boost factor may depend on several factors: ratio of packet
|
| - // number of I to P frames, how much protection placed on P frames, etc.
|
| - const uint8_t packetFrameDelta = (uint8_t)
|
| - (0.5 + parameters->packetsPerFrame);
|
| - const uint8_t packetFrameKey = (uint8_t)
|
| - (0.5 + parameters->packetsPerFrameKey);
|
| - const uint8_t boostKey = BoostCodeRateKey(packetFrameDelta,
|
| - packetFrameKey);
|
| -
|
| - rateIndexTable = (uint8_t) VCM_MAX(VCM_MIN(
|
| - 1 + (boostKey * effRateFecTable - ratePar1) /
|
| - ratePar1,ratePar2),0);
|
| - uint16_t indexTableKey = rateIndexTable * kPacketLossMax + packetLoss;
|
| -
|
| - indexTableKey = VCM_MIN(indexTableKey, kSizeCodeRateXORTable);
|
| -
|
| - // Check on table index
|
| - assert(indexTableKey < kSizeCodeRateXORTable);
|
| -
|
| - // Protection factor for I frame
|
| - codeRateKey = kCodeRateXORTable[indexTableKey];
|
| -
|
| - // Boosting for Key frame.
|
| - int boostKeyProt = _scaleProtKey * codeRateDelta;
|
| - if (boostKeyProt >= kPacketLossMax)
|
| - {
|
| - boostKeyProt = kPacketLossMax - 1;
|
| - }
|
| + // Check limit on amount of protection for P frame; 50% is max.
|
| + if (codeRateDelta >= kPacketLossMax) {
|
| + codeRateDelta = kPacketLossMax - 1;
|
| + }
|
|
|
| - // Make sure I frame protection is at least larger than P frame protection,
|
| - // and at least as high as filtered packet loss.
|
| - codeRateKey = static_cast<uint8_t> (VCM_MAX(packetLoss,
|
| - VCM_MAX(boostKeyProt, codeRateKey)));
|
| + float adjustFec = 1.0f;
|
| + // Avoid additional adjustments when layers are active.
|
| + // TODO(mikhal/marco): Update adjusmtent based on layer info.
|
| + if (parameters->numLayers == 1) {
|
| + adjustFec = _qmRobustness->AdjustFecFactor(
|
| + codeRateDelta, parameters->bitRate, parameters->frameRate,
|
| + parameters->rtt, packetLoss);
|
| + }
|
|
|
| - // Check limit on amount of protection for I frame: 50% is max.
|
| - if (codeRateKey >= kPacketLossMax)
|
| - {
|
| - codeRateKey = kPacketLossMax - 1;
|
| - }
|
| + codeRateDelta = static_cast<uint8_t>(codeRateDelta * adjustFec);
|
|
|
| - _protectionFactorK = codeRateKey;
|
| - _protectionFactorD = codeRateDelta;
|
| + // For Key frame:
|
| + // Effectively at a higher rate, so we scale/boost the rate
|
| + // The boost factor may depend on several factors: ratio of packet
|
| + // number of I to P frames, how much protection placed on P frames, etc.
|
| + const uint8_t packetFrameDelta = (uint8_t)(0.5 + parameters->packetsPerFrame);
|
| + const uint8_t packetFrameKey =
|
| + (uint8_t)(0.5 + parameters->packetsPerFrameKey);
|
| + const uint8_t boostKey = BoostCodeRateKey(packetFrameDelta, packetFrameKey);
|
|
|
| - // Generally there is a rate mis-match between the FEC cost estimated
|
| - // in mediaOpt and the actual FEC cost sent out in RTP module.
|
| - // This is more significant at low rates (small # of source packets), where
|
| - // the granularity of the FEC decreases. In this case, non-zero protection
|
| - // in mediaOpt may generate 0 FEC packets in RTP sender (since actual #FEC
|
| - // is based on rounding off protectionFactor on actual source packet number).
|
| - // The correction factor (_corrFecCost) attempts to corrects this, at least
|
| - // for cases of low rates (small #packets) and low protection levels.
|
| + rateIndexTable = (uint8_t)VCM_MAX(
|
| + VCM_MIN(1 + (boostKey * effRateFecTable - ratePar1) / ratePar1, ratePar2),
|
| + 0);
|
| + uint16_t indexTableKey = rateIndexTable * kPacketLossMax + packetLoss;
|
|
|
| - float numPacketsFl = 1.0f + ((float) bitRatePerFrame * 1000.0
|
| - / (float) (8.0 * _maxPayloadSize) + 0.5);
|
| + indexTableKey = VCM_MIN(indexTableKey, kSizeCodeRateXORTable);
|
|
|
| - const float estNumFecGen = 0.5f + static_cast<float> (_protectionFactorD *
|
| - numPacketsFl / 255.0f);
|
| + // Check on table index
|
| + assert(indexTableKey < kSizeCodeRateXORTable);
|
|
|
| + // Protection factor for I frame
|
| + codeRateKey = kCodeRateXORTable[indexTableKey];
|
|
|
| - // We reduce cost factor (which will reduce overhead for FEC and
|
| - // hybrid method) and not the protectionFactor.
|
| - _corrFecCost = 1.0f;
|
| - if (estNumFecGen < 1.1f && _protectionFactorD < minProtLevelFec)
|
| - {
|
| - _corrFecCost = 0.5f;
|
| - }
|
| - if (estNumFecGen < 0.9f && _protectionFactorD < minProtLevelFec)
|
| - {
|
| - _corrFecCost = 0.0f;
|
| - }
|
| + // Boosting for Key frame.
|
| + int boostKeyProt = _scaleProtKey * codeRateDelta;
|
| + if (boostKeyProt >= kPacketLossMax) {
|
| + boostKeyProt = kPacketLossMax - 1;
|
| + }
|
|
|
| - // TODO (marpan): Set the UEP protection on/off for Key and Delta frames
|
| - _useUepProtectionK = _qmRobustness->SetUepProtection(codeRateKey,
|
| - parameters->bitRate,
|
| - packetLoss,
|
| - 0);
|
| + // Make sure I frame protection is at least larger than P frame protection,
|
| + // and at least as high as filtered packet loss.
|
| + codeRateKey = static_cast<uint8_t>(
|
| + VCM_MAX(packetLoss, VCM_MAX(boostKeyProt, codeRateKey)));
|
|
|
| - _useUepProtectionD = _qmRobustness->SetUepProtection(codeRateDelta,
|
| - parameters->bitRate,
|
| - packetLoss,
|
| - 1);
|
| + // Check limit on amount of protection for I frame: 50% is max.
|
| + if (codeRateKey >= kPacketLossMax) {
|
| + codeRateKey = kPacketLossMax - 1;
|
| + }
|
|
|
| - // DONE WITH FEC PROTECTION SETTINGS
|
| - return true;
|
| + _protectionFactorK = codeRateKey;
|
| + _protectionFactorD = codeRateDelta;
|
| +
|
| + // Generally there is a rate mis-match between the FEC cost estimated
|
| + // in mediaOpt and the actual FEC cost sent out in RTP module.
|
| + // This is more significant at low rates (small # of source packets), where
|
| + // the granularity of the FEC decreases. In this case, non-zero protection
|
| + // in mediaOpt may generate 0 FEC packets in RTP sender (since actual #FEC
|
| + // is based on rounding off protectionFactor on actual source packet number).
|
| + // The correction factor (_corrFecCost) attempts to corrects this, at least
|
| + // for cases of low rates (small #packets) and low protection levels.
|
| +
|
| + float numPacketsFl = 1.0f + (static_cast<float>(bitRatePerFrame) * 1000.0 /
|
| + static_cast<float>(8.0 * _maxPayloadSize) +
|
| + 0.5);
|
| +
|
| + const float estNumFecGen =
|
| + 0.5f + static_cast<float>(_protectionFactorD * numPacketsFl / 255.0f);
|
| +
|
| + // We reduce cost factor (which will reduce overhead for FEC and
|
| + // hybrid method) and not the protectionFactor.
|
| + _corrFecCost = 1.0f;
|
| + if (estNumFecGen < 1.1f && _protectionFactorD < minProtLevelFec) {
|
| + _corrFecCost = 0.5f;
|
| + }
|
| + if (estNumFecGen < 0.9f && _protectionFactorD < minProtLevelFec) {
|
| + _corrFecCost = 0.0f;
|
| + }
|
| +
|
| + // TODO(marpan): Set the UEP protection on/off for Key and Delta frames
|
| + _useUepProtectionK = _qmRobustness->SetUepProtection(
|
| + codeRateKey, parameters->bitRate, packetLoss, 0);
|
| +
|
| + _useUepProtectionD = _qmRobustness->SetUepProtection(
|
| + codeRateDelta, parameters->bitRate, packetLoss, 1);
|
| +
|
| + // DONE WITH FEC PROTECTION SETTINGS
|
| + return true;
|
| }
|
|
|
| int VCMFecMethod::BitsPerFrame(const VCMProtectionParameters* parameters) {
|
| // When temporal layers are available FEC will only be applied on the base
|
| // layer.
|
| const float bitRateRatio =
|
| - kVp8LayerRateAlloction[parameters->numLayers - 1][0];
|
| + kVp8LayerRateAlloction[parameters->numLayers - 1][0];
|
| float frameRateRatio = powf(1 / 2.0, parameters->numLayers - 1);
|
| float bitRate = parameters->bitRate * bitRateRatio;
|
| float frameRate = parameters->frameRate * frameRateRatio;
|
| @@ -485,64 +438,59 @@ int VCMFecMethod::BitsPerFrame(const VCMProtectionParameters* parameters) {
|
| return static_cast<int>(adjustmentFactor * bitRate / frameRate);
|
| }
|
|
|
| -bool
|
| -VCMFecMethod::EffectivePacketLoss(const VCMProtectionParameters* parameters)
|
| -{
|
| - // Effective packet loss to encoder is based on RPL (residual packet loss)
|
| - // this is a soft setting based on degree of FEC protection
|
| - // RPL = received/input packet loss - average_FEC_recovery
|
| - // note: received/input packet loss may be filtered based on FilteredLoss
|
| -
|
| - // Effective Packet Loss, NA in current version.
|
| - _effectivePacketLoss = 0;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool
|
| -VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters)
|
| -{
|
| - // Compute the protection factor
|
| - ProtectionFactor(parameters);
|
| -
|
| - // Compute the effective packet loss
|
| - EffectivePacketLoss(parameters);
|
| -
|
| - // Protection/fec rates obtained above is defined relative to total number
|
| - // of packets (total rate: source+fec) FEC in RTP module assumes protection
|
| - // factor is defined relative to source number of packets so we should
|
| - // convert the factor to reduce mismatch between mediaOpt suggested rate and
|
| - // the actual rate
|
| - _protectionFactorK = ConvertFECRate(_protectionFactorK);
|
| - _protectionFactorD = ConvertFECRate(_protectionFactorD);
|
| -
|
| - return true;
|
| -}
|
| -VCMLossProtectionLogic::VCMLossProtectionLogic(int64_t nowMs):
|
| -_currentParameters(),
|
| -_rtt(0),
|
| -_lossPr(0.0f),
|
| -_bitRate(0.0f),
|
| -_frameRate(0.0f),
|
| -_keyFrameSize(0.0f),
|
| -_fecRateKey(0),
|
| -_fecRateDelta(0),
|
| -_lastPrUpdateT(0),
|
| -_lossPr255(0.9999f),
|
| -_lossPrHistory(),
|
| -_shortMaxLossPr255(0),
|
| -_packetsPerFrame(0.9999f),
|
| -_packetsPerFrameKey(0.9999f),
|
| -_codecWidth(0),
|
| -_codecHeight(0),
|
| -_numLayers(1)
|
| -{
|
| - Reset(nowMs);
|
| -}
|
| -
|
| -VCMLossProtectionLogic::~VCMLossProtectionLogic()
|
| -{
|
| - Release();
|
| +bool VCMFecMethod::EffectivePacketLoss(
|
| + const VCMProtectionParameters* parameters) {
|
| + // Effective packet loss to encoder is based on RPL (residual packet loss)
|
| + // this is a soft setting based on degree of FEC protection
|
| + // RPL = received/input packet loss - average_FEC_recovery
|
| + // note: received/input packet loss may be filtered based on FilteredLoss
|
| +
|
| + // Effective Packet Loss, NA in current version.
|
| + _effectivePacketLoss = 0;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) {
|
| + // Compute the protection factor
|
| + ProtectionFactor(parameters);
|
| +
|
| + // Compute the effective packet loss
|
| + EffectivePacketLoss(parameters);
|
| +
|
| + // Protection/fec rates obtained above is defined relative to total number
|
| + // of packets (total rate: source+fec) FEC in RTP module assumes protection
|
| + // factor is defined relative to source number of packets so we should
|
| + // convert the factor to reduce mismatch between mediaOpt suggested rate and
|
| + // the actual rate
|
| + _protectionFactorK = ConvertFECRate(_protectionFactorK);
|
| + _protectionFactorD = ConvertFECRate(_protectionFactorD);
|
| +
|
| + return true;
|
| +}
|
| +VCMLossProtectionLogic::VCMLossProtectionLogic(int64_t nowMs)
|
| + : _currentParameters(),
|
| + _rtt(0),
|
| + _lossPr(0.0f),
|
| + _bitRate(0.0f),
|
| + _frameRate(0.0f),
|
| + _keyFrameSize(0.0f),
|
| + _fecRateKey(0),
|
| + _fecRateDelta(0),
|
| + _lastPrUpdateT(0),
|
| + _lossPr255(0.9999f),
|
| + _lossPrHistory(),
|
| + _shortMaxLossPr255(0),
|
| + _packetsPerFrame(0.9999f),
|
| + _packetsPerFrameKey(0.9999f),
|
| + _codecWidth(0),
|
| + _codecHeight(0),
|
| + _numLayers(1) {
|
| + Reset(nowMs);
|
| +}
|
| +
|
| +VCMLossProtectionLogic::~VCMLossProtectionLogic() {
|
| + Release();
|
| }
|
|
|
| void VCMLossProtectionLogic::SetMethod(
|
| @@ -550,7 +498,7 @@ void VCMLossProtectionLogic::SetMethod(
|
| if (_selectedMethod && _selectedMethod->Type() == newMethodType)
|
| return;
|
|
|
| - switch(newMethodType) {
|
| + switch (newMethodType) {
|
| case kNack:
|
| _selectedMethod.reset(new VCMNackMethod());
|
| break;
|
| @@ -567,92 +515,70 @@ void VCMLossProtectionLogic::SetMethod(
|
| UpdateMethod();
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdateRtt(int64_t rtt)
|
| -{
|
| - _rtt = rtt;
|
| +void VCMLossProtectionLogic::UpdateRtt(int64_t rtt) {
|
| + _rtt = rtt;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdateMaxLossHistory(uint8_t lossPr255,
|
| - int64_t now)
|
| -{
|
| - if (_lossPrHistory[0].timeMs >= 0 &&
|
| - now - _lossPrHistory[0].timeMs < kLossPrShortFilterWinMs)
|
| - {
|
| - if (lossPr255 > _shortMaxLossPr255)
|
| - {
|
| - _shortMaxLossPr255 = lossPr255;
|
| - }
|
| +void VCMLossProtectionLogic::UpdateMaxLossHistory(uint8_t lossPr255,
|
| + int64_t now) {
|
| + if (_lossPrHistory[0].timeMs >= 0 &&
|
| + now - _lossPrHistory[0].timeMs < kLossPrShortFilterWinMs) {
|
| + if (lossPr255 > _shortMaxLossPr255) {
|
| + _shortMaxLossPr255 = lossPr255;
|
| }
|
| - else
|
| - {
|
| - // Only add a new value to the history once a second
|
| - if (_lossPrHistory[0].timeMs == -1)
|
| - {
|
| - // First, no shift
|
| - _shortMaxLossPr255 = lossPr255;
|
| - }
|
| - else
|
| - {
|
| - // Shift
|
| - for (int32_t i = (kLossPrHistorySize - 2); i >= 0; i--)
|
| - {
|
| - _lossPrHistory[i + 1].lossPr255 = _lossPrHistory[i].lossPr255;
|
| - _lossPrHistory[i + 1].timeMs = _lossPrHistory[i].timeMs;
|
| - }
|
| - }
|
| - if (_shortMaxLossPr255 == 0)
|
| - {
|
| - _shortMaxLossPr255 = lossPr255;
|
| - }
|
| -
|
| - _lossPrHistory[0].lossPr255 = _shortMaxLossPr255;
|
| - _lossPrHistory[0].timeMs = now;
|
| - _shortMaxLossPr255 = 0;
|
| + } else {
|
| + // Only add a new value to the history once a second
|
| + if (_lossPrHistory[0].timeMs == -1) {
|
| + // First, no shift
|
| + _shortMaxLossPr255 = lossPr255;
|
| + } else {
|
| + // Shift
|
| + for (int32_t i = (kLossPrHistorySize - 2); i >= 0; i--) {
|
| + _lossPrHistory[i + 1].lossPr255 = _lossPrHistory[i].lossPr255;
|
| + _lossPrHistory[i + 1].timeMs = _lossPrHistory[i].timeMs;
|
| + }
|
| }
|
| + if (_shortMaxLossPr255 == 0) {
|
| + _shortMaxLossPr255 = lossPr255;
|
| + }
|
| +
|
| + _lossPrHistory[0].lossPr255 = _shortMaxLossPr255;
|
| + _lossPrHistory[0].timeMs = now;
|
| + _shortMaxLossPr255 = 0;
|
| + }
|
| }
|
|
|
| -uint8_t
|
| -VCMLossProtectionLogic::MaxFilteredLossPr(int64_t nowMs) const
|
| -{
|
| - uint8_t maxFound = _shortMaxLossPr255;
|
| - if (_lossPrHistory[0].timeMs == -1)
|
| - {
|
| - return maxFound;
|
| +uint8_t VCMLossProtectionLogic::MaxFilteredLossPr(int64_t nowMs) const {
|
| + uint8_t maxFound = _shortMaxLossPr255;
|
| + if (_lossPrHistory[0].timeMs == -1) {
|
| + return maxFound;
|
| + }
|
| + for (int32_t i = 0; i < kLossPrHistorySize; i++) {
|
| + if (_lossPrHistory[i].timeMs == -1) {
|
| + break;
|
| }
|
| - for (int32_t i = 0; i < kLossPrHistorySize; i++)
|
| - {
|
| - if (_lossPrHistory[i].timeMs == -1)
|
| - {
|
| - break;
|
| - }
|
| - if (nowMs - _lossPrHistory[i].timeMs >
|
| - kLossPrHistorySize * kLossPrShortFilterWinMs)
|
| - {
|
| - // This sample (and all samples after this) is too old
|
| - break;
|
| - }
|
| - if (_lossPrHistory[i].lossPr255 > maxFound)
|
| - {
|
| - // This sample is the largest one this far into the history
|
| - maxFound = _lossPrHistory[i].lossPr255;
|
| - }
|
| + if (nowMs - _lossPrHistory[i].timeMs >
|
| + kLossPrHistorySize * kLossPrShortFilterWinMs) {
|
| + // This sample (and all samples after this) is too old
|
| + break;
|
| }
|
| - return maxFound;
|
| + if (_lossPrHistory[i].lossPr255 > maxFound) {
|
| + // This sample is the largest one this far into the history
|
| + maxFound = _lossPrHistory[i].lossPr255;
|
| + }
|
| + }
|
| + return maxFound;
|
| }
|
|
|
| -uint8_t VCMLossProtectionLogic::FilteredLoss(
|
| - int64_t nowMs,
|
| - FilterPacketLossMode filter_mode,
|
| - uint8_t lossPr255) {
|
| -
|
| +uint8_t VCMLossProtectionLogic::FilteredLoss(int64_t nowMs,
|
| + FilterPacketLossMode filter_mode,
|
| + uint8_t lossPr255) {
|
| // Update the max window filter.
|
| UpdateMaxLossHistory(lossPr255, nowMs);
|
|
|
| // Update the recursive average filter.
|
| - _lossPr255.Apply(static_cast<float> (nowMs - _lastPrUpdateT),
|
| - static_cast<float> (lossPr255));
|
| + _lossPr255.Apply(static_cast<float>(nowMs - _lastPrUpdateT),
|
| + static_cast<float>(lossPr255));
|
| _lastPrUpdateT = nowMs;
|
|
|
| // Filtered loss: default is received loss (no filtering).
|
| @@ -672,98 +598,80 @@ uint8_t VCMLossProtectionLogic::FilteredLoss(
|
| return filtered_loss;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdateFilteredLossPr(uint8_t packetLossEnc)
|
| -{
|
| - _lossPr = (float) packetLossEnc / (float) 255.0;
|
| +void VCMLossProtectionLogic::UpdateFilteredLossPr(uint8_t packetLossEnc) {
|
| + _lossPr = static_cast<float>(packetLossEnc) / 255.0;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdateBitRate(float bitRate)
|
| -{
|
| - _bitRate = bitRate;
|
| +void VCMLossProtectionLogic::UpdateBitRate(float bitRate) {
|
| + _bitRate = bitRate;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets, int64_t nowMs)
|
| -{
|
| - _packetsPerFrame.Apply(static_cast<float>(nowMs - _lastPacketPerFrameUpdateT),
|
| - nPackets);
|
| - _lastPacketPerFrameUpdateT = nowMs;
|
| +void VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets,
|
| + int64_t nowMs) {
|
| + _packetsPerFrame.Apply(static_cast<float>(nowMs - _lastPacketPerFrameUpdateT),
|
| + nPackets);
|
| + _lastPacketPerFrameUpdateT = nowMs;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs)
|
| -{
|
| - _packetsPerFrameKey.Apply(static_cast<float>(nowMs -
|
| - _lastPacketPerFrameUpdateTKey), nPackets);
|
| - _lastPacketPerFrameUpdateTKey = nowMs;
|
| +void VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets,
|
| + int64_t nowMs) {
|
| + _packetsPerFrameKey.Apply(
|
| + static_cast<float>(nowMs - _lastPacketPerFrameUpdateTKey), nPackets);
|
| + _lastPacketPerFrameUpdateTKey = nowMs;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdateKeyFrameSize(float keyFrameSize)
|
| -{
|
| - _keyFrameSize = keyFrameSize;
|
| +void VCMLossProtectionLogic::UpdateKeyFrameSize(float keyFrameSize) {
|
| + _keyFrameSize = keyFrameSize;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::UpdateFrameSize(uint16_t width,
|
| - uint16_t height)
|
| -{
|
| - _codecWidth = width;
|
| - _codecHeight = height;
|
| +void VCMLossProtectionLogic::UpdateFrameSize(uint16_t width, uint16_t height) {
|
| + _codecWidth = width;
|
| + _codecHeight = height;
|
| }
|
|
|
| void VCMLossProtectionLogic::UpdateNumLayers(int numLayers) {
|
| _numLayers = (numLayers == 0) ? 1 : numLayers;
|
| }
|
|
|
| -bool
|
| -VCMLossProtectionLogic::UpdateMethod()
|
| -{
|
| - if (!_selectedMethod)
|
| - return false;
|
| - _currentParameters.rtt = _rtt;
|
| - _currentParameters.lossPr = _lossPr;
|
| - _currentParameters.bitRate = _bitRate;
|
| - _currentParameters.frameRate = _frameRate; // rename actual frame rate?
|
| - _currentParameters.keyFrameSize = _keyFrameSize;
|
| - _currentParameters.fecRateDelta = _fecRateDelta;
|
| - _currentParameters.fecRateKey = _fecRateKey;
|
| - _currentParameters.packetsPerFrame = _packetsPerFrame.filtered();
|
| - _currentParameters.packetsPerFrameKey = _packetsPerFrameKey.filtered();
|
| - _currentParameters.codecWidth = _codecWidth;
|
| - _currentParameters.codecHeight = _codecHeight;
|
| - _currentParameters.numLayers = _numLayers;
|
| - return _selectedMethod->UpdateParameters(&_currentParameters);
|
| -}
|
| -
|
| -VCMProtectionMethod*
|
| -VCMLossProtectionLogic::SelectedMethod() const
|
| -{
|
| - return _selectedMethod.get();
|
| +bool VCMLossProtectionLogic::UpdateMethod() {
|
| + if (!_selectedMethod)
|
| + return false;
|
| + _currentParameters.rtt = _rtt;
|
| + _currentParameters.lossPr = _lossPr;
|
| + _currentParameters.bitRate = _bitRate;
|
| + _currentParameters.frameRate = _frameRate; // rename actual frame rate?
|
| + _currentParameters.keyFrameSize = _keyFrameSize;
|
| + _currentParameters.fecRateDelta = _fecRateDelta;
|
| + _currentParameters.fecRateKey = _fecRateKey;
|
| + _currentParameters.packetsPerFrame = _packetsPerFrame.filtered();
|
| + _currentParameters.packetsPerFrameKey = _packetsPerFrameKey.filtered();
|
| + _currentParameters.codecWidth = _codecWidth;
|
| + _currentParameters.codecHeight = _codecHeight;
|
| + _currentParameters.numLayers = _numLayers;
|
| + return _selectedMethod->UpdateParameters(&_currentParameters);
|
| +}
|
| +
|
| +VCMProtectionMethod* VCMLossProtectionLogic::SelectedMethod() const {
|
| + return _selectedMethod.get();
|
| }
|
|
|
| VCMProtectionMethodEnum VCMLossProtectionLogic::SelectedType() const {
|
| return _selectedMethod ? _selectedMethod->Type() : kNone;
|
| }
|
|
|
| -void
|
| -VCMLossProtectionLogic::Reset(int64_t nowMs)
|
| -{
|
| - _lastPrUpdateT = nowMs;
|
| - _lastPacketPerFrameUpdateT = nowMs;
|
| - _lastPacketPerFrameUpdateTKey = nowMs;
|
| - _lossPr255.Reset(0.9999f);
|
| - _packetsPerFrame.Reset(0.9999f);
|
| - _fecRateDelta = _fecRateKey = 0;
|
| - for (int32_t i = 0; i < kLossPrHistorySize; i++)
|
| - {
|
| - _lossPrHistory[i].lossPr255 = 0;
|
| - _lossPrHistory[i].timeMs = -1;
|
| - }
|
| - _shortMaxLossPr255 = 0;
|
| - Release();
|
| +void VCMLossProtectionLogic::Reset(int64_t nowMs) {
|
| + _lastPrUpdateT = nowMs;
|
| + _lastPacketPerFrameUpdateT = nowMs;
|
| + _lastPacketPerFrameUpdateTKey = nowMs;
|
| + _lossPr255.Reset(0.9999f);
|
| + _packetsPerFrame.Reset(0.9999f);
|
| + _fecRateDelta = _fecRateKey = 0;
|
| + for (int32_t i = 0; i < kLossPrHistorySize; i++) {
|
| + _lossPrHistory[i].lossPr255 = 0;
|
| + _lossPrHistory[i].timeMs = -1;
|
| + }
|
| + _shortMaxLossPr255 = 0;
|
| + Release();
|
| }
|
|
|
| void VCMLossProtectionLogic::Release() {
|
|
|