From e25b0148c923be83ce26ca7e1c0f84e42919d2e1 Mon Sep 17 00:00:00 2001 From: "mikhal@google.com" Date: Thu, 16 Jun 2011 16:11:33 +0000 Subject: [PATCH] Clean up of media_opt_util.cc Review URL: http://webrtc-codereview.appspot.com/33007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@92 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../main/source/media_opt_util.cc | 700 +++++++++++------- 1 file changed, 417 insertions(+), 283 deletions(-) diff --git a/modules/video_coding/main/source/media_opt_util.cc b/modules/video_coding/main/source/media_opt_util.cc index 140479301..3b7e8df89 100644 --- a/modules/video_coding/main/source/media_opt_util.cc +++ b/modules/video_coding/main/source/media_opt_util.cc @@ -22,34 +22,39 @@ namespace webrtc { -bool VCMProtectionMethod::BetterThan(VCMProtectionMethod *pm) +bool +VCMProtectionMethod::BetterThan(VCMProtectionMethod *pm) { - if (pm == NULL) { - return true; + if (pm == NULL) + { + return true; } return pm->_score > _score; } -bool VCMNackFecMethod::ProtectionFactor(const VCMProtectionParameters* /*parameters*/) +bool +VCMNackFecMethod::ProtectionFactor(const VCMProtectionParameters* /*parameters*/) { // use FEC model with modification with RTT for now return true; } -bool VCMNackFecMethod::EffectivePacketLoss(const VCMProtectionParameters* /*parameters*/) +bool +VCMNackFecMethod::EffectivePacketLoss(const + VCMProtectionParameters* /*parameters*/) { // use FEC model with modification with RTT for now return true; } -bool VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) +bool +VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) { - // Hybrid Nack FEC has three operational modes: // 1. Low RTT - Nack only (Set FEC rates to zero) // 2. High RTT - FEC Only - // 3. Medium RTT values - Hybrid ; in hybrid mode, we will only nack the residual - // following the decoding of the FEC (and not in all cases, refer to JB logic) + // 3. Medium RTT values - Hybrid ; in hybrid mode, we will only nack the + // residual following the decoding of the FEC (refer to JB logic) // Low RTT - NACK only mode if (parameters->rtt < kLowRttNackMs) @@ -66,8 +71,8 @@ bool VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameter } // otherwise: we count on FEC; if the RTT is below a threshold, then we can // nack the residual, based on a decision made in the JB. - // TODO(mikhal): adapt the FEC rate based on the RTT, i.e. the the - // level on which we will rely on NACK, e.g. less as we approach upper threshold. + // TODO(mikhal): adapt the FEC rate based on the RTT, i.e. the the level on + // which we will rely on NACK, e.g. less as we approach upper threshold. VCMFecMethod fecMethod; const WebRtc_UWord8 plossMax = 129; @@ -115,13 +120,15 @@ bool VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameter // Bit cost for NackFec - // NACK cost: based on residual packet loss (since we should only NACK packets - // not recovered by FEC) + // NACK cost: based on residual packet loss (since we should only NACK + // packets not recovered by FEC) _efficiency = 0.0f; if (parameters->rtt < kHighRttNackMs) { - _efficiency = parameters->bitRate * resPacketLoss / (1.0f + resPacketLoss); - } else + _efficiency = parameters->bitRate * resPacketLoss / + (1.0f + resPacketLoss); + } + else { // efficiency based on FEC only // add FEC cost: ignore I frames for now @@ -131,10 +138,11 @@ bool VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameter } _score = _efficiency; - // 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 + // 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 WebRtc_UWord8 codeRate = protFactorK; _protectionFactorK = fecMethod.ConvertFECRate(codeRate); codeRate = protFactorD; @@ -143,23 +151,25 @@ bool VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameter return true; } -bool VCMNackMethod::EffectivePacketLoss(WebRtc_UWord8 effPacketLoss, WebRtc_UWord16 rttTime) +bool +VCMNackMethod::EffectivePacketLoss(WebRtc_UWord8 effPacketLoss, + WebRtc_UWord16 rttTime) { - WebRtc_UWord16 rttMax = MaxRttNack(); // For large RTT, we should rely on some Error Resilience, so we set // packetLossEnc = 0 for RTT less than the NACK threshold if (rttTime < rttMax) - effPacketLoss = 0; //may want a softer transition here - + { + effPacketLoss = 0; //may want a softer transition here + } _effectivePacketLoss = effPacketLoss; return true; - } -bool VCMNackMethod::UpdateParameters(const VCMProtectionParameters* parameters) +bool +VCMNackMethod::UpdateParameters(const VCMProtectionParameters* parameters) { // Compute the effective packet loss for ER WebRtc_UWord8 effPacketLoss = (WebRtc_UWord8) (255 * parameters->lossPr); @@ -167,50 +177,55 @@ bool VCMNackMethod::UpdateParameters(const VCMProtectionParameters* parameters) EffectivePacketLoss(effPacketLoss, rttTime); // Compute the NACK bit cost - _efficiency = parameters->bitRate * parameters->lossPr / (1.0f + parameters->lossPr); + _efficiency = parameters->bitRate * parameters->lossPr / + (1.0f + parameters->lossPr); _score = _efficiency; if (parameters->rtt > _NACK_MAX_RTT) { _score = 0.0f; return false; } - return true; } -WebRtc_UWord8 VCMFecMethod::BoostCodeRateKey(WebRtc_UWord8 packetFrameDelta, - WebRtc_UWord8 packetFrameKey) const +WebRtc_UWord8 +VCMFecMethod::BoostCodeRateKey(WebRtc_UWord8 packetFrameDelta, + WebRtc_UWord8 packetFrameKey) const { - WebRtc_UWord8 boostRateKey = 2; - // default: ratio scales the FEC protection up for I frames - WebRtc_UWord8 ratio = 1; + WebRtc_UWord8 boostRateKey = 2; + // default: ratio scales the FEC protection up for I frames + WebRtc_UWord8 ratio = 1; - if (packetFrameDelta > 0) - ratio = (WebRtc_Word8) (packetFrameKey / packetFrameDelta); - - ratio = VCM_MAX(boostRateKey, ratio); - - return ratio; + if (packetFrameDelta > 0) + { + ratio = (WebRtc_Word8) (packetFrameKey / packetFrameDelta); + } + ratio = VCM_MAX(boostRateKey, ratio); + return ratio; } -WebRtc_UWord8 VCMFecMethod::ConvertFECRate(WebRtc_UWord8 codeRateRTP) const +WebRtc_UWord8 +VCMFecMethod::ConvertFECRate(WebRtc_UWord8 codeRateRTP) const { - return static_cast (VCM_MIN(255,(0.5 + 255.0*codeRateRTP/(float)(255 - codeRateRTP)))); + return static_cast (VCM_MIN(255,(0.5 + 255.0 * codeRateRTP / + (float)(255 - codeRateRTP)))); } // AvgRecoveryFEC: average recovery from FEC, assuming random packet loss model // Computed offline for a range of FEC code parameters and loss rates -float VCMFecMethod::AvgRecoveryFEC(const VCMProtectionParameters* parameters) const +float +VCMFecMethod::AvgRecoveryFEC(const VCMProtectionParameters* parameters) const { - // Total (avg) bits available per frame: total rate over actual/sent frame rate - // units are kbits/frame - const WebRtc_UWord16 bitRatePerFrame = static_cast (parameters->bitRate - / (parameters->frameRate)); + // Total (avg) bits available per frame: total rate over actual/sent frame + // rate units are kbits/frame + const WebRtc_UWord16 bitRatePerFrame = static_cast + (parameters->bitRate / (parameters->frameRate)); // Total (avg) number of packets per frame (source and fec): - const WebRtc_UWord8 avgTotPackets = 1 + (WebRtc_UWord8) ((float) bitRatePerFrame * 1000.0 - / (float) (8.0 * _maxPayloadSize) + 0.5); + const WebRtc_UWord8 avgTotPackets = 1 + + (WebRtc_UWord8) ((float) bitRatePerFrame * 1000.0 + / (float) (8.0 * _maxPayloadSize) + 0.5); // parameters for tables const WebRtc_UWord8 codeSize = 24; @@ -219,51 +234,62 @@ float VCMFecMethod::AvgRecoveryFEC(const VCMProtectionParameters* parameters) co // Get index for table const float protectionFactor = (float) _protectionFactorD / (float) 255; - WebRtc_UWord8 fecPacketsPerFrame = (WebRtc_UWord8) (0.5 + protectionFactor * avgTotPackets); + WebRtc_UWord8 fecPacketsPerFrame = (WebRtc_UWord8) (0.5 + protectionFactor + * avgTotPackets); WebRtc_UWord8 sourcePacketsPerFrame = avgTotPackets - fecPacketsPerFrame; - if (fecPacketsPerFrame == 0) { - return 0.0; // no protection, so avg. recov from FEC == 0 + if (fecPacketsPerFrame == 0) + { + return 0.0; // no protection, so avg. recov from FEC == 0 } // table defined up to codeSizexcodeSize code - if (sourcePacketsPerFrame > codeSize) { - sourcePacketsPerFrame = codeSize; + if (sourcePacketsPerFrame > codeSize) + { + sourcePacketsPerFrame = codeSize; } // check: protection factor is maxed at 50%, so this should never happen - if (sourcePacketsPerFrame < 1) { - assert("average number of source packets below 1\n"); + if (sourcePacketsPerFrame < 1) + { + assert("average number of source packets below 1\n"); } // index for ER tables: up to codeSizexcodeSize mask WebRtc_UWord16 codeIndexTable[codeSize * codeSize]; WebRtc_UWord16 k = -1; - for (WebRtc_UWord8 i = 1; i <= codeSize; i++) { - for (WebRtc_UWord8 j = 1; j <= i; j++) { - k += 1; - codeIndexTable[(j - 1) * codeSize + i - 1] = k; - } + for (WebRtc_UWord8 i = 1; i <= codeSize; i++) + { + for (WebRtc_UWord8 j = 1; j <= i; j++) + { + k += 1; + codeIndexTable[(j - 1) * codeSize + i - 1] = k; + } } - const WebRtc_UWord8 lossRate = (WebRtc_UWord8) (255.0 * parameters->lossPr + 0.5f); + const WebRtc_UWord8 lossRate = (WebRtc_UWord8) (255.0 * + parameters->lossPr + 0.5f); const WebRtc_UWord16 codeIndex = (fecPacketsPerFrame - 1) * codeSize - + (sourcePacketsPerFrame - 1); - const WebRtc_UWord16 indexTable = codeIndexTable[codeIndex] * plossMax + lossRate; + + (sourcePacketsPerFrame - 1); + const WebRtc_UWord16 indexTable = codeIndexTable[codeIndex] * plossMax + + lossRate; - const WebRtc_UWord16 codeIndex2 = (fecPacketsPerFrame) * codeSize + (sourcePacketsPerFrame); - WebRtc_UWord16 indexTable2 = codeIndexTable[codeIndex2] * plossMax + lossRate; + const WebRtc_UWord16 codeIndex2 = (fecPacketsPerFrame) * codeSize + + (sourcePacketsPerFrame); + WebRtc_UWord16 indexTable2 = codeIndexTable[codeIndex2] * plossMax + + lossRate; // checks on table index - if (indexTable >= maxErTableSize) { - assert("ER table index too large\n"); + if (indexTable >= maxErTableSize) + { + assert("ER table index too large\n"); } - if (indexTable2 >= maxErTableSize) { - indexTable2 = indexTable; + if (indexTable2 >= maxErTableSize) + { + indexTable2 = indexTable; } - // // Get the average effective packet loss recovery from FEC // this is from tables, computed using random loss model @@ -271,23 +297,24 @@ float VCMFecMethod::AvgRecoveryFEC(const VCMProtectionParameters* parameters) co WebRtc_UWord8 avgFecRecov2 = 0; float avgFecRecov = 0; - if (fecPacketsPerFrame > 0) { - avgFecRecov1 = VCMAvgFECRecoveryXOR[indexTable]; - avgFecRecov2 = VCMAvgFECRecoveryXOR[indexTable2]; + if (fecPacketsPerFrame > 0) + { + avgFecRecov1 = VCMAvgFECRecoveryXOR[indexTable]; + avgFecRecov2 = VCMAvgFECRecoveryXOR[indexTable2]; } // interpolate over two FEC codes const float weightRpl = (float) (0.5 + protectionFactor * avgTotPackets) - (float) fecPacketsPerFrame; - avgFecRecov = (float) weightRpl * (float) avgFecRecov2 + (float) (1.0 - weightRpl) - * (float) avgFecRecov1; + avgFecRecov = (float) weightRpl * (float) avgFecRecov2 + (float) + (1.0 - weightRpl) * (float) avgFecRecov1; return avgFecRecov; } -bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) +bool +VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { - // FEC PROTECTION SETTINGS: varies with packet loss and bitrate const float bitRate = parameters->bitRate; @@ -303,20 +330,22 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) // // Just for testing: for the case where we randomly lose slices instead of // RTP packets and use SingleMode packetization in RTP module - // const WebRtc_UWord16 slice_size = 3000/6; //corresponds to rate=1000k with 4 cores + // const WebRtc_UWord16 slice_size = 3000/6; //@ 1000k with 4 cores //float slice_mtu = (float)_maxPayloadSize/(float)slice_size; const float slice_mtu = 1.0; // - //Total (avg) bits available per frame: total rate over actual/sent frame rate - //units are kbits/frame - const WebRtc_UWord16 bitRatePerFrame = static_cast (slice_mtu * bitRate - / (parameters->frameRate)); + //Total (avg) bits available per frame: total rate over actual/sent frame + // rate. Units are kbits/frame + const WebRtc_UWord16 bitRatePerFrame = static_cast + (slice_mtu * bitRate + / (parameters->frameRate)); //Total (avg) number of packets per frame (source and fec): - const WebRtc_UWord8 avgTotPackets = 1 + (WebRtc_UWord8) ((float) bitRatePerFrame * 1000.0 - / (float) (8.0 * _maxPayloadSize) + 0.5); + const WebRtc_UWord8 avgTotPackets = 1 + (WebRtc_UWord8) + ((float) bitRatePerFrame * 1000.0 + / (float) (8.0 * _maxPayloadSize) + 0.5); // TODO(marpan): Tune model for FEC Protection. // Better modulation of protection with available bits/frame @@ -324,71 +353,88 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) // FEC Tables include this effect already, but need to tune model off-line float weight1 = 0.5; float weight2 = 0.5; - if (avgTotPackets > 4) { - weight1 = 1.0; - weight2 = 0.; + if (avgTotPackets > 4) + { + weight1 = 1.0; + weight2 = 0.; } - if (avgTotPackets > 6) { - weight1 = 1.5; - weight2 = 0.; + if (avgTotPackets > 6) + { + weight1 = 1.5; + weight2 = 0.; } - // // Fec rate parameters: for P and I frame WebRtc_UWord8 codeRateDelta = 0; WebRtc_UWord8 codeRateKey = 0; - // Get index for new table: the FEC protection depends on the (average) available bits/frame - // the range on the rate index corresponds to rates (bps) from 200k to 8000k, for 30fps + // Get index for new table: the FEC protection depends on the (average) + // available bits/frame the range on the rate index corresponds to rates + // (bps) from 200k to 8000k, for 30fps WebRtc_UWord8 rateIndexTable = - (WebRtc_UWord8) VCM_MAX(VCM_MIN((bitRatePerFrame-ratePar1)/ratePar1,ratePar2),0); + (WebRtc_UWord8) VCM_MAX(VCM_MIN((bitRatePerFrame - ratePar1) / + ratePar1, ratePar2), 0); - // Restrict packet loss range to 50 for now%: current tables defined only up to 50% - if (packetLoss >= plossMax) { - packetLoss = plossMax - 1; + // Restrict packet loss range to 50 for now%: current tables defined only + // up to 50% + if (packetLoss >= plossMax) + { + packetLoss = plossMax - 1; } WebRtc_UWord16 indexTable = rateIndexTable * plossMax + packetLoss; // check on table index - if (indexTable >= maxFecTableSize) { - assert("FEC table index too large\n"); + if (indexTable >= maxFecTableSize) + { + assert("FEC table index too large\n"); } - // // For Key frame: effectively at a higher rate, so we scale/boost the rate // index. 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. // default is 2 - const WebRtc_UWord8 packetFrameDelta = (WebRtc_UWord8) (0.5 + parameters->packetsPerFrame); - const WebRtc_UWord8 packetFrameKey = (WebRtc_UWord8) (0.5 + parameters->packetsPerFrameKey); - const WebRtc_UWord8 boostKey = BoostCodeRateKey(packetFrameDelta, packetFrameKey); - rateIndexTable - = (WebRtc_UWord8) VCM_MAX(VCM_MIN(1+(boostKey*bitRatePerFrame-ratePar1)/ratePar1,ratePar2),0); + const WebRtc_UWord8 packetFrameDelta = (WebRtc_UWord8) + (0.5 + parameters->packetsPerFrame); + const WebRtc_UWord8 packetFrameKey = (WebRtc_UWord8) + (0.5 + parameters->packetsPerFrameKey); + const WebRtc_UWord8 boostKey = BoostCodeRateKey(packetFrameDelta, + packetFrameKey); + rateIndexTable = (WebRtc_UWord8) VCM_MAX(VCM_MIN( + 1 + (boostKey * bitRatePerFrame - ratePar1) / + ratePar1,ratePar2),0); WebRtc_UWord16 indexTableKey = rateIndexTable * plossMax + packetLoss; indexTableKey = VCM_MIN(indexTableKey, maxFecTableSize); - codeRateDelta = VCMCodeRateXORTable[indexTable]; //protection factor for P frame - codeRateKey = VCMCodeRateXORTable[indexTableKey]; //protection factor for I frame + // protection factor for P frame + codeRateDelta = VCMCodeRateXORTable[indexTable]; + // protection factor for I frame + codeRateKey = VCMCodeRateXORTable[indexTableKey]; - //average with minimum protection level given by (average) total number of packets - if (packetLoss > 0) { - codeRateDelta = static_cast ((weight1 * (float) codeRateDelta + weight2 * 255.0 - / (float) avgTotPackets)); + // average with minimum protection level given by (average) total + // number of packets + if (packetLoss > 0) + { + codeRateDelta = static_cast ((weight1 * (float) + codeRateDelta + weight2 * 255.0 + / (float) avgTotPackets)); } //check limit on amount of protection for P frame; 50% is max - if (codeRateDelta >= plossMax) { - codeRateDelta = plossMax - 1; + if (codeRateDelta >= plossMax) + { + codeRateDelta = plossMax - 1; } - //make sure I frame protection is at least larger than P frame protection, and at least as high as received loss - codeRateKey - = static_cast (VCM_MAX(packetLoss,VCM_MAX(_scaleProtKey*codeRateDelta, codeRateKey))); + // make sure I frame protection is at least larger than P frame protection, + // and at least as high as received loss + codeRateKey = static_cast (VCM_MAX(packetLoss, + VCM_MAX(_scaleProtKey * codeRateDelta, codeRateKey))); //check limit on amount of protection for I frame: 50% is max - if (codeRateKey >= plossMax) { - codeRateKey = plossMax - 1; + if (codeRateKey >= plossMax) + { + codeRateKey = plossMax - 1; } _protectionFactorK = codeRateKey; @@ -398,30 +444,31 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) return true; } -bool VCMFecMethod::EffectivePacketLoss(const VCMProtectionParameters* parameters) +bool +VCMFecMethod::EffectivePacketLoss(const VCMProtectionParameters* parameters) { // ER SETTINGS: - //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 according to FilteredLoss + // 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 - //The input packet loss: + // The input packet loss: WebRtc_UWord8 effPacketLoss = (WebRtc_UWord8) (255 * parameters->lossPr); float scaleErRS = 0.5; float scaleErXOR = 0.5; float minErLevel = (float) 0.025; - //float scaleErRS = 1.0; - //float scaleErXOR = 1.0; - //float minErLevel = (float) 0.0; + // float scaleErRS = 1.0; + // float scaleErXOR = 1.0; + // float minErLevel = (float) 0.0; float avgFecRecov = 0.; - //Effective packet loss for ER: + // Effective packet loss for ER: float scaleEr = scaleErXOR; avgFecRecov = AvgRecoveryFEC(parameters); - //Residual Packet Loss: + // Residual Packet Loss: _residualPacketLoss = (float) (effPacketLoss - avgFecRecov) / (float) 255.0; //Effective Packet Loss for encoder: @@ -433,13 +480,12 @@ bool VCMFecMethod::EffectivePacketLoss(const VCMProtectionParameters* parameters } // DONE WITH ER SETTING - return true; } -bool VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) +bool +VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) { - // Compute the protection factor ProtectionFactor(parameters); @@ -449,46 +495,58 @@ bool VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters) // Compute the bit cost // Ignore key frames for now. float fecRate = static_cast (_protectionFactorD) / 255.0f; - if (fecRate >= 0.0f) { - // use this formula if the fecRate (protection factor) is defined relative to number of source packets - // this is the case for the previous tables: - // _efficiency = parameters->bitRate * ( 1.0 - 1.0 / (1.0 + fecRate)); + if (fecRate >= 0.0f) + { + // use this formula if the fecRate (protection factor) is defined + // relative to number of source packets + // this is the case for the previous tables: + // _efficiency = parameters->bitRate * ( 1.0 - 1.0 / (1.0 + fecRate)); - // in the new tables, the fecRate is defined relative to total number of packets (total rate), - // so overhead cost is: - _efficiency = parameters->bitRate * fecRate; - } else { - _efficiency = 0.0f; + // in the new tables, the fecRate is defined relative to total number of + // packets (total rate), so overhead cost is: + _efficiency = parameters->bitRate * fecRate; + } + else + { + _efficiency = 0.0f; } _score = _efficiency; - // 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 + // 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; } -bool VCMIntraReqMethod::UpdateParameters(const VCMProtectionParameters* parameters) +bool +VCMIntraReqMethod::UpdateParameters(const VCMProtectionParameters* parameters) { float packetRate = parameters->packetsPerFrame * parameters->frameRate; // Assume that all lost packets cohere to different frames float lossRate = parameters->lossPr * packetRate; - if (parameters->keyFrameSize <= 1e-3) { - _score = FLT_MAX; - return false; + if (parameters->keyFrameSize <= 1e-3) + { + _score = FLT_MAX; + return false; } _efficiency = lossRate * parameters->keyFrameSize; _score = _efficiency; - if (parameters->lossPr >= 1.0f / parameters->keyFrameSize || parameters->rtt > _IREQ_MAX_RTT) { - return false; + if (parameters->lossPr >= 1.0f / parameters->keyFrameSize || + parameters->rtt > _IREQ_MAX_RTT) + { + return false; } return true; } -bool VCMPeriodicIntraMethod::UpdateParameters(const VCMProtectionParameters* /*parameters*/) +bool +VCMPeriodicIntraMethod::UpdateParameters(const + VCMProtectionParameters* /*parameters*/) { // Periodic I-frames. The last thing we want to use. _efficiency = 0.0f; @@ -496,18 +554,23 @@ bool VCMPeriodicIntraMethod::UpdateParameters(const VCMProtectionParameters* /*p return true; } -bool VCMMbIntraRefreshMethod::UpdateParameters(const VCMProtectionParameters* parameters) +bool +VCMMbIntraRefreshMethod::UpdateParameters(const + VCMProtectionParameters* parameters) { // Assume optimal for now. - _efficiency = parameters->bitRate * parameters->lossPr / (1.0f + parameters->lossPr); + _efficiency = parameters->bitRate * parameters->lossPr / + (1.0f + parameters->lossPr); _score = _efficiency; - if (parameters->bitRate < _MBREF_MIN_BITRATE) { - return false; + if (parameters->bitRate < _MBREF_MIN_BITRATE) + { + return false; } return true; } -WebRtc_UWord16 VCMNackMethod::MaxRttNack() const +WebRtc_UWord16 +VCMNackMethod::MaxRttNack() const { return _NACK_MAX_RTT; } @@ -517,52 +580,65 @@ VCMLossProtectionLogic::~VCMLossProtectionLogic() ClearLossProtections(); } -void VCMLossProtectionLogic::ClearLossProtections() +void +VCMLossProtectionLogic::ClearLossProtections() { ListItem *item; while ((item = _availableMethods.First()) != 0) { - VCMProtectionMethod *method = static_cast (item->GetItem()); - if (method != NULL) { - delete method; + VCMProtectionMethod *method = static_cast + (item->GetItem()); + if (method != NULL) + { + delete method; } _availableMethods.PopFront(); } _selectedMethod = NULL; } -bool VCMLossProtectionLogic::AddMethod(VCMProtectionMethod *newMethod) +bool +VCMLossProtectionLogic::AddMethod(VCMProtectionMethod *newMethod) { VCMProtectionMethod *method; ListItem *item; - if (newMethod == NULL) { - return false; - } - for (item = _availableMethods.First(); item != NULL; item = _availableMethods.Next(item)) { - method = static_cast (item->GetItem()); - if (method != NULL && method->Type() == newMethod->Type()) { + if (newMethod == NULL) + { return false; - } + } + for (item = _availableMethods.First(); item != NULL; + item = _availableMethods.Next(item)) + { + method = static_cast (item->GetItem()); + if (method != NULL && method->Type() == newMethod->Type()) + { + return false; + } } _availableMethods.PushBack(newMethod); return true; - } -bool VCMLossProtectionLogic::RemoveMethod(VCMProtectionMethodEnum methodType) +bool +VCMLossProtectionLogic::RemoveMethod(VCMProtectionMethodEnum methodType) { VCMProtectionMethod *method; ListItem *item; bool foundAndRemoved = false; - for (item = _availableMethods.First(); item != NULL; item = _availableMethods.Next(item)) { - method = static_cast (item->GetItem()); - if (method != NULL && method->Type() == methodType) { - if (_selectedMethod != NULL && _selectedMethod->Type() == method->Type()) { - _selectedMethod = NULL; + for (item = _availableMethods.First(); item != NULL; + item = _availableMethods.Next(item)) + { + method = static_cast (item->GetItem()); + if (method != NULL && method->Type() == methodType) + { + if (_selectedMethod != NULL && + _selectedMethod->Type() == method->Type()) + { + _selectedMethod = NULL; + } + _availableMethods.Erase(item); + item = NULL; + delete method; + foundAndRemoved = true; } - _availableMethods.Erase(item); - item = NULL; - delete method; - foundAndRemoved = true; - } } return foundAndRemoved; } @@ -572,154 +648,199 @@ VCMLossProtectionLogic::FindMethod(VCMProtectionMethodEnum methodType) const { VCMProtectionMethod *method; ListItem *item; - for (item = _availableMethods.First(); item != NULL; item = _availableMethods.Next(item)) { - method = static_cast (item->GetItem()); - if (method != NULL && method->Type() == methodType) { - return method; - } + for (item = _availableMethods.First(); item != NULL; + item = _availableMethods.Next(item)) + { + method = static_cast (item->GetItem()); + if (method != NULL && method->Type() == methodType) + { + return method; + } } return NULL; } -float VCMLossProtectionLogic::HighestOverhead() const +float +VCMLossProtectionLogic::HighestOverhead() const { VCMProtectionMethod *method; ListItem *item; float highestOverhead = 0.0f; - for (item = _availableMethods.First(); item != NULL; item = _availableMethods.Next(item)) { - method = static_cast (item->GetItem()); - if (method != NULL && method->RequiredBitRate() > highestOverhead) { - highestOverhead = method->RequiredBitRate(); - } + for (item = _availableMethods.First(); item != NULL; + item = _availableMethods.Next(item)) + { + method = static_cast (item->GetItem()); + if (method != NULL && method->RequiredBitRate() > highestOverhead) + { + highestOverhead = method->RequiredBitRate(); + } } return highestOverhead; } -void VCMLossProtectionLogic::UpdateRtt(WebRtc_UWord32 rtt) +void +VCMLossProtectionLogic::UpdateRtt(WebRtc_UWord32 rtt) { _rtt = rtt; } -void VCMLossProtectionLogic::UpdateResidualPacketLoss(float residualPacketLoss) { +void +VCMLossProtectionLogic::UpdateResidualPacketLoss(float residualPacketLoss) +{ _residualPacketLoss = residualPacketLoss; } -void VCMLossProtectionLogic::UpdateFecType(VCMFecTypes fecType) +void +VCMLossProtectionLogic::UpdateFecType(VCMFecTypes fecType) { _fecType = fecType; } -void VCMLossProtectionLogic::UpdateLossPr(WebRtc_UWord8 lossPr255) +void +VCMLossProtectionLogic::UpdateLossPr(WebRtc_UWord8 lossPr255) { - WebRtc_UWord32 now = static_cast (VCMTickTime::MillisecondTimestamp()); + WebRtc_UWord32 now = static_cast + (VCMTickTime::MillisecondTimestamp()); UpdateMaxLossHistory(lossPr255, now); - _lossPr255.Apply(static_cast (now - _lastPrUpdateT), static_cast (lossPr255)); + _lossPr255.Apply(static_cast (now - _lastPrUpdateT), + static_cast (lossPr255)); _lastPrUpdateT = now; _lossPr = _lossPr255.Value() / 255.0f; } -void VCMLossProtectionLogic::UpdateMaxLossHistory(WebRtc_UWord8 lossPr255, WebRtc_Word64 now) +void +VCMLossProtectionLogic::UpdateMaxLossHistory(WebRtc_UWord8 lossPr255, + WebRtc_Word64 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 (WebRtc_Word32 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; + 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 (WebRtc_Word32 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; - - } + _lossPrHistory[0].lossPr255 = _shortMaxLossPr255; + _lossPrHistory[0].timeMs = now; + _shortMaxLossPr255 = 0; + } } -WebRtc_UWord8 VCMLossProtectionLogic::MaxFilteredLossPr(WebRtc_Word64 nowMs) const +WebRtc_UWord8 +VCMLossProtectionLogic::MaxFilteredLossPr(WebRtc_Word64 nowMs) const { WebRtc_UWord8 maxFound = _shortMaxLossPr255; - if (_lossPrHistory[0].timeMs == -1) { - return maxFound; + if (_lossPrHistory[0].timeMs == -1) + { + return maxFound; } - for (WebRtc_Word32 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; - } + for (WebRtc_Word32 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; + } } return maxFound; } -WebRtc_UWord8 VCMLossProtectionLogic::FilteredLoss() const +WebRtc_UWord8 +VCMLossProtectionLogic::FilteredLoss() const { - //take the average received loss //return static_cast(_lossPr255.Value() + 0.5f); //TODO: Update for hybrid //take the windowed max of the received loss - if (_selectedMethod != NULL && _selectedMethod->Type() == kFEC) { - return MaxFilteredLossPr(static_cast (VCMTickTime::MillisecondTimestamp())); - } else { - return static_cast (_lossPr255.Value() + 0.5); + if (_selectedMethod != NULL && _selectedMethod->Type() == kFEC) + { + return MaxFilteredLossPr(static_cast + (VCMTickTime::MillisecondTimestamp())); + } + else + { + return static_cast (_lossPr255.Value() + 0.5); } - } -void VCMLossProtectionLogic::UpdateFilteredLossPr(WebRtc_UWord8 packetLossEnc) +void +VCMLossProtectionLogic::UpdateFilteredLossPr(WebRtc_UWord8 packetLossEnc) { _lossPr = (float) packetLossEnc / (float) 255.0; } -void VCMLossProtectionLogic::UpdateBitRate(float bitRate) +void +VCMLossProtectionLogic::UpdateBitRate(float bitRate) { _bitRate = bitRate; } -void VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets) +void +VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets) { - WebRtc_UWord32 now = static_cast (VCMTickTime::MillisecondTimestamp()); - _packetsPerFrame.Apply(static_cast (now - _lastPacketPerFrameUpdateT), nPackets); + WebRtc_UWord32 now = static_cast + (VCMTickTime::MillisecondTimestamp()); + _packetsPerFrame.Apply(static_cast (now - + _lastPacketPerFrameUpdateT), nPackets); _lastPacketPerFrameUpdateT = now; } -void VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets) +void +VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets) { - WebRtc_UWord32 now = static_cast (VCMTickTime::MillisecondTimestamp()); - _packetsPerFrameKey.Apply(static_cast (now - _lastPacketPerFrameUpdateTKey), nPackets); + WebRtc_UWord32 now = static_cast + (VCMTickTime::MillisecondTimestamp()); + _packetsPerFrameKey.Apply(static_cast (now - + _lastPacketPerFrameUpdateTKey), nPackets); _lastPacketPerFrameUpdateTKey = now; } -void VCMLossProtectionLogic::UpdateKeyFrameSize(float keyFrameSize) +void +VCMLossProtectionLogic::UpdateKeyFrameSize(float keyFrameSize) { _keyFrameSize = keyFrameSize; } -bool VCMLossProtectionLogic::UpdateMethod(VCMProtectionMethod *newMethod /*=NULL */) +bool +VCMLossProtectionLogic::UpdateMethod(VCMProtectionMethod *newMethod /*=NULL */) { _currentParameters.rtt = _rtt; _currentParameters.lossPr = _lossPr; _currentParameters.bitRate = _bitRate; - _currentParameters.frameRate = _frameRate; //should this be named actual frame rate? + _currentParameters.frameRate = _frameRate; // rename actual frame rate? _currentParameters.keyFrameSize = _keyFrameSize; _currentParameters.fecRateDelta = _fecRateDelta; _currentParameters.fecRateKey = _fecRateKey; @@ -728,32 +849,42 @@ bool VCMLossProtectionLogic::UpdateMethod(VCMProtectionMethod *newMethod /*=NULL _currentParameters.residualPacketLoss = _residualPacketLoss; _currentParameters.fecType = _fecType; - if (newMethod == NULL) { - //_selectedMethod = _bestNotOkMethod = NULL; - VCMProtectionMethod *method; - ListItem *item; - for (item = _availableMethods.First(); item != NULL; item = _availableMethods.Next(item)) { - method = static_cast (item->GetItem()); - if (method != NULL) { - if (method->Type() == kFEC) { - _selectedMethod = method; - } - if (method->Type() == kNACK) { - _selectedMethod = method; - } - if (method->Type() == kNackFec) { - _selectedMethod = method; - } - method->UpdateParameters(&_currentParameters); + if (newMethod == NULL) + { + //_selectedMethod = _bestNotOkMethod = NULL; + VCMProtectionMethod *method; + ListItem *item; + for (item = _availableMethods.First(); item != NULL; + item = _availableMethods.Next(item)) + { + method = static_cast (item->GetItem()); + if (method != NULL) + { + if (method->Type() == kFEC) + { + _selectedMethod = method; + } + if (method->Type() == kNACK) + { + _selectedMethod = method; + } + if (method->Type() == kNackFec) + { + _selectedMethod = method; + } + method->UpdateParameters(&_currentParameters); + } } - } - if (_selectedMethod != NULL && _selectedMethod->Type() != kFEC) { - _selectedMethod = method; - } - } else { - _selectedMethod = newMethod; - _selectedMethod->UpdateParameters(&_currentParameters); - } + if (_selectedMethod != NULL && _selectedMethod->Type() != kFEC) + { + _selectedMethod = method; + } + } + else + { + _selectedMethod = newMethod; + _selectedMethod->UpdateParameters(&_currentParameters); + } return true; } @@ -765,14 +896,17 @@ VCMLossProtectionLogic::SelectedMethod() const void VCMLossProtectionLogic::Reset() { - _lastPrUpdateT = static_cast (VCMTickTime::MillisecondTimestamp()); - _lastPacketPerFrameUpdateT = static_cast (VCMTickTime::MillisecondTimestamp()); + _lastPrUpdateT = static_cast + (VCMTickTime::MillisecondTimestamp()); + _lastPacketPerFrameUpdateT = static_cast + (VCMTickTime::MillisecondTimestamp()); _lossPr255.Reset(0.9999f); _packetsPerFrame.Reset(0.9999f); _fecRateDelta = _fecRateKey = 0; - for (WebRtc_Word32 i = 0; i < kLossPrHistorySize; i++) { - _lossPrHistory[i].lossPr255 = 0; - _lossPrHistory[i].timeMs = -1; + for (WebRtc_Word32 i = 0; i < kLossPrHistorySize; i++) + { + _lossPrHistory[i].lossPr255 = 0; + _lossPrHistory[i].timeMs = -1; } _shortMaxLossPr255 = 0; ClearLossProtections();