Adding a first simple version of overuse detection, but not hooked up.

BUG=
R=asapersson@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4268 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2013-06-26 11:23:01 +00:00
parent 1c986e7c89
commit e6168f5f41
4 changed files with 224 additions and 0 deletions

View File

@ -0,0 +1,82 @@
/*
* 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.
*/
#include "webrtc/video_engine/overuse_frame_detector.h"
#include <cassert>
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc {
// TODO(mflodman) Test different thresholds.
const int64_t kProcessIntervalMs = 2000;
const int kOveruseHistoryMs = 5000;
const float kMinEncodeRatio = 29 / 30.0f;
OveruseFrameDetector::OveruseFrameDetector(Clock* clock,
OveruseObserver* observer)
: crit_(CriticalSectionWrapper::CreateCriticalSection()),
observer_(observer),
clock_(clock),
last_process_time_(clock->TimeInMilliseconds()) {
assert(observer);
}
OveruseFrameDetector::~OveruseFrameDetector() {
}
void OveruseFrameDetector::CapturedFrame() {
CriticalSectionScoped cs(crit_.get());
CleanOldSamples();
capture_times_.push_back(clock_->TimeInMilliseconds());
}
void OveruseFrameDetector::EncodedFrame() {
CriticalSectionScoped cs(crit_.get());
encode_times_.push_back(clock_->TimeInMilliseconds());
}
int32_t OveruseFrameDetector::TimeUntilNextProcess() {
return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds();
}
int32_t OveruseFrameDetector::Process() {
CriticalSectionScoped cs(crit_.get());
if (clock_->TimeInMilliseconds() < last_process_time_ + kProcessIntervalMs)
return 0;
last_process_time_ = clock_->TimeInMilliseconds();
CleanOldSamples();
if (encode_times_.size() == 0 || capture_times_.size() == 0)
return 0;
float encode_ratio = encode_times_.size() /
static_cast<float>(capture_times_.size());
if (encode_ratio < kMinEncodeRatio) {
observer_->OveruseDetected();
}
return 0;
}
void OveruseFrameDetector::CleanOldSamples() {
int64_t time_now = clock_->TimeInMilliseconds();
while (capture_times_.size() > 0 &&
capture_times_.front() < time_now - kOveruseHistoryMs) {
capture_times_.pop_front();
}
while (encode_times_.size() > 0 &&
encode_times_.front() < time_now - kOveruseHistoryMs) {
encode_times_.pop_front();
}
}
} // namespace webrtc

View File

@ -0,0 +1,73 @@
/*
* 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_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
#define WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
#include <list>
#include "webrtc/modules/interface/module.h"
#include "webrtc/system_wrappers/interface/constructor_magic.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
namespace webrtc {
class Clock;
class CriticalSectionWrapper;
class OveruseObserver {
public:
// Called when an overuse has been detected, based on the number of calls to
// 'CapturedFrame' and 'EncodedFrame'.
virtual void OveruseDetected() = 0;
virtual ~OveruseObserver() {}
};
// Use to detect system overuse based on the number of captured frames vs. the
// number of encoded frames.
class OveruseFrameDetector : public Module {
public:
OveruseFrameDetector(Clock* clock, OveruseObserver* observer);
~OveruseFrameDetector();
// Called for each new captured frame.
void CapturedFrame();
// Called for every encoded frame.
void EncodedFrame();
// Implements Module.
virtual int32_t TimeUntilNextProcess();
virtual int32_t Process();
private:
void CleanOldSamples();
// Protecting all members.
scoped_ptr<CriticalSectionWrapper> crit_;
// Observer getting overuse reports.
OveruseObserver* observer_;
Clock* clock_;
int64_t last_process_time_;
// Capture time for frames.
std::list<int64_t> capture_times_;
// Start encode time for a frame.
std::list<int64_t> encode_times_;
DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
};
} // namespace webrtc
#endif // WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_

View File

@ -0,0 +1,66 @@
/*
* 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.
*/
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/video_engine/overuse_frame_detector.h"
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Return;
namespace webrtc {
const int kProcessIntervalMs = 2000;
class MockOveruseObserver : public OveruseObserver {
public:
MockOveruseObserver() {}
virtual ~MockOveruseObserver() {}
MOCK_METHOD0(OveruseDetected, void());
};
class OveruseFrameDetectorTest : public ::testing::Test {
protected:
virtual void SetUp() {
clock_.reset(new SimulatedClock(1234));
observer_.reset(new MockOveruseObserver());
overuse_detector_.reset(new OveruseFrameDetector(clock_.get(),
observer_.get()));
}
scoped_ptr<SimulatedClock> clock_;
scoped_ptr<MockOveruseObserver> observer_;
scoped_ptr<OveruseFrameDetector> overuse_detector_;
};
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
EXPECT_EQ(overuse_detector_->TimeUntilNextProcess(), kProcessIntervalMs);
overuse_detector_->CapturedFrame();
overuse_detector_->EncodedFrame();
clock_->AdvanceTimeMilliseconds(kProcessIntervalMs);
EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
overuse_detector_->Process();
overuse_detector_->CapturedFrame();
clock_->AdvanceTimeMilliseconds(kProcessIntervalMs);
EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
overuse_detector_->Process();
clock_->AdvanceTimeMilliseconds(5000);
overuse_detector_->CapturedFrame();
overuse_detector_->EncodedFrame();
EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
overuse_detector_->Process();
}
} // namespace webrtc

View File

@ -50,6 +50,7 @@
# headers
'call_stats.h',
'encoder_state_feedback.h',
'overuse_frame_detector.h',
'stream_synchronization.h',
'vie_base_impl.h',
'vie_capture_impl.h',
@ -83,6 +84,7 @@
# ViE
'call_stats.cc',
'encoder_state_feedback.cc',
'overuse_frame_detector.cc',
'stream_synchronization.cc',
'vie_base_impl.cc',
'vie_capture_impl.cc',
@ -152,6 +154,7 @@
'sources': [
'call_stats_unittest.cc',
'encoder_state_feedback_unittest.cc',
'overuse_frame_detector_unittest.cc',
'stream_synchronization_unittest.cc',
'vie_remb_unittest.cc',
],