Fix bug on key frame boost allocation, and some update/cleanup to same function.
Review URL: http://webrtc-codereview.appspot.com/50001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@123 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
3c45dfd178
commit
0d7e5bc712
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VCMProtectionMethod::BetterThan(VCMProtectionMethod *pm)
|
VCMProtectionMethod::BetterThan(VCMProtectionMethod *pm)
|
||||||
{
|
{
|
||||||
@ -317,9 +316,16 @@ VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
|
|||||||
{
|
{
|
||||||
// FEC PROTECTION SETTINGS: varies with packet loss and bitrate
|
// FEC PROTECTION SETTINGS: varies with packet loss and bitrate
|
||||||
|
|
||||||
const float bitRate = parameters->bitRate;
|
|
||||||
WebRtc_UWord8 packetLoss = (WebRtc_UWord8) (255 * parameters->lossPr);
|
WebRtc_UWord8 packetLoss = (WebRtc_UWord8) (255 * parameters->lossPr);
|
||||||
|
|
||||||
|
// No protection if (filtered) packetLoss is 0
|
||||||
|
if (packetLoss == 0)
|
||||||
|
{
|
||||||
|
_protectionFactorK = 0;
|
||||||
|
_protectionFactorD = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Size of tables
|
// Size of tables
|
||||||
const WebRtc_UWord16 maxFecTableSize = 6450;
|
const WebRtc_UWord16 maxFecTableSize = 6450;
|
||||||
// Parameters for range of rate and packet loss for tables
|
// Parameters for range of rate and packet loss for tables
|
||||||
@ -327,36 +333,36 @@ VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
|
|||||||
const WebRtc_UWord8 ratePar2 = 49;
|
const WebRtc_UWord8 ratePar2 = 49;
|
||||||
const WebRtc_UWord8 plossMax = 129;
|
const WebRtc_UWord8 plossMax = 129;
|
||||||
|
|
||||||
//
|
const float bitRate = parameters->bitRate;
|
||||||
// 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; //@ 1000k with 4 cores
|
|
||||||
|
|
||||||
//float slice_mtu = (float)_maxPayloadSize/(float)slice_size;
|
// Total (avg) bits available per frame: total rate over actual/frame_rate.
|
||||||
const float slice_mtu = 1.0;
|
// Units are kbits/frame
|
||||||
//
|
|
||||||
|
|
||||||
//Total (avg) bits available per frame: total rate over actual/sent frame
|
|
||||||
// rate. Units are kbits/frame
|
|
||||||
const WebRtc_UWord16 bitRatePerFrame = static_cast<WebRtc_UWord16>
|
const WebRtc_UWord16 bitRatePerFrame = static_cast<WebRtc_UWord16>
|
||||||
(slice_mtu * bitRate
|
(bitRate /
|
||||||
/ (parameters->frameRate));
|
(parameters->frameRate));
|
||||||
|
|
||||||
//Total (avg) number of packets per frame (source and fec):
|
// Total (avg) number of packets per frame (source and fec):
|
||||||
const WebRtc_UWord8 avgTotPackets = 1 + (WebRtc_UWord8)
|
const WebRtc_UWord8 avgTotPackets = 1 + (WebRtc_UWord8)
|
||||||
((float) bitRatePerFrame * 1000.0
|
((float) bitRatePerFrame * 1000.0
|
||||||
/ (float) (8.0 * _maxPayloadSize) + 0.5);
|
/ (float) (8.0 * _maxPayloadSize) + 0.5);
|
||||||
|
|
||||||
// TODO(marpan): Tune model for FEC Protection.
|
|
||||||
// Better modulation of protection with available bits/frame
|
// First partition protection: ~ 20%
|
||||||
// (or avgTotpackets) using weight factors
|
WebRtc_UWord8 firstPartitionProt = (WebRtc_UWord8) (255 * 0.20);
|
||||||
// FEC Tables include this effect already, but need to tune model off-line
|
|
||||||
|
// Threshold on packetLoss and bitRrate/frameRate (=average #packets),
|
||||||
|
// above which we allocate protection to cover at least roughly
|
||||||
|
// first partition size.
|
||||||
|
WebRtc_UWord8 lossThr = 0;
|
||||||
|
WebRtc_UWord8 packetNumThr = 1;
|
||||||
|
|
||||||
|
// Modulation of protection with available bits/frame (or avgTotpackets)
|
||||||
float weight1 = 0.5;
|
float weight1 = 0.5;
|
||||||
float weight2 = 0.5;
|
float weight2 = 0.5;
|
||||||
if (avgTotPackets > 4)
|
if (avgTotPackets > 4)
|
||||||
{
|
{
|
||||||
weight1 = 1.0;
|
weight1 = 0.75;
|
||||||
weight2 = 0.;
|
weight2 = 0.25;
|
||||||
}
|
}
|
||||||
if (avgTotPackets > 6)
|
if (avgTotPackets > 6)
|
||||||
{
|
{
|
||||||
@ -364,41 +370,62 @@ VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
|
|||||||
weight2 = 0.;
|
weight2 = 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fec rate parameters: for P and I frame
|
// FEC rate parameters: for P and I frame
|
||||||
WebRtc_UWord8 codeRateDelta = 0;
|
WebRtc_UWord8 codeRateDelta = 0;
|
||||||
WebRtc_UWord8 codeRateKey = 0;
|
WebRtc_UWord8 codeRateKey = 0;
|
||||||
|
|
||||||
// Get index for new table: the FEC protection depends on the (average)
|
// Get index for table: the FEC protection depends on the (average)
|
||||||
// available bits/frame the range on the rate index corresponds to rates
|
// available bits/frame. The range on the rate index corresponds to rates
|
||||||
// (bps) from 200k to 8000k, for 30fps
|
// (bps) from 200k to 8000k, for 30fps
|
||||||
WebRtc_UWord8 rateIndexTable =
|
WebRtc_UWord8 rateIndexTable =
|
||||||
(WebRtc_UWord8) VCM_MAX(VCM_MIN((bitRatePerFrame - ratePar1) /
|
(WebRtc_UWord8) VCM_MAX(VCM_MIN((bitRatePerFrame - ratePar1) /
|
||||||
ratePar1, ratePar2), 0);
|
ratePar1, ratePar2), 0);
|
||||||
|
|
||||||
// Restrict packet loss range to 50 for now%: current tables defined only
|
// Restrict packet loss range to 50:
|
||||||
// up to 50%
|
// current tables defined only up to 50%
|
||||||
if (packetLoss >= plossMax)
|
if (packetLoss >= plossMax)
|
||||||
{
|
{
|
||||||
packetLoss = plossMax - 1;
|
packetLoss = plossMax - 1;
|
||||||
}
|
}
|
||||||
WebRtc_UWord16 indexTable = rateIndexTable * plossMax + packetLoss;
|
WebRtc_UWord16 indexTable = rateIndexTable * plossMax + packetLoss;
|
||||||
|
|
||||||
// check on table index
|
// Check on table index
|
||||||
if (indexTable >= maxFecTableSize)
|
assert(indexTable < maxFecTableSize);
|
||||||
|
|
||||||
|
// Protection factor for P frame
|
||||||
|
codeRateDelta = VCMCodeRateXORTable[indexTable];
|
||||||
|
|
||||||
|
if (packetLoss > lossThr && avgTotPackets > packetNumThr)
|
||||||
{
|
{
|
||||||
assert("FEC table index too large\n");
|
// Average with minimum protection level given by (average) total
|
||||||
|
// number of packets
|
||||||
|
codeRateDelta = static_cast<WebRtc_UWord8>((weight1 *
|
||||||
|
(float) codeRateDelta + weight2 * 255.0 / (float) avgTotPackets));
|
||||||
|
|
||||||
|
// Set a minimum based on first partition size.
|
||||||
|
if (codeRateDelta < firstPartitionProt)
|
||||||
|
{
|
||||||
|
codeRateDelta = firstPartitionProt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Key frame: effectively at a higher rate, so we scale/boost the rate
|
// Check limit on amount of protection for P frame; 50% is max.
|
||||||
// index. The boost factor may depend on several factors: ratio of packet
|
if (codeRateDelta >= plossMax)
|
||||||
|
{
|
||||||
|
codeRateDelta = plossMax - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
// number of I to P frames, how much protection placed on P frames, etc.
|
||||||
// default is 2
|
|
||||||
const WebRtc_UWord8 packetFrameDelta = (WebRtc_UWord8)
|
const WebRtc_UWord8 packetFrameDelta = (WebRtc_UWord8)
|
||||||
(0.5 + parameters->packetsPerFrame);
|
(0.5 + parameters->packetsPerFrame);
|
||||||
const WebRtc_UWord8 packetFrameKey = (WebRtc_UWord8)
|
const WebRtc_UWord8 packetFrameKey = (WebRtc_UWord8)
|
||||||
(0.5 + parameters->packetsPerFrameKey);
|
(0.5 + parameters->packetsPerFrameKey);
|
||||||
const WebRtc_UWord8 boostKey = BoostCodeRateKey(packetFrameDelta,
|
const WebRtc_UWord8 boostKey = BoostCodeRateKey(packetFrameDelta,
|
||||||
packetFrameKey);
|
packetFrameKey);
|
||||||
|
|
||||||
rateIndexTable = (WebRtc_UWord8) VCM_MAX(VCM_MIN(
|
rateIndexTable = (WebRtc_UWord8) VCM_MAX(VCM_MIN(
|
||||||
1 + (boostKey * bitRatePerFrame - ratePar1) /
|
1 + (boostKey * bitRatePerFrame - ratePar1) /
|
||||||
ratePar1,ratePar2),0);
|
ratePar1,ratePar2),0);
|
||||||
@ -406,32 +433,25 @@ VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
|
|||||||
|
|
||||||
indexTableKey = VCM_MIN(indexTableKey, maxFecTableSize);
|
indexTableKey = VCM_MIN(indexTableKey, maxFecTableSize);
|
||||||
|
|
||||||
// protection factor for P frame
|
// Check on table index
|
||||||
codeRateDelta = VCMCodeRateXORTable[indexTable];
|
assert(indexTableKey < maxFecTableSize);
|
||||||
// protection factor for I frame
|
|
||||||
|
// Protection factor for I frame
|
||||||
codeRateKey = VCMCodeRateXORTable[indexTableKey];
|
codeRateKey = VCMCodeRateXORTable[indexTableKey];
|
||||||
|
|
||||||
// average with minimum protection level given by (average) total
|
// Boosting for Key frame.
|
||||||
// number of packets
|
WebRtc_UWord32 boostKeyProt = _scaleProtKey * codeRateDelta;
|
||||||
if (packetLoss > 0)
|
if ( boostKeyProt >= plossMax)
|
||||||
{
|
{
|
||||||
codeRateDelta = static_cast<WebRtc_UWord8> ((weight1 * (float)
|
boostKeyProt = plossMax - 1;
|
||||||
codeRateDelta + weight2 * 255.0
|
|
||||||
/ (float) avgTotPackets));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//check limit on amount of protection for P frame; 50% is max
|
// Make sure I frame protection is at least larger than P frame protection,
|
||||||
if (codeRateDelta >= plossMax)
|
// and at least as high as filtered packet loss.
|
||||||
{
|
|
||||||
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<WebRtc_UWord8> (VCM_MAX(packetLoss,
|
codeRateKey = static_cast<WebRtc_UWord8> (VCM_MAX(packetLoss,
|
||||||
VCM_MAX(_scaleProtKey * codeRateDelta, codeRateKey)));
|
VCM_MAX(boostKeyProt, codeRateKey)));
|
||||||
|
|
||||||
//check limit on amount of protection for I frame: 50% is max
|
// Check limit on amount of protection for I frame: 50% is max.
|
||||||
if (codeRateKey >= plossMax)
|
if (codeRateKey >= plossMax)
|
||||||
{
|
{
|
||||||
codeRateKey = plossMax - 1;
|
codeRateKey = plossMax - 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user