Reset estimate if no frame has been seen for a certain time (to avoid large jitter if stop sending).
Add delay before start processing after a reset. BUG=1577 R=mflodman@webrtc.org, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/8699006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5561 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
92fdfebedd
commit
b60346e951
@ -29,11 +29,16 @@ namespace webrtc {
|
||||
namespace {
|
||||
const int64_t kProcessIntervalMs = 5000;
|
||||
|
||||
// Number of initial process times before reporting.
|
||||
const int64_t kMinProcessCountBeforeReporting = 3;
|
||||
|
||||
const int64_t kFrameTimeoutIntervalMs = 1500;
|
||||
|
||||
// Consecutive checks above threshold to trigger overuse.
|
||||
const int kConsecutiveChecksAboveThreshold = 2;
|
||||
|
||||
// Minimum samples required to perform a check.
|
||||
const size_t kMinFrameSampleCount = 15;
|
||||
const size_t kMinFrameSampleCount = 120;
|
||||
|
||||
// Weight factor to apply to the standard deviation.
|
||||
const float kWeightFactor = 0.997f;
|
||||
@ -238,9 +243,11 @@ OveruseFrameDetector::OveruseFrameDetector(Clock* clock,
|
||||
: crit_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
normaluse_stddev_ms_(normaluse_stddev_ms),
|
||||
overuse_stddev_ms_(overuse_stddev_ms),
|
||||
min_process_count_before_reporting_(kMinProcessCountBeforeReporting),
|
||||
observer_(NULL),
|
||||
clock_(clock),
|
||||
next_process_time_(clock_->TimeInMilliseconds()),
|
||||
num_process_times_(0),
|
||||
last_capture_time_(0),
|
||||
last_overuse_time_(0),
|
||||
checks_above_threshold_(0),
|
||||
@ -288,26 +295,34 @@ int32_t OveruseFrameDetector::TimeUntilNextProcess() {
|
||||
return next_process_time_ - clock_->TimeInMilliseconds();
|
||||
}
|
||||
|
||||
bool OveruseFrameDetector::DetectFrameTimeout(int64_t now) const {
|
||||
if (last_capture_time_ == 0) {
|
||||
return false;
|
||||
}
|
||||
return (now - last_capture_time_) > kFrameTimeoutIntervalMs;
|
||||
}
|
||||
|
||||
void OveruseFrameDetector::FrameCaptured(int width, int height) {
|
||||
CriticalSectionScoped cs(crit_.get());
|
||||
|
||||
int64_t now = clock_->TimeInMilliseconds();
|
||||
int num_pixels = width * height;
|
||||
if (num_pixels != num_pixels_) {
|
||||
if (num_pixels != num_pixels_ || DetectFrameTimeout(now)) {
|
||||
// Frame size changed, reset statistics.
|
||||
num_pixels_ = num_pixels;
|
||||
capture_deltas_.Reset();
|
||||
last_capture_time_ = 0;
|
||||
capture_queue_delay_->ClearFrames();
|
||||
num_process_times_ = 0;
|
||||
}
|
||||
|
||||
int64_t time = clock_->TimeInMilliseconds();
|
||||
if (last_capture_time_ != 0) {
|
||||
capture_deltas_.AddSample(time - last_capture_time_);
|
||||
encode_usage_->AddSample(time - last_capture_time_);
|
||||
capture_deltas_.AddSample(now - last_capture_time_);
|
||||
encode_usage_->AddSample(now - last_capture_time_);
|
||||
}
|
||||
last_capture_time_ = time;
|
||||
last_capture_time_ = now;
|
||||
|
||||
capture_queue_delay_->FrameCaptured(time);
|
||||
capture_queue_delay_->FrameCaptured(now);
|
||||
}
|
||||
|
||||
void OveruseFrameDetector::FrameProcessingStarted() {
|
||||
@ -342,6 +357,7 @@ int32_t OveruseFrameDetector::Process() {
|
||||
|
||||
int64_t diff_ms = now - next_process_time_ + kProcessIntervalMs;
|
||||
next_process_time_ = now + kProcessIntervalMs;
|
||||
++num_process_times_;
|
||||
|
||||
// Don't trigger overuse unless we've seen a certain number of frames.
|
||||
if (capture_deltas_.Count() < kMinFrameSampleCount)
|
||||
@ -349,6 +365,10 @@ int32_t OveruseFrameDetector::Process() {
|
||||
|
||||
capture_queue_delay_->CalculateDelayChange(diff_ms);
|
||||
|
||||
if (num_process_times_ <= min_process_count_before_reporting_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IsOverusing()) {
|
||||
// If the last thing we did was going up, and now have to back down, we need
|
||||
// to check if this peak was short. If so we should back off to avoid going
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "webrtc/modules/interface/module.h"
|
||||
#include "webrtc/system_wrappers/interface/constructor_magic.h"
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||
#include "webrtc/test/testsupport/gtest_prod_util.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -104,6 +105,19 @@ class OveruseFrameDetector : public Module {
|
||||
virtual int32_t Process() OVERRIDE;
|
||||
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(OveruseFrameDetectorTest, TriggerOveruse);
|
||||
FRIEND_TEST_ALL_PREFIXES(OveruseFrameDetectorTest, OveruseAndRecover);
|
||||
FRIEND_TEST_ALL_PREFIXES(OveruseFrameDetectorTest, DoubleOveruseAndRecover);
|
||||
FRIEND_TEST_ALL_PREFIXES(
|
||||
OveruseFrameDetectorTest, TriggerNormalUsageWithMinProcessCount);
|
||||
FRIEND_TEST_ALL_PREFIXES(
|
||||
OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage);
|
||||
FRIEND_TEST_ALL_PREFIXES(OveruseFrameDetectorTest, LastCaptureJitter);
|
||||
|
||||
void set_min_process_count_before_reporting(int64_t count) {
|
||||
min_process_count_before_reporting_ = count;
|
||||
}
|
||||
|
||||
class EncodeTimeAvg;
|
||||
class EncodeUsage;
|
||||
class CaptureQueueDelay;
|
||||
@ -111,6 +125,8 @@ class OveruseFrameDetector : public Module {
|
||||
bool IsOverusing();
|
||||
bool IsUnderusing(int64_t time_now);
|
||||
|
||||
bool DetectFrameTimeout(int64_t now) const;
|
||||
|
||||
// Protecting all members.
|
||||
scoped_ptr<CriticalSectionWrapper> crit_;
|
||||
|
||||
@ -118,11 +134,14 @@ class OveruseFrameDetector : public Module {
|
||||
const float normaluse_stddev_ms_;
|
||||
const float overuse_stddev_ms_;
|
||||
|
||||
int64_t min_process_count_before_reporting_;
|
||||
|
||||
// Observer getting overuse reports.
|
||||
CpuOveruseObserver* observer_;
|
||||
|
||||
Clock* clock_;
|
||||
int64_t next_process_time_;
|
||||
int64_t num_process_times_;
|
||||
|
||||
Statistics capture_deltas_;
|
||||
int64_t last_capture_time_;
|
||||
|
@ -50,11 +50,11 @@ class OveruseFrameDetectorTest : public ::testing::Test {
|
||||
|
||||
EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
|
||||
|
||||
InsertFramesWithInterval(50, regular_frame_interval_ms);
|
||||
InsertFramesWithInterval(200, regular_frame_interval_ms);
|
||||
InsertFramesWithInterval(50, 110);
|
||||
overuse_detector_->Process();
|
||||
|
||||
InsertFramesWithInterval(50, regular_frame_interval_ms);
|
||||
InsertFramesWithInterval(200, regular_frame_interval_ms);
|
||||
InsertFramesWithInterval(50, 110);
|
||||
overuse_detector_->Process();
|
||||
}
|
||||
@ -74,21 +74,35 @@ class OveruseFrameDetectorTest : public ::testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
|
||||
overuse_detector_->set_min_process_count_before_reporting(0);
|
||||
TriggerOveruse();
|
||||
}
|
||||
|
||||
TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
|
||||
overuse_detector_->set_min_process_count_before_reporting(0);
|
||||
TriggerOveruse();
|
||||
TriggerNormalUsage();
|
||||
}
|
||||
|
||||
TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
|
||||
overuse_detector_->set_min_process_count_before_reporting(0);
|
||||
TriggerOveruse();
|
||||
TriggerOveruse();
|
||||
TriggerNormalUsage();
|
||||
}
|
||||
|
||||
TEST_F(OveruseFrameDetectorTest, TriggerNormalUsageWithMinProcessCount) {
|
||||
overuse_detector_->set_min_process_count_before_reporting(1);
|
||||
InsertFramesWithInterval(900, 33);
|
||||
overuse_detector_->Process();
|
||||
EXPECT_EQ(-1, overuse_detector_->last_capture_jitter_ms());
|
||||
clock_->AdvanceTimeMilliseconds(5000);
|
||||
overuse_detector_->Process();
|
||||
EXPECT_GT(overuse_detector_->last_capture_jitter_ms(), 0);
|
||||
}
|
||||
|
||||
TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
|
||||
overuse_detector_->set_min_process_count_before_reporting(0);
|
||||
EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
|
||||
|
||||
for(size_t i = 0; i < 64; ++i)
|
||||
@ -96,6 +110,7 @@ TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
|
||||
}
|
||||
|
||||
TEST_F(OveruseFrameDetectorTest, LastCaptureJitter) {
|
||||
overuse_detector_->set_min_process_count_before_reporting(0);
|
||||
EXPECT_EQ(-1, overuse_detector_->last_capture_jitter_ms());
|
||||
TriggerOveruse();
|
||||
EXPECT_GT(overuse_detector_->last_capture_jitter_ms(), 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user