Remove MimdRateControl and factories for RemoteBitrateEstimor.

BUG=
R=stefan@webrtc.org

Review URL: https://codereview.webrtc.org/1208083002.

Cr-Commit-Position: refs/heads/master@{#9541}
This commit is contained in:
Erik Språng 2015-07-06 10:50:47 +02:00
parent d92f2674d7
commit 468e62a974
26 changed files with 439 additions and 948 deletions

View File

@ -29,16 +29,12 @@ source_set("rbe_components") {
"aimd_rate_control.h",
"inter_arrival.cc",
"inter_arrival.h",
"mimd_rate_control.cc",
"mimd_rate_control.h",
"overuse_detector.cc",
"overuse_detector.h",
"overuse_estimator.cc",
"overuse_estimator.h",
"remote_bitrate_estimator_abs_send_time.cc",
"remote_bitrate_estimator_single_stream.cc",
"remote_rate_control.cc",
"remote_rate_control.h",
]
configs += [ "../..:common_config" ]

View File

@ -21,6 +21,7 @@ namespace webrtc {
static const int64_t kDefaultRttMs = 200;
static const int64_t kLogIntervalMs = 1000;
static const double kWithinIncomingBitrateHysteresis = 1.05;
static const int64_t kMaxFeedbackIntervalMs = 1000;
AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
: min_configured_bitrate_bps_(min_bitrate_bps),
@ -41,10 +42,6 @@ AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
rtt_(kDefaultRttMs),
time_of_last_log_(-1) {}
RateControlType AimdRateControl::GetControlType() const {
return kAimdControl;
}
uint32_t AimdRateControl::GetMinBitrate() const {
return min_configured_bitrate_bps_;
}

View File

@ -11,38 +11,37 @@
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_AIMD_RATE_CONTROL_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_AIMD_RATE_CONTROL_H_
#include "webrtc/base/constructormagic.h"
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
namespace webrtc {
// A RemoteRateControl implementation based on additive increases of
// A rate control implementation based on additive increases of
// bitrate when no over-use is detected and multiplicative decreases when
// over-uses are detected. When we think the available bandwidth has changes or
// is unknown, we will switch to a "slow-start mode" where we increase
// multiplicatively.
class AimdRateControl : public RemoteRateControl {
class AimdRateControl {
public:
explicit AimdRateControl(uint32_t min_bitrate_bps);
virtual ~AimdRateControl() {}
// Implements RemoteRateControl.
bool ValidEstimate() const override;
RateControlType GetControlType() const override;
uint32_t GetMinBitrate() const override;
int64_t GetFeedbackInterval() const override;
// Returns true if there is a valid estimate of the incoming bitrate, false
// otherwise.
bool ValidEstimate() const;
uint32_t GetMinBitrate() const;
int64_t GetFeedbackInterval() const;
// Returns true if the bitrate estimate hasn't been changed for more than
// an RTT, or if the incoming_bitrate is more than 5% above the current
// estimate. Should be used to decide if we should reduce the rate further
// when over-using.
bool TimeToReduceFurther(int64_t time_now,
uint32_t incoming_bitrate_bps) const override;
uint32_t LatestEstimate() const override;
uint32_t UpdateBandwidthEstimate(int64_t now_ms) override;
void SetRtt(int64_t rtt) override;
RateControlRegion Update(const RateControlInput* input,
int64_t now_ms) override;
void SetEstimate(int bitrate_bps, int64_t now_ms) override;
uint32_t incoming_bitrate_bps) const;
uint32_t LatestEstimate() const;
uint32_t UpdateBandwidthEstimate(int64_t now_ms);
void SetRtt(int64_t rtt);
RateControlRegion Update(const RateControlInput* input, int64_t now_ms);
void SetEstimate(int bitrate_bps, int64_t now_ms);
private:
// Update the target bitrate according based on, among other things,

View File

@ -25,11 +25,6 @@ namespace webrtc {
class Clock;
enum RateControlType {
kMimdControl,
kAimdControl
};
// RemoteBitrateObserver is used to signal changes in bitrate estimates for
// the incoming streams.
class RemoteBitrateObserver {
@ -125,28 +120,6 @@ class RemoteBitrateEstimator : public CallStatsObserver, public Module {
static const int64_t kStreamTimeOutMs = 2000;
};
struct RemoteBitrateEstimatorFactory {
RemoteBitrateEstimatorFactory() {}
virtual ~RemoteBitrateEstimatorFactory() {}
virtual RemoteBitrateEstimator* Create(
RemoteBitrateObserver* observer,
Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps) const;
};
struct AbsoluteSendTimeRemoteBitrateEstimatorFactory
: public RemoteBitrateEstimatorFactory {
AbsoluteSendTimeRemoteBitrateEstimatorFactory() {}
virtual ~AbsoluteSendTimeRemoteBitrateEstimatorFactory() {}
virtual RemoteBitrateEstimator* Create(
RemoteBitrateObserver* observer,
Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps) const;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_REMOTE_BITRATE_ESTIMATOR_H_

View File

@ -1,328 +0,0 @@
/*
* Copyright (c) 2014 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/modules/remote_bitrate_estimator/mimd_rate_control.h"
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
namespace webrtc {
const int64_t kDefaultRttMs = 200;
const int64_t kLogIntervalMs = 1000;
MimdRateControl::MimdRateControl(uint32_t min_bitrate_bps)
: min_configured_bit_rate_(min_bitrate_bps),
max_configured_bit_rate_(30000000),
current_bit_rate_(max_configured_bit_rate_),
max_hold_rate_(0),
avg_max_bit_rate_(-1.0f),
var_max_bit_rate_(0.4f),
rate_control_state_(kRcHold),
came_from_state_(kRcDecrease),
rate_control_region_(kRcMaxUnknown),
last_bit_rate_change_(-1),
current_input_(kBwNormal, 0, 1.0),
updated_(false),
time_first_incoming_estimate_(-1),
initialized_bit_rate_(false),
avg_change_period_(1000.0f),
last_change_ms_(-1),
beta_(0.9f),
rtt_(kDefaultRttMs),
time_of_last_log_(-1)
{
}
RateControlType MimdRateControl::GetControlType() const {
return kMimdControl;
}
uint32_t MimdRateControl::GetMinBitrate() const {
return min_configured_bit_rate_;
}
bool MimdRateControl::ValidEstimate() const {
return initialized_bit_rate_;
}
int64_t MimdRateControl::GetFeedbackInterval() const {
return kMaxFeedbackIntervalMs;
}
bool MimdRateControl::TimeToReduceFurther(int64_t time_now,
uint32_t incoming_bitrate_bps) const {
const int64_t bitrate_reduction_interval =
std::max<int64_t>(std::min<int64_t>(rtt_, 200), 10);
if (time_now - last_bit_rate_change_ >= bitrate_reduction_interval) {
return true;
}
if (ValidEstimate()) {
const int threshold = static_cast<int>(1.05 * incoming_bitrate_bps);
const int bitrate_difference = LatestEstimate() - incoming_bitrate_bps;
return bitrate_difference > threshold;
}
return false;
}
uint32_t MimdRateControl::LatestEstimate() const {
return current_bit_rate_;
}
uint32_t MimdRateControl::UpdateBandwidthEstimate(int64_t now_ms) {
current_bit_rate_ = ChangeBitRate(current_bit_rate_,
current_input_._incomingBitRate,
current_input_._noiseVar,
now_ms);
if (now_ms - time_of_last_log_ > kLogIntervalMs) {
time_of_last_log_ = now_ms;
}
return current_bit_rate_;
}
void MimdRateControl::SetRtt(int64_t rtt) {
rtt_ = rtt;
}
RateControlRegion MimdRateControl::Update(const RateControlInput* input,
int64_t now_ms) {
assert(input);
// Set the initial bit rate value to what we're receiving the first half
// second.
if (!initialized_bit_rate_) {
if (time_first_incoming_estimate_ < 0) {
if (input->_incomingBitRate > 0) {
time_first_incoming_estimate_ = now_ms;
}
} else if (now_ms - time_first_incoming_estimate_ > 500 &&
input->_incomingBitRate > 0) {
current_bit_rate_ = input->_incomingBitRate;
initialized_bit_rate_ = true;
}
}
if (updated_ && current_input_._bwState == kBwOverusing) {
// Only update delay factor and incoming bit rate. We always want to react
// on an over-use.
current_input_._noiseVar = input->_noiseVar;
current_input_._incomingBitRate = input->_incomingBitRate;
return rate_control_region_;
}
updated_ = true;
current_input_ = *input;
return rate_control_region_;
}
void MimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
}
uint32_t MimdRateControl::ChangeBitRate(uint32_t current_bit_rate,
uint32_t incoming_bit_rate,
double noise_var,
int64_t now_ms) {
if (!updated_) {
return current_bit_rate_;
}
updated_ = false;
UpdateChangePeriod(now_ms);
ChangeState(current_input_, now_ms);
// calculated here because it's used in multiple places
const float incoming_bit_rate_kbps = incoming_bit_rate / 1000.0f;
// Calculate the max bit rate std dev given the normalized
// variance and the current incoming bit rate.
const float std_max_bit_rate = sqrt(var_max_bit_rate_ * avg_max_bit_rate_);
bool recovery = false;
switch (rate_control_state_) {
case kRcHold: {
max_hold_rate_ = std::max(max_hold_rate_, incoming_bit_rate);
break;
}
case kRcIncrease: {
if (avg_max_bit_rate_ >= 0) {
if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 3 * std_max_bit_rate) {
ChangeRegion(kRcMaxUnknown);
avg_max_bit_rate_ = -1.0;
} else if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 2.5 *
std_max_bit_rate) {
ChangeRegion(kRcAboveMax);
}
}
const int64_t response_time =
static_cast<int64_t>(avg_change_period_ + 0.5f) + rtt_ + 300;
double alpha = RateIncreaseFactor(now_ms, last_bit_rate_change_,
response_time, noise_var);
current_bit_rate = static_cast<uint32_t>(current_bit_rate * alpha) + 1000;
if (max_hold_rate_ > 0 && beta_ * max_hold_rate_ > current_bit_rate) {
current_bit_rate = static_cast<uint32_t>(beta_ * max_hold_rate_);
avg_max_bit_rate_ = beta_ * max_hold_rate_ / 1000.0f;
ChangeRegion(kRcNearMax);
recovery = true;
}
max_hold_rate_ = 0;
last_bit_rate_change_ = now_ms;
break;
}
case kRcDecrease: {
if (incoming_bit_rate < min_configured_bit_rate_) {
current_bit_rate = min_configured_bit_rate_;
} else {
// Set bit rate to something slightly lower than max
// to get rid of any self-induced delay.
current_bit_rate = static_cast<uint32_t>(beta_ * incoming_bit_rate +
0.5);
if (current_bit_rate > current_bit_rate_) {
// Avoid increasing the rate when over-using.
if (rate_control_region_ != kRcMaxUnknown) {
current_bit_rate = static_cast<uint32_t>(beta_ * avg_max_bit_rate_ *
1000 + 0.5f);
}
current_bit_rate = std::min(current_bit_rate, current_bit_rate_);
}
ChangeRegion(kRcNearMax);
if (incoming_bit_rate_kbps < avg_max_bit_rate_ - 3 * std_max_bit_rate) {
avg_max_bit_rate_ = -1.0f;
}
UpdateMaxBitRateEstimate(incoming_bit_rate_kbps);
}
// Stay on hold until the pipes are cleared.
ChangeState(kRcHold);
last_bit_rate_change_ = now_ms;
break;
}
default:
assert(false);
}
if (!recovery && (incoming_bit_rate > 100000 || current_bit_rate > 150000) &&
current_bit_rate > 1.5 * incoming_bit_rate) {
// Allow changing the bit rate if we are operating at very low rates
// Don't change the bit rate if the send side is too far off
current_bit_rate = current_bit_rate_;
last_bit_rate_change_ = now_ms;
}
return current_bit_rate;
}
double MimdRateControl::RateIncreaseFactor(int64_t now_ms,
int64_t last_ms,
int64_t reaction_time_ms,
double noise_var) const {
// alpha = 1.02 + B ./ (1 + exp(b*(tr - (c1*s2 + c2))))
// Parameters
const double B = 0.0407;
const double b = 0.0025;
const double c1 = -6700.0 / (33 * 33);
const double c2 = 800.0;
const double d = 0.85;
double alpha = 1.005 + B / (1 + exp( b * (d * reaction_time_ms -
(c1 * noise_var + c2))));
if (alpha < 1.005) {
alpha = 1.005;
} else if (alpha > 1.3) {
alpha = 1.3;
}
if (last_ms > -1) {
alpha = pow(alpha, (now_ms - last_ms) / 1000.0);
}
if (rate_control_region_ == kRcNearMax) {
// We're close to our previous maximum. Try to stabilize the
// bit rate in this region, by increasing in smaller steps.
alpha = alpha - (alpha - 1.0) / 2.0;
} else if (rate_control_region_ == kRcMaxUnknown) {
alpha = alpha + (alpha - 1.0) * 2.0;
}
return alpha;
}
void MimdRateControl::UpdateChangePeriod(int64_t now_ms) {
int64_t change_period = 0;
if (last_change_ms_ > -1) {
change_period = now_ms - last_change_ms_;
}
last_change_ms_ = now_ms;
avg_change_period_ = 0.9f * avg_change_period_ + 0.1f * change_period;
}
void MimdRateControl::UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps) {
const float alpha = 0.05f;
if (avg_max_bit_rate_ == -1.0f) {
avg_max_bit_rate_ = incoming_bit_rate_kbps;
} else {
avg_max_bit_rate_ = (1 - alpha) * avg_max_bit_rate_ +
alpha * incoming_bit_rate_kbps;
}
// Estimate the max bit rate variance and normalize the variance
// with the average max bit rate.
const float norm = std::max(avg_max_bit_rate_, 1.0f);
var_max_bit_rate_ = (1 - alpha) * var_max_bit_rate_ +
alpha * (avg_max_bit_rate_ - incoming_bit_rate_kbps) *
(avg_max_bit_rate_ - incoming_bit_rate_kbps) / norm;
// 0.4 ~= 14 kbit/s at 500 kbit/s
if (var_max_bit_rate_ < 0.4f) {
var_max_bit_rate_ = 0.4f;
}
// 2.5f ~= 35 kbit/s at 500 kbit/s
if (var_max_bit_rate_ > 2.5f) {
var_max_bit_rate_ = 2.5f;
}
}
void MimdRateControl::ChangeState(const RateControlInput& input,
int64_t now_ms) {
switch (current_input_._bwState) {
case kBwNormal:
if (rate_control_state_ == kRcHold) {
last_bit_rate_change_ = now_ms;
ChangeState(kRcIncrease);
}
break;
case kBwOverusing:
if (rate_control_state_ != kRcDecrease) {
ChangeState(kRcDecrease);
}
break;
case kBwUnderusing:
ChangeState(kRcHold);
break;
default:
assert(false);
}
}
void MimdRateControl::ChangeRegion(RateControlRegion region) {
rate_control_region_ = region;
switch (rate_control_region_) {
case kRcAboveMax:
case kRcMaxUnknown:
beta_ = 0.9f;
break;
case kRcNearMax:
beta_ = 0.95f;
break;
default:
assert(false);
}
}
void MimdRateControl::ChangeState(RateControlState new_state) {
came_from_state_ = rate_control_state_;
rate_control_state_ = new_state;
}
} // namespace webrtc

View File

@ -1,80 +0,0 @@
/*
* Copyright (c) 2014 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_REMOTE_BITRATE_ESTIMATOR_MIMD_RATE_CONTROL_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_MIMD_RATE_CONTROL_H_
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
namespace webrtc {
// A RemoteRateControl implementation based on multiplicative increases of
// bitrate when no over-use is detected and multiplicative decreases when
// over-uses are detected.
class MimdRateControl : public RemoteRateControl {
public:
explicit MimdRateControl(uint32_t min_bitrate_bps);
virtual ~MimdRateControl() {}
// Implements RemoteRateControl.
RateControlType GetControlType() const override;
uint32_t GetMinBitrate() const override;
bool ValidEstimate() const override;
int64_t GetFeedbackInterval() const override;
bool TimeToReduceFurther(int64_t time_now,
uint32_t incoming_bitrate_bps) const override;
uint32_t LatestEstimate() const override;
uint32_t UpdateBandwidthEstimate(int64_t now_ms) override;
void SetRtt(int64_t rtt) override;
RateControlRegion Update(const RateControlInput* input,
int64_t now_ms) override;
void SetEstimate(int bitrate_bps, int64_t now_ms) override;
private:
uint32_t ChangeBitRate(uint32_t current_bit_rate,
uint32_t incoming_bit_rate,
double delay_factor,
int64_t now_ms);
double RateIncreaseFactor(int64_t now_ms,
int64_t last_ms,
int64_t reaction_time_ms,
double noise_var) const;
void UpdateChangePeriod(int64_t now_ms);
void UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps);
void ChangeState(const RateControlInput& input, int64_t now_ms);
void ChangeState(RateControlState new_state);
void ChangeRegion(RateControlRegion region);
uint32_t min_configured_bit_rate_;
uint32_t max_configured_bit_rate_;
uint32_t current_bit_rate_;
uint32_t max_hold_rate_;
float avg_max_bit_rate_;
float var_max_bit_rate_;
RateControlState rate_control_state_;
RateControlState came_from_state_;
RateControlRegion rate_control_region_;
int64_t last_bit_rate_change_;
RateControlInput current_input_;
bool updated_;
int64_t time_first_incoming_estimate_;
bool initialized_bit_rate_;
float avg_change_period_;
int64_t last_change_ms_;
float beta_;
int64_t rtt_;
int64_t time_of_last_log_;
DISALLOW_IMPLICIT_CONSTRUCTORS(MimdRateControl);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_MIMD_RATE_CONTROL_H_

View File

@ -25,8 +25,6 @@
'aimd_rate_control.h',
'inter_arrival.cc',
'inter_arrival.h',
'mimd_rate_control.cc',
'mimd_rate_control.h',
'overuse_detector.cc',
'overuse_detector.h',
'overuse_estimator.cc',
@ -34,9 +32,9 @@
'rate_statistics.cc',
'rate_statistics.h',
'remote_bitrate_estimator_abs_send_time.cc',
'remote_bitrate_estimator_abs_send_time.h',
'remote_bitrate_estimator_single_stream.cc',
'remote_rate_control.cc',
'remote_rate_control.h',
'remote_bitrate_estimator_single_stream.h',
'test/bwe_test_logging.cc',
'test/bwe_test_logging.h',
], # source

View File

@ -8,18 +8,14 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
#include <math.h>
#include <map>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h"
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
#include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
@ -67,74 +63,9 @@ std::vector<K> Keys(const std::map<K, V>& map) {
return keys;
}
struct Probe {
Probe(int64_t send_time_ms, int64_t recv_time_ms, size_t payload_size)
: send_time_ms(send_time_ms),
recv_time_ms(recv_time_ms),
payload_size(payload_size) {}
int64_t send_time_ms;
int64_t recv_time_ms;
size_t payload_size;
};
struct Cluster {
Cluster()
: send_mean_ms(0.0f),
recv_mean_ms(0.0f),
mean_size(0),
count(0),
num_above_min_delta(0) {}
int GetSendBitrateBps() const {
assert(send_mean_ms > 0);
return mean_size * 8 * 1000 / send_mean_ms;
}
int GetRecvBitrateBps() const {
assert(recv_mean_ms > 0);
return mean_size * 8 * 1000 / recv_mean_ms;
}
float send_mean_ms;
float recv_mean_ms;
// TODO(holmer): Add some variance metric as well?
size_t mean_size;
int count;
int num_above_min_delta;
};
class RemoteBitrateEstimatorAbsSendTimeImpl : public RemoteBitrateEstimator {
public:
RemoteBitrateEstimatorAbsSendTimeImpl(RemoteBitrateObserver* observer,
Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps);
virtual ~RemoteBitrateEstimatorAbsSendTimeImpl() {}
void IncomingPacketFeedbackVector(
const std::vector<PacketInfo>& packet_feedback_vector) override;
void IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) override;
// This class relies on Process() being called periodically (at least once
// every other second) for streams to be timed out properly. Therefore it
// shouldn't be detached from the ProcessThread except if it's about to be
// deleted.
int32_t Process() override;
int64_t TimeUntilNextProcess() override;
void OnRttUpdate(int64_t rtt) override;
void RemoveStream(unsigned int ssrc) override;
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
unsigned int* bitrate_bps) const override;
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
private:
typedef std::map<unsigned int, int64_t> Ssrcs;
static bool IsWithinClusterBounds(int send_delta_ms,
const Cluster& cluster_aggregate) {
bool RemoteBitrateEstimatorAbsSendTime::IsWithinClusterBounds(
int send_delta_ms,
const Cluster& cluster_aggregate) {
if (cluster_aggregate.count == 0)
return true;
float cluster_mean = cluster_aggregate.send_mean_ms /
@ -142,91 +73,43 @@ class RemoteBitrateEstimatorAbsSendTimeImpl : public RemoteBitrateEstimator {
return fabs(static_cast<float>(send_delta_ms) - cluster_mean) < 2.5f;
}
static void AddCluster(std::list<Cluster>* clusters, Cluster* cluster) {
void RemoteBitrateEstimatorAbsSendTime::AddCluster(
std::list<Cluster>* clusters,
Cluster* cluster) {
cluster->send_mean_ms /= static_cast<float>(cluster->count);
cluster->recv_mean_ms /= static_cast<float>(cluster->count);
cluster->mean_size /= cluster->count;
clusters->push_back(*cluster);
}
int Id() const {
int RemoteBitrateEstimatorAbsSendTime::Id() const {
return static_cast<int>(reinterpret_cast<uint64_t>(this));
}
void IncomingPacketInfo(int64_t arrival_time_ms,
uint32_t send_time_24bits,
size_t payload_size,
uint32_t ssrc,
bool was_paced);
bool IsProbe(int64_t send_time_ms, int payload_size) const
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
// Triggers a new estimate calculation.
void UpdateEstimate(int64_t now_ms)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void UpdateStats(int propagation_delta_ms, int64_t now_ms)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void ComputeClusters(std::list<Cluster>* clusters) const;
std::list<Cluster>::const_iterator FindBestProbe(
const std::list<Cluster>& clusters) const
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void ProcessClusters(int64_t now_ms)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
bool IsBitrateImproving(int probe_bitrate_bps) const
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
Clock* clock_;
Ssrcs ssrcs_ GUARDED_BY(crit_sect_.get());
rtc::scoped_ptr<InterArrival> inter_arrival_ GUARDED_BY(crit_sect_.get());
OveruseEstimator estimator_ GUARDED_BY(crit_sect_.get());
OveruseDetector detector_ GUARDED_BY(crit_sect_.get());
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
rtc::scoped_ptr<RemoteRateControl> remote_rate_ GUARDED_BY(crit_sect_.get());
int64_t last_process_time_;
std::vector<int> recent_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
std::vector<int64_t> recent_update_time_ms_ GUARDED_BY(crit_sect_.get());
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
int total_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
std::list<Probe> probes_;
size_t total_probes_received_;
int64_t first_packet_time_ms_;
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorAbsSendTimeImpl);
};
RemoteBitrateEstimatorAbsSendTimeImpl::RemoteBitrateEstimatorAbsSendTimeImpl(
RemoteBitrateObserver* observer,
Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps)
: crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
observer_(observer),
clock_(clock),
ssrcs_(),
inter_arrival_(),
estimator_(OverUseDetectorOptions()),
detector_(OverUseDetectorOptions()),
incoming_bitrate_(1000, 8000),
remote_rate_(RemoteRateControl::Create(control_type, min_bitrate_bps)),
last_process_time_(-1),
process_interval_ms_(kProcessIntervalMs),
total_propagation_delta_ms_(0),
total_probes_received_(0),
first_packet_time_ms_(-1) {
RemoteBitrateEstimatorAbsSendTime::RemoteBitrateEstimatorAbsSendTime(
RemoteBitrateObserver* observer,
Clock* clock,
uint32_t min_bitrate_bps)
: crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
observer_(observer),
clock_(clock),
ssrcs_(),
inter_arrival_(),
estimator_(OverUseDetectorOptions()),
detector_(OverUseDetectorOptions()),
incoming_bitrate_(1000, 8000),
remote_rate_(min_bitrate_bps),
last_process_time_(-1),
process_interval_ms_(kProcessIntervalMs),
total_propagation_delta_ms_(0),
total_probes_received_(0),
first_packet_time_ms_(-1) {
assert(observer_);
assert(clock_);
LOG(LS_INFO) << "RemoteBitrateEstimatorAbsSendTime: Instantiating.";
}
void RemoteBitrateEstimatorAbsSendTimeImpl::ComputeClusters(
void RemoteBitrateEstimatorAbsSendTime::ComputeClusters(
std::list<Cluster>* clusters) const {
Cluster current;
int64_t prev_send_time = -1;
@ -258,7 +141,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::ComputeClusters(
}
std::list<Cluster>::const_iterator
RemoteBitrateEstimatorAbsSendTimeImpl::FindBestProbe(
RemoteBitrateEstimatorAbsSendTime::FindBestProbe(
const std::list<Cluster>& clusters) const {
int highest_probe_bitrate_bps = 0;
std::list<Cluster>::const_iterator best_it = clusters.end();
@ -290,7 +173,7 @@ RemoteBitrateEstimatorAbsSendTimeImpl::FindBestProbe(
return best_it;
}
void RemoteBitrateEstimatorAbsSendTimeImpl::ProcessClusters(int64_t now_ms) {
void RemoteBitrateEstimatorAbsSendTime::ProcessClusters(int64_t now_ms) {
std::list<Cluster> clusters;
ComputeClusters(&clusters);
if (clusters.empty()) {
@ -312,7 +195,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::ProcessClusters(int64_t now_ms) {
<< " bps. Mean send delta: " << best_it->send_mean_ms
<< " ms, mean recv delta: " << best_it->recv_mean_ms
<< " ms, num probes: " << best_it->count;
remote_rate_->SetEstimate(probe_bitrate_bps, now_ms);
remote_rate_.SetEstimate(probe_bitrate_bps, now_ms);
}
}
@ -322,16 +205,16 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::ProcessClusters(int64_t now_ms) {
probes_.clear();
}
bool RemoteBitrateEstimatorAbsSendTimeImpl::IsBitrateImproving(
bool RemoteBitrateEstimatorAbsSendTime::IsBitrateImproving(
int new_bitrate_bps) const {
bool initial_probe = !remote_rate_->ValidEstimate() && new_bitrate_bps > 0;
bool initial_probe = !remote_rate_.ValidEstimate() && new_bitrate_bps > 0;
bool bitrate_above_estimate =
remote_rate_->ValidEstimate() &&
new_bitrate_bps > static_cast<int>(remote_rate_->LatestEstimate());
remote_rate_.ValidEstimate() &&
new_bitrate_bps > static_cast<int>(remote_rate_.LatestEstimate());
return initial_probe || bitrate_above_estimate;
}
void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketFeedbackVector(
void RemoteBitrateEstimatorAbsSendTime::IncomingPacketFeedbackVector(
const std::vector<PacketInfo>& packet_feedback_vector) {
for (const auto& packet_info : packet_feedback_vector) {
// TODO(holmer): We should get rid of this conversion if possible as we may
@ -344,11 +227,10 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketFeedbackVector(
}
}
void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacket(
int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) {
void RemoteBitrateEstimatorAbsSendTime::IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) {
if (!header.extension.hasAbsoluteSendTime) {
LOG(LS_WARNING) << "RemoteBitrateEstimatorAbsSendTimeImpl: Incoming packet "
"is missing absolute send time extension!";
@ -357,7 +239,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacket(
payload_size, header.ssrc, was_paced);
}
void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
void RemoteBitrateEstimatorAbsSendTime::IncomingPacketInfo(
int64_t arrival_time_ms,
uint32_t send_time_24bits,
size_t payload_size,
@ -385,7 +267,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
int size_delta = 0;
// For now only try to detect probes while we don't have a valid estimate.
if (was_paced &&
(!remote_rate_->ValidEstimate() ||
(!remote_rate_.ValidEstimate() ||
now_ms - first_packet_time_ms_ < kInitialProbingIntervalMs)) {
// TODO(holmer): Use a map instead to get correct order?
if (total_probes_received_ < kMaxProbePackets) {
@ -405,9 +287,9 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
ProcessClusters(now_ms);
}
if (!inter_arrival_.get()) {
inter_arrival_.reset(new InterArrival(
(kTimestampGroupLengthMs << kInterArrivalShift) / 1000, kTimestampToMs,
remote_rate_->GetControlType() == kAimdControl));
inter_arrival_.reset(
new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
kTimestampToMs, true));
}
if (inter_arrival_->ComputeDeltas(timestamp, arrival_time_ms, payload_size,
&ts_delta, &t_delta, &size_delta)) {
@ -420,7 +302,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
if (detector_.State() == kBwOverusing) {
unsigned int incoming_bitrate = incoming_bitrate_.Rate(now_ms);
if (prior_state != kBwOverusing ||
remote_rate_->TimeToReduceFurther(now_ms, incoming_bitrate)) {
remote_rate_.TimeToReduceFurther(now_ms, incoming_bitrate)) {
// The first overuse should immediately trigger a new estimate.
// We also have to update the estimate immediately if we are overusing
// and the target bitrate is too high compared to what we are receiving.
@ -429,7 +311,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
}
}
int32_t RemoteBitrateEstimatorAbsSendTimeImpl::Process() {
int32_t RemoteBitrateEstimatorAbsSendTime::Process() {
if (TimeUntilNextProcess() > 0) {
return 0;
}
@ -441,7 +323,7 @@ int32_t RemoteBitrateEstimatorAbsSendTimeImpl::Process() {
return 0;
}
int64_t RemoteBitrateEstimatorAbsSendTimeImpl::TimeUntilNextProcess() {
int64_t RemoteBitrateEstimatorAbsSendTime::TimeUntilNextProcess() {
if (last_process_time_ < 0) {
return 0;
}
@ -452,7 +334,7 @@ int64_t RemoteBitrateEstimatorAbsSendTimeImpl::TimeUntilNextProcess() {
}
}
void RemoteBitrateEstimatorAbsSendTimeImpl::UpdateEstimate(int64_t now_ms) {
void RemoteBitrateEstimatorAbsSendTime::UpdateEstimate(int64_t now_ms) {
if (!inter_arrival_.get()) {
// No packets have been received on the active streams.
return;
@ -475,44 +357,44 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::UpdateEstimate(int64_t now_ms) {
const RateControlInput input(detector_.State(),
incoming_bitrate_.Rate(now_ms),
estimator_.var_noise());
const RateControlRegion region = remote_rate_->Update(&input, now_ms);
unsigned int target_bitrate = remote_rate_->UpdateBandwidthEstimate(now_ms);
if (remote_rate_->ValidEstimate()) {
process_interval_ms_ = remote_rate_->GetFeedbackInterval();
const RateControlRegion region = remote_rate_.Update(&input, now_ms);
unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(now_ms);
if (remote_rate_.ValidEstimate()) {
process_interval_ms_ = remote_rate_.GetFeedbackInterval();
observer_->OnReceiveBitrateChanged(Keys(ssrcs_), target_bitrate);
}
detector_.SetRateControlRegion(region);
}
void RemoteBitrateEstimatorAbsSendTimeImpl::OnRttUpdate(int64_t rtt) {
void RemoteBitrateEstimatorAbsSendTime::OnRttUpdate(int64_t rtt) {
CriticalSectionScoped cs(crit_sect_.get());
remote_rate_->SetRtt(rtt);
remote_rate_.SetRtt(rtt);
}
void RemoteBitrateEstimatorAbsSendTimeImpl::RemoveStream(unsigned int ssrc) {
void RemoteBitrateEstimatorAbsSendTime::RemoveStream(unsigned int ssrc) {
CriticalSectionScoped cs(crit_sect_.get());
ssrcs_.erase(ssrc);
}
bool RemoteBitrateEstimatorAbsSendTimeImpl::LatestEstimate(
bool RemoteBitrateEstimatorAbsSendTime::LatestEstimate(
std::vector<unsigned int>* ssrcs,
unsigned int* bitrate_bps) const {
CriticalSectionScoped cs(crit_sect_.get());
assert(ssrcs);
assert(bitrate_bps);
if (!remote_rate_->ValidEstimate()) {
if (!remote_rate_.ValidEstimate()) {
return false;
}
*ssrcs = Keys(ssrcs_);
if (ssrcs_.empty()) {
*bitrate_bps = 0;
} else {
*bitrate_bps = remote_rate_->LatestEstimate();
*bitrate_bps = remote_rate_.LatestEstimate();
}
return true;
}
bool RemoteBitrateEstimatorAbsSendTimeImpl::GetStats(
bool RemoteBitrateEstimatorAbsSendTime::GetStats(
ReceiveBandwidthEstimatorStats* output) const {
{
CriticalSectionScoped cs(crit_sect_.get());
@ -527,8 +409,8 @@ bool RemoteBitrateEstimatorAbsSendTimeImpl::GetStats(
return true;
}
void RemoteBitrateEstimatorAbsSendTimeImpl::UpdateStats(
int propagation_delta_ms, int64_t now_ms) {
void RemoteBitrateEstimatorAbsSendTime::UpdateStats(int propagation_delta_ms,
int64_t now_ms) {
// The caller must enter crit_sect_ before the call.
// Remove the oldest entry if the size limit is reached.
@ -548,17 +430,4 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::UpdateStats(
total_propagation_delta_ms_ =
std::max(total_propagation_delta_ms_ + propagation_delta_ms, 0);
}
RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create(
RemoteBitrateObserver* observer,
Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps) const {
LOG(LS_INFO) << "AbsoluteSendTimeRemoteBitrateEstimatorFactory: "
"Instantiating.";
return new RemoteBitrateEstimatorAbsSendTimeImpl(observer,
clock,
control_type,
min_bitrate_bps);
}
} // namespace webrtc

View File

@ -0,0 +1,154 @@
/*
* 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_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_H_
#include <list>
#include <map>
#include <vector>
#include "webrtc/base/checks.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h"
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
#include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc {
struct Probe {
Probe(int64_t send_time_ms, int64_t recv_time_ms, size_t payload_size)
: send_time_ms(send_time_ms),
recv_time_ms(recv_time_ms),
payload_size(payload_size) {}
int64_t send_time_ms;
int64_t recv_time_ms;
size_t payload_size;
};
struct Cluster {
Cluster()
: send_mean_ms(0.0f),
recv_mean_ms(0.0f),
mean_size(0),
count(0),
num_above_min_delta(0) {}
int GetSendBitrateBps() const {
CHECK_GT(send_mean_ms, 0.0f);
return mean_size * 8 * 1000 / send_mean_ms;
}
int GetRecvBitrateBps() const {
CHECK_GT(recv_mean_ms, 0.0f);
return mean_size * 8 * 1000 / recv_mean_ms;
}
float send_mean_ms;
float recv_mean_ms;
// TODO(holmer): Add some variance metric as well?
size_t mean_size;
int count;
int num_above_min_delta;
};
class RemoteBitrateEstimatorAbsSendTime : public RemoteBitrateEstimator {
public:
RemoteBitrateEstimatorAbsSendTime(RemoteBitrateObserver* observer,
Clock* clock,
uint32_t min_bitrate_bps);
virtual ~RemoteBitrateEstimatorAbsSendTime() {}
void IncomingPacketFeedbackVector(
const std::vector<PacketInfo>& packet_feedback_vector) override;
void IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) override;
// This class relies on Process() being called periodically (at least once
// every other second) for streams to be timed out properly. Therefore it
// shouldn't be detached from the ProcessThread except if it's about to be
// deleted.
int32_t Process() override;
int64_t TimeUntilNextProcess() override;
void OnRttUpdate(int64_t rtt) override;
void RemoveStream(unsigned int ssrc) override;
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
unsigned int* bitrate_bps) const override;
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
private:
typedef std::map<unsigned int, int64_t> Ssrcs;
static bool IsWithinClusterBounds(int send_delta_ms,
const Cluster& cluster_aggregate);
static void AddCluster(std::list<Cluster>* clusters, Cluster* cluster);
int Id() const;
void IncomingPacketInfo(int64_t arrival_time_ms,
uint32_t send_time_24bits,
size_t payload_size,
uint32_t ssrc,
bool was_paced);
bool IsProbe(int64_t send_time_ms, int payload_size) const
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
// Triggers a new estimate calculation.
void UpdateEstimate(int64_t now_ms)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void UpdateStats(int propagation_delta_ms, int64_t now_ms)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void ComputeClusters(std::list<Cluster>* clusters) const;
std::list<Cluster>::const_iterator FindBestProbe(
const std::list<Cluster>& clusters) const
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void ProcessClusters(int64_t now_ms)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
bool IsBitrateImproving(int probe_bitrate_bps) const
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
Clock* clock_;
Ssrcs ssrcs_ GUARDED_BY(crit_sect_.get());
rtc::scoped_ptr<InterArrival> inter_arrival_ GUARDED_BY(crit_sect_.get());
OveruseEstimator estimator_ GUARDED_BY(crit_sect_.get());
OveruseDetector detector_ GUARDED_BY(crit_sect_.get());
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
AimdRateControl remote_rate_ GUARDED_BY(crit_sect_.get());
int64_t last_process_time_;
std::vector<int> recent_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
std::vector<int64_t> recent_update_time_ms_ GUARDED_BY(crit_sect_.get());
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
int total_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
std::list<Probe> probes_;
size_t total_probes_received_;
int64_t first_packet_time_ms_;
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorAbsSendTime);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_H_

View File

@ -9,6 +9,7 @@
*/
#include "webrtc/base/constructormagic.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
namespace webrtc {
@ -20,12 +21,9 @@ class RemoteBitrateEstimatorAbsSendTimeTest :
RemoteBitrateEstimatorAbsSendTimeTest() {}
virtual void SetUp() {
bitrate_estimator_.reset(
AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
bitrate_observer_.get(),
&clock_,
kAimdControl,
kRemoteBitrateEstimatorMinBitrateBps));
bitrate_estimator_.reset(new RemoteBitrateEstimatorAbsSendTime(
bitrate_observer_.get(), &clock_,
kRemoteBitrateEstimatorMinBitrateBps));
}
protected:
DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorAbsSendTimeTest);

View File

@ -7,17 +7,16 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <map>
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h"
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
#include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
@ -28,28 +27,7 @@ namespace webrtc {
enum { kTimestampGroupLengthMs = 5 };
static const double kTimestampToMs = 1.0 / 90.0;
class RemoteBitrateEstimatorImpl : public RemoteBitrateEstimator {
public:
RemoteBitrateEstimatorImpl(RemoteBitrateObserver* observer,
Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps);
virtual ~RemoteBitrateEstimatorImpl();
void IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) override;
int32_t Process() override;
int64_t TimeUntilNextProcess() override;
void OnRttUpdate(int64_t rtt) override;
void RemoveStream(unsigned int ssrc) override;
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
unsigned int* bitrate_bps) const override;
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
private:
struct Detector {
struct RemoteBitrateEstimatorSingleStream::Detector {
explicit Detector(int64_t last_packet_time_ms,
const OverUseDetectorOptions& options,
bool enable_burst_grouping)
@ -64,43 +42,22 @@ class RemoteBitrateEstimatorImpl : public RemoteBitrateEstimator {
OveruseDetector detector;
};
typedef std::map<unsigned int, Detector*> SsrcOveruseEstimatorMap;
// Triggers a new estimate calculation.
void UpdateEstimate(int64_t time_now)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void GetSsrcs(std::vector<unsigned int>* ssrcs) const
SHARED_LOCKS_REQUIRED(crit_sect_.get());
Clock* clock_;
SsrcOveruseEstimatorMap overuse_detectors_ GUARDED_BY(crit_sect_.get());
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
rtc::scoped_ptr<RemoteRateControl> remote_rate_ GUARDED_BY(crit_sect_.get());
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
int64_t last_process_time_;
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorImpl);
};
RemoteBitrateEstimatorImpl::RemoteBitrateEstimatorImpl(
RemoteBitrateObserver* observer,
Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps)
: clock_(clock),
incoming_bitrate_(1000, 8000),
remote_rate_(RemoteRateControl::Create(control_type, min_bitrate_bps)),
observer_(observer),
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
last_process_time_(-1),
process_interval_ms_(kProcessIntervalMs) {
RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
RemoteBitrateObserver* observer,
Clock* clock,
uint32_t min_bitrate_bps)
: clock_(clock),
incoming_bitrate_(1000, 8000),
remote_rate_(new AimdRateControl(min_bitrate_bps)),
observer_(observer),
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
last_process_time_(-1),
process_interval_ms_(kProcessIntervalMs) {
assert(observer_);
LOG(LS_INFO) << "RemoteBitrateEstimatorSingleStream: Instantiating.";
}
RemoteBitrateEstimatorImpl::~RemoteBitrateEstimatorImpl() {
RemoteBitrateEstimatorSingleStream::~RemoteBitrateEstimatorSingleStream() {
while (!overuse_detectors_.empty()) {
SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
delete it->second;
@ -108,10 +65,10 @@ RemoteBitrateEstimatorImpl::~RemoteBitrateEstimatorImpl() {
}
}
void RemoteBitrateEstimatorImpl::IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) {
void RemoteBitrateEstimatorSingleStream::IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) {
uint32_t ssrc = header.ssrc;
uint32_t rtp_timestamp = header.timestamp +
header.extension.transmissionTimeOffset;
@ -126,10 +83,8 @@ void RemoteBitrateEstimatorImpl::IncomingPacket(int64_t arrival_time_ms,
// automatically cleaned up when we have one RemoteBitrateEstimator per REMB
// group.
std::pair<SsrcOveruseEstimatorMap::iterator, bool> insert_result =
overuse_detectors_.insert(std::make_pair(ssrc, new Detector(
now_ms,
OverUseDetectorOptions(),
remote_rate_->GetControlType() == kAimdControl)));
overuse_detectors_.insert(std::make_pair(
ssrc, new Detector(now_ms, OverUseDetectorOptions(), true)));
it = insert_result.first;
}
Detector* estimator = it->second;
@ -161,7 +116,7 @@ void RemoteBitrateEstimatorImpl::IncomingPacket(int64_t arrival_time_ms,
}
}
int32_t RemoteBitrateEstimatorImpl::Process() {
int32_t RemoteBitrateEstimatorSingleStream::Process() {
if (TimeUntilNextProcess() > 0) {
return 0;
}
@ -173,7 +128,7 @@ int32_t RemoteBitrateEstimatorImpl::Process() {
return 0;
}
int64_t RemoteBitrateEstimatorImpl::TimeUntilNextProcess() {
int64_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
if (last_process_time_ < 0) {
return 0;
}
@ -184,7 +139,7 @@ int64_t RemoteBitrateEstimatorImpl::TimeUntilNextProcess() {
}
}
void RemoteBitrateEstimatorImpl::UpdateEstimate(int64_t now_ms) {
void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
BandwidthUsage bw_state = kBwNormal;
double sum_var_noise = 0.0;
SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
@ -209,8 +164,7 @@ void RemoteBitrateEstimatorImpl::UpdateEstimate(int64_t now_ms) {
}
// We can't update the estimate if we don't have any active streams.
if (overuse_detectors_.empty()) {
remote_rate_.reset(RemoteRateControl::Create(
remote_rate_->GetControlType(), remote_rate_->GetMinBitrate()));
remote_rate_.reset(new AimdRateControl(remote_rate_->GetMinBitrate()));
return;
}
double mean_noise_var = sum_var_noise /
@ -231,12 +185,12 @@ void RemoteBitrateEstimatorImpl::UpdateEstimate(int64_t now_ms) {
}
}
void RemoteBitrateEstimatorImpl::OnRttUpdate(int64_t rtt) {
void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t rtt) {
CriticalSectionScoped cs(crit_sect_.get());
remote_rate_->SetRtt(rtt);
}
void RemoteBitrateEstimatorImpl::RemoveStream(unsigned int ssrc) {
void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
CriticalSectionScoped cs(crit_sect_.get());
SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.find(ssrc);
if (it != overuse_detectors_.end()) {
@ -245,7 +199,7 @@ void RemoteBitrateEstimatorImpl::RemoveStream(unsigned int ssrc) {
}
}
bool RemoteBitrateEstimatorImpl::LatestEstimate(
bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
std::vector<unsigned int>* ssrcs,
unsigned int* bitrate_bps) const {
CriticalSectionScoped cs(crit_sect_.get());
@ -261,13 +215,13 @@ bool RemoteBitrateEstimatorImpl::LatestEstimate(
return true;
}
bool RemoteBitrateEstimatorImpl::GetStats(
bool RemoteBitrateEstimatorSingleStream::GetStats(
ReceiveBandwidthEstimatorStats* output) const {
// Not implemented.
return false;
}
void RemoteBitrateEstimatorImpl::GetSsrcs(
void RemoteBitrateEstimatorSingleStream::GetSsrcs(
std::vector<unsigned int>* ssrcs) const {
assert(ssrcs);
ssrcs->resize(overuse_detectors_.size());
@ -278,13 +232,4 @@ void RemoteBitrateEstimatorImpl::GetSsrcs(
}
}
RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create(
webrtc::RemoteBitrateObserver* observer,
webrtc::Clock* clock,
RateControlType control_type,
uint32_t min_bitrate_bps) const {
LOG(LS_INFO) << "RemoteBitrateEstimatorFactory: Instantiating.";
return new RemoteBitrateEstimatorImpl(observer, clock, control_type,
min_bitrate_bps);
}
} // namespace webrtc

View File

@ -0,0 +1,69 @@
/*
* 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_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_SINGLE_STREAM_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_SINGLE_STREAM_H_
#include <map>
#include <vector>
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc {
class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
public:
RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
Clock* clock,
uint32_t min_bitrate_bps);
virtual ~RemoteBitrateEstimatorSingleStream();
void IncomingPacket(int64_t arrival_time_ms,
size_t payload_size,
const RTPHeader& header,
bool was_paced) override;
int32_t Process() override;
int64_t TimeUntilNextProcess() override;
void OnRttUpdate(int64_t rtt) override;
void RemoveStream(unsigned int ssrc) override;
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
unsigned int* bitrate_bps) const override;
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
private:
struct Detector;
typedef std::map<unsigned int, Detector*> SsrcOveruseEstimatorMap;
// Triggers a new estimate calculation.
void UpdateEstimate(int64_t time_now)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
void GetSsrcs(std::vector<unsigned int>* ssrcs) const
SHARED_LOCKS_REQUIRED(crit_sect_.get());
Clock* clock_;
SsrcOveruseEstimatorMap overuse_detectors_ GUARDED_BY(crit_sect_.get());
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
rtc::scoped_ptr<AimdRateControl> remote_rate_ GUARDED_BY(crit_sect_.get());
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
int64_t last_process_time_;
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorSingleStream);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_SINGLE_STREAM_H_

View File

@ -9,6 +9,7 @@
*/
#include "webrtc/base/constructormagic.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
namespace webrtc {
@ -20,10 +21,8 @@ class RemoteBitrateEstimatorSingleTest :
RemoteBitrateEstimatorSingleTest() {}
virtual void SetUp() {
bitrate_estimator_.reset(RemoteBitrateEstimatorFactory().Create(
bitrate_observer_.get(),
&clock_,
kMimdControl,
bitrate_estimator_.reset(new RemoteBitrateEstimatorSingleStream(
bitrate_observer_.get(), &clock_,
kRemoteBitrateEstimatorMinBitrateBps));
}
protected:
@ -39,35 +38,35 @@ TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseReordering) {
}
TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseRtpTimestamps) {
RateIncreaseRtpTimestampsTestHelper(1621);
RateIncreaseRtpTimestampsTestHelper(1089);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStream) {
CapacityDropTestHelper(1, false, 733);
CapacityDropTestHelper(1, false, 700);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStreamWrap) {
CapacityDropTestHelper(1, true, 733);
CapacityDropTestHelper(1, true, 700);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropTwoStreamsWrap) {
CapacityDropTestHelper(2, true, 700);
CapacityDropTestHelper(2, true, 666);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThreeStreamsWrap) {
CapacityDropTestHelper(3, true, 733);
CapacityDropTestHelper(3, true, 700);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirteenStreamsWrap) {
CapacityDropTestHelper(13, true, 733);
CapacityDropTestHelper(13, true, 700);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropNineteenStreamsWrap) {
CapacityDropTestHelper(19, true, 733);
CapacityDropTestHelper(19, true, 700);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirtyStreamsWrap) {
CapacityDropTestHelper(30, true, 733);
CapacityDropTestHelper(30, true, 700);
}
TEST_F(RemoteBitrateEstimatorSingleTest, TestTimestampGrouping) {

View File

@ -533,7 +533,7 @@ void RemoteBitrateEstimatorTest::TestTimestampGroupingTestHelper() {
kFrameIntervalAbsSendTime);
}
EXPECT_TRUE(bitrate_observer_->updated());
EXPECT_NEAR(450000u, bitrate_observer_->latest_bitrate(), 20000u);
EXPECT_NEAR(470000u, bitrate_observer_->latest_bitrate(), 10000u);
// Insert batches of frames which were sent very close in time. Also simulate
// capacity over-use to see that we back off correctly.

View File

@ -1,30 +0,0 @@
/*
* 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
* 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/modules/remote_bitrate_estimator/remote_rate_control.h"
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
#include "webrtc/modules/remote_bitrate_estimator/mimd_rate_control.h"
namespace webrtc {
// static
const int64_t RemoteRateControl::kMaxFeedbackIntervalMs = 1000;
RemoteRateControl* RemoteRateControl::Create(RateControlType control_type,
uint32_t min_bitrate_bps) {
if (control_type == kAimdControl) {
return new AimdRateControl(min_bitrate_bps);
} else {
return new MimdRateControl(min_bitrate_bps);
}
}
} // namespace webrtc

View File

@ -1,51 +0,0 @@
/*
* 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
* 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_REMOTE_BITRATE_ESTIMATOR_REMOTE_RATE_CONTROL_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_RATE_CONTROL_H_
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
namespace webrtc {
class RemoteRateControl {
public:
static RemoteRateControl* Create(RateControlType control_type,
uint32_t min_bitrate_bps);
virtual ~RemoteRateControl() {}
// Returns true if there is a valid estimate of the incoming bitrate, false
// otherwise.
virtual bool ValidEstimate() const = 0;
virtual RateControlType GetControlType() const = 0;
virtual uint32_t GetMinBitrate() const = 0;
virtual int64_t GetFeedbackInterval() const = 0;
// Returns true if the bitrate estimate hasn't been changed for more than
// an RTT, or if the incoming_bitrate is more than 5% above the current
// estimate. Should be used to decide if we should reduce the rate further
// when over-using.
virtual bool TimeToReduceFurther(int64_t time_now,
uint32_t incoming_bitrate_bps) const = 0;
virtual uint32_t LatestEstimate() const = 0;
virtual uint32_t UpdateBandwidthEstimate(int64_t now_ms) = 0;
virtual void SetRtt(int64_t rtt) = 0;
virtual RateControlRegion Update(const RateControlInput* input,
int64_t now_ms) = 0;
virtual void SetEstimate(int bitrate_bps, int64_t time_now_ms) = 0;
protected:
static const int64_t kMaxFeedbackIntervalMs;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_RATE_CONTROL_H_

View File

@ -15,6 +15,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/common.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
@ -67,10 +68,10 @@ RembReceiver::RembReceiver(int flow_id, bool plot)
clock_(0),
recv_stats_(ReceiveStatistics::Create(&clock_)),
latest_estimate_bps_(-1),
estimator_(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
last_feedback_ms_(-1),
estimator_(new RemoteBitrateEstimatorAbsSendTime(
this,
&clock_,
kAimdControl,
kRemoteBitrateEstimatorMinBitrateBps)) {
std::stringstream ss;
ss << "Estimate_" << flow_id_ << "#1";

View File

@ -11,6 +11,7 @@
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
namespace webrtc {
@ -22,8 +23,9 @@ const int kFeedbackIntervalMs = 50;
FullBweSender::FullBweSender(int kbps, BitrateObserver* observer, Clock* clock)
: bitrate_controller_(
BitrateController::CreateBitrateController(clock, observer)),
rbe_(AbsoluteSendTimeRemoteBitrateEstimatorFactory()
.Create(this, clock, kAimdControl, 1000 * kMinBitrateKbps)),
rbe_(new RemoteBitrateEstimatorAbsSendTime(this,
clock,
1000 * kMinBitrateKbps)),
feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()),
clock_(clock),
send_time_history_(10000),

View File

@ -13,7 +13,8 @@
#include <stdio.h>
#include <string>
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
#include "webrtc/test/rtp_file_reader.h"
@ -51,16 +52,14 @@ bool ParseArgsAndSetupEstimator(int argc,
if (estimator) {
switch (extension) {
case webrtc::kRtpExtensionAbsoluteSendTime: {
webrtc::AbsoluteSendTimeRemoteBitrateEstimatorFactory factory;
*estimator = factory.Create(observer, clock, webrtc::kAimdControl,
kMinBitrateBps);
*estimator = new webrtc::RemoteBitrateEstimatorAbsSendTime(
observer, clock, kMinBitrateBps);
*estimator_used = "AbsoluteSendTimeRemoteBitrateEstimator";
break;
}
case webrtc::kRtpExtensionTransmissionTimeOffset: {
webrtc::RemoteBitrateEstimatorFactory factory;
*estimator = factory.Create(observer, clock, webrtc::kAimdControl,
kMinBitrateBps);
*estimator = new webrtc::RemoteBitrateEstimatorSingleStream(
observer, clock, kMinBitrateBps);
*estimator_used = "RemoteBitrateEstimator";
break;
}

View File

@ -13,6 +13,7 @@
#include "webrtc/common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
@ -67,12 +68,10 @@ class RtcpFormatRembTest : public ::testing::Test {
system_clock_(Clock::GetRealTimeClock()),
receive_statistics_(ReceiveStatistics::Create(system_clock_)),
remote_bitrate_observer_(),
remote_bitrate_estimator_(
RemoteBitrateEstimatorFactory().Create(
&remote_bitrate_observer_,
system_clock_,
kMimdControl,
kRemoteBitrateEstimatorMinBitrateBps)) {}
remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream(
&remote_bitrate_observer_,
system_clock_,
kRemoteBitrateEstimatorMinBitrateBps)) {}
void SetUp() override;
void TearDown() override;

View File

@ -18,7 +18,7 @@
// Note: This file has no directory. Lint warning must be ignored.
#include "webrtc/common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
@ -69,12 +69,10 @@ class RtcpReceiverTest : public ::testing::Test {
: over_use_detector_options_(),
system_clock_(1335900000),
remote_bitrate_observer_(),
remote_bitrate_estimator_(
RemoteBitrateEstimatorFactory().Create(
&remote_bitrate_observer_,
&system_clock_,
kMimdControl,
kRemoteBitrateEstimatorMinBitrateBps)) {
remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream(
&remote_bitrate_observer_,
&system_clock_,
kRemoteBitrateEstimatorMinBitrateBps)) {
test_transport_ = new TestTransport();
RtpRtcp::Configuration configuration;

View File

@ -18,7 +18,7 @@
#include "webrtc/common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
@ -279,15 +279,13 @@ class RtcpSenderTest : public ::testing::Test {
RtcpSenderTest()
: over_use_detector_options_(),
clock_(1335900000),
rtp_payload_registry_(new RTPPayloadRegistry(
RTPPayloadStrategy::CreateStrategy(false))),
rtp_payload_registry_(
new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))),
remote_bitrate_observer_(),
remote_bitrate_estimator_(
RemoteBitrateEstimatorFactory().Create(
&remote_bitrate_observer_,
&clock_,
kMimdControl,
kRemoteBitrateEstimatorMinBitrateBps)),
remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream(
&remote_bitrate_observer_,
&clock_,
kRemoteBitrateEstimatorMinBitrateBps)),
receive_statistics_(ReceiveStatistics::Create(&clock_)) {
test_transport_ = new TestTransport();

View File

@ -272,13 +272,16 @@ class BitrateEstimatorTest : public test::CallTest {
std::vector<Stream*> streams_;
};
static const char* kAbsSendTimeLog =
"RemoteBitrateEstimatorAbsSendTime: Instantiating.";
static const char* kSingleStreamLog =
"RemoteBitrateEstimatorSingleStream: Instantiating.";
TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) {
send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
streams_.push_back(new Stream(this, false));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
}
@ -286,13 +289,10 @@ TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) {
TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForAudio) {
send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
receiver_trace_.PushExpectedLogLine(
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
streams_.push_back(new Stream(this, true));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
}
@ -300,30 +300,24 @@ TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForAudio) {
TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForVideo) {
send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
receiver_trace_.PushExpectedLogLine(
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
streams_.push_back(new Stream(this, false));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
}
TEST_F(BitrateEstimatorTest, SwitchesToASTForAudio) {
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
streams_.push_back(new Stream(this, true));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
receiver_trace_.PushExpectedLogLine(
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
streams_.push_back(new Stream(this, true));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
}
@ -331,18 +325,15 @@ TEST_F(BitrateEstimatorTest, SwitchesToASTForAudio) {
TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) {
send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
streams_.push_back(new Stream(this, false));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
send_config_.rtp.extensions[0] =
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
receiver_trace_.PushExpectedLogLine(
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
streams_.push_back(new Stream(this, false));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
}
@ -350,18 +341,15 @@ TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) {
TEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOFForVideo) {
send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
streams_.push_back(new Stream(this, false));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
send_config_.rtp.extensions[0] =
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
receiver_trace_.PushExpectedLogLine(
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
streams_.push_back(new Stream(this, false));
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
@ -369,8 +357,7 @@ TEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOFForVideo) {
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId);
receiver_trace_.PushExpectedLogLine(
"WrappingBitrateEstimator: Switching to transmission time offset RBE.");
receiver_trace_.PushExpectedLogLine(
"RemoteBitrateEstimatorFactory: Instantiating.");
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
streams_.push_back(new Stream(this, false));
streams_[0]->StopSending();
streams_[1]->StopSending();

View File

@ -11,6 +11,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/common.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
@ -24,6 +26,7 @@ namespace webrtc {
namespace {
static const int kMaxPacketSize = 1500;
const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
std::vector<uint32_t> GenerateSsrcs(size_t num_streams,
uint32_t ssrc_offset) {
@ -36,9 +39,7 @@ std::vector<uint32_t> GenerateSsrcs(size_t num_streams,
StreamObserver::StreamObserver(const SsrcMap& rtx_media_ssrcs,
newapi::Transport* feedback_transport,
Clock* clock,
RemoteBitrateEstimatorFactory* rbe_factory,
RateControlType control_type)
Clock* clock)
: clock_(clock),
test_done_(EventWrapper::Create()),
rtp_parser_(RtpHeaderParser::Create()),
@ -46,6 +47,7 @@ StreamObserver::StreamObserver(const SsrcMap& rtx_media_ssrcs,
receive_stats_(ReceiveStatistics::Create(clock)),
payload_registry_(
new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))),
remote_bitrate_estimator_(nullptr),
expected_bitrate_bps_(0),
start_bitrate_bps_(0),
rtx_media_ssrcs_(rtx_media_ssrcs),
@ -72,10 +74,6 @@ StreamObserver::StreamObserver(const SsrcMap& rtx_media_ssrcs,
kAbsSendTimeExtensionId);
rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId);
const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
remote_bitrate_estimator_.reset(
rbe_factory->Create(this, clock, control_type,
kRemoteBitrateEstimatorMinBitrateBps));
payload_registry_->SetRtxPayloadType(RampUpTest::kSendRtxPayloadType,
RampUpTest::kFakeSendPayloadType);
}
@ -121,6 +119,7 @@ bool StreamObserver::SendRtp(const uint8_t* packet, size_t length) {
EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header));
receive_stats_->IncomingPacket(header, length, false);
payload_registry_->SetIncomingPayloadType(header);
DCHECK(remote_bitrate_estimator_ != nullptr);
remote_bitrate_estimator_->IncomingPacket(clock_->TimeInMilliseconds(),
length - 12, header, true);
if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) {
@ -159,6 +158,10 @@ EventTypeWrapper StreamObserver::Wait() {
return test_done_->Wait(test::CallTest::kLongTimeoutMs);
}
void StreamObserver::SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe) {
remote_bitrate_estimator_.reset(rbe);
}
void StreamObserver::ReportResult(const std::string& measurement,
size_t value,
const std::string& units) {
@ -214,11 +217,9 @@ LowRateStreamObserver::LowRateStreamObserver(
rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsSendTimeExtensionId);
AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory;
const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 10000;
remote_bitrate_estimator_.reset(
rbe_factory.Create(this, clock, kAimdControl,
kRemoteBitrateEstimatorMinBitrateBps));
remote_bitrate_estimator_.reset(new RemoteBitrateEstimatorAbsSendTime(
this, clock, kRemoteBitrateEstimatorMinBitrateBps));
forward_transport_config_.link_capacity_kbps =
kHighBandwidthLimitBps / 1000;
forward_transport_config_.queue_length_packets = 100; // Something large.
@ -382,27 +383,26 @@ void RampUpTest::RunRampUpTest(size_t num_streams,
CreateSendConfig(num_streams);
send_config_.rtp.extensions.clear();
rtc::scoped_ptr<RemoteBitrateEstimatorFactory> rbe_factory;
RateControlType control_type;
test::DirectTransport receiver_transport;
StreamObserver stream_observer(rtx_ssrc_map, &receiver_transport,
Clock::GetRealTimeClock());
if (extension_type == RtpExtension::kAbsSendTime) {
control_type = kAimdControl;
rbe_factory.reset(new AbsoluteSendTimeRemoteBitrateEstimatorFactory);
stream_observer.SetRemoteBitrateEstimator(
new RemoteBitrateEstimatorAbsSendTime(
&stream_observer, Clock::GetRealTimeClock(),
kRemoteBitrateEstimatorMinBitrateBps));
send_config_.rtp.extensions.push_back(RtpExtension(
extension_type.c_str(), kAbsSendTimeExtensionId));
} else {
control_type = kMimdControl;
rbe_factory.reset(new RemoteBitrateEstimatorFactory);
stream_observer.SetRemoteBitrateEstimator(
new RemoteBitrateEstimatorSingleStream(
&stream_observer, Clock::GetRealTimeClock(),
kRemoteBitrateEstimatorMinBitrateBps));
send_config_.rtp.extensions.push_back(RtpExtension(
extension_type.c_str(), kTransmissionTimeOffsetExtensionId));
}
test::DirectTransport receiver_transport;
StreamObserver stream_observer(rtx_ssrc_map,
&receiver_transport,
Clock::GetRealTimeClock(),
rbe_factory.get(),
control_type);
Call::Config call_config(&stream_observer);
if (start_bitrate_bps != 0) {
call_config.bitrate_config.start_bitrate_bps = start_bitrate_bps;

View File

@ -40,9 +40,7 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
typedef std::map<uint32_t, uint32_t> SsrcMap;
StreamObserver(const SsrcMap& rtx_media_ssrcs,
newapi::Transport* feedback_transport,
Clock* clock,
RemoteBitrateEstimatorFactory* rbe_factory,
RateControlType control_type);
Clock* clock);
void set_expected_bitrate_bps(unsigned int expected_bitrate_bps);
@ -57,6 +55,8 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
EventTypeWrapper Wait();
void SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe);
private:
void ReportResult(const std::string& measurement,
size_t value,

View File

@ -16,7 +16,8 @@
#include "webrtc/experiments.h"
#include "webrtc/modules/pacing/include/paced_sender.h"
#include "webrtc/modules/pacing/include/packet_router.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/utility/interface/process_thread.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
@ -43,13 +44,11 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator {
clock_(clock),
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
min_bitrate_bps_(config.Get<RemoteBitrateEstimatorMinRate>().min_rate),
rbe_(RemoteBitrateEstimatorFactory().Create(observer_,
rbe_(new RemoteBitrateEstimatorSingleStream(observer_,
clock_,
kAimdControl,
min_bitrate_bps_)),
using_absolute_send_time_(false),
packets_since_absolute_send_time_(0) {
}
packets_since_absolute_send_time_(0) {}
virtual ~WrappingBitrateEstimator() {}
@ -122,11 +121,11 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator {
// Instantiate RBE for Time Offset or Absolute Send Time extensions.
void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
if (using_absolute_send_time_) {
rbe_.reset(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
observer_, clock_, kAimdControl, min_bitrate_bps_));
rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_,
min_bitrate_bps_));
} else {
rbe_.reset(RemoteBitrateEstimatorFactory().Create(
observer_, clock_, kAimdControl, min_bitrate_bps_));
rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_,
min_bitrate_bps_));
}
}