Raw packet loss rate reported by RTP_RTCP module may vary too drastically over time. This CL is to add a filter to the value in VoE before lending it to audio coding module.

The filter is an exponential filter borrowed from video coding module.

The method is written in a new class called PacketLossProtector (not sure if the name is nice), which can be used in the future for more sophisticated logic.

BUG=
R=henrika@webrtc.org, stefan@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6709 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
minyue@webrtc.org
2014-07-16 21:28:26 +00:00
parent 4c3e9917e7
commit 74aaf29a0f
20 changed files with 391 additions and 204 deletions

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/video_coding/utility/include/exp_filter.h"
#include <math.h>
namespace webrtc {
void
VCMExpFilter::Reset(float alpha)
{
_alpha = alpha;
_filtered = -1.0;
}
float
VCMExpFilter::Apply(float exp, float sample)
{
if (_filtered == -1.0)
{
// Initialize filtered bit rates
_filtered = sample;
}
else if (exp == 1.0)
{
_filtered = _alpha * _filtered + (1 - _alpha) * sample;
}
else
{
float alpha = pow(_alpha, exp);
_filtered = alpha * _filtered + (1 - alpha) * sample;
}
if (_max != -1 && _filtered > _max)
{
_filtered = _max;
}
return _filtered;
}
void
VCMExpFilter::UpdateBase(float alpha)
{
_alpha = alpha;
}
float
VCMExpFilter::Value() const
{
return _filtered;
}
}

View File

@ -86,25 +86,27 @@ FrameDropper::Fill(uint32_t frameSizeBytes, bool deltaFrame)
{
_keyFrameSizeAvgKbits.Apply(1, frameSizeKbits);
_keyFrameRatio.Apply(1.0, 1.0);
if (frameSizeKbits > _keyFrameSizeAvgKbits.Value())
if (frameSizeKbits > _keyFrameSizeAvgKbits.filtered())
{
// Remove the average key frame size since we
// compensate for key frames when adding delta
// frames.
frameSizeKbits -= _keyFrameSizeAvgKbits.Value();
frameSizeKbits -= _keyFrameSizeAvgKbits.filtered();
}
else
{
// Shouldn't be negative, so zero is the lower bound.
frameSizeKbits = 0;
}
if (_keyFrameRatio.Value() > 1e-5 && 1 / _keyFrameRatio.Value() < _keyFrameSpreadFrames)
if (_keyFrameRatio.filtered() > 1e-5 &&
1 / _keyFrameRatio.filtered() < _keyFrameSpreadFrames)
{
// We are sending key frames more often than our upper bound for
// how much we allow the key frame compensation to be spread
// out in time. Therefor we must use the key frame ratio rather
// than keyFrameSpreadFrames.
_keyFrameCount = static_cast<int32_t>(1 / _keyFrameRatio.Value() + 0.5);
_keyFrameCount =
static_cast<int32_t>(1 / _keyFrameRatio.filtered() + 0.5);
}
else
{
@ -145,13 +147,14 @@ FrameDropper::Leak(uint32_t inputFrameRate)
if (_keyFrameCount > 0)
{
// Perform the key frame compensation
if (_keyFrameRatio.Value() > 0 && 1 / _keyFrameRatio.Value() < _keyFrameSpreadFrames)
if (_keyFrameRatio.filtered() > 0 &&
1 / _keyFrameRatio.filtered() < _keyFrameSpreadFrames)
{
T -= _keyFrameSizeAvgKbits.Value() * _keyFrameRatio.Value();
T -= _keyFrameSizeAvgKbits.filtered() * _keyFrameRatio.filtered();
}
else
{
T -= _keyFrameSizeAvgKbits.Value() / _keyFrameSpreadFrames;
T -= _keyFrameSizeAvgKbits.filtered() / _keyFrameSpreadFrames;
}
_keyFrameCount--;
}
@ -232,11 +235,11 @@ FrameDropper::DropFrame()
_dropCount = 0;
}
if (_dropRatio.Value() >= 0.5f) // Drops per keep
if (_dropRatio.filtered() >= 0.5f) // Drops per keep
{
// limit is the number of frames we should drop between each kept frame
// to keep our drop ratio. limit is positive in this case.
float denom = 1.0f - _dropRatio.Value();
float denom = 1.0f - _dropRatio.filtered();
if (denom < 1e-5)
{
denom = (float)1e-5;
@ -252,7 +255,7 @@ FrameDropper::DropFrame()
if (_dropCount < 0)
{
// Reset the _dropCount since it was negative and should be positive.
if (_dropRatio.Value() > 0.4f)
if (_dropRatio.filtered() > 0.4f)
{
_dropCount = -_dropCount;
}
@ -274,12 +277,13 @@ FrameDropper::DropFrame()
return false;
}
}
else if (_dropRatio.Value() > 0.0f && _dropRatio.Value() < 0.5f) // Keeps per drop
else if (_dropRatio.filtered() > 0.0f &&
_dropRatio.filtered() < 0.5f) // Keeps per drop
{
// limit is the number of frames we should keep between each drop
// in order to keep the drop ratio. limit is negative in this case,
// and the _dropCount is also negative.
float denom = _dropRatio.Value();
float denom = _dropRatio.filtered();
if (denom < 1e-5)
{
denom = (float)1e-5;
@ -289,7 +293,7 @@ FrameDropper::DropFrame()
{
// Reset the _dropCount since we have a positive
// _dropCount, and it should be negative.
if (_dropRatio.Value() < 0.6f)
if (_dropRatio.filtered() < 0.6f)
{
_dropCount = -_dropCount;
}
@ -350,7 +354,7 @@ FrameDropper::ActualFrameRate(uint32_t inputFrameRate) const
{
return static_cast<float>(inputFrameRate);
}
return inputFrameRate * (1.0f - _dropRatio.Value());
return inputFrameRate * (1.0f - _dropRatio.filtered());
}
// Put a cap on the accumulator, i.e., don't let it grow beyond some level.

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_
#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_
namespace webrtc
{
/**********************/
/* ExpFilter class */
/**********************/
class VCMExpFilter
{
public:
VCMExpFilter(float alpha, float max = -1.0) : _alpha(alpha), _filtered(-1.0), _max(max) {}
// Resets the filter to its initial state, and resets alpha to the given value
//
// Input:
// - alpha : the new value of the filter factor base.
void Reset(float alpha);
// Applies the filter with the given exponent on the provided sample
//
// Input:
// - exp : Exponent T in y(k) = alpha^T * y(k-1) + (1 - alpha^T) * x(k)
// - sample : x(k) in the above filter equation
float Apply(float exp, float sample);
// Return current filtered value: y(k)
//
// Return value : The current filter output
float Value() const;
// Change the filter factor base
//
// Input:
// - alpha : The new filter factor base.
void UpdateBase(float alpha);
private:
float _alpha; // Filter factor base
float _filtered; // Current filter output
const float _max;
}; // end of ExpFilter class
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_

View File

@ -11,7 +11,7 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_
#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_
#include "webrtc/modules/video_coding/utility/include/exp_filter.h"
#include "webrtc/base/exp_filter.h"
#include "webrtc/typedefs.h"
namespace webrtc
@ -72,23 +72,23 @@ private:
void UpdateRatio();
void CapAccumulator();
VCMExpFilter _keyFrameSizeAvgKbits;
VCMExpFilter _keyFrameRatio;
float _keyFrameSpreadFrames;
int32_t _keyFrameCount;
float _accumulator;
float _accumulatorMax;
float _targetBitRate;
bool _dropNext;
VCMExpFilter _dropRatio;
int32_t _dropCount;
float _windowSize;
float _incoming_frame_rate;
bool _wasBelowMax;
bool _enabled;
bool _fastMode;
float _cap_buffer_size;
float _max_time_drops;
rtc::ExpFilter _keyFrameSizeAvgKbits;
rtc::ExpFilter _keyFrameRatio;
float _keyFrameSpreadFrames;
int32_t _keyFrameCount;
float _accumulator;
float _accumulatorMax;
float _targetBitRate;
bool _dropNext;
rtc::ExpFilter _dropRatio;
int32_t _dropCount;
float _windowSize;
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

@ -18,9 +18,7 @@
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
'sources': [
'include/exp_filter.h',
'include/frame_dropper.h',
'exp_filter.cc',
'frame_dropper.cc',
],
},