diff options
Diffstat (limited to 'webrtc/modules/video_coding/utility')
15 files changed, 482 insertions, 578 deletions
diff --git a/webrtc/modules/video_coding/utility/frame_dropper.cc b/webrtc/modules/video_coding/utility/frame_dropper.cc index 5262c5b88a..a0aa67be4e 100644 --- a/webrtc/modules/video_coding/utility/frame_dropper.cc +++ b/webrtc/modules/video_coding/utility/frame_dropper.cc @@ -8,12 +8,11 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/video_coding/utility/include/frame_dropper.h" +#include "webrtc/modules/video_coding/utility/frame_dropper.h" #include "webrtc/system_wrappers/include/trace.h" -namespace webrtc -{ +namespace webrtc { const float kDefaultKeyFrameSizeAvgKBits = 0.9f; const float kDefaultKeyFrameRatio = 0.99f; @@ -22,339 +21,266 @@ const float kDefaultDropRatioMax = 0.96f; const float kDefaultMaxTimeToDropFrames = 4.0f; // In seconds. FrameDropper::FrameDropper() -: -_keyFrameSizeAvgKbits(kDefaultKeyFrameSizeAvgKBits), -_keyFrameRatio(kDefaultKeyFrameRatio), -_dropRatio(kDefaultDropRatioAlpha, kDefaultDropRatioMax), -_enabled(true), -_max_time_drops(kDefaultMaxTimeToDropFrames) -{ - Reset(); + : _keyFrameSizeAvgKbits(kDefaultKeyFrameSizeAvgKBits), + _keyFrameRatio(kDefaultKeyFrameRatio), + _dropRatio(kDefaultDropRatioAlpha, kDefaultDropRatioMax), + _enabled(true), + _max_time_drops(kDefaultMaxTimeToDropFrames) { + Reset(); } FrameDropper::FrameDropper(float max_time_drops) -: -_keyFrameSizeAvgKbits(kDefaultKeyFrameSizeAvgKBits), -_keyFrameRatio(kDefaultKeyFrameRatio), -_dropRatio(kDefaultDropRatioAlpha, kDefaultDropRatioMax), -_enabled(true), -_max_time_drops(max_time_drops) -{ - Reset(); + : _keyFrameSizeAvgKbits(kDefaultKeyFrameSizeAvgKBits), + _keyFrameRatio(kDefaultKeyFrameRatio), + _dropRatio(kDefaultDropRatioAlpha, kDefaultDropRatioMax), + _enabled(true), + _max_time_drops(max_time_drops) { + Reset(); } -void -FrameDropper::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 FrameDropper::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 -FrameDropper::Enable(bool enable) -{ - _enabled = enable; +void FrameDropper::Enable(bool enable) { + _enabled = enable; } -void -FrameDropper::Fill(size_t 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.filtered()) - { - // Remove the average key frame size since we - // compensate for key frames when adding delta - // frames. - frameSizeKbits -= _keyFrameSizeAvgKbits.filtered(); - } - else - { - // Shouldn't be negative, so zero is the lower bound. - frameSizeKbits = 0; - } - 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.filtered() + 0.5); - } - else - { - // Compensate for the key frame the following frames - _keyFrameCount = static_cast<int32_t>(_keyFrameSpreadFrames + 0.5); - } +void FrameDropper::Fill(size_t 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.filtered()) { + // Remove the average key frame size since we + // compensate for key frames when adding delta + // frames. + frameSizeKbits -= _keyFrameSizeAvgKbits.filtered(); + } else { + // Shouldn't be negative, so zero is the lower bound. + frameSizeKbits = 0; } - else - { - // Decrease the keyFrameRatio - _keyFrameRatio.Apply(1.0, 0.0); + 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.filtered() + 0.5); + } else { + // Compensate for the key frame the following frames + _keyFrameCount = static_cast<int32_t>(_keyFrameSpreadFrames + 0.5); } - // Change the level of the accumulator (bucket) - _accumulator += frameSizeKbits; - CapAccumulator(); + } else { + // Decrease the keyFrameRatio + _keyFrameRatio.Apply(1.0, 0.0); + } + // Change the level of the accumulator (bucket) + _accumulator += frameSizeKbits; + CapAccumulator(); } -void -FrameDropper::Leak(uint32_t 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.filtered() > 0 && - 1 / _keyFrameRatio.filtered() < _keyFrameSpreadFrames) - { - T -= _keyFrameSizeAvgKbits.filtered() * _keyFrameRatio.filtered(); - } - else - { - T -= _keyFrameSizeAvgKbits.filtered() / _keyFrameSpreadFrames; - } - _keyFrameCount--; - } - _accumulator -= T; - if (_accumulator < 0.0f) - { - _accumulator = 0.0f; +void FrameDropper::Leak(uint32_t 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.filtered() > 0 && + 1 / _keyFrameRatio.filtered() < _keyFrameSpreadFrames) { + T -= _keyFrameSizeAvgKbits.filtered() * _keyFrameRatio.filtered(); + } else { + T -= _keyFrameSizeAvgKbits.filtered() / _keyFrameSpreadFrames; } - UpdateRatio(); + _keyFrameCount--; + } + _accumulator -= T; + if (_accumulator < 0.0f) { + _accumulator = 0.0f; + } + UpdateRatio(); } -void -FrameDropper::UpdateNack(uint32_t nackBytes) -{ - if (!_enabled) - { - return; - } - _accumulator += static_cast<float>(nackBytes) * 8.0f / 1000.0f; +void FrameDropper::UpdateNack(uint32_t nackBytes) { + if (!_enabled) { + return; + } + _accumulator += static_cast<float>(nackBytes) * 8.0f / 1000.0f; } -void -FrameDropper::FillBucket(float inKbits, float outKbits) -{ - _accumulator += (inKbits - outKbits); +void FrameDropper::FillBucket(float inKbits, float outKbits) { + _accumulator += (inKbits - outKbits); } -void -FrameDropper::UpdateRatio() -{ - if (_accumulator > 1.3f * _accumulatorMax) - { - // Too far above accumulator max, react faster - _dropRatio.UpdateBase(0.8f); +void FrameDropper::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; } - else - { - // Go back to normal reaction - _dropRatio.UpdateBase(0.9f); + if (_fastMode) { + // always drop in aggressive mode + _dropNext = true; } - 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); - } - _wasBelowMax = _accumulator < _accumulatorMax; + _dropRatio.Apply(1.0f, 1.0f); + _dropRatio.UpdateBase(0.9f); + } else { + _dropRatio.Apply(1.0f, 0.0f); + } + _wasBelowMax = _accumulator < _accumulatorMax; } -// This function signals when to drop frames to the caller. It makes use of the dropRatio +// This function signals when to drop frames to the caller. It makes use of the +// dropRatio // to smooth out the drops over time. -bool -FrameDropper::DropFrame() -{ - if (!_enabled) - { - return false; +bool FrameDropper::DropFrame() { + if (!_enabled) { + return false; + } + if (_dropNext) { + _dropNext = false; + _dropCount = 0; + } + + 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.filtered(); + if (denom < 1e-5) { + denom = 1e-5f; + } + int32_t limit = static_cast<int32_t>(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 (_dropNext) - { - _dropNext = false; + if (_dropCount < 0) { + // Reset the _dropCount since it was negative and should be positive. + if (_dropRatio.filtered() > 0.4f) { + _dropCount = -_dropCount; + } else { _dropCount = 0; + } } - - 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.filtered(); - if (denom < 1e-5) - { - denom = (float)1e-5; - } - int32_t limit = static_cast<int32_t>(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.filtered() > 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; - } + 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.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.filtered(); - if (denom < 1e-5) - { - denom = (float)1e-5; - } - int32_t limit = -static_cast<int32_t>(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.filtered() < 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; - } + } 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.filtered(); + if (denom < 1e-5) { + denom = 1e-5f; } - _dropCount = 0; - return false; + int32_t limit = -static_cast<int32_t>(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.filtered() < 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; + // A simpler version, unfiltered and quicker + // bool dropNext = _dropNext; + // _dropNext = false; + // return dropNext; } -void -FrameDropper::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; +void FrameDropper::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 -FrameDropper::ActualFrameRate(uint32_t inputFrameRate) const -{ - if (!_enabled) - { - return static_cast<float>(inputFrameRate); - } - return inputFrameRate * (1.0f - _dropRatio.filtered()); +float FrameDropper::ActualFrameRate(uint32_t inputFrameRate) const { + if (!_enabled) { + return static_cast<float>(inputFrameRate); + } + return inputFrameRate * (1.0f - _dropRatio.filtered()); } // Put a cap on the accumulator, i.e., don't let it grow beyond some level. @@ -366,5 +292,4 @@ void FrameDropper::CapAccumulator() { _accumulator = max_accumulator; } } - -} +} // namespace webrtc diff --git a/webrtc/modules/video_coding/utility/frame_dropper.h b/webrtc/modules/video_coding/utility/frame_dropper.h new file mode 100644 index 0000000000..7ec85ea880 --- /dev/null +++ b/webrtc/modules/video_coding/utility/frame_dropper.h @@ -0,0 +1,96 @@ +/* + * 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_FRAME_DROPPER_H_ +#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_FRAME_DROPPER_H_ + +#include <cstddef> + +#include "webrtc/base/exp_filter.h" +#include "webrtc/typedefs.h" + +namespace webrtc { + +// 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 FrameDropper { + public: + FrameDropper(); + explicit FrameDropper(float max_time_drops); + virtual ~FrameDropper() {} + + // Resets the FrameDropper to its initial state. + // This means that the frameRateWeight is set to its + // default value as well. + virtual void Reset(); + + virtual 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 + virtual 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. + virtual void Fill(size_t frameSizeBytes, bool deltaFrame); + + virtual void Leak(uint32_t inputFrameRate); + + void UpdateNack(uint32_t nackBytes); + + // Sets the target bit rate and the frame rate produced by + // the camera. + // + // Input: + // - bitRate : The target bit rate + virtual 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. + virtual float ActualFrameRate(uint32_t inputFrameRate) const; + + private: + void FillBucket(float inKbits, float outKbits); + void UpdateRatio(); + void CapAccumulator(); + + 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 + +#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_FRAME_DROPPER_H_ diff --git a/webrtc/modules/video_coding/utility/include/frame_dropper.h b/webrtc/modules/video_coding/utility/include/frame_dropper.h deleted file mode 100644 index 2b78a7264f..0000000000 --- a/webrtc/modules/video_coding/utility/include/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_UTILITY_INCLUDE_FRAME_DROPPER_H_ -#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_ - -#include <cstddef> - -#include "webrtc/base/exp_filter.h" -#include "webrtc/typedefs.h" - -namespace webrtc -{ - -// 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 FrameDropper -{ -public: - FrameDropper(); - explicit FrameDropper(float max_time_drops); - virtual ~FrameDropper() {} - - // Resets the FrameDropper to its initial state. - // This means that the frameRateWeight is set to its - // default value as well. - virtual void Reset(); - - virtual 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 - virtual 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. - virtual void Fill(size_t frameSizeBytes, bool deltaFrame); - - virtual void Leak(uint32_t inputFrameRate); - - void UpdateNack(uint32_t nackBytes); - - // Sets the target bit rate and the frame rate produced by - // the camera. - // - // Input: - // - bitRate : The target bit rate - virtual 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. - virtual float ActualFrameRate(uint32_t inputFrameRate) const; - -private: - void FillBucket(float inKbits, float outKbits); - void UpdateRatio(); - void CapAccumulator(); - - 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 - -#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_ diff --git a/webrtc/modules/video_coding/utility/include/mock/mock_frame_dropper.h b/webrtc/modules/video_coding/utility/include/mock/mock_frame_dropper.h deleted file mode 100644 index 1e31e5442a..0000000000 --- a/webrtc/modules/video_coding/utility/include/mock/mock_frame_dropper.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013 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_MOCK_MOCK_FRAME_DROPPER_H_ -#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_MOCK_MOCK_FRAME_DROPPER_H_ - -#include <string> - -#include "testing/gmock/include/gmock/gmock.h" -#include "webrtc/modules/video_coding/utility/include/frame_dropper.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -class MockFrameDropper : public FrameDropper { - public: - MOCK_METHOD0(Reset, - void()); - MOCK_METHOD1(Enable, - void(bool enable)); - MOCK_METHOD0(DropFrame, - bool()); - MOCK_METHOD2(Fill, - void(size_t frameSizeBytes, bool deltaFrame)); - MOCK_METHOD1(Leak, - void(uint32_t inputFrameRate)); - MOCK_METHOD2(SetRates, - void(float bitRate, float incoming_frame_rate)); - MOCK_CONST_METHOD1(ActualFrameRate, - float(uint32_t inputFrameRate)); -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_MOCK_MOCK_FRAME_DROPPER_H_ diff --git a/webrtc/modules/video_coding/utility/include/vp8_header_parser.h b/webrtc/modules/video_coding/utility/include/vp8_header_parser.h deleted file mode 100644 index 88796ecd0e..0000000000 --- a/webrtc/modules/video_coding/utility/include/vp8_header_parser.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015 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_VP8_PARSE_HEADER_H_ -#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_VP8_PARSE_HEADER_H_ - -namespace webrtc { - -namespace vp8 { - -enum { - MB_FEATURE_TREE_PROBS = 3, - NUM_MB_SEGMENTS = 4, - NUM_REF_LF_DELTAS = 4, - NUM_MODE_LF_DELTAS = 4, -}; - -typedef struct VP8BitReader VP8BitReader; -struct VP8BitReader { - // Boolean decoder. - uint32_t value_; // Current value. - uint32_t range_; // Current range minus 1. In [127, 254] interval. - int bits_; // Number of valid bits left. - // Read buffer. - const uint8_t* buf_; // Next byte to be read. - const uint8_t* buf_end_; // End of read buffer. - int eof_; // True if input is exhausted. -}; - -const uint8_t kVP8Log2Range[128] = { - 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0 -}; - -// range = ((range - 1) << kVP8Log2Range[range]) + 1 -const uint8_t kVP8NewRange[128] = { - 127, 127, 191, 127, 159, 191, 223, 127, - 143, 159, 175, 191, 207, 223, 239, 127, - 135, 143, 151, 159, 167, 175, 183, 191, - 199, 207, 215, 223, 231, 239, 247, 127, - 131, 135, 139, 143, 147, 151, 155, 159, - 163, 167, 171, 175, 179, 183, 187, 191, - 195, 199, 203, 207, 211, 215, 219, 223, - 227, 231, 235, 239, 243, 247, 251, 127, - 129, 131, 133, 135, 137, 139, 141, 143, - 145, 147, 149, 151, 153, 155, 157, 159, - 161, 163, 165, 167, 169, 171, 173, 175, - 177, 179, 181, 183, 185, 187, 189, 191, - 193, 195, 197, 199, 201, 203, 205, 207, - 209, 211, 213, 215, 217, 219, 221, 223, - 225, 227, 229, 231, 233, 235, 237, 239, - 241, 243, 245, 247, 249, 251, 253, 127 -}; - -// Gets the QP, QP range: [0, 127]. -// Returns true on success, false otherwise. -bool GetQp(const uint8_t* buf, size_t length, int* qp); - -} // namespace vp8 - -} // namespace webrtc - -#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_VP8_PARSE_HEADER_H_ diff --git a/webrtc/modules/video_coding/utility/mock/mock_frame_dropper.h b/webrtc/modules/video_coding/utility/mock/mock_frame_dropper.h new file mode 100644 index 0000000000..b68a4b8d5d --- /dev/null +++ b/webrtc/modules/video_coding/utility/mock/mock_frame_dropper.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013 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_MOCK_MOCK_FRAME_DROPPER_H_ +#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_MOCK_MOCK_FRAME_DROPPER_H_ + +#include <string> + +#include "testing/gmock/include/gmock/gmock.h" +#include "webrtc/modules/video_coding/utility/frame_dropper.h" +#include "webrtc/typedefs.h" + +namespace webrtc { + +class MockFrameDropper : public FrameDropper { + public: + MOCK_METHOD0(Reset, void()); + MOCK_METHOD1(Enable, void(bool enable)); + MOCK_METHOD0(DropFrame, bool()); + MOCK_METHOD2(Fill, void(size_t frameSizeBytes, bool deltaFrame)); + MOCK_METHOD1(Leak, void(uint32_t inputFrameRate)); + MOCK_METHOD2(SetRates, void(float bitRate, float incoming_frame_rate)); + MOCK_CONST_METHOD1(ActualFrameRate, float(uint32_t inputFrameRate)); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_MOCK_MOCK_FRAME_DROPPER_H_ diff --git a/webrtc/modules/video_coding/utility/include/moving_average.h b/webrtc/modules/video_coding/utility/moving_average.h index 49c42c4ed4..494bfd51fb 100644 --- a/webrtc/modules/video_coding/utility/include/moving_average.h +++ b/webrtc/modules/video_coding/utility/moving_average.h @@ -16,7 +16,7 @@ #include "webrtc/typedefs.h" namespace webrtc { -template<class T> +template <class T> class MovingAverage { public: MovingAverage(); @@ -30,17 +30,17 @@ class MovingAverage { std::list<T> samples_; }; -template<class T> -MovingAverage<T>::MovingAverage() : sum_(static_cast<T>(0)) { -} +template <class T> +MovingAverage<T>::MovingAverage() + : sum_(static_cast<T>(0)) {} -template<class T> +template <class T> void MovingAverage<T>::AddSample(T sample) { samples_.push_back(sample); sum_ += sample; } -template<class T> +template <class T> bool MovingAverage<T>::GetAverage(size_t num_samples, T* avg) { if (num_samples > samples_.size()) return false; @@ -55,17 +55,17 @@ bool MovingAverage<T>::GetAverage(size_t num_samples, T* avg) { return true; } -template<class T> +template <class T> void MovingAverage<T>::Reset() { sum_ = static_cast<T>(0); samples_.clear(); } -template<class T> +template <class T> int MovingAverage<T>::size() { return samples_.size(); } } // namespace webrtc -#endif // WEBRTC_MODULES_VIDEO_CODING_MOVING_AVERAGE_SCALER_H_ +#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_MOVING_AVERAGE_H_ diff --git a/webrtc/modules/video_coding/utility/qp_parser.cc b/webrtc/modules/video_coding/utility/qp_parser.cc index 62ce31351e..0916cb0094 100644 --- a/webrtc/modules/video_coding/utility/qp_parser.cc +++ b/webrtc/modules/video_coding/utility/qp_parser.cc @@ -8,10 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/video_coding/utility/include/qp_parser.h" +#include "webrtc/modules/video_coding/utility/qp_parser.h" #include "webrtc/common_types.h" -#include "webrtc/modules/video_coding/utility/include/vp8_header_parser.h" +#include "webrtc/modules/video_coding/utility/vp8_header_parser.h" namespace webrtc { diff --git a/webrtc/modules/video_coding/utility/include/qp_parser.h b/webrtc/modules/video_coding/utility/qp_parser.h index 805b37b45c..0b644ef61c 100644 --- a/webrtc/modules/video_coding/utility/include/qp_parser.h +++ b/webrtc/modules/video_coding/utility/qp_parser.h @@ -11,7 +11,7 @@ #ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_QP_PARSER_H_ #define WEBRTC_MODULES_VIDEO_CODING_UTILITY_QP_PARSER_H_ -#include "webrtc/modules/video_coding/main/source/encoded_frame.h" +#include "webrtc/modules/video_coding/encoded_frame.h" namespace webrtc { diff --git a/webrtc/modules/video_coding/utility/quality_scaler.cc b/webrtc/modules/video_coding/utility/quality_scaler.cc index ec7715230e..76bf9f5b03 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler.cc +++ b/webrtc/modules/video_coding/utility/quality_scaler.cc @@ -7,7 +7,7 @@ * 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/quality_scaler.h" +#include "webrtc/modules/video_coding/utility/quality_scaler.h" namespace webrtc { @@ -26,8 +26,7 @@ QualityScaler::QualityScaler() downscale_shift_(0), framerate_down_(false), min_width_(kDefaultMinDownscaleDimension), - min_height_(kDefaultMinDownscaleDimension) { -} + min_height_(kDefaultMinDownscaleDimension) {} void QualityScaler::Init(int low_qp_threshold, int high_qp_threshold, @@ -91,7 +90,7 @@ void QualityScaler::OnEncodeFrame(const VideoFrame& frame) { AdjustScale(false); } } else if (average_qp_.GetAverage(num_samples_, &avg_qp) && - avg_qp <= low_qp_threshold_) { + avg_qp <= low_qp_threshold_) { if (use_framerate_reduction_ && framerate_down_) { target_framerate_ = -1; framerate_down_ = false; @@ -104,7 +103,7 @@ void QualityScaler::OnEncodeFrame(const VideoFrame& frame) { assert(downscale_shift_ >= 0); for (int shift = downscale_shift_; shift > 0 && (res_.width / 2 >= min_width_) && - (res_.height / 2 >= min_height_); + (res_.height / 2 >= min_height_); --shift) { res_.width /= 2; res_.height /= 2; @@ -124,13 +123,8 @@ const VideoFrame& QualityScaler::GetScaledFrame(const VideoFrame& frame) { if (res.width == frame.width()) return frame; - scaler_.Set(frame.width(), - frame.height(), - res.width, - res.height, - kI420, - kI420, - kScaleBox); + scaler_.Set(frame.width(), frame.height(), res.width, res.height, kI420, + kI420, kScaleBox); if (scaler_.Scale(frame, &scaled_frame_) != 0) return frame; diff --git a/webrtc/modules/video_coding/utility/include/quality_scaler.h b/webrtc/modules/video_coding/utility/quality_scaler.h index 29a1496c05..a1233cca51 100644 --- a/webrtc/modules/video_coding/utility/include/quality_scaler.h +++ b/webrtc/modules/video_coding/utility/quality_scaler.h @@ -12,7 +12,7 @@ #define WEBRTC_MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_ #include "webrtc/common_video/libyuv/include/scaler.h" -#include "webrtc/modules/video_coding/utility/include/moving_average.h" +#include "webrtc/modules/video_coding/utility/moving_average.h" namespace webrtc { class QualityScaler { diff --git a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc index 2ce1107472..bad73a748c 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc +++ b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/video_coding/utility/include/quality_scaler.h" +#include "webrtc/modules/video_coding/utility/quality_scaler.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,6 +33,7 @@ class QualityScalerTest : public ::testing::Test { int width; int height; }; + protected: enum ScaleDirection { kKeepScaleAtHighQp, @@ -43,8 +44,8 @@ class QualityScalerTest : public ::testing::Test { enum BadQualityMetric { kDropFrame, kReportLowQP }; QualityScalerTest() { - input_frame_.CreateEmptyFrame( - kWidth, kHeight, kWidth, kHalfWidth, kHalfWidth); + input_frame_.CreateEmptyFrame(kWidth, kHeight, kWidth, kHalfWidth, + kHalfWidth); qs_.Init(kMaxQp / QualityScaler::kDefaultLowQpDenominator, kHighQp, false); qs_.ReportFramerate(kFramerate); qs_.OnEncodeFrame(input_frame_); @@ -97,7 +98,8 @@ class QualityScalerTest : public ::testing::Test { int num_second, int initial_framerate); - void VerifyQualityAdaptation(int initial_framerate, int seconds, + void VerifyQualityAdaptation(int initial_framerate, + int seconds, bool expect_spatial_resize, bool expect_framerate_reduction); @@ -183,8 +185,8 @@ TEST_F(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) { void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() { const int initial_min_dimension = input_frame_.width() < input_frame_.height() - ? input_frame_.width() - : input_frame_.height(); + ? input_frame_.width() + : input_frame_.height(); int min_dimension = initial_min_dimension; int current_shift = 0; // Drop all frames to force-trigger downscaling. @@ -229,14 +231,14 @@ TEST_F(QualityScalerTest, const int kOddWidth = 517; const int kHalfOddWidth = (kOddWidth + 1) / 2; const int kOddHeight = 1239; - input_frame_.CreateEmptyFrame( - kOddWidth, kOddHeight, kOddWidth, kHalfOddWidth, kHalfOddWidth); + input_frame_.CreateEmptyFrame(kOddWidth, kOddHeight, kOddWidth, kHalfOddWidth, + kHalfOddWidth); ContinuouslyDownscalesByHalfDimensionsAndBackUp(); } void QualityScalerTest::DoesNotDownscaleFrameDimensions(int width, int height) { - input_frame_.CreateEmptyFrame( - width, height, width, (width + 1) / 2, (width + 1) / 2); + input_frame_.CreateEmptyFrame(width, height, width, (width + 1) / 2, + (width + 1) / 2); for (int i = 0; i < kFramerate * kNumSeconds; ++i) { qs_.ReportDroppedFrame(); @@ -259,7 +261,9 @@ TEST_F(QualityScalerTest, DoesNotDownscaleFrom1Px) { } QualityScalerTest::Resolution QualityScalerTest::TriggerResolutionChange( - BadQualityMetric dropframe_lowqp, int num_second, int initial_framerate) { + BadQualityMetric dropframe_lowqp, + int num_second, + int initial_framerate) { QualityScalerTest::Resolution res; res.framerate = initial_framerate; qs_.OnEncodeFrame(input_frame_); @@ -288,7 +292,9 @@ QualityScalerTest::Resolution QualityScalerTest::TriggerResolutionChange( } void QualityScalerTest::VerifyQualityAdaptation( - int initial_framerate, int seconds, bool expect_spatial_resize, + int initial_framerate, + int seconds, + bool expect_spatial_resize, bool expect_framerate_reduction) { const int kDisabledBadQpThreshold = kMaxQp + 1; qs_.Init(kMaxQp / QualityScaler::kDefaultLowQpDenominator, @@ -298,8 +304,8 @@ void QualityScalerTest::VerifyQualityAdaptation( int init_height = qs_.GetScaledResolution().height; // Test reducing framerate by dropping frame continuously. - QualityScalerTest::Resolution res = TriggerResolutionChange( - kDropFrame, seconds, initial_framerate); + QualityScalerTest::Resolution res = + TriggerResolutionChange(kDropFrame, seconds, initial_framerate); if (expect_framerate_reduction) { EXPECT_LT(res.framerate, initial_framerate); diff --git a/webrtc/modules/video_coding/utility/video_coding_utility.gyp b/webrtc/modules/video_coding/utility/video_coding_utility.gyp index f0764bb7bf..42cbb3d4e0 100644 --- a/webrtc/modules/video_coding/utility/video_coding_utility.gyp +++ b/webrtc/modules/video_coding/utility/video_coding_utility.gyp @@ -19,14 +19,14 @@ ], 'sources': [ 'frame_dropper.cc', - 'include/frame_dropper.h', - 'include/moving_average.h', - 'include/qp_parser.h', - 'include/quality_scaler.h', - 'include/vp8_header_parser.h', + 'frame_dropper.h', + 'moving_average.h', 'qp_parser.cc', + 'qp_parser.h', 'quality_scaler.cc', + 'quality_scaler.h', 'vp8_header_parser.cc', + 'vp8_header_parser.h', ], }, ], # targets diff --git a/webrtc/modules/video_coding/utility/vp8_header_parser.cc b/webrtc/modules/video_coding/utility/vp8_header_parser.cc index dc5a0e5d15..631385d0f2 100644 --- a/webrtc/modules/video_coding/utility/vp8_header_parser.cc +++ b/webrtc/modules/video_coding/utility/vp8_header_parser.cc @@ -7,12 +7,9 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#include <stdint.h> -#include <stdio.h> +#include "webrtc/modules/video_coding/utility/vp8_header_parser.h" -#include "webrtc/modules/video_coding/utility/include/vp8_header_parser.h" - -#include "webrtc/system_wrappers/include/logging.h" +#include "webrtc/base/logging.h" namespace webrtc { @@ -46,12 +43,12 @@ static void VP8LoadNewBytes(VP8BitReader* const br) { const uint32_t in_bits = *(const uint32_t*)(br->buf_); br->buf_ += BITS >> 3; #if defined(WEBRTC_ARCH_BIG_ENDIAN) - bits = static_cast<uint32_t>(in_bits); - if (BITS != 8 * sizeof(uint32_t)) - bits >>= (8 * sizeof(uint32_t) - BITS); + bits = static_cast<uint32_t>(in_bits); + if (BITS != 8 * sizeof(uint32_t)) + bits >>= (8 * sizeof(uint32_t) - BITS); #else - bits = BSwap32(in_bits); - bits >>= 32 - BITS; + bits = BSwap32(in_bits); + bits >>= 32 - BITS; #endif br->value_ = bits | (br->value_ << BITS); br->bits_ += BITS; @@ -63,12 +60,12 @@ static void VP8LoadNewBytes(VP8BitReader* const br) { static void VP8InitBitReader(VP8BitReader* const br, const uint8_t* const start, const uint8_t* const end) { - br->range_ = 255 - 1; - br->buf_ = start; + br->range_ = 255 - 1; + br->buf_ = start; br->buf_end_ = end; - br->value_ = 0; - br->bits_ = -8; // To load the very first 8bits. - br->eof_ = 0; + br->value_ = 0; + br->bits_ = -8; // To load the very first 8bits. + br->eof_ = 0; VP8LoadNewBytes(br); } @@ -125,7 +122,7 @@ static void ParseSegmentHeader(VP8BitReader* br) { int s; VP8Get(br); for (s = 0; s < NUM_MB_SEGMENTS; ++s) { - VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; + VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; } for (s = 0; s < NUM_MB_SEGMENTS; ++s) { VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; diff --git a/webrtc/modules/video_coding/utility/vp8_header_parser.h b/webrtc/modules/video_coding/utility/vp8_header_parser.h new file mode 100644 index 0000000000..b0c684c578 --- /dev/null +++ b/webrtc/modules/video_coding/utility/vp8_header_parser.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 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_VP8_HEADER_PARSER_H_ +#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_VP8_HEADER_PARSER_H_ + +#include <stdint.h> +#include <stdio.h> + +namespace webrtc { + +namespace vp8 { + +enum { + MB_FEATURE_TREE_PROBS = 3, + NUM_MB_SEGMENTS = 4, + NUM_REF_LF_DELTAS = 4, + NUM_MODE_LF_DELTAS = 4, +}; + +typedef struct VP8BitReader VP8BitReader; +struct VP8BitReader { + // Boolean decoder. + uint32_t value_; // Current value. + uint32_t range_; // Current range minus 1. In [127, 254] interval. + int bits_; // Number of valid bits left. + // Read buffer. + const uint8_t* buf_; // Next byte to be read. + const uint8_t* buf_end_; // End of read buffer. + int eof_; // True if input is exhausted. +}; + +const uint8_t kVP8Log2Range[128] = { + 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; + +// range = ((range - 1) << kVP8Log2Range[range]) + 1 +const uint8_t kVP8NewRange[128] = { + 127, 127, 191, 127, 159, 191, 223, 127, 143, 159, 175, 191, 207, 223, 239, + 127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239, + 247, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, + 183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, + 243, 247, 251, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, + 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, + 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, + 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, + 241, 243, 245, 247, 249, 251, 253, 127}; + +// Gets the QP, QP range: [0, 127]. +// Returns true on success, false otherwise. +bool GetQp(const uint8_t* buf, size_t length, int* qp); + +} // namespace vp8 + +} // namespace webrtc + +#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_VP8_HEADER_PARSER_H_ |