Refactoring temporal layers implementation and adding VideoCodecMode for easier control of codec settings.
Review URL: https://webrtc-codereview.appspot.com/1105007
git-svn-id: http://webrtc.googlecode.com/svn/trunk@3528 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/video_coding/main/source/Android.mk b/webrtc/modules/video_coding/main/source/Android.mk
index 2ecf45d..9ebdbed 100644
--- a/webrtc/modules/video_coding/main/source/Android.mk
+++ b/webrtc/modules/video_coding/main/source/Android.mk
@@ -23,9 +23,7 @@
content_metrics_processing.cc \
decoding_state.cc \
encoded_frame.cc \
- exp_filter.cc \
frame_buffer.cc \
- frame_dropper.cc \
generic_decoder.cc \
generic_encoder.cc \
inter_frame_delay.cc \
@@ -57,6 +55,7 @@
$(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../../../../common_video/vplib/main/interface \
$(LOCAL_PATH)/../../../../common_video/interface \
+ $(LOCAL_PATH)/../../utility/include \
$(LOCAL_PATH)/../../../../system_wrappers/interface
LOCAL_SHARED_LIBRARIES := \
diff --git a/webrtc/modules/video_coding/main/source/exp_filter.cc b/webrtc/modules/video_coding/main/source/exp_filter.cc
deleted file mode 100644
index 1d6f9a7..0000000
--- a/webrtc/modules/video_coding/main/source/exp_filter.cc
+++ /dev/null
@@ -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 "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;
-}
-
-}
diff --git a/webrtc/modules/video_coding/main/source/exp_filter.h b/webrtc/modules/video_coding/main/source/exp_filter.h
deleted file mode 100644
index 46d206a..0000000
--- a/webrtc/modules/video_coding/main/source/exp_filter.h
+++ /dev/null
@@ -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_EXP_FILTER_H_
-#define WEBRTC_MODULES_VIDEO_CODING_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_EXP_FILTER_H_
diff --git a/webrtc/modules/video_coding/main/source/frame_dropper.cc b/webrtc/modules/video_coding/main/source/frame_dropper.cc
deleted file mode 100644
index 09d031c..0000000
--- a/webrtc/modules/video_coding/main/source/frame_dropper.cc
+++ /dev/null
@@ -1,350 +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 "frame_dropper.h"
-#include "internal_defines.h"
-#include "trace.h"
-
-namespace webrtc
-{
-
-VCMFrameDropper::VCMFrameDropper(WebRtc_Word32 vcmId)
-:
-_vcmId(vcmId),
-_keyFrameSizeAvgKbits(0.9f),
-_keyFrameRatio(0.99f),
-_dropRatio(0.9f, 0.96f),
-_enabled(true)
-{
- Reset();
-}
-
-void
-VCMFrameDropper::Reset()
-{
- _keyFrameRatio.Reset(0.99f);
- _keyFrameRatio.Apply(1.0f, 1.0f/300.0f); // 1 key frame every 10th second in 30 fps
- _keyFrameSizeAvgKbits.Reset(0.9f);
- _keyFrameCount = 0;
- _accumulator = 0.0f;
- _accumulatorMax = 150.0f; // assume 300 kb/s and 0.5 s window
- _targetBitRate = 300.0f;
- _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
- _dropCount = 0;
- _windowSize = 0.5f;
- _wasBelowMax = 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
-VCMFrameDropper::Enable(bool enable)
-{
- _enabled = enable;
-}
-
-void
-VCMFrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame)
-{
- if (!_enabled)
- {
- return;
- }
- float frameSizeKbits = 8.0f * static_cast<float>(frameSizeBytes) / 1000.0f;
- if (!deltaFrame && !_fastMode) // fast mode does not treat key-frames any different
- {
- _keyFrameSizeAvgKbits.Apply(1, frameSizeKbits);
- _keyFrameRatio.Apply(1.0, 1.0);
- if (frameSizeKbits > _keyFrameSizeAvgKbits.Value())
- {
- // Remove the average key frame size since we
- // compensate for key frames when adding delta
- // frames.
- frameSizeKbits -= _keyFrameSizeAvgKbits.Value();
- }
- else
- {
- // Shouldn't be negative, so zero is the lower bound.
- frameSizeKbits = 0;
- }
- if (_keyFrameRatio.Value() > 1e-5 && 1 / _keyFrameRatio.Value() < _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<WebRtc_Word32>(1 / _keyFrameRatio.Value() + 0.5);
- }
- else
- {
- // Compensate for the key frame the following frames
- _keyFrameCount = static_cast<WebRtc_Word32>(_keyFrameSpreadFrames + 0.5);
- }
- }
- else
- {
- // Decrease the keyFrameRatio
- _keyFrameRatio.Apply(1.0, 0.0);
- }
- // Change the level of the accumulator (bucket)
- _accumulator += frameSizeKbits;
- CapAccumulator();
-}
-
-void
-VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate)
-{
- if (!_enabled)
- {
- return;
- }
- if (inputFrameRate < 1)
- {
- return;
- }
- if (_targetBitRate < 0.0f)
- {
- return;
- }
- _keyFrameSpreadFrames = 0.5f * inputFrameRate;
- // T is the expected bits per frame (target). If all frames were the same size,
- // we would get T bits per frame. Notice that T is also weighted to be able to
- // force a lower frame rate if wanted.
- float T = _targetBitRate / inputFrameRate;
- if (_keyFrameCount > 0)
- {
- // Perform the key frame compensation
- if (_keyFrameRatio.Value() > 0 && 1 / _keyFrameRatio.Value() < _keyFrameSpreadFrames)
- {
- T -= _keyFrameSizeAvgKbits.Value() * _keyFrameRatio.Value();
- }
- else
- {
- T -= _keyFrameSizeAvgKbits.Value() / _keyFrameSpreadFrames;
- }
- _keyFrameCount--;
- }
- _accumulator -= T;
- UpdateRatio();
-}
-
-void
-VCMFrameDropper::UpdateNack(WebRtc_UWord32 nackBytes)
-{
- if (!_enabled)
- {
- return;
- }
- _accumulator += static_cast<float>(nackBytes) * 8.0f / 1000.0f;
-}
-
-void
-VCMFrameDropper::FillBucket(float inKbits, float outKbits)
-{
- _accumulator += (inKbits - outKbits);
-}
-
-void
-VCMFrameDropper::UpdateRatio()
-{
- if (_accumulator > 1.3f * _accumulatorMax)
- {
- // Too far above accumulator max, react faster
- _dropRatio.UpdateBase(0.8f);
- }
- else
- {
- // Go back to normal reaction
- _dropRatio.UpdateBase(0.9f);
- }
- if (_accumulator > _accumulatorMax)
- {
- // We are above accumulator max, and should ideally
- // drop a frame. Increase the dropRatio and drop
- // the frame later.
- if (_wasBelowMax)
- {
- _dropNext = true;
- }
- if (_fastMode)
- {
- // always drop in aggressive mode
- _dropNext = true;
- }
-
- _dropRatio.Apply(1.0f, 1.0f);
- _dropRatio.UpdateBase(0.9f);
- }
- else
- {
- _dropRatio.Apply(1.0f, 0.0f);
- }
- if (_accumulator < 0.0f)
- {
- _accumulator = 0.0f;
- }
- _wasBelowMax = _accumulator < _accumulatorMax;
- WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, VCMId(_vcmId), "FrameDropper: dropRatio = %f accumulator = %f, accumulatorMax = %f", _dropRatio.Value(), _accumulator, _accumulatorMax);
-}
-
-// This function signals when to drop frames to the caller. It makes use of the dropRatio
-// to smooth out the drops over time.
-bool
-VCMFrameDropper::DropFrame()
-{
- if (!_enabled)
- {
- return false;
- }
- if (_dropNext)
- {
- _dropNext = false;
- _dropCount = 0;
- }
-
- if (_dropRatio.Value() >= 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();
- if (denom < 1e-5)
- {
- 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.
- if (_dropRatio.Value() > 0.4f)
- {
- _dropCount = -_dropCount;
- }
- else
- {
- _dropCount = 0;
- }
- }
- if (_dropCount < limit)
- {
- // As long we are below the limit we should drop frames.
- _dropCount++;
- return true;
- }
- else
- {
- // Only when we reset _dropCount a frame should be kept.
- _dropCount = 0;
- return false;
- }
- }
- else if (_dropRatio.Value() > 0.0f && _dropRatio.Value() < 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();
- if (denom < 1e-5)
- {
- denom = (float)1e-5;
- }
- WebRtc_Word32 limit = -static_cast<WebRtc_Word32>(1.0f / denom - 1.0f + 0.5f);
- if (_dropCount > 0)
- {
- // Reset the _dropCount since we have a positive
- // _dropCount, and it should be negative.
- if (_dropRatio.Value() < 0.6f)
- {
- _dropCount = -_dropCount;
- }
- else
- {
- _dropCount = 0;
- }
- }
- if (_dropCount > limit)
- {
- if (_dropCount == 0)
- {
- // Drop frames when we reset _dropCount.
- _dropCount--;
- return true;
- }
- else
- {
- // Keep frames as long as we haven't reached limit.
- _dropCount--;
- return false;
- }
- }
- else
- {
- _dropCount = 0;
- return false;
- }
- }
- _dropCount = 0;
- return false;
-
- // A simpler version, unfiltered and quicker
- //bool dropNext = _dropNext;
- //_dropNext = false;
- //return dropNext;
-}
-
-void
-VCMFrameDropper::SetRates(float bitRate, float incoming_frame_rate)
-{
- // Bit rate of -1 means infinite bandwidth.
- _accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds)
- if (_targetBitRate > 0.0f && bitRate < _targetBitRate && _accumulator > _accumulatorMax)
- {
- // Rescale the accumulator level if the accumulator max decreases
- _accumulator = bitRate / _targetBitRate * _accumulator;
- }
- _targetBitRate = bitRate;
- CapAccumulator();
- _incoming_frame_rate = incoming_frame_rate;
-}
-
-float
-VCMFrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const
-{
- if (!_enabled)
- {
- return static_cast<float>(inputFrameRate);
- }
- 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;
- }
-}
-
-}
diff --git a/webrtc/modules/video_coding/main/source/frame_dropper.h b/webrtc/modules/video_coding/main/source/frame_dropper.h
deleted file mode 100644
index fdf024c..0000000
--- a/webrtc/modules/video_coding/main/source/frame_dropper.h
+++ /dev/null
@@ -1,98 +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_FRAME_DROPPER_H_
-#define WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_
-
-#include "exp_filter.h"
-#include "typedefs.h"
-
-namespace webrtc
-{
-
-/******************************/
-/* VCMFrameDropper class */
-/****************************/
-// The Frame Dropper implements a variant of the leaky bucket algorithm
-// for keeping track of when to drop frames to avoid bit rate
-// over use when the encoder can't keep its bit rate.
-class VCMFrameDropper
-{
-public:
- VCMFrameDropper(WebRtc_Word32 vcmId = 0);
- // Resets the FrameDropper to its initial state.
- // This means that the frameRateWeight is set to its
- // default value as well.
- void Reset();
-
- void Enable(bool enable);
- // Answers the question if it's time to drop a frame
- // if we want to reach a given frame rate. Must be
- // called for every frame.
- //
- // Return value : True if we should drop the current frame
- bool DropFrame();
- // Updates the FrameDropper with the size of the latest encoded
- // frame. The FrameDropper calculates a new drop ratio (can be
- // seen as the probability to drop a frame) and updates its
- // internal statistics.
- //
- // Input:
- // - frameSizeBytes : The size of the latest frame
- // returned from the encoder.
- // - deltaFrame : True if the encoder returned
- // a key frame.
- void Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame);
-
- void Leak(WebRtc_UWord32 inputFrameRate);
-
- void UpdateNack(WebRtc_UWord32 nackBytes);
-
- // Sets the target bit rate and the frame rate produced by
- // the camera.
- //
- // Input:
- // - bitRate : The target bit rate
- 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;
- VCMExpFilter _keyFrameRatio;
- float _keyFrameSpreadFrames;
- WebRtc_Word32 _keyFrameCount;
- float _accumulator;
- float _accumulatorMax;
- float _targetBitRate;
- bool _dropNext;
- VCMExpFilter _dropRatio;
- WebRtc_Word32 _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
-
-#endif // WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_
diff --git a/webrtc/modules/video_coding/main/source/media_opt_util.h b/webrtc/modules/video_coding/main/source/media_opt_util.h
index 7cf97fb..f4a8ba4 100644
--- a/webrtc/modules/video_coding/main/source/media_opt_util.h
+++ b/webrtc/modules/video_coding/main/source/media_opt_util.h
@@ -11,15 +11,14 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
#define WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
-#include "typedefs.h"
-#include "trace.h"
-#include "exp_filter.h"
-#include "internal_defines.h"
-#include "qm_select.h"
-
#include <cmath>
#include <cstdlib>
+#include "webrtc/modules/video_coding/utility/include/exp_filter.h"
+#include "webrtc/modules/video_coding/main/source/internal_defines.h"
+#include "webrtc/modules/video_coding/main/source/qm_select.h"
+#include "webrtc/system_wrappers/interface/trace.h"
+#include "webrtc/typedefs.h"
namespace webrtc
{
diff --git a/webrtc/modules/video_coding/main/source/media_optimization.cc b/webrtc/modules/video_coding/main/source/media_optimization.cc
index dd428b4..8836fd8 100644
--- a/webrtc/modules/video_coding/main/source/media_optimization.cc
+++ b/webrtc/modules/video_coding/main/source/media_optimization.cc
@@ -8,11 +8,11 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "media_optimization.h"
+#include "webrtc/modules/video_coding/main/source/media_optimization.h"
-#include "content_metrics_processing.h"
-#include "frame_dropper.h"
-#include "qm_select.h"
+#include "webrtc/modules/video_coding/utility/include/frame_dropper.h"
+#include "webrtc/modules/video_coding/main/source/content_metrics_processing.h"
+#include "webrtc/modules/video_coding/main/source/qm_select.h"
#include "webrtc/system_wrappers/interface/clock.h"
namespace webrtc {
@@ -45,7 +45,7 @@
memset(_sendStatistics, 0, sizeof(_sendStatistics));
memset(_incomingFrameTimes, -1, sizeof(_incomingFrameTimes));
- _frameDropper = new VCMFrameDropper(_id);
+ _frameDropper = new FrameDropper;
_lossProtLogic = new VCMLossProtectionLogic(_clock->TimeInMilliseconds());
_content = new VCMContentMetricsProcessing();
_qmResolution = new VCMQmResolution();
diff --git a/webrtc/modules/video_coding/main/source/media_optimization.h b/webrtc/modules/video_coding/main/source/media_optimization.h
index a642c5d..e0d67b1 100644
--- a/webrtc/modules/video_coding/main/source/media_optimization.h
+++ b/webrtc/modules/video_coding/main/source/media_optimization.h
@@ -24,8 +24,8 @@
enum { kBitrateAverageWinMs = 1000 };
class Clock;
+class FrameDropper;
class VCMContentMetricsProcessing;
-class VCMFrameDropper;
struct VCMEncodedFrameSample
{
@@ -170,7 +170,7 @@
WebRtc_UWord16 _codecHeight;
float _userFrameRate;
- VCMFrameDropper* _frameDropper;
+ FrameDropper* _frameDropper;
VCMLossProtectionLogic* _lossProtLogic;
WebRtc_UWord8 _fractionLost;
diff --git a/webrtc/modules/video_coding/main/source/video_coding.gypi b/webrtc/modules/video_coding/main/source/video_coding.gypi
index fab85dd..3f5eb35 100644
--- a/webrtc/modules/video_coding/main/source/video_coding.gypi
+++ b/webrtc/modules/video_coding/main/source/video_coding.gypi
@@ -14,6 +14,7 @@
'dependencies': [
'webrtc_i420',
'<(webrtc_root)/common_video/common_video.gyp:common_video',
+ '<(webrtc_root)/modules/video_coding/utility/video_coding_utility.gyp:video_coding_utility',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
'<(webrtc_vp8_dir)/vp8.gyp:webrtc_vp8',
],
@@ -42,10 +43,8 @@
'encoded_frame.h',
'er_tables_xor.h',
'event.h',
- 'exp_filter.h',
'fec_tables_xor.h',
'frame_buffer.h',
- 'frame_dropper.h',
'generic_decoder.h',
'generic_encoder.h',
'inter_frame_delay.h',
@@ -73,9 +72,7 @@
'content_metrics_processing.cc',
'decoding_state.cc',
'encoded_frame.cc',
- 'exp_filter.cc',
'frame_buffer.cc',
- 'frame_dropper.cc',
'generic_decoder.cc',
'generic_encoder.cc',
'inter_frame_delay.cc',