Put some bounds on VCM frame dropper.

Review URL: https://webrtc-codereview.appspot.com/873005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2893 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
marpan@webrtc.org 2012-10-09 20:43:56 +00:00
parent 71c13765ad
commit 1dd8d4bca4
3 changed files with 35 additions and 11 deletions

View File

@ -35,8 +35,8 @@ VCMFrameDropper::Reset()
_accumulator = 0.0f;
_accumulatorMax = 150.0f; // assume 300 kb/s and 0.5 s window
_targetBitRate = 300.0f;
_userFrameRate = 30;
_keyFrameSpreadFrames = 0.5f * _userFrameRate;
_incoming_frame_rate = 30;
_keyFrameSpreadFrames = 0.5f * _incoming_frame_rate;
_dropNext = false;
_dropRatio.Reset(0.9f);
_dropRatio.Apply(0.0f, 0.0f); // Initialize to 0
@ -45,6 +45,10 @@ VCMFrameDropper::Reset()
_wasBelowMax = true;
_enabled = true;
_fastMode = false; // start with normal (non-aggressive) mode
// Cap for the encoder buffer level/accumulator, in secs.
_cap_buffer_size = 3.0f;
// Cap on maximum amount of dropped frames between kept frames, in secs.
_max_time_drops = 4.0f;
}
void
@ -98,6 +102,7 @@ VCMFrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame)
}
// Change the level of the accumulator (bucket)
_accumulator += frameSizeKbits;
CapAccumulator();
}
void
@ -135,7 +140,6 @@ VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate)
}
_accumulator -= T;
UpdateRatio();
}
void
@ -222,6 +226,13 @@ VCMFrameDropper::DropFrame()
denom = (float)1e-5;
}
WebRtc_Word32 limit = static_cast<WebRtc_Word32>(1.0f / denom - 1.0f + 0.5f);
// Put a bound on the max amount of dropped frames between each kept
// frame, in terms of frame rate and window size (secs).
int max_limit = static_cast<int>(_incoming_frame_rate *
_max_time_drops);
if (limit > max_limit) {
limit = max_limit;
}
if (_dropCount < 0)
{
// Reset the _dropCount since it was negative and should be positive.
@ -302,7 +313,7 @@ VCMFrameDropper::DropFrame()
}
void
VCMFrameDropper::SetRates(float bitRate, float userFrameRate)
VCMFrameDropper::SetRates(float bitRate, float incoming_frame_rate)
{
// Bit rate of -1 means infinite bandwidth.
_accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds)
@ -312,10 +323,8 @@ VCMFrameDropper::SetRates(float bitRate, float userFrameRate)
_accumulator = bitRate / _targetBitRate * _accumulator;
}
_targetBitRate = bitRate;
if (userFrameRate > 0.0f)
{
_userFrameRate = userFrameRate;
}
CapAccumulator();
_incoming_frame_rate = incoming_frame_rate;
}
float
@ -328,4 +337,14 @@ VCMFrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const
return inputFrameRate * (1.0f - _dropRatio.Value());
}
// Put a cap on the accumulator, i.e., don't let it grow beyond some level.
// This is a temporary fix for screencasting where very large frames from
// encoder will cause very slow response (too many frame drops).
void VCMFrameDropper::CapAccumulator() {
float max_accumulator = _targetBitRate * _cap_buffer_size;
if (_accumulator > max_accumulator) {
_accumulator = max_accumulator;
}
}
}

View File

@ -60,16 +60,18 @@ public:
//
// Input:
// - bitRate : The target bit rate
void SetRates(float bitRate, float userFrameRate);
void SetRates(float bitRate, float incoming_frame_rate);
// Return value : The current average frame rate produced
// if the DropFrame() function is used as
// instruction of when to drop frames.
float ActualFrameRate(WebRtc_UWord32 inputFrameRate) const;
private:
void FillBucket(float inKbits, float outKbits);
void UpdateRatio();
void CapAccumulator();
WebRtc_Word32 _vcmId;
VCMExpFilter _keyFrameSizeAvgKbits;
@ -83,10 +85,12 @@ private:
VCMExpFilter _dropRatio;
WebRtc_Word32 _dropCount;
float _windowSize;
float _userFrameRate;
float _incoming_frame_rate;
bool _wasBelowMax;
bool _enabled;
bool _fastMode;
float _cap_buffer_size;
float _max_time_drops;
}; // end of VCMFrameDropper class
} // namespace webrtc

View File

@ -176,7 +176,8 @@ VCMMediaOptimization::SetTargetRates(WebRtc_UWord32 bitRate,
_targetBitRate = bitRate - protection_overhead_kbps;
// Update encoding rates following protection settings
_frameDropper->SetRates(static_cast<float>(_targetBitRate), 0);
_frameDropper->SetRates(static_cast<float>(_targetBitRate),
_incomingFrameRate);
if (_enableQm)
{