Reland of "Change TWCC send interval to reduce overhead on low BW situations."

"Change TWCC send interval to reduce overhead on low BW situations." was first committed in https://codereview.webrtc.org/2381833003/

but was reverted in https://codereview.webrtc.org/2468413009/ due to "float-cast-overflow".

BUG=webrtc:6442, webrtc:6669

Review-Url: https://codereview.webrtc.org/2482823002
Cr-Commit-Position: refs/heads/master@{#14954}
This commit is contained in:
minyue
2016-11-07 07:51:20 -08:00
committed by Commit bot
parent 6a5047dad3
commit 8927b0596c
4 changed files with 77 additions and 8 deletions

View File

@ -342,6 +342,7 @@ void CongestionController::MaybeTriggerOnNetworkChanged() {
if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {
observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
remote_estimator_proxy_.OnBitrateChanged(bitrate_bps);
}
}

View File

@ -11,6 +11,7 @@
#include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h"
#include <limits>
#include <algorithm>
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
@ -22,8 +23,10 @@
namespace webrtc {
// TODO(sprang): Tune these!
const int RemoteEstimatorProxy::kDefaultProcessIntervalMs = 50;
const int RemoteEstimatorProxy::kBackWindowMs = 500;
const int RemoteEstimatorProxy::kMinSendIntervalMs = 50;
const int RemoteEstimatorProxy::kMaxSendIntervalMs = 250;
const int RemoteEstimatorProxy::kDefaultSendIntervalMs = 100;
// The maximum allowed value for a timestamp in milliseconds. This is lower
// than the numerical limit since we often convert to microseconds.
@ -37,7 +40,8 @@ RemoteEstimatorProxy::RemoteEstimatorProxy(Clock* clock,
last_process_time_ms_(-1),
media_ssrc_(0),
feedback_sequence_(0),
window_start_seq_(-1) {}
window_start_seq_(-1),
send_interval_ms_(kDefaultSendIntervalMs) {}
RemoteEstimatorProxy::~RemoteEstimatorProxy() {}
@ -68,11 +72,12 @@ bool RemoteEstimatorProxy::LatestEstimate(std::vector<unsigned int>* ssrcs,
}
int64_t RemoteEstimatorProxy::TimeUntilNextProcess() {
int64_t now = clock_->TimeInMilliseconds();
int64_t time_until_next = 0;
if (last_process_time_ms_ != -1 &&
now - last_process_time_ms_ < kDefaultProcessIntervalMs) {
time_until_next = (last_process_time_ms_ + kDefaultProcessIntervalMs - now);
if (last_process_time_ms_ != -1) {
rtc::CritScope cs(&lock_);
int64_t now = clock_->TimeInMilliseconds();
if (now - last_process_time_ms_ < send_interval_ms_)
time_until_next = (last_process_time_ms_ + send_interval_ms_ - now);
}
return time_until_next;
}
@ -92,6 +97,24 @@ void RemoteEstimatorProxy::Process() {
}
}
void RemoteEstimatorProxy::OnBitrateChanged(int bitrate_bps) {
// TwccReportSize = Ipv4(20B) + UDP(8B) + SRTP(10B) +
// AverageTwccReport(30B)
// TwccReport size at 50ms interval is 24 byte.
// TwccReport size at 250ms interval is 36 byte.
// AverageTwccReport = (TwccReport(50ms) + TwccReport(250ms)) / 2
constexpr int kTwccReportSize = 20 + 8 + 10 + 30;
constexpr double kMinTwccRate =
kTwccReportSize * 8.0 * 1000.0 / kMaxSendIntervalMs;
constexpr double kMaxTwccRate =
kTwccReportSize * 8.0 * 1000.0 / kMinSendIntervalMs;
// Let TWCC reports occupy 5% of total bandwidth.
rtc::CritScope cs(&lock_);
send_interval_ms_ = static_cast<int>(0.5 + kTwccReportSize * 8.0 * 1000.0 /
(std::max(std::min(0.05 * bitrate_bps, kMaxTwccRate), kMinTwccRate)));
}
void RemoteEstimatorProxy::OnPacketArrival(uint16_t sequence_number,
int64_t arrival_time) {
if (arrival_time < 0 || arrival_time > kMaxTimeMs) {

View File

@ -47,8 +47,11 @@ class RemoteEstimatorProxy : public RemoteBitrateEstimator {
void SetMinBitrate(int min_bitrate_bps) override {}
int64_t TimeUntilNextProcess() override;
void Process() override;
void OnBitrateChanged(int bitrate);
static const int kDefaultProcessIntervalMs;
static const int kMinSendIntervalMs;
static const int kMaxSendIntervalMs;
static const int kDefaultSendIntervalMs;
static const int kBackWindowMs;
private:
@ -68,6 +71,7 @@ class RemoteEstimatorProxy : public RemoteBitrateEstimator {
int64_t window_start_seq_ GUARDED_BY(&lock_);
// Map unwrapped seq -> time.
std::map<int64_t, int64_t> packet_arrival_times_ GUARDED_BY(&lock_);
int64_t send_interval_ms_ GUARDED_BY(&lock_);
};
} // namespace webrtc

View File

@ -42,7 +42,7 @@ class RemoteEstimatorProxyTest : public ::testing::Test {
void Process() {
clock_.AdvanceTimeMilliseconds(
RemoteEstimatorProxy::kDefaultProcessIntervalMs);
RemoteEstimatorProxy::kDefaultSendIntervalMs);
proxy_.Process();
}
@ -350,4 +350,45 @@ TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
Process();
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsZeroBeforeFirstProcess) {
EXPECT_EQ(0, proxy_.TimeUntilNextProcess());
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsDefaultOnUnkownBitrate) {
Process();
EXPECT_EQ(RemoteEstimatorProxy::kDefaultSendIntervalMs,
proxy_.TimeUntilNextProcess());
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMinIntervalOn300kbps) {
Process();
proxy_.OnBitrateChanged(300000);
EXPECT_EQ(RemoteEstimatorProxy::kMinSendIntervalMs,
proxy_.TimeUntilNextProcess());
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn0kbps) {
Process();
// TimeUntilNextProcess should be limited by |kMaxSendIntervalMs| when
// bitrate is small. We choose 0 bps as a special case, which also tests
// erroneous behaviors like division-by-zero.
proxy_.OnBitrateChanged(0);
EXPECT_EQ(RemoteEstimatorProxy::kMaxSendIntervalMs,
proxy_.TimeUntilNextProcess());
}
TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn20kbps) {
Process();
proxy_.OnBitrateChanged(20000);
EXPECT_EQ(RemoteEstimatorProxy::kMaxSendIntervalMs,
proxy_.TimeUntilNextProcess());
}
TEST_F(RemoteEstimatorProxyTest, TwccReportsUse5PercentOfAvailableBandwidth) {
Process();
proxy_.OnBitrateChanged(80000);
// 80kbps * 0.05 = TwccReportSize(68B * 8b/B) * 1000ms / SendInterval(136ms)
EXPECT_EQ(136, proxy_.TimeUntilNextProcess());
}
} // namespace webrtc