Push back on the video encoder to avoid building queues in the pacer.

Implemented behind the field trial "WebRTC-PacerPushbackExperiment/Enabled/"

BUG=webrtc:8171, webrtc:8287

Review-Url: https://codereview.webrtc.org/3004783002
Cr-Commit-Position: refs/heads/master@{#19969}
This commit is contained in:
philipel 2017-09-26 05:36:58 -07:00 committed by Commit Bot
parent e19d8bfd5b
commit a42055116d
3 changed files with 72 additions and 4 deletions

View file

@ -154,6 +154,9 @@ class SendSideCongestionController : public CallStatsObserver,
rtc::RaceChecker worker_race_;
bool pacer_pushback_experiment_ = false;
float encoding_rate_ = 1.0;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SendSideCongestionController);
};

View file

@ -32,6 +32,7 @@ namespace webrtc {
namespace {
const char kCwndExperiment[] = "WebRTC-CwndExperiment";
const char kPacerPushbackExperiment[] = "WebRTC-PacerPushbackExperiment";
const int64_t kDefaultAcceptedQueueMs = 250;
bool CwndExperimentEnabled() {
@ -122,7 +123,9 @@ SendSideCongestionController::SendSideCongestionController(
delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)),
in_cwnd_experiment_(CwndExperimentEnabled()),
accepted_queue_ms_(kDefaultAcceptedQueueMs),
was_in_alr_(0) {
was_in_alr_(false),
pacer_pushback_experiment_(
webrtc::field_trial::IsEnabled(kPacerPushbackExperiment)) {
delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
if (in_cwnd_experiment_ &&
!ReadCwndExperimentParameter(&accepted_queue_ms_)) {
@ -159,7 +162,9 @@ SendSideCongestionController::SendSideCongestionController(
delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)),
in_cwnd_experiment_(CwndExperimentEnabled()),
accepted_queue_ms_(kDefaultAcceptedQueueMs),
was_in_alr_(0) {
was_in_alr_(false),
pacer_pushback_experiment_(
webrtc::field_trial::IsEnabled(kPacerPushbackExperiment)) {
delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
if (in_cwnd_experiment_ &&
!ReadCwndExperimentParameter(&accepted_queue_ms_)) {
@ -416,7 +421,26 @@ void SendSideCongestionController::MaybeTriggerOnNetworkChanged() {
retransmission_rate_limiter_->SetMaxRate(bitrate_bps);
}
bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps;
if (!pacer_pushback_experiment_) {
bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps;
} else {
if (IsNetworkDown()) {
bitrate_bps = 0;
} else {
int64_t queue_length_ms = pacer_->ExpectedQueueTimeMs();
if (queue_length_ms == 0) {
encoding_rate_ = 1.0;
} else if (queue_length_ms > 50) {
float encoding_rate = 1.0 - queue_length_ms / 1000.0;
encoding_rate_ = std::min(encoding_rate_, encoding_rate);
encoding_rate_ = std::max(encoding_rate_, 0.0f);
}
bitrate_bps *= encoding_rate_;
bitrate_bps = bitrate_bps < 50000 ? 0 : bitrate_bps;
}
}
if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {
int64_t probing_interval_ms;

View file

@ -8,22 +8,24 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
#include "modules/bitrate_controller/include/bitrate_controller.h"
#include "modules/congestion_controller/congestion_controller_unittests_helper.h"
#include "modules/congestion_controller/include/mock/mock_congestion_observer.h"
#include "modules/congestion_controller/include/send_side_congestion_controller.h"
#include "modules/pacing/mock/mock_paced_sender.h"
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "rtc_base/socket.h"
#include "system_wrappers/include/clock.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
using testing::_;
using testing::AtLeast;
using testing::Ge;
using testing::NiceMock;
using testing::Return;
using testing::SaveArg;
@ -455,5 +457,44 @@ TEST_F(SendSideCongestionControllerTest, UpdatesDelayBasedEstimate) {
PacketTransmissionAndFeedbackBlock(&seq_num, kRunTimeMs, 50);
EXPECT_LT(*target_bitrate_bps_, bitrate_before_delay);
}
TEST_F(SendSideCongestionControllerTest, PacerQueueEncodeRatePushback) {
ScopedFieldTrials pushback_field_trial(
"WebRTC-PacerPushbackExperiment/Enabled/");
SetUp();
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0));
controller_->Process();
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(100));
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 0.9, _, _, _));
controller_->Process();
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(50));
controller_->Process();
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0));
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
controller_->Process();
const uint32_t kMinAdjustedBps = 50000;
int expected_queue_threshold =
1000 - kMinAdjustedBps * 1000.0 / kInitialBitrateBps;
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
.WillOnce(Return(expected_queue_threshold));
EXPECT_CALL(observer_, OnNetworkChanged(Ge(kMinAdjustedBps), _, _, _));
controller_->Process();
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs())
.WillOnce(Return(expected_queue_threshold + 1));
EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _));
controller_->Process();
EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0));
EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _));
controller_->Process();
}
} // namespace test
} // namespace webrtc