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; _accumulator = 0.0f;
_accumulatorMax = 150.0f; // assume 300 kb/s and 0.5 s window _accumulatorMax = 150.0f; // assume 300 kb/s and 0.5 s window
_targetBitRate = 300.0f; _targetBitRate = 300.0f;
_userFrameRate = 30; _incoming_frame_rate = 30;
_keyFrameSpreadFrames = 0.5f * _userFrameRate; _keyFrameSpreadFrames = 0.5f * _incoming_frame_rate;
_dropNext = false; _dropNext = false;
_dropRatio.Reset(0.9f); _dropRatio.Reset(0.9f);
_dropRatio.Apply(0.0f, 0.0f); // Initialize to 0 _dropRatio.Apply(0.0f, 0.0f); // Initialize to 0
@ -45,6 +45,10 @@ VCMFrameDropper::Reset()
_wasBelowMax = true; _wasBelowMax = true;
_enabled = true; _enabled = true;
_fastMode = false; // start with normal (non-aggressive) mode _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 void
@ -98,6 +102,7 @@ VCMFrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame)
} }
// Change the level of the accumulator (bucket) // Change the level of the accumulator (bucket)
_accumulator += frameSizeKbits; _accumulator += frameSizeKbits;
CapAccumulator();
} }
void void
@ -135,7 +140,6 @@ VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate)
} }
_accumulator -= T; _accumulator -= T;
UpdateRatio(); UpdateRatio();
} }
void void
@ -222,6 +226,13 @@ VCMFrameDropper::DropFrame()
denom = (float)1e-5; denom = (float)1e-5;
} }
WebRtc_Word32 limit = static_cast<WebRtc_Word32>(1.0f / denom - 1.0f + 0.5f); 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) if (_dropCount < 0)
{ {
// Reset the _dropCount since it was negative and should be positive. // Reset the _dropCount since it was negative and should be positive.
@ -302,7 +313,7 @@ VCMFrameDropper::DropFrame()
} }
void void
VCMFrameDropper::SetRates(float bitRate, float userFrameRate) VCMFrameDropper::SetRates(float bitRate, float incoming_frame_rate)
{ {
// Bit rate of -1 means infinite bandwidth. // Bit rate of -1 means infinite bandwidth.
_accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds) _accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds)
@ -312,10 +323,8 @@ VCMFrameDropper::SetRates(float bitRate, float userFrameRate)
_accumulator = bitRate / _targetBitRate * _accumulator; _accumulator = bitRate / _targetBitRate * _accumulator;
} }
_targetBitRate = bitRate; _targetBitRate = bitRate;
if (userFrameRate > 0.0f) CapAccumulator();
{ _incoming_frame_rate = incoming_frame_rate;
_userFrameRate = userFrameRate;
}
} }
float float
@ -328,4 +337,14 @@ VCMFrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const
return inputFrameRate * (1.0f - _dropRatio.Value()); 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: // Input:
// - bitRate : The target bit rate // - 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 // Return value : The current average frame rate produced
// if the DropFrame() function is used as // if the DropFrame() function is used as
// instruction of when to drop frames. // instruction of when to drop frames.
float ActualFrameRate(WebRtc_UWord32 inputFrameRate) const; float ActualFrameRate(WebRtc_UWord32 inputFrameRate) const;
private: private:
void FillBucket(float inKbits, float outKbits); void FillBucket(float inKbits, float outKbits);
void UpdateRatio(); void UpdateRatio();
void CapAccumulator();
WebRtc_Word32 _vcmId; WebRtc_Word32 _vcmId;
VCMExpFilter _keyFrameSizeAvgKbits; VCMExpFilter _keyFrameSizeAvgKbits;
@ -83,10 +85,12 @@ private:
VCMExpFilter _dropRatio; VCMExpFilter _dropRatio;
WebRtc_Word32 _dropCount; WebRtc_Word32 _dropCount;
float _windowSize; float _windowSize;
float _userFrameRate; float _incoming_frame_rate;
bool _wasBelowMax; bool _wasBelowMax;
bool _enabled; bool _enabled;
bool _fastMode; bool _fastMode;
float _cap_buffer_size;
float _max_time_drops;
}; // end of VCMFrameDropper class }; // end of VCMFrameDropper class
} // namespace webrtc } // namespace webrtc

View File

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