diff --git a/src/modules/video_coding/main/source/media_opt_util.cc b/src/modules/video_coding/main/source/media_opt_util.cc index f042bf0a9..4d98486a9 100644 --- a/src/modules/video_coding/main/source/media_opt_util.cc +++ b/src/modules/video_coding/main/source/media_opt_util.cc @@ -114,7 +114,7 @@ VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) // Add FEC cost: ignore I frames for now float fecRate = static_cast (_protectionFactorD) / 255.0f; - _efficiency = parameters->bitRate * fecRate; + _efficiency = parameters->bitRate * fecRate * _corrFecCost; // Add NACK cost, when applicable if (parameters->rtt < kHighRttNackMs) @@ -430,6 +430,27 @@ VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) _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/low # of packets. + const float estNumFecGen = 0.5f + static_cast (_protectionFactorD * + avgTotPackets / 255.0f); + // Note we reduce cost factor (which will reduce overhead for FEC and + // hybrid method) and not the protectionFactor. + _corrFecCost = 1.0f; + if (estNumFecGen < 1.5f) + { + _corrFecCost = 0.5f; + } + if (estNumFecGen < 1.0f) + { + _corrFecCost = 0.0f; + } // TODO (marpan): Set the UEP protection on/off for Key and Delta frames _useUepProtectionK = _qmRobustness->SetUepProtection(codeRateKey, bitRate, @@ -485,7 +506,7 @@ VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) // in the new tables, the fecRate is defined relative to total number of // packets (total rate), so overhead cost is: - _efficiency = parameters->bitRate * fecRate; + _efficiency = parameters->bitRate * fecRate * _corrFecCost; } else { diff --git a/src/modules/video_coding/main/source/media_opt_util.h b/src/modules/video_coding/main/source/media_opt_util.h index e3419f058..6a03ada44 100644 --- a/src/modules/video_coding/main/source/media_opt_util.h +++ b/src/modules/video_coding/main/source/media_opt_util.h @@ -92,8 +92,8 @@ public: VCMProtectionMethod(VCMProtectionMethodEnum type) : _effectivePacketLoss(0), _protectionFactorK(0), _protectionFactorD(0), _residualPacketLossFec(0.0), _scaleProtKey(2.0), _maxPayloadSize(1460), - _useUepProtectionK(false), _useUepProtectionD(true), _efficiency(0), - _type(type) + _useUepProtectionK(false), _useUepProtectionD(true), _corrFecCost(1.0), + _efficiency(0), _type(type) {_qmRobustness = new VCMQmRobustness();} virtual ~VCMProtectionMethod() { delete _qmRobustness;} @@ -157,6 +157,7 @@ public: VCMQmRobustness* _qmRobustness; bool _useUepProtectionK; bool _useUepProtectionD; + float _corrFecCost; protected: float _efficiency;