Add AlrDetector

This is a simple application limited region detector that is quite conservative
at the moment. We detect as being application-limited if we see sending rate
as less than 30% of the estimated bandwidth over 500 ms. The moment we detect
a single burst above 30% over a 100 ms period, we consider ourselves network
limited.

This class is currently not used. A follow up CL will leverage this to enable probing.

BUG=webrtc:6332

Review-Url: https://codereview.webrtc.org/2340763004
Cr-Commit-Position: refs/heads/master@{#14505}
This commit is contained in:
isheriff 2016-10-04 08:43:09 -07:00 committed by Commit bot
parent 52f6f2057c
commit 3168781d2f
8 changed files with 201 additions and 9 deletions

View File

@ -382,6 +382,7 @@ if (rtc_include_tests) {
"congestion_controller/transport_feedback_adapter_unittest.cc",
"media_file/media_file_unittest.cc",
"module_common_types_unittest.cc",
"pacing/alr_detector_unittest.cc",
"pacing/bitrate_prober_unittest.cc",
"pacing/paced_sender_unittest.cc",
"pacing/packet_router_unittest.cc",

View File

@ -10,6 +10,8 @@ import("../../build/webrtc.gni")
rtc_static_library("pacing") {
sources = [
"alr_detector.cc",
"alr_detector.h",
"bitrate_prober.cc",
"bitrate_prober.h",
"paced_sender.cc",

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2016 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/pacing/alr_detector.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
namespace {
// Time period over which outgoing traffic is measured and considered a single
// data point.
constexpr int kMeasurementPeriodMs = 100;
// Minimum number of consecutive measurements over |kMeasurementPeriodMs| time
// that indicate sending rate is below |kUsagePercent| to consider being
// application limited.
constexpr int kApplicationLimitedThreshold = 5;
// Sent traffic percentage as a function of network capaicty to consider traffic
// as application limited.
// NOTE: This is intentionally conservative at the moment until BW adjustments
// of application limited region is fine tuned.
constexpr int kUsagePercent = 30;
} // namespace
namespace webrtc {
AlrDetector::AlrDetector()
: measurement_interval_bytes_sent_(0),
measurement_interval_elapsed_time_ms_(0),
estimated_bitrate_bps_(0),
application_limited_count_(0) {}
AlrDetector::~AlrDetector() {}
void AlrDetector::OnBytesSent(size_t bytes_sent, int64_t elapsed_time_ms) {
if (measurement_interval_elapsed_time_ms_ > kMeasurementPeriodMs) {
RTC_DCHECK(estimated_bitrate_bps_);
int max_bytes =
(measurement_interval_elapsed_time_ms_ * estimated_bitrate_bps_) /
(8 * 1000);
RTC_DCHECK_GT(max_bytes, 0);
int utilization =
static_cast<int>((measurement_interval_bytes_sent_ * 100) / max_bytes);
if (utilization < kUsagePercent) {
application_limited_count_++;
if (application_limited_count_ == kApplicationLimitedThreshold)
LOG(LS_INFO) << "ALR start";
} else {
if (application_limited_count_ >= kApplicationLimitedThreshold)
LOG(LS_INFO) << "ALR stop";
application_limited_count_ = 0;
}
measurement_interval_elapsed_time_ms_ = elapsed_time_ms;
measurement_interval_bytes_sent_ = bytes_sent;
} else {
measurement_interval_elapsed_time_ms_ += elapsed_time_ms;
measurement_interval_bytes_sent_ += bytes_sent;
}
}
void AlrDetector::SetEstimatedBitrate(int bitrate_bps) {
RTC_DCHECK(bitrate_bps);
estimated_bitrate_bps_ = bitrate_bps;
}
bool AlrDetector::InApplicationLimitedRegion() {
return application_limited_count_ >= kApplicationLimitedThreshold;
}
} // namespace webrtc

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016 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_PACING_ALR_DETECTOR_H_
#define WEBRTC_MODULES_PACING_ALR_DETECTOR_H_
#include "webrtc/common_types.h"
#include "webrtc/modules/pacing/paced_sender.h"
#include "webrtc/typedefs.h"
namespace webrtc {
// Application limited region detector is a class that utilizes signals of
// elapsed time and bytes sent to estimate whether network traffic is
// currently limited by the application's ability to generate traffic.
//
// AlrDetector provides a signal that can be utilized to adjust
// estimate bandwidth.
// Note: This class is not thread-safe.
class AlrDetector {
public:
AlrDetector();
~AlrDetector();
void OnBytesSent(size_t bytes_sent, int64_t elapsed_time_ms);
// Set current estimated bandwidth.
void SetEstimatedBitrate(int bitrate_bps);
// Returns true if currently in application-limited region.
bool InApplicationLimitedRegion();
private:
size_t measurement_interval_bytes_sent_;
int64_t measurement_interval_elapsed_time_ms_;
int estimated_bitrate_bps_;
// Number of consecutive periods over which we observe traffic is application
// limited.
int application_limited_count_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_PACING_ALR_DETECTOR_H_

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016 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/test/gtest.h"
#include "webrtc/modules/pacing/alr_detector.h"
namespace {
constexpr int kMeasuredIntervalMs = 110;
constexpr int kEstimatedBitrateBps = 300000;
constexpr int kBytesInIntervalAtEstimatedBitrate =
(kEstimatedBitrateBps / 8) * kMeasuredIntervalMs / 1000;
} // namespace
namespace webrtc {
TEST(AlrDetectorTest, ApplicationLimitedWhenLittleDataSent) {
AlrDetector alr_detector;
alr_detector.SetEstimatedBitrate(kEstimatedBitrateBps);
for (int i = 0; i < 6; i++)
alr_detector.OnBytesSent(0, kMeasuredIntervalMs);
EXPECT_EQ(alr_detector.InApplicationLimitedRegion(), true);
for (int i = 0; i < 6; i++)
alr_detector.OnBytesSent(100, kMeasuredIntervalMs);
EXPECT_EQ(alr_detector.InApplicationLimitedRegion(), true);
}
TEST(AlrDetectorTest, NetworkLimitedWhenSendingCloseToEstimate) {
AlrDetector alr_detector;
alr_detector.SetEstimatedBitrate(kEstimatedBitrateBps);
for (int i = 0; i < 6; i++)
alr_detector.OnBytesSent(kBytesInIntervalAtEstimatedBitrate,
kMeasuredIntervalMs);
EXPECT_EQ(alr_detector.InApplicationLimitedRegion(), false);
}
} // namespace webrtc

View File

@ -19,6 +19,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/pacing/alr_detector.h"
#include "webrtc/modules/pacing/bitrate_prober.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
@ -248,6 +249,7 @@ const float PacedSender::kDefaultPaceMultiplier = 2.5f;
PacedSender::PacedSender(Clock* clock, PacketSender* packet_sender)
: clock_(clock),
packet_sender_(packet_sender),
alr_detector_(new AlrDetector()),
critsect_(CriticalSectionWrapper::CreateCriticalSection()),
paused_(false),
media_budget_(new paced_sender::IntervalBudget(0)),
@ -260,7 +262,7 @@ PacedSender::PacedSender(Clock* clock, PacketSender* packet_sender)
time_last_update_us_(clock->TimeInMicroseconds()),
packets_(new paced_sender::PacketQueue(clock)),
packet_counter_(0) {
UpdateBytesPerInterval(kMinPacketLimitMs);
UpdateBudgetWithElapsedTime(kMinPacketLimitMs);
}
PacedSender::~PacedSender() {}
@ -298,6 +300,7 @@ void PacedSender::SetEstimatedBitrate(uint32_t bitrate_bps) {
pacing_bitrate_kbps_ =
std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) *
kDefaultPaceMultiplier;
alr_detector_->SetEstimatedBitrate(bitrate_bps);
}
void PacedSender::SetSendBitrateLimits(int min_send_bitrate_bps,
@ -397,8 +400,8 @@ void PacedSender::Process() {
media_budget_->set_target_rate_kbps(target_bitrate_kbps);
int64_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms);
UpdateBytesPerInterval(delta_time_ms);
elapsed_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms);
UpdateBudgetWithElapsedTime(elapsed_time_ms);
}
bool is_probing = prober_->IsProbing();
@ -443,6 +446,7 @@ void PacedSender::Process() {
}
if (is_probing && bytes_sent > 0)
prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent);
alr_detector_->OnBytesSent(bytes_sent, elapsed_time_ms);
}
bool PacedSender::SendPacket(const paced_sender::Packet& packet,
@ -469,8 +473,7 @@ bool PacedSender::SendPacket(const paced_sender::Packet& packet,
// are allocating bandwidth for audio.
if (packet.priority != kHighPriority) {
// Update media bytes sent.
media_budget_->UseBudget(packet.bytes);
padding_budget_->UseBudget(packet.bytes);
UpdateBudgetWithBytesSent(packet.bytes);
}
}
@ -484,14 +487,18 @@ size_t PacedSender::SendPadding(size_t padding_needed, int probe_cluster_id) {
critsect_->Enter();
if (bytes_sent > 0) {
media_budget_->UseBudget(bytes_sent);
padding_budget_->UseBudget(bytes_sent);
UpdateBudgetWithBytesSent(bytes_sent);
}
return bytes_sent;
}
void PacedSender::UpdateBytesPerInterval(int64_t delta_time_ms) {
void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) {
media_budget_->IncreaseBudget(delta_time_ms);
padding_budget_->IncreaseBudget(delta_time_ms);
}
void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) {
media_budget_->UseBudget(bytes_sent);
padding_budget_->UseBudget(bytes_sent);
}
} // namespace webrtc

View File

@ -21,6 +21,7 @@
#include "webrtc/typedefs.h"
namespace webrtc {
class AlrDetector;
class BitrateProber;
class Clock;
class CriticalSectionWrapper;
@ -132,7 +133,9 @@ class PacedSender : public Module, public RtpPacketSender {
private:
// Updates the number of bytes that can be sent for the next time interval.
void UpdateBytesPerInterval(int64_t delta_time_in_ms)
void UpdateBudgetWithElapsedTime(int64_t delta_time_in_ms)
EXCLUSIVE_LOCKS_REQUIRED(critsect_);
void UpdateBudgetWithBytesSent(size_t bytes)
EXCLUSIVE_LOCKS_REQUIRED(critsect_);
bool SendPacket(const paced_sender::Packet& packet, int probe_cluster_id)
@ -142,6 +145,7 @@ class PacedSender : public Module, public RtpPacketSender {
Clock* const clock_;
PacketSender* const packet_sender_;
std::unique_ptr<AlrDetector> alr_detector_ GUARDED_BY(critsect_);
std::unique_ptr<CriticalSectionWrapper> critsect_;
bool paused_ GUARDED_BY(critsect_);

View File

@ -17,6 +17,8 @@
'<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
],
'sources': [
'alr_detector.cc',
'alr_detector.h',
'bitrate_prober.cc',
'bitrate_prober.h',
'paced_sender.cc',