Expose a set of options to the OveruseDetector supporting experiments
Updated overuse_detector.* to use google style naming convention Removed OveruseDetector::Reset Review URL: https://webrtc-codereview.appspot.com/666005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2443 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
f494fd0954
commit
bd7aeba8fb
@ -571,5 +571,32 @@ struct VideoCodec
|
||||
unsigned char numberOfSimulcastStreams;
|
||||
SimulcastStream simulcastStream[kMaxSimulcastStreams];
|
||||
};
|
||||
|
||||
// Bandwidth over-use detector options. These are used to drive
|
||||
// experimentation with bandwidth estimation parameters.
|
||||
// See modules/remote_bitrate_estimator/overuse_detector.h
|
||||
struct OverUseDetectorOptions {
|
||||
OverUseDetectorOptions()
|
||||
: initial_slope(8.0/512.0),
|
||||
initial_offset(0),
|
||||
initial_e(),
|
||||
initial_process_noise(),
|
||||
initial_avg_noise(0.0),
|
||||
initial_var_noise(500),
|
||||
initial_threshold(25.0) {
|
||||
initial_e[0][0] = 100;
|
||||
initial_e[1][1] = 1e-1;
|
||||
initial_e[0][1] = initial_e[1][0] = 0;
|
||||
initial_process_noise[0] = 1e-10;
|
||||
initial_process_noise[1] = 1e-2;
|
||||
}
|
||||
double initial_slope;
|
||||
double initial_offset;
|
||||
double initial_e[2][2];
|
||||
double initial_process_noise[2];
|
||||
double initial_avg_noise;
|
||||
double initial_var_noise;
|
||||
double initial_threshold;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_COMMON_TYPES_H
|
||||
|
@ -39,7 +39,8 @@ class RemoteBitrateObserver {
|
||||
|
||||
class RemoteBitrateEstimator {
|
||||
public:
|
||||
explicit RemoteBitrateEstimator(RemoteBitrateObserver* observer);
|
||||
RemoteBitrateEstimator(RemoteBitrateObserver* observer,
|
||||
const OverUseDetectorOptions& options);
|
||||
|
||||
// Called for each incoming packet. If this is a new SSRC, a new
|
||||
// BitrateControl will be created.
|
||||
@ -65,6 +66,16 @@ class RemoteBitrateEstimator {
|
||||
|
||||
private:
|
||||
struct BitrateControls {
|
||||
explicit BitrateControls(const OverUseDetectorOptions& options)
|
||||
: remote_rate(),
|
||||
overuse_detector(options),
|
||||
incoming_bitrate() {
|
||||
}
|
||||
BitrateControls(const BitrateControls& other)
|
||||
: remote_rate(other.remote_rate),
|
||||
overuse_detector(other.overuse_detector),
|
||||
incoming_bitrate(other.incoming_bitrate) {
|
||||
}
|
||||
RemoteRateControl remote_rate;
|
||||
OverUseDetector overuse_detector;
|
||||
BitRateStats incoming_bitrate;
|
||||
@ -72,6 +83,7 @@ class RemoteBitrateEstimator {
|
||||
|
||||
typedef std::map<unsigned int, BitrateControls> SsrcBitrateControlsMap;
|
||||
|
||||
const OverUseDetectorOptions& options_;
|
||||
SsrcBitrateControlsMap bitrate_controls_;
|
||||
RemoteBitrateObserver* observer_;
|
||||
scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
|
@ -23,163 +23,128 @@
|
||||
extern MatlabEngine eng; // global variable defined elsewhere
|
||||
#endif
|
||||
|
||||
#define INIT_CAPACITY_SLOPE 8.0/512.0
|
||||
#define DETECTOR_THRESHOLD 25.0
|
||||
#define OVER_USING_TIME_THRESHOLD 100
|
||||
#define MIN_FRAME_PERIOD_HISTORY_LEN 60
|
||||
|
||||
namespace webrtc {
|
||||
OverUseDetector::OverUseDetector()
|
||||
: firstPacket_(true),
|
||||
currentFrame_(),
|
||||
prevFrame_(),
|
||||
numOfDeltas_(0),
|
||||
slope_(INIT_CAPACITY_SLOPE),
|
||||
offset_(0),
|
||||
OverUseDetector::OverUseDetector(const OverUseDetectorOptions& options)
|
||||
: options_(options),
|
||||
first_packet_(true),
|
||||
current_frame_(),
|
||||
prev_frame_(),
|
||||
num_of_deltas_(0),
|
||||
slope_(options_.initial_slope),
|
||||
offset_(options_.initial_offset),
|
||||
E_(),
|
||||
processNoise_(),
|
||||
avgNoise_(0.0),
|
||||
varNoise_(500),
|
||||
threshold_(DETECTOR_THRESHOLD),
|
||||
tsDeltaHist_(),
|
||||
prevOffset_(0.0),
|
||||
timeOverUsing_(-1),
|
||||
overUseCounter_(0),
|
||||
#ifndef WEBRTC_BWE_MATLAB
|
||||
hypothesis_(kBwNormal) {
|
||||
#else
|
||||
plot1_(NULL),
|
||||
plot2_(NULL),
|
||||
plot3_(NULL),
|
||||
plot4_(NULL) {
|
||||
#endif
|
||||
E_[0][0] = 100;
|
||||
E_[1][1] = 1e-1;
|
||||
E_[0][1] = E_[1][0] = 0;
|
||||
processNoise_[0] = 1e-10;
|
||||
processNoise_[1] = 1e-2;
|
||||
process_noise_(),
|
||||
avg_noise_(options_.initial_avg_noise),
|
||||
var_noise_(options_.initial_var_noise),
|
||||
threshold_(options_.initial_threshold),
|
||||
ts_delta_hist_(),
|
||||
prev_offset_(0.0),
|
||||
time_over_using_(-1),
|
||||
over_use_counter_(0),
|
||||
hypothesis_(kBwNormal),
|
||||
plots_() {
|
||||
memcpy(E_, options_.initial_e, sizeof(E_));
|
||||
memcpy(process_noise_, options_.initial_process_noise,
|
||||
sizeof(process_noise_));
|
||||
}
|
||||
|
||||
OverUseDetector::~OverUseDetector() {
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
if (plot1_) {
|
||||
eng.DeletePlot(plot1_);
|
||||
plot1_ = NULL;
|
||||
if (plots_.plot1_) {
|
||||
eng.DeletePlot(plots_.plot1_);
|
||||
plots_.plot1_ = NULL;
|
||||
}
|
||||
if (plot2_) {
|
||||
eng.DeletePlot(plot2_);
|
||||
plot2_ = NULL;
|
||||
if (plots_.plot2_) {
|
||||
eng.DeletePlot(plots_.plot2_);
|
||||
plots_.plot2_ = NULL;
|
||||
}
|
||||
if (plot3_) {
|
||||
eng.DeletePlot(plot3_);
|
||||
plot3_ = NULL;
|
||||
if (plots_.plot3_) {
|
||||
eng.DeletePlot(plots_.plot3_);
|
||||
plots_.plot3_ = NULL;
|
||||
}
|
||||
if (plot4_) {
|
||||
eng.DeletePlot(plot4_);
|
||||
plot4_ = NULL;
|
||||
if (plots_.plot4_) {
|
||||
eng.DeletePlot(plots_.plot4_);
|
||||
plots_.plot4_ = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
tsDeltaHist_.clear();
|
||||
ts_delta_hist_.clear();
|
||||
}
|
||||
|
||||
void OverUseDetector::Reset() {
|
||||
firstPacket_ = true;
|
||||
currentFrame_.size_ = 0;
|
||||
currentFrame_.completeTimeMs_ = -1;
|
||||
currentFrame_.timestamp_ = -1;
|
||||
prevFrame_.size_ = 0;
|
||||
prevFrame_.completeTimeMs_ = -1;
|
||||
prevFrame_.timestamp_ = -1;
|
||||
numOfDeltas_ = 0;
|
||||
slope_ = INIT_CAPACITY_SLOPE;
|
||||
offset_ = 0;
|
||||
E_[0][0] = 100;
|
||||
E_[1][1] = 1e-1;
|
||||
E_[0][1] = E_[1][0] = 0;
|
||||
processNoise_[0] = 1e-10;
|
||||
processNoise_[1] = 1e-2;
|
||||
avgNoise_ = 0.0;
|
||||
varNoise_ = 500;
|
||||
threshold_ = DETECTOR_THRESHOLD;
|
||||
prevOffset_ = 0.0;
|
||||
timeOverUsing_ = -1;
|
||||
overUseCounter_ = 0;
|
||||
hypothesis_ = kBwNormal;
|
||||
tsDeltaHist_.clear();
|
||||
}
|
||||
|
||||
void OverUseDetector::Update(WebRtc_UWord16 packetSize,
|
||||
WebRtc_UWord32 timestamp,
|
||||
const WebRtc_Word64 nowMS) {
|
||||
void OverUseDetector::Update(uint16_t packet_size,
|
||||
uint32_t timestamp,
|
||||
const int64_t now_ms) {
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
// Create plots
|
||||
const WebRtc_Word64 startTimeMs = nowMS;
|
||||
if (plot1_ == NULL) {
|
||||
plot1_ = eng.NewPlot(new MatlabPlot());
|
||||
plot1_->AddLine(1000, "b.", "scatter");
|
||||
const int64_t startTimeMs = nowMS;
|
||||
if (plots_.plot1_ == NULL) {
|
||||
plots_.plot1_ = eng.NewPlot(new MatlabPlot());
|
||||
plots_.plot1_->AddLine(1000, "b.", "scatter");
|
||||
}
|
||||
if (plot2_ == NULL) {
|
||||
plot2_ = eng.NewPlot(new MatlabPlot());
|
||||
plot2_->AddTimeLine(30, "b", "offset", startTimeMs);
|
||||
plot2_->AddTimeLine(30, "r--", "limitPos", startTimeMs);
|
||||
plot2_->AddTimeLine(30, "k.", "trigger", startTimeMs);
|
||||
plot2_->AddTimeLine(30, "ko", "detection", startTimeMs);
|
||||
// plot2_->AddTimeLine(30, "g", "slowMean", startTimeMs);
|
||||
if (plots_.plot2_ == NULL) {
|
||||
plots_.plot2_ = eng.NewPlot(new MatlabPlot());
|
||||
plots_.plot2_->AddTimeLine(30, "b", "offset", startTimeMs);
|
||||
plots_.plot2_->AddTimeLine(30, "r--", "limitPos", startTimeMs);
|
||||
plots_.plot2_->AddTimeLine(30, "k.", "trigger", startTimeMs);
|
||||
plots_.plot2_->AddTimeLine(30, "ko", "detection", startTimeMs);
|
||||
// plots_.plot2_->AddTimeLine(30, "g", "slowMean", startTimeMs);
|
||||
}
|
||||
if (plot3_ == NULL) {
|
||||
plot3_ = eng.NewPlot(new MatlabPlot());
|
||||
plot3_->AddTimeLine(30, "b", "noiseVar", startTimeMs);
|
||||
if (plots_.plot3_ == NULL) {
|
||||
plots_.plot3_ = eng.NewPlot(new MatlabPlot());
|
||||
plots_.plot3_->AddTimeLine(30, "b", "noiseVar", startTimeMs);
|
||||
}
|
||||
if (plot4_ == NULL) {
|
||||
plot4_ = eng.NewPlot(new MatlabPlot());
|
||||
// plot4_->AddTimeLine(60, "b", "p11", startTimeMs);
|
||||
// plot4_->AddTimeLine(60, "r", "p12", startTimeMs);
|
||||
plot4_->AddTimeLine(60, "g", "p22", startTimeMs);
|
||||
// plot4_->AddTimeLine(60, "g--", "p22_hat", startTimeMs);
|
||||
// plot4_->AddTimeLine(30, "b.-", "deltaFs", startTimeMs);
|
||||
if (plots_.plot4_ == NULL) {
|
||||
plots_.plot4_ = eng.NewPlot(new MatlabPlot());
|
||||
// plots_.plot4_->AddTimeLine(60, "b", "p11", startTimeMs);
|
||||
// plots_.plot4_->AddTimeLine(60, "r", "p12", startTimeMs);
|
||||
plots_.plot4_->AddTimeLine(60, "g", "p22", startTimeMs);
|
||||
// plots_.plot4_->AddTimeLine(60, "g--", "p22_hat", startTimeMs);
|
||||
// plots_.plot4_->AddTimeLine(30, "b.-", "deltaFs", startTimeMs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool wrapped = false;
|
||||
bool completeFrame = false;
|
||||
if (currentFrame_.timestamp_ == -1) {
|
||||
currentFrame_.timestamp_ = timestamp;
|
||||
if (current_frame_.timestamp_ == -1) {
|
||||
current_frame_.timestamp_ = timestamp;
|
||||
} else if (OldTimestamp(
|
||||
timestamp,
|
||||
static_cast<WebRtc_UWord32>(currentFrame_.timestamp_),
|
||||
static_cast<uint32_t>(current_frame_.timestamp_),
|
||||
&wrapped)) {
|
||||
// Don't update with old data
|
||||
return;
|
||||
} else if (timestamp != currentFrame_.timestamp_) {
|
||||
} else if (timestamp != current_frame_.timestamp_) {
|
||||
// First packet of a later frame, the previous frame sample is ready
|
||||
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1,
|
||||
"Frame complete at %I64i", currentFrame_.completeTimeMs_);
|
||||
if (prevFrame_.completeTimeMs_ >= 0) { // This is our second frame
|
||||
WebRtc_Word64 tDelta = 0;
|
||||
double tsDelta = 0;
|
||||
"Frame complete at %I64i", current_frame_.completeTimeMs_);
|
||||
if (prev_frame_.completeTimeMs_ >= 0) { // This is our second frame
|
||||
int64_t t_delta = 0;
|
||||
double ts_delta = 0;
|
||||
// Check for wrap
|
||||
OldTimestamp(
|
||||
static_cast<WebRtc_UWord32>(prevFrame_.timestamp_),
|
||||
static_cast<WebRtc_UWord32>(currentFrame_.timestamp_),
|
||||
static_cast<uint32_t>(prev_frame_.timestamp_),
|
||||
static_cast<uint32_t>(current_frame_.timestamp_),
|
||||
&wrapped);
|
||||
CompensatedTimeDelta(currentFrame_, prevFrame_, tDelta, tsDelta,
|
||||
CompensatedTimeDelta(current_frame_, prev_frame_, t_delta, ts_delta,
|
||||
wrapped);
|
||||
UpdateKalman(tDelta, tsDelta, currentFrame_.size_,
|
||||
prevFrame_.size_);
|
||||
UpdateKalman(t_delta, ts_delta, current_frame_.size_,
|
||||
prev_frame_.size_);
|
||||
}
|
||||
// The new timestamp is now the current frame,
|
||||
// and the old timestamp becomes the previous frame.
|
||||
prevFrame_ = currentFrame_;
|
||||
currentFrame_.timestamp_ = timestamp;
|
||||
currentFrame_.size_ = 0;
|
||||
currentFrame_.completeTimeMs_ = -1;
|
||||
prev_frame_ = current_frame_;
|
||||
current_frame_.timestamp_ = timestamp;
|
||||
current_frame_.size_ = 0;
|
||||
current_frame_.completeTimeMs_ = -1;
|
||||
completeFrame = true;
|
||||
}
|
||||
// Accumulate the frame size
|
||||
currentFrame_.size_ += packetSize;
|
||||
currentFrame_.completeTimeMs_ = nowMS;
|
||||
current_frame_.size_ += packet_size;
|
||||
current_frame_.completeTimeMs_ = now_ms;
|
||||
}
|
||||
|
||||
BandwidthUsage OverUseDetector::State() const {
|
||||
@ -187,18 +152,18 @@ BandwidthUsage OverUseDetector::State() const {
|
||||
}
|
||||
|
||||
double OverUseDetector::NoiseVar() const {
|
||||
return varNoise_;
|
||||
return var_noise_;
|
||||
}
|
||||
|
||||
void OverUseDetector::SetRateControlRegion(RateControlRegion region) {
|
||||
switch (region) {
|
||||
case kRcMaxUnknown: {
|
||||
threshold_ = DETECTOR_THRESHOLD;
|
||||
threshold_ = options_.initial_threshold;
|
||||
break;
|
||||
}
|
||||
case kRcAboveMax:
|
||||
case kRcNearMax: {
|
||||
threshold_ = DETECTOR_THRESHOLD / 2;
|
||||
threshold_ = options_.initial_threshold / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -206,47 +171,47 @@ void OverUseDetector::SetRateControlRegion(RateControlRegion region) {
|
||||
|
||||
void OverUseDetector::CompensatedTimeDelta(const FrameSample& currentFrame,
|
||||
const FrameSample& prevFrame,
|
||||
WebRtc_Word64& tDelta,
|
||||
double& tsDelta,
|
||||
int64_t& t_delta,
|
||||
double& ts_delta,
|
||||
bool wrapped) {
|
||||
numOfDeltas_++;
|
||||
if (numOfDeltas_ > 1000) {
|
||||
numOfDeltas_ = 1000;
|
||||
num_of_deltas_++;
|
||||
if (num_of_deltas_ > 1000) {
|
||||
num_of_deltas_ = 1000;
|
||||
}
|
||||
// Add wrap-around compensation
|
||||
WebRtc_Word64 wrapCompensation = 0;
|
||||
int64_t wrapCompensation = 0;
|
||||
if (wrapped) {
|
||||
wrapCompensation = static_cast<WebRtc_Word64>(1)<<32;
|
||||
wrapCompensation = static_cast<int64_t>(1)<<32;
|
||||
}
|
||||
tsDelta = (currentFrame.timestamp_
|
||||
ts_delta = (currentFrame.timestamp_
|
||||
+ wrapCompensation
|
||||
- prevFrame.timestamp_) / 90.0;
|
||||
tDelta = currentFrame.completeTimeMs_ - prevFrame.completeTimeMs_;
|
||||
assert(tsDelta > 0);
|
||||
t_delta = currentFrame.completeTimeMs_ - prevFrame.completeTimeMs_;
|
||||
assert(ts_delta > 0);
|
||||
}
|
||||
|
||||
double OverUseDetector::CurrentDrift() {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void OverUseDetector::UpdateKalman(WebRtc_Word64 tDelta,
|
||||
double tsDelta,
|
||||
WebRtc_UWord32 frameSize,
|
||||
WebRtc_UWord32 prevFrameSize) {
|
||||
const double minFramePeriod = UpdateMinFramePeriod(tsDelta);
|
||||
void OverUseDetector::UpdateKalman(int64_t t_delta,
|
||||
double ts_delta,
|
||||
uint32_t frame_size,
|
||||
uint32_t prev_frame_size) {
|
||||
const double minFramePeriod = UpdateMinFramePeriod(ts_delta);
|
||||
const double drift = CurrentDrift();
|
||||
// Compensate for drift
|
||||
const double tTsDelta = tDelta - tsDelta / drift;
|
||||
double fsDelta = static_cast<double>(frameSize) - prevFrameSize;
|
||||
const double tTsDelta = t_delta - ts_delta / drift;
|
||||
double fsDelta = static_cast<double>(frame_size) - prev_frame_size;
|
||||
|
||||
// Update the Kalman filter
|
||||
const double scaleFactor = minFramePeriod / (1000.0 / 30.0);
|
||||
E_[0][0] += processNoise_[0] * scaleFactor;
|
||||
E_[1][1] += processNoise_[1] * scaleFactor;
|
||||
E_[0][0] += process_noise_[0] * scaleFactor;
|
||||
E_[1][1] += process_noise_[1] * scaleFactor;
|
||||
|
||||
if ((hypothesis_ == kBwOverusing && offset_ < prevOffset_) ||
|
||||
(hypothesis_ == kBwUnderUsing && offset_ > prevOffset_)) {
|
||||
E_[1][1] += 10 * processNoise_[1] * scaleFactor;
|
||||
if ((hypothesis_ == kBwOverusing && offset_ < prev_offset_) ||
|
||||
(hypothesis_ == kBwUnderUsing && offset_ > prev_offset_)) {
|
||||
E_[1][1] += 10 * process_noise_[1] * scaleFactor;
|
||||
}
|
||||
|
||||
const double h[2] = {fsDelta, 1.0};
|
||||
@ -255,17 +220,17 @@ void OverUseDetector::UpdateKalman(WebRtc_Word64 tDelta,
|
||||
|
||||
const double residual = tTsDelta - slope_*h[0] - offset_;
|
||||
|
||||
const bool stableState =
|
||||
(BWE_MIN(numOfDeltas_, 60) * fabsf(offset_) < threshold_);
|
||||
const bool stable_state =
|
||||
(BWE_MIN(num_of_deltas_, 60) * fabsf(offset_) < threshold_);
|
||||
// We try to filter out very late frames. For instance periodic key
|
||||
// frames doesn't fit the Gaussian model well.
|
||||
if (fabsf(residual) < 3 * sqrt(varNoise_)) {
|
||||
UpdateNoiseEstimate(residual, minFramePeriod, stableState);
|
||||
if (fabsf(residual) < 3 * sqrt(var_noise_)) {
|
||||
UpdateNoiseEstimate(residual, minFramePeriod, stable_state);
|
||||
} else {
|
||||
UpdateNoiseEstimate(3 * sqrt(varNoise_), minFramePeriod, stableState);
|
||||
UpdateNoiseEstimate(3 * sqrt(var_noise_), minFramePeriod, stable_state);
|
||||
}
|
||||
|
||||
const double denom = varNoise_ + h[0]*Eh[0] + h[1]*Eh[1];
|
||||
const double denom = var_noise_ + h[0]*Eh[0] + h[1]*Eh[1];
|
||||
|
||||
const double K[2] = {Eh[0] / denom,
|
||||
Eh[1] / denom};
|
||||
@ -287,114 +252,114 @@ void OverUseDetector::UpdateKalman(WebRtc_Word64 tDelta,
|
||||
E_[0][0] >= 0);
|
||||
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
// plot4_->Append("p11",E_[0][0]);
|
||||
// plot4_->Append("p12",E_[0][1]);
|
||||
plot4_->Append("p22", E_[1][1]);
|
||||
// plot4_->Append("p22_hat", 0.5*(processNoise_[1] +
|
||||
// sqrt(processNoise_[1]*(processNoise_[1] + 4*varNoise_))));
|
||||
// plot4_->Append("deltaFs", fsDelta);
|
||||
plot4_->Plot();
|
||||
// plots_.plot4_->Append("p11",E_[0][0]);
|
||||
// plots_.plot4_->Append("p12",E_[0][1]);
|
||||
plots_.plot4_->Append("p22", E_[1][1]);
|
||||
// plots_.plot4_->Append("p22_hat", 0.5*(process_noise_[1] +
|
||||
// sqrt(process_noise_[1]*(process_noise_[1] + 4*var_noise_))));
|
||||
// plots_.plot4_->Append("deltaFs", fsDelta);
|
||||
plots_.plot4_->Plot();
|
||||
#endif
|
||||
slope_ = slope_ + K[0] * residual;
|
||||
prevOffset_ = offset_;
|
||||
prev_offset_ = offset_;
|
||||
offset_ = offset_ + K[1] * residual;
|
||||
|
||||
Detect(tsDelta);
|
||||
Detect(ts_delta);
|
||||
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
plot1_->Append("scatter",
|
||||
static_cast<double>(currentFrame_.size_) - prevFrame_.size_,
|
||||
static_cast<double>(tDelta-tsDelta));
|
||||
plot1_->MakeTrend("scatter", "slope", slope_, offset_, "k-");
|
||||
plot1_->MakeTrend("scatter", "thresholdPos",
|
||||
slope_, offset_ + 2 * sqrt(varNoise_), "r-");
|
||||
plot1_->MakeTrend("scatter", "thresholdNeg",
|
||||
slope_, offset_ - 2 * sqrt(varNoise_), "r-");
|
||||
plot1_->Plot();
|
||||
plots_.plot1_->Append("scatter",
|
||||
static_cast<double>(current_frame_.size_) - prev_frame_.size_,
|
||||
static_cast<double>(t_delta - ts_delta));
|
||||
plots_.plot1_->MakeTrend("scatter", "slope", slope_, offset_, "k-");
|
||||
plots_.plot1_->MakeTrend("scatter", "thresholdPos",
|
||||
slope_, offset_ + 2 * sqrt(var_noise_), "r-");
|
||||
plots_.plot1_->MakeTrend("scatter", "thresholdNeg",
|
||||
slope_, offset_ - 2 * sqrt(var_noise_), "r-");
|
||||
plots_.plot1_->Plot();
|
||||
|
||||
plot2_->Append("offset", offset_);
|
||||
plot2_->Append("limitPos", threshold_/BWE_MIN(numOfDeltas_, 60));
|
||||
plot2_->Plot();
|
||||
plots_.plot2_->Append("offset", offset_);
|
||||
plots_.plot2_->Append("limitPos", threshold_/BWE_MIN(num_of_deltas_, 60));
|
||||
plots_.plot2_->Plot();
|
||||
|
||||
plot3_->Append("noiseVar", varNoise_);
|
||||
plot3_->Plot();
|
||||
plots_.plot3_->Append("noiseVar", var_noise_);
|
||||
plots_.plot3_->Plot();
|
||||
#endif
|
||||
}
|
||||
|
||||
double OverUseDetector::UpdateMinFramePeriod(double tsDelta) {
|
||||
double minFramePeriod = tsDelta;
|
||||
if (tsDeltaHist_.size() >= MIN_FRAME_PERIOD_HISTORY_LEN) {
|
||||
std::list<double>::iterator firstItem = tsDeltaHist_.begin();
|
||||
tsDeltaHist_.erase(firstItem);
|
||||
double OverUseDetector::UpdateMinFramePeriod(double ts_delta) {
|
||||
double minFramePeriod = ts_delta;
|
||||
if (ts_delta_hist_.size() >= MIN_FRAME_PERIOD_HISTORY_LEN) {
|
||||
std::list<double>::iterator firstItem = ts_delta_hist_.begin();
|
||||
ts_delta_hist_.erase(firstItem);
|
||||
}
|
||||
std::list<double>::iterator it = tsDeltaHist_.begin();
|
||||
for (; it != tsDeltaHist_.end(); it++) {
|
||||
std::list<double>::iterator it = ts_delta_hist_.begin();
|
||||
for (; it != ts_delta_hist_.end(); it++) {
|
||||
minFramePeriod = BWE_MIN(*it, minFramePeriod);
|
||||
}
|
||||
tsDeltaHist_.push_back(tsDelta);
|
||||
ts_delta_hist_.push_back(ts_delta);
|
||||
return minFramePeriod;
|
||||
}
|
||||
|
||||
void OverUseDetector::UpdateNoiseEstimate(double residual,
|
||||
double tsDelta,
|
||||
bool stableState) {
|
||||
if (!stableState) {
|
||||
double ts_delta,
|
||||
bool stable_state) {
|
||||
if (!stable_state) {
|
||||
return;
|
||||
}
|
||||
// Faster filter during startup to faster adapt to the jitter level
|
||||
// of the network alpha is tuned for 30 frames per second, but
|
||||
double alpha = 0.01;
|
||||
if (numOfDeltas_ > 10*30) {
|
||||
if (num_of_deltas_ > 10*30) {
|
||||
alpha = 0.002;
|
||||
}
|
||||
// Only update the noise estimate if we're not over-using
|
||||
// beta is a function of alpha and the time delta since
|
||||
// the previous update.
|
||||
const double beta = pow(1 - alpha, tsDelta * 30.0 / 1000.0);
|
||||
avgNoise_ = beta * avgNoise_
|
||||
const double beta = pow(1 - alpha, ts_delta * 30.0 / 1000.0);
|
||||
avg_noise_ = beta * avg_noise_
|
||||
+ (1 - beta) * residual;
|
||||
varNoise_ = beta * varNoise_
|
||||
+ (1 - beta) * (avgNoise_ - residual) * (avgNoise_ - residual);
|
||||
if (varNoise_ < 1e-7) {
|
||||
varNoise_ = 1e-7;
|
||||
var_noise_ = beta * var_noise_
|
||||
+ (1 - beta) * (avg_noise_ - residual) * (avg_noise_ - residual);
|
||||
if (var_noise_ < 1e-7) {
|
||||
var_noise_ = 1e-7;
|
||||
}
|
||||
}
|
||||
|
||||
BandwidthUsage OverUseDetector::Detect(double tsDelta) {
|
||||
if (numOfDeltas_ < 2) {
|
||||
BandwidthUsage OverUseDetector::Detect(double ts_delta) {
|
||||
if (num_of_deltas_ < 2) {
|
||||
return kBwNormal;
|
||||
}
|
||||
const double T = BWE_MIN(numOfDeltas_, 60) * offset_;
|
||||
const double T = BWE_MIN(num_of_deltas_, 60) * offset_;
|
||||
if (fabsf(T) > threshold_) {
|
||||
if (offset_ > 0) {
|
||||
if (timeOverUsing_ == -1) {
|
||||
if (time_over_using_ == -1) {
|
||||
// Initialize the timer. Assume that we've been
|
||||
// over-using half of the time since the previous
|
||||
// sample.
|
||||
timeOverUsing_ = tsDelta / 2;
|
||||
time_over_using_ = ts_delta / 2;
|
||||
} else {
|
||||
// Increment timer
|
||||
timeOverUsing_ += tsDelta;
|
||||
time_over_using_ += ts_delta;
|
||||
}
|
||||
overUseCounter_++;
|
||||
if (timeOverUsing_ > OVER_USING_TIME_THRESHOLD
|
||||
&& overUseCounter_ > 1) {
|
||||
if (offset_ >= prevOffset_) {
|
||||
over_use_counter_++;
|
||||
if (time_over_using_ > OVER_USING_TIME_THRESHOLD
|
||||
&& over_use_counter_ > 1) {
|
||||
if (offset_ >= prev_offset_) {
|
||||
#ifdef _DEBUG
|
||||
if (hypothesis_ != kBwOverusing) {
|
||||
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwOverusing");
|
||||
}
|
||||
#endif
|
||||
timeOverUsing_ = 0;
|
||||
overUseCounter_ = 0;
|
||||
time_over_using_ = 0;
|
||||
over_use_counter_ = 0;
|
||||
hypothesis_ = kBwOverusing;
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
plot2_->Append("detection", offset_); // plot it later
|
||||
plots_.plot2_->Append("detection", offset_); // plot it later
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
plot2_->Append("trigger", offset_); // plot it later
|
||||
plots_.plot2_->Append("trigger", offset_); // plot it later
|
||||
#endif
|
||||
} else {
|
||||
#ifdef _DEBUG
|
||||
@ -402,8 +367,8 @@ BandwidthUsage OverUseDetector::Detect(double tsDelta) {
|
||||
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwUnderUsing");
|
||||
}
|
||||
#endif
|
||||
timeOverUsing_ = -1;
|
||||
overUseCounter_ = 0;
|
||||
time_over_using_ = -1;
|
||||
over_use_counter_ = 0;
|
||||
hypothesis_ = kBwUnderUsing;
|
||||
}
|
||||
} else {
|
||||
@ -412,25 +377,25 @@ BandwidthUsage OverUseDetector::Detect(double tsDelta) {
|
||||
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "BWE: kBwNormal");
|
||||
}
|
||||
#endif
|
||||
timeOverUsing_ = -1;
|
||||
overUseCounter_ = 0;
|
||||
time_over_using_ = -1;
|
||||
over_use_counter_ = 0;
|
||||
hypothesis_ = kBwNormal;
|
||||
}
|
||||
return hypothesis_;
|
||||
}
|
||||
|
||||
bool OverUseDetector::OldTimestamp(uint32_t newTimestamp,
|
||||
uint32_t existingTimestamp,
|
||||
bool OverUseDetector::OldTimestamp(uint32_t new_timestamp,
|
||||
uint32_t existing_timestamp,
|
||||
bool* wrapped) {
|
||||
bool tmpWrapped =
|
||||
(newTimestamp < 0x0000ffff && existingTimestamp > 0xffff0000) ||
|
||||
(newTimestamp > 0xffff0000 && existingTimestamp < 0x0000ffff);
|
||||
(new_timestamp < 0x0000ffff && existing_timestamp > 0xffff0000) ||
|
||||
(new_timestamp > 0xffff0000 && existing_timestamp < 0x0000ffff);
|
||||
*wrapped = tmpWrapped;
|
||||
if (existingTimestamp > newTimestamp && !tmpWrapped) {
|
||||
if (existing_timestamp > new_timestamp && !tmpWrapped) {
|
||||
return true;
|
||||
} else if (existingTimestamp <= newTimestamp && !tmpWrapped) {
|
||||
} else if (existing_timestamp <= new_timestamp && !tmpWrapped) {
|
||||
return false;
|
||||
} else if (existingTimestamp < newTimestamp && tmpWrapped) {
|
||||
} else if (existing_timestamp < new_timestamp && tmpWrapped) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -25,13 +25,12 @@ enum RateControlRegion;
|
||||
|
||||
class OverUseDetector {
|
||||
public:
|
||||
OverUseDetector();
|
||||
explicit OverUseDetector(const OverUseDetectorOptions& options);
|
||||
~OverUseDetector();
|
||||
void Update(const WebRtc_UWord16 packetSize,
|
||||
const WebRtc_UWord32 timestamp,
|
||||
const WebRtc_Word64 nowMS);
|
||||
void Update(const WebRtc_UWord16 packet_size,
|
||||
const uint32_t timestamp,
|
||||
const int64_t now_ms);
|
||||
BandwidthUsage State() const;
|
||||
void Reset();
|
||||
double NoiseVar() const;
|
||||
void SetRateControlRegion(RateControlRegion region);
|
||||
|
||||
@ -39,52 +38,59 @@ class OverUseDetector {
|
||||
struct FrameSample {
|
||||
FrameSample() : size_(0), completeTimeMs_(-1), timestamp_(-1) {}
|
||||
|
||||
WebRtc_UWord32 size_;
|
||||
WebRtc_Word64 completeTimeMs_;
|
||||
WebRtc_Word64 timestamp_;
|
||||
uint32_t size_;
|
||||
int64_t completeTimeMs_;
|
||||
int64_t timestamp_;
|
||||
};
|
||||
|
||||
static bool OldTimestamp(uint32_t newTimestamp,
|
||||
uint32_t existingTimestamp,
|
||||
struct DebugPlots {
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
DebugPlots() : plot1(NULL), plot2(NULL), plot3(NULL), plot4(NULL) {}
|
||||
MatlabPlot* plot1;
|
||||
MatlabPlot* plot2;
|
||||
MatlabPlot* plot3;
|
||||
MatlabPlot* plot4;
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool OldTimestamp(uint32_t new_timestamp,
|
||||
uint32_t existing_timestamp,
|
||||
bool* wrapped);
|
||||
|
||||
void CompensatedTimeDelta(const FrameSample& currentFrame,
|
||||
const FrameSample& prevFrame,
|
||||
WebRtc_Word64& tDelta,
|
||||
double& tsDelta,
|
||||
void CompensatedTimeDelta(const FrameSample& current_frame,
|
||||
const FrameSample& prev_frame,
|
||||
int64_t& t_delta,
|
||||
double& ts_delta,
|
||||
bool wrapped);
|
||||
void UpdateKalman(WebRtc_Word64 tDelta,
|
||||
double tsDelta,
|
||||
WebRtc_UWord32 frameSize,
|
||||
WebRtc_UWord32 prevFrameSize);
|
||||
double UpdateMinFramePeriod(double tsDelta);
|
||||
void UpdateNoiseEstimate(double residual, double tsDelta, bool stableState);
|
||||
BandwidthUsage Detect(double tsDelta);
|
||||
void UpdateKalman(int64_t t_delta,
|
||||
double ts_elta,
|
||||
uint32_t frame_size,
|
||||
uint32_t prev_frame_size);
|
||||
double UpdateMinFramePeriod(double ts_delta);
|
||||
void UpdateNoiseEstimate(double residual, double ts_delta, bool stable_state);
|
||||
BandwidthUsage Detect(double ts_delta);
|
||||
double CurrentDrift();
|
||||
|
||||
bool firstPacket_;
|
||||
FrameSample currentFrame_;
|
||||
FrameSample prevFrame_;
|
||||
WebRtc_UWord16 numOfDeltas_;
|
||||
OverUseDetectorOptions options_; // Must be first member
|
||||
// variable. Cannot be const
|
||||
// because we need to be copyable.
|
||||
bool first_packet_;
|
||||
FrameSample current_frame_;
|
||||
FrameSample prev_frame_;
|
||||
uint16_t num_of_deltas_;
|
||||
double slope_;
|
||||
double offset_;
|
||||
double E_[2][2];
|
||||
double processNoise_[2];
|
||||
double avgNoise_;
|
||||
double varNoise_;
|
||||
double process_noise_[2];
|
||||
double avg_noise_;
|
||||
double var_noise_;
|
||||
double threshold_;
|
||||
std::list<double> tsDeltaHist_;
|
||||
double prevOffset_;
|
||||
double timeOverUsing_;
|
||||
WebRtc_UWord16 overUseCounter_;
|
||||
std::list<double> ts_delta_hist_;
|
||||
double prev_offset_;
|
||||
double time_over_using_;
|
||||
uint16_t over_use_counter_;
|
||||
BandwidthUsage hypothesis_;
|
||||
|
||||
#ifdef WEBRTC_BWE_MATLAB
|
||||
MatlabPlot* plot1_;
|
||||
MatlabPlot* plot2_;
|
||||
MatlabPlot* plot3_;
|
||||
MatlabPlot* plot4_;
|
||||
#endif
|
||||
DebugPlots plots_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
|
@ -15,8 +15,10 @@
|
||||
namespace webrtc {
|
||||
|
||||
RemoteBitrateEstimator::RemoteBitrateEstimator(
|
||||
RemoteBitrateObserver* observer)
|
||||
: observer_(observer),
|
||||
RemoteBitrateObserver* observer,
|
||||
const OverUseDetectorOptions& options)
|
||||
: options_(options),
|
||||
observer_(observer),
|
||||
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()) {
|
||||
assert(observer_);
|
||||
}
|
||||
@ -35,12 +37,11 @@ void RemoteBitrateEstimator::IncomingPacket(unsigned int ssrc,
|
||||
// callback will no longer be called for the old SSRC. This will be
|
||||
// automatically cleaned up when we have one RemoteBitrateEstimator per REMB
|
||||
// group.
|
||||
bitrate_controls_[ssrc] = BitrateControls();
|
||||
bitrate_controls_.insert(std::make_pair(ssrc, BitrateControls(options_)));
|
||||
it = bitrate_controls_.find(ssrc);
|
||||
}
|
||||
OverUseDetector* overuse_detector =
|
||||
&bitrate_controls_[ssrc].overuse_detector;
|
||||
bitrate_controls_[ssrc].incoming_bitrate.Update(packet_size, arrival_time);
|
||||
OverUseDetector* overuse_detector = &it->second.overuse_detector;
|
||||
it->second.incoming_bitrate.Update(packet_size, arrival_time);
|
||||
const BandwidthUsage prior_state = overuse_detector->State();
|
||||
overuse_detector->Update(packet_size, rtp_timestamp, arrival_time);
|
||||
if (prior_state != overuse_detector->State() &&
|
||||
|
@ -123,7 +123,7 @@ class RemoteBitrateEstimatorTest : public ::testing::Test {
|
||||
virtual void SetUp() {
|
||||
bitrate_observer_.reset(new TestBitrateObserver);
|
||||
bitrate_estimator_.reset(new RemoteBitrateEstimator(
|
||||
bitrate_observer_.get()));
|
||||
bitrate_observer_.get(), over_use_detector_options_));
|
||||
// Framerate: 30 fps; Start bitrate: 300 kbps; Link capacity: 1000 kbps,
|
||||
// Start time: 0.
|
||||
stream_generator_.reset(new StreamGenerator(30, 3e5, 1e6, 0));
|
||||
@ -196,6 +196,7 @@ class RemoteBitrateEstimatorTest : public ::testing::Test {
|
||||
return bitrate_bps;
|
||||
}
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
scoped_ptr<RemoteBitrateEstimator> bitrate_estimator_;
|
||||
scoped_ptr<TestBitrateObserver> bitrate_observer_;
|
||||
scoped_ptr<StreamGenerator> stream_generator_;
|
||||
|
@ -59,11 +59,14 @@ class TestTransport : public Transport {
|
||||
class RtcpFormatRembTest : public ::testing::Test {
|
||||
protected:
|
||||
RtcpFormatRembTest()
|
||||
: remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(&remote_bitrate_observer_) {}
|
||||
: over_use_detector_options_(),
|
||||
remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(&remote_bitrate_observer_,
|
||||
over_use_detector_options_) {}
|
||||
virtual void SetUp();
|
||||
virtual void TearDown();
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
RtpRtcpClock* system_clock_;
|
||||
ModuleRtpRtcpImpl* dummy_rtp_rtcp_impl_;
|
||||
RTCPSender* rtcp_sender_;
|
||||
|
@ -183,8 +183,10 @@ class TestTransport : public Transport,
|
||||
class RtcpReceiverTest : public ::testing::Test {
|
||||
protected:
|
||||
RtcpReceiverTest()
|
||||
: remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(&remote_bitrate_observer_) {
|
||||
: over_use_detector_options_(),
|
||||
remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(&remote_bitrate_observer_,
|
||||
over_use_detector_options_) {
|
||||
// system_clock_ = ModuleRTPUtility::GetSystemClock();
|
||||
system_clock_ = new FakeSystemClock();
|
||||
test_transport_ = new TestTransport();
|
||||
@ -221,6 +223,7 @@ class RtcpReceiverTest : public ::testing::Test {
|
||||
return result;
|
||||
}
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
FakeSystemClock* system_clock_;
|
||||
ModuleRtpRtcpImpl* rtp_rtcp_impl_;
|
||||
RTCPReceiver* rtcp_receiver_;
|
||||
|
@ -98,8 +98,10 @@ class TestTransport : public Transport,
|
||||
class RtcpSenderTest : public ::testing::Test {
|
||||
protected:
|
||||
RtcpSenderTest()
|
||||
: remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(&remote_bitrate_observer_) {
|
||||
: over_use_detector_options_(),
|
||||
remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(&remote_bitrate_observer_,
|
||||
over_use_detector_options_) {
|
||||
system_clock_ = ModuleRTPUtility::GetSystemClock();
|
||||
test_transport_ = new TestTransport();
|
||||
|
||||
@ -133,6 +135,7 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
packet_type) != 0U;
|
||||
}
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
RtpRtcpClock* system_clock_;
|
||||
ModuleRtpRtcpImpl* rtp_rtcp_impl_;
|
||||
RTCPSender* rtcp_sender_;
|
||||
|
@ -19,10 +19,12 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
ChannelGroup::ChannelGroup(ProcessThread* process_thread)
|
||||
ChannelGroup::ChannelGroup(ProcessThread* process_thread,
|
||||
const OverUseDetectorOptions& options)
|
||||
: remb_(new VieRemb(process_thread)),
|
||||
bitrate_controller_(BitrateController::CreateBitrateController()),
|
||||
remote_bitrate_estimator_(new RemoteBitrateEstimator(remb_.get())) {
|
||||
remote_bitrate_estimator_(new RemoteBitrateEstimator(remb_.get(),
|
||||
options)) {
|
||||
}
|
||||
|
||||
ChannelGroup::~ChannelGroup() {
|
||||
|
@ -18,6 +18,7 @@
|
||||
namespace webrtc {
|
||||
|
||||
class BitrateController;
|
||||
struct OverUseDetectorOptions;
|
||||
class ProcessThread;
|
||||
class RemoteBitrateEstimator;
|
||||
class RemoteBitrateObserver;
|
||||
@ -29,7 +30,8 @@ class VieRemb;
|
||||
// group are assumed to send/receive data to the same end-point.
|
||||
class ChannelGroup {
|
||||
public:
|
||||
explicit ChannelGroup(ProcessThread* process_thread);
|
||||
ChannelGroup(ProcessThread* process_thread,
|
||||
const OverUseDetectorOptions& options);
|
||||
~ChannelGroup();
|
||||
|
||||
void AddChannel(int channel_id);
|
||||
|
@ -27,7 +27,8 @@ namespace webrtc {
|
||||
ViEChannelManager::ViEChannelManager(
|
||||
int engine_id,
|
||||
int number_of_cores,
|
||||
ViEPerformanceMonitor& vie_performance_monitor)
|
||||
ViEPerformanceMonitor& vie_performance_monitor,
|
||||
const OverUseDetectorOptions& options)
|
||||
: channel_id_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
engine_id_(engine_id),
|
||||
number_of_cores_(number_of_cores),
|
||||
@ -35,7 +36,8 @@ ViEChannelManager::ViEChannelManager(
|
||||
free_channel_ids_size_(kViEMaxNumberOfChannels),
|
||||
voice_sync_interface_(NULL),
|
||||
voice_engine_(NULL),
|
||||
module_process_thread_(NULL) {
|
||||
module_process_thread_(NULL),
|
||||
over_use_detector_options_(options) {
|
||||
WEBRTC_TRACE(kTraceMemory, kTraceVideo, ViEId(engine_id),
|
||||
"ViEChannelManager::ViEChannelManager(engine_id: %d)",
|
||||
engine_id);
|
||||
@ -87,7 +89,8 @@ int ViEChannelManager::CreateChannel(int& channel_id) {
|
||||
}
|
||||
|
||||
// Create a new channel group and add this channel.
|
||||
ChannelGroup* group = new ChannelGroup(module_process_thread_);
|
||||
ChannelGroup* group = new ChannelGroup(module_process_thread_,
|
||||
over_use_detector_options_);
|
||||
BitrateController* bitrate_controller = group->GetBitrateController();
|
||||
ViEEncoder* vie_encoder = new ViEEncoder(engine_id_, new_channel_id,
|
||||
number_of_cores_,
|
||||
|
@ -43,7 +43,8 @@ class ViEChannelManager: private ViEManagerBase {
|
||||
public:
|
||||
ViEChannelManager(int engine_id,
|
||||
int number_of_cores,
|
||||
ViEPerformanceMonitor& vie_performance_monitor);
|
||||
ViEPerformanceMonitor& vie_performance_monitor,
|
||||
const OverUseDetectorOptions& options);
|
||||
~ViEChannelManager();
|
||||
|
||||
void SetModuleProcessThread(ProcessThread& module_process_thread);
|
||||
@ -125,6 +126,7 @@ class ViEChannelManager: private ViEManagerBase {
|
||||
|
||||
VoiceEngine* voice_engine_;
|
||||
ProcessThread* module_process_thread_;
|
||||
const OverUseDetectorOptions& over_use_detector_options_;
|
||||
};
|
||||
|
||||
class ViEChannelManagerScoped: private ViEManagerScopedBase {
|
||||
|
@ -26,9 +26,11 @@ ViESharedData::ViESharedData()
|
||||
: instance_id_(++instance_counter_),
|
||||
initialized_(false),
|
||||
number_cores_(CpuInfo::DetectNumberOfCores()),
|
||||
over_use_detector_options_(),
|
||||
vie_performance_monitor_(ViEPerformanceMonitor(instance_id_)),
|
||||
channel_manager_(*new ViEChannelManager(instance_id_, number_cores_,
|
||||
vie_performance_monitor_)),
|
||||
vie_performance_monitor_,
|
||||
over_use_detector_options_)),
|
||||
input_manager_(*new ViEInputManager(instance_id_)),
|
||||
render_manager_(*new ViERenderManager(instance_id_)),
|
||||
module_process_thread_(ProcessThread::CreateProcessThread()),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 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
|
||||
@ -50,6 +50,7 @@ class ViESharedData {
|
||||
bool initialized_;
|
||||
const int number_cores_;
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
ViEPerformanceMonitor vie_performance_monitor_;
|
||||
ViEChannelManager& channel_manager_;
|
||||
ViEInputManager& input_manager_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user