diff --git a/modules/video_coding/media_opt_util.cc b/modules/video_coding/media_opt_util.cc index 4afe47dd8d..125e6db81d 100644 --- a/modules/video_coding/media_opt_util.cc +++ b/modules/video_coding/media_opt_util.cc @@ -22,6 +22,7 @@ #include "modules/video_coding/include/video_coding_defines.h" #include "modules/video_coding/nack_fec_tables.h" #include "modules/video_coding/utility/simulcast_rate_allocator.h" +#include "rtc_base/numerics/safe_conversions.h" namespace webrtc { // Max value of loss rates in off-line model @@ -127,8 +128,8 @@ bool VCMNackFecMethod::ProtectionFactor( // Adjust FEC with NACK on (for delta frame only) // table depends on RTT relative to rttMax (NACK Threshold) - _protectionFactorD = static_cast( - adjustRtt * static_cast(_protectionFactorD)); + _protectionFactorD = rtc::saturated_cast( + adjustRtt * rtc::saturated_cast(_protectionFactorD)); // update FEC rates after applying adjustment VCMFecMethod::UpdateProtectionFactorD(_protectionFactorD); } @@ -150,10 +151,10 @@ int VCMNackFecMethod::ComputeMaxFramesFec( // RTP module based on the actual number of packets and the protection factor. float base_layer_framerate = parameters->frameRate / - static_cast(1 << (parameters->numLayers - 1)); + rtc::saturated_cast(1 << (parameters->numLayers - 1)); int max_frames_fec = std::max( - static_cast(2.0f * base_layer_framerate * parameters->rtt / 1000.0f + - 0.5f), + rtc::saturated_cast( + 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. @@ -268,9 +269,9 @@ uint8_t VCMFecMethod::BoostCodeRateKey(uint8_t packetFrameDelta, } uint8_t VCMFecMethod::ConvertFECRate(uint8_t codeRateRTP) const { - return static_cast(VCM_MIN( - 255, - (0.5 + 255.0 * codeRateRTP / static_cast(255 - codeRateRTP)))); + return rtc::saturated_cast( + VCM_MIN(255, (0.5 + 255.0 * codeRateRTP / + rtc::saturated_cast(255 - codeRateRTP)))); } // Update FEC with protectionFactorD @@ -287,7 +288,7 @@ 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 = static_cast(255 * parameters->lossPr); + uint8_t packetLoss = rtc::saturated_cast(255 * parameters->lossPr); if (packetLoss == 0) { _protectionFactorK = 0; _protectionFactorD = 0; @@ -298,7 +299,7 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { // first partition size, thresholds, table pars, spatial resoln fac. // First partition protection: ~ 20% - uint8_t firstPartitionProt = static_cast(255 * 0.20); + uint8_t firstPartitionProt = rtc::saturated_cast(255 * 0.20); // Minimum protection level needed to generate one FEC packet for one // source packet/frame (in RTP sender) @@ -314,9 +315,9 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { const uint8_t ratePar2 = 49; // Spatial resolution size, relative to a reference size. - float spatialSizeToRef = - static_cast(parameters->codecWidth * parameters->codecHeight) / - (static_cast(704 * 576)); + float spatialSizeToRef = rtc::saturated_cast(parameters->codecWidth * + parameters->codecHeight) / + (rtc::saturated_cast(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. @@ -325,10 +326,9 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { const int bitRatePerFrame = BitsPerFrame(parameters); // Average number of packets per frame (source and fec): - const uint8_t avgTotPackets = static_cast( - std::min(static_cast(std::numeric_limits::max()), - 1.5f + static_cast(bitRatePerFrame) * 1000.0f / - static_cast(8.0 * _maxPayloadSize))); + const uint8_t avgTotPackets = rtc::saturated_cast( + 1.5f + rtc::saturated_cast(bitRatePerFrame) * 1000.0f / + rtc::saturated_cast(8.0 * _maxPayloadSize)); // FEC rate parameters: for P and I frame uint8_t codeRateDelta = 0; @@ -338,8 +338,8 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { // The range on the rate index corresponds to rates (bps) // from ~200k to ~8000k, for 30fps const uint16_t effRateFecTable = - static_cast(resolnFac * bitRatePerFrame); - uint8_t rateIndexTable = static_cast( + rtc::saturated_cast(resolnFac * bitRatePerFrame); + uint8_t rateIndexTable = rtc::saturated_cast( VCM_MAX(VCM_MIN((effRateFecTable - ratePar1) / ratePar1, ratePar2), 0)); // Restrict packet loss range to 50: @@ -372,12 +372,12 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { // 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 = - static_cast(0.5 + parameters->packetsPerFrame); + rtc::saturated_cast(0.5 + parameters->packetsPerFrame); const uint8_t packetFrameKey = - static_cast(0.5 + parameters->packetsPerFrameKey); + rtc::saturated_cast(0.5 + parameters->packetsPerFrameKey); const uint8_t boostKey = BoostCodeRateKey(packetFrameDelta, packetFrameKey); - rateIndexTable = static_cast(VCM_MAX( + rateIndexTable = rtc::saturated_cast(VCM_MAX( VCM_MIN(1 + (boostKey * effRateFecTable - ratePar1) / ratePar1, ratePar2), 0)); uint16_t indexTableKey = rateIndexTable * kPacketLossMax + packetLoss; @@ -398,7 +398,7 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { // 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( + codeRateKey = rtc::saturated_cast( VCM_MAX(packetLoss, VCM_MAX(boostKeyProt, codeRateKey))); // Check limit on amount of protection for I frame: 50% is max. @@ -418,12 +418,14 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { // 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(bitRatePerFrame) * 1000.0 / - static_cast(8.0 * _maxPayloadSize) + - 0.5); + float numPacketsFl = + 1.0f + (rtc::saturated_cast(bitRatePerFrame) * 1000.0 / + rtc::saturated_cast(8.0 * _maxPayloadSize) + + 0.5); const float estNumFecGen = - 0.5f + static_cast(_protectionFactorD * numPacketsFl / 255.0f); + 0.5f + + rtc::saturated_cast(_protectionFactorD * numPacketsFl / 255.0f); // We reduce cost factor (which will reduce overhead for FEC and // hybrid method) and not the protectionFactor. @@ -455,7 +457,7 @@ int VCMFecMethod::BitsPerFrame(const VCMProtectionParameters* parameters) { if (frameRate < 1.0f) frameRate = 1.0f; // Average bits per frame (units of kbits) - return static_cast(adjustmentFactor * bitRate / frameRate); + return rtc::saturated_cast(adjustmentFactor * bitRate / frameRate); } bool VCMFecMethod::EffectivePacketLoss( @@ -597,8 +599,8 @@ uint8_t VCMLossProtectionLogic::FilteredLoss(int64_t nowMs, UpdateMaxLossHistory(lossPr255, nowMs); // Update the recursive average filter. - _lossPr255.Apply(static_cast(nowMs - _lastPrUpdateT), - static_cast(lossPr255)); + _lossPr255.Apply(rtc::saturated_cast(nowMs - _lastPrUpdateT), + rtc::saturated_cast(lossPr255)); _lastPrUpdateT = nowMs; // Filtered loss: default is received loss (no filtering). @@ -608,7 +610,7 @@ uint8_t VCMLossProtectionLogic::FilteredLoss(int64_t nowMs, case kNoFilter: break; case kAvgFilter: - filtered_loss = static_cast(_lossPr255.filtered() + 0.5); + filtered_loss = rtc::saturated_cast(_lossPr255.filtered() + 0.5); break; case kMaxFilter: filtered_loss = MaxFilteredLossPr(nowMs); @@ -619,7 +621,7 @@ uint8_t VCMLossProtectionLogic::FilteredLoss(int64_t nowMs, } void VCMLossProtectionLogic::UpdateFilteredLossPr(uint8_t packetLossEnc) { - _lossPr = static_cast(packetLossEnc) / 255.0; + _lossPr = rtc::saturated_cast(packetLossEnc) / 255.0; } void VCMLossProtectionLogic::UpdateBitRate(float bitRate) { @@ -628,15 +630,16 @@ void VCMLossProtectionLogic::UpdateBitRate(float bitRate) { void VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets, int64_t nowMs) { - _packetsPerFrame.Apply(static_cast(nowMs - _lastPacketPerFrameUpdateT), - nPackets); + _packetsPerFrame.Apply( + rtc::saturated_cast(nowMs - _lastPacketPerFrameUpdateT), nPackets); _lastPacketPerFrameUpdateT = nowMs; } void VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs) { _packetsPerFrameKey.Apply( - static_cast(nowMs - _lastPacketPerFrameUpdateTKey), nPackets); + rtc::saturated_cast(nowMs - _lastPacketPerFrameUpdateTKey), + nPackets); _lastPacketPerFrameUpdateTKey = nowMs; }