Move delay_based_bwe_ into CongestionController

BUG=webrtc:7058

Review-Url: https://codereview.webrtc.org/2725823002
Cr-Commit-Position: refs/heads/master@{#17146}
This commit is contained in:
elad.alon
2017-03-09 06:40:08 -08:00
committed by Commit bot
parent 45b5fe549f
commit 5bbf43f9d4
13 changed files with 370 additions and 331 deletions

View File

@ -86,8 +86,7 @@ AudioSendStream::AudioSendStream(
}
}
channel_proxy_->RegisterSenderCongestionControlObjects(
congestion_controller->pacer(),
congestion_controller->GetTransportFeedbackObserver(), packet_router,
congestion_controller->pacer(), congestion_controller, packet_router,
bandwidth_observer_.get());
if (!SetupSendCodec()) {
LOG(LS_ERROR) << "Failed to set up send codec state.";

View File

@ -151,15 +151,13 @@ struct ConfigHelper {
.Times(1);
EXPECT_CALL(*channel_proxy_,
RegisterSenderCongestionControlObjects(
congestion_controller_.pacer(),
congestion_controller_.GetTransportFeedbackObserver(),
congestion_controller_.pacer(), &congestion_controller_,
packet_router(), Ne(nullptr)))
.Times(1);
} else {
EXPECT_CALL(*channel_proxy_,
RegisterSenderCongestionControlObjects(
congestion_controller_.pacer(),
congestion_controller_.GetTransportFeedbackObserver(),
congestion_controller_.pacer(), &congestion_controller_,
packet_router(), Eq(nullptr)))
.Times(1);
}

View File

@ -62,6 +62,8 @@ if (rtc_include_tests) {
testonly = true
sources = [
"congestion_controller_unittest.cc",
"congestion_controller_unittests_helper.cc",
"congestion_controller_unittests_helper.h",
"delay_based_bwe_unittest.cc",
"delay_based_bwe_unittest_helper.cc",
"delay_based_bwe_unittest_helper.h",

View File

@ -160,6 +160,7 @@ CongestionController::CongestionController(
std::unique_ptr<PacedSender> pacer)
: clock_(clock),
observer_(observer),
event_log_(event_log),
packet_router_(packet_router),
pacer_(std::move(pacer)),
bitrate_controller_(
@ -169,15 +170,16 @@ CongestionController::CongestionController(
new RateLimiter(clock, kRetransmitWindowSizeMs)),
remote_bitrate_estimator_(remote_bitrate_observer, clock_),
remote_estimator_proxy_(clock_, packet_router_),
transport_feedback_adapter_(event_log, clock_, bitrate_controller_.get()),
transport_feedback_adapter_(clock_),
min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
max_bitrate_bps_(0),
last_reported_bitrate_bps_(0),
last_reported_fraction_loss_(0),
last_reported_rtt_(0),
network_state_(kNetworkUp) {
transport_feedback_adapter_.InitBwe();
transport_feedback_adapter_.SetMinBitrate(min_bitrate_bps_);
network_state_(kNetworkUp),
delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)) {
delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
worker_thread_checker_.DetachFromThread();
}
CongestionController::~CongestionController() {}
@ -210,9 +212,12 @@ void CongestionController::SetBweBitrates(int min_bitrate_bps,
remote_bitrate_estimator_.SetMinBitrate(min_bitrate_bps);
min_bitrate_bps_ = min_bitrate_bps;
if (start_bitrate_bps > 0)
transport_feedback_adapter_.SetStartBitrate(start_bitrate_bps);
transport_feedback_adapter_.SetMinBitrate(min_bitrate_bps_);
{
rtc::CritScope cs(&bwe_lock_);
if (start_bitrate_bps > 0)
delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
}
MaybeTriggerOnNetworkChanged();
}
@ -231,9 +236,12 @@ void CongestionController::ResetBweAndBitrates(int bitrate_bps,
remote_bitrate_estimator_.SetMinBitrate(min_bitrate_bps);
transport_feedback_adapter_.ClearSendTimeHistory();
transport_feedback_adapter_.InitBwe();
transport_feedback_adapter_.SetStartBitrate(bitrate_bps);
transport_feedback_adapter_.SetMinBitrate(min_bitrate_bps);
{
rtc::CritScope cs(&bwe_lock_);
delay_based_bwe_.reset(new DelayBasedBwe(event_log_, clock_));
delay_based_bwe_->SetStartBitrate(bitrate_bps);
delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
}
probe_controller_->Reset();
probe_controller_->SetBitrates(min_bitrate_bps, bitrate_bps, max_bitrate_bps);
@ -254,11 +262,6 @@ RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator(
}
}
TransportFeedbackObserver*
CongestionController::GetTransportFeedbackObserver() {
return &transport_feedback_adapter_;
}
RateLimiter* CongestionController::GetRetransmissionRateLimiter() {
return retransmission_rate_limiter_.get();
}
@ -286,7 +289,7 @@ void CongestionController::SignalNetworkState(NetworkState state) {
pacer_->Pause();
}
{
rtc::CritScope cs(&critsect_);
rtc::CritScope cs(&network_state_lock_);
network_state_ = state;
}
probe_controller_->OnNetworkStateChanged(state);
@ -310,7 +313,10 @@ void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) {
void CongestionController::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
remote_bitrate_estimator_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
transport_feedback_adapter_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
{
rtc::CritScope cs(&bwe_lock_);
delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
}
}
int64_t CongestionController::TimeUntilNextProcess() {
@ -325,6 +331,32 @@ void CongestionController::Process() {
MaybeTriggerOnNetworkChanged();
}
void CongestionController::AddPacket(uint16_t sequence_number,
size_t length,
const PacedPacketInfo& pacing_info) {
transport_feedback_adapter_.AddPacket(sequence_number, length, pacing_info);
}
void CongestionController::OnTransportFeedback(
const rtcp::TransportFeedback& feedback) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
transport_feedback_adapter_.OnTransportFeedback(feedback);
DelayBasedBwe::Result result;
{
rtc::CritScope cs(&bwe_lock_);
result = delay_based_bwe_->IncomingPacketFeedbackVector(
transport_feedback_adapter_.GetTransportFeedbackVector());
}
if (result.updated)
bitrate_controller_->OnDelayBasedBweResult(result);
}
std::vector<PacketFeedback> CongestionController::GetTransportFeedbackVector()
const {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
return transport_feedback_adapter_.GetTransportFeedbackVector();
}
void CongestionController::MaybeTriggerOnNetworkChanged() {
// TODO(perkj): |observer_| can be nullptr if the ctor that accepts a
// BitrateObserver is used. Remove this check once the ctor is removed.
@ -345,9 +377,13 @@ void CongestionController::MaybeTriggerOnNetworkChanged() {
bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps;
if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {
observer_->OnNetworkChanged(
bitrate_bps, fraction_loss, rtt,
transport_feedback_adapter_.GetProbingIntervalMs());
int64_t probing_interval_ms;
{
rtc::CritScope cs(&bwe_lock_);
probing_interval_ms = delay_based_bwe_->GetProbingIntervalMs();
}
observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt,
probing_interval_ms);
remote_estimator_proxy_.OnBitrateChanged(bitrate_bps);
}
}
@ -356,7 +392,7 @@ bool CongestionController::HasNetworkParametersToReportChanged(
uint32_t bitrate_bps,
uint8_t fraction_loss,
int64_t rtt) {
rtc::CritScope cs(&critsect_);
rtc::CritScope cs(&network_state_lock_);
bool changed =
last_reported_bitrate_bps_ != bitrate_bps ||
(bitrate_bps > 0 && (last_reported_fraction_loss_ != fraction_loss ||
@ -376,7 +412,7 @@ bool CongestionController::IsSendQueueFull() const {
}
bool CongestionController::IsNetworkDown() const {
rtc::CritScope cs(&critsect_);
rtc::CritScope cs(&network_state_lock_);
return network_state_ == kNetworkDown;
}

View File

@ -8,13 +8,15 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
#include "webrtc/modules/congestion_controller/congestion_controller_unittests_helper.h"
#include "webrtc/modules/congestion_controller/include/mock/mock_congestion_controller.h"
#include "webrtc/modules/pacing/mock/mock_paced_sender.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/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
@ -27,6 +29,8 @@ using testing::SaveArg;
using testing::StrictMock;
namespace {
const webrtc::PacedPacketInfo kPacingInfo0(0, 5, 2000);
const webrtc::PacedPacketInfo kPacingInfo1(1, 8, 4000);
// Helper to convert some time format to resolution used in absolute send time
// header extension, rounded upwards. |t| is the time to convert, in some
@ -43,7 +47,7 @@ namespace test {
class CongestionControllerTest : public ::testing::Test {
protected:
CongestionControllerTest() : clock_(123456) {}
CongestionControllerTest() : clock_(123456), target_bitrate_observer_(this) {}
~CongestionControllerTest() override {}
void SetUp() override {
@ -64,8 +68,74 @@ class CongestionControllerTest : public ::testing::Test {
controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps);
}
// Custom setup - use an observer that tracks the target bitrate, without
// prescribing on which iterations it must change (like a mock would).
void TargetBitrateTrackingSetup() {
std::unique_ptr<PacedSender> pacer(new NiceMock<MockPacedSender>());
controller_.reset(new CongestionController(
&clock_, &target_bitrate_observer_, &remote_bitrate_observer_,
&event_log_, &packet_router_, std::move(pacer)));
controller_->SetBweBitrates(0, kInitialBitrateBps, 5 * kInitialBitrateBps);
}
void OnSentPacket(const PacketFeedback& packet_feedback) {
controller_->AddPacket(packet_feedback.sequence_number,
packet_feedback.payload_size,
packet_feedback.pacing_info);
controller_->OnSentPacket(rtc::SentPacket(packet_feedback.sequence_number,
packet_feedback.send_time_ms));
}
// Allows us to track the target bitrate, without prescribing the exact
// iterations when this would hapen, like a mock would.
class TargetBitrateObserver : public CongestionController::Observer {
public:
explicit TargetBitrateObserver(CongestionControllerTest* owner)
: owner_(owner) {}
~TargetBitrateObserver() override = default;
void OnNetworkChanged(uint32_t bitrate_bps,
uint8_t fraction_loss, // 0 - 255.
int64_t rtt_ms,
int64_t probing_interval_ms) override {
owner_->target_bitrate_bps_ = rtc::Optional<uint32_t>(bitrate_bps);
}
private:
CongestionControllerTest* owner_;
};
void PacketTransmissionAndFeedbackBlock(uint16_t* seq_num,
int64_t runtime_ms,
int64_t delay) {
int64_t delay_buildup = 0;
int64_t start_time_ms = clock_.TimeInMilliseconds();
while (clock_.TimeInMilliseconds() - start_time_ms < runtime_ms) {
constexpr size_t kPayloadSize = 1000;
PacketFeedback packet(clock_.TimeInMilliseconds() + delay_buildup,
clock_.TimeInMilliseconds(), *seq_num, kPayloadSize,
PacedPacketInfo());
delay_buildup += delay; // Delay has to increase, or it's just RTT.
OnSentPacket(packet);
// Create expected feedback and send into adapter.
std::unique_ptr<rtcp::TransportFeedback> feedback(
new rtcp::TransportFeedback());
feedback->SetBase(packet.sequence_number, packet.arrival_time_ms * 1000);
EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number,
packet.arrival_time_ms * 1000));
rtc::Buffer raw_packet = feedback->Build();
feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(),
raw_packet.size());
EXPECT_TRUE(feedback.get() != nullptr);
controller_->OnTransportFeedback(*feedback.get());
clock_.AdvanceTimeMilliseconds(50);
controller_->Process();
++(*seq_num);
}
}
SimulatedClock clock_;
StrictMock<MockCongestionObserver> observer_;
TargetBitrateObserver target_bitrate_observer_;
NiceMock<MockPacedSender>* pacer_;
NiceMock<MockRemoteBitrateObserver> remote_bitrate_observer_;
NiceMock<MockRtcEventLog> event_log_;
@ -73,6 +143,8 @@ class CongestionControllerTest : public ::testing::Test {
PacketRouter packet_router_;
std::unique_ptr<CongestionController> controller_;
const uint32_t kInitialBitrateBps = 60000;
rtc::Optional<uint32_t> target_bitrate_bps_;
};
TEST_F(CongestionControllerTest, OnNetworkChanged) {
@ -253,5 +325,116 @@ TEST_F(CongestionControllerTest, ProbeOnBweReset) {
20 * kInitialBitrateBps);
}
// Estimated bitrate reduced when the feedbacks arrive with such a long delay,
// that the send-time-history no longer holds the feedbacked packets.
TEST_F(CongestionControllerTest, LongFeedbackDelays) {
TargetBitrateTrackingSetup();
const int64_t kFeedbackTimeoutMs = 60001;
const int kMaxConsecutiveFailedLookups = 5;
for (int i = 0; i < kMaxConsecutiveFailedLookups; ++i) {
std::vector<PacketFeedback> packets;
packets.push_back(
PacketFeedback(i * 100, 2 * i * 100, 0, 1500, kPacingInfo0));
packets.push_back(
PacketFeedback(i * 100 + 10, 2 * i * 100 + 10, 1, 1500, kPacingInfo0));
packets.push_back(
PacketFeedback(i * 100 + 20, 2 * i * 100 + 20, 2, 1500, kPacingInfo0));
packets.push_back(
PacketFeedback(i * 100 + 30, 2 * i * 100 + 30, 3, 1500, kPacingInfo1));
packets.push_back(
PacketFeedback(i * 100 + 40, 2 * i * 100 + 40, 4, 1500, kPacingInfo1));
for (const PacketFeedback& packet : packets)
OnSentPacket(packet);
rtcp::TransportFeedback feedback;
feedback.SetBase(packets[0].sequence_number,
packets[0].arrival_time_ms * 1000);
for (const PacketFeedback& packet : packets) {
EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
packet.arrival_time_ms * 1000));
}
feedback.Build();
clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs);
PacketFeedback later_packet(kFeedbackTimeoutMs + i * 100 + 40,
kFeedbackTimeoutMs + i * 200 + 40, 5, 1500,
kPacingInfo1);
OnSentPacket(later_packet);
controller_->OnTransportFeedback(feedback);
// Check that packets have timed out.
for (PacketFeedback& packet : packets) {
packet.send_time_ms = -1;
packet.payload_size = 0;
packet.pacing_info = PacedPacketInfo();
}
ComparePacketFeedbackVectors(packets,
controller_->GetTransportFeedbackVector());
}
controller_->Process();
EXPECT_EQ(kInitialBitrateBps / 2, target_bitrate_bps_);
// Test with feedback that isn't late enough to time out.
{
std::vector<PacketFeedback> packets;
packets.push_back(PacketFeedback(100, 200, 0, 1500, kPacingInfo0));
packets.push_back(PacketFeedback(110, 210, 1, 1500, kPacingInfo0));
packets.push_back(PacketFeedback(120, 220, 2, 1500, kPacingInfo0));
packets.push_back(PacketFeedback(130, 230, 3, 1500, kPacingInfo1));
packets.push_back(PacketFeedback(140, 240, 4, 1500, kPacingInfo1));
for (const PacketFeedback& packet : packets)
OnSentPacket(packet);
rtcp::TransportFeedback feedback;
feedback.SetBase(packets[0].sequence_number,
packets[0].arrival_time_ms * 1000);
for (const PacketFeedback& packet : packets) {
EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
packet.arrival_time_ms * 1000));
}
feedback.Build();
clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs - 1);
PacketFeedback later_packet(kFeedbackTimeoutMs + 140,
kFeedbackTimeoutMs + 240, 5, 1500,
kPacingInfo1);
OnSentPacket(later_packet);
controller_->OnTransportFeedback(feedback);
ComparePacketFeedbackVectors(packets,
controller_->GetTransportFeedbackVector());
}
}
// Bandwidth estimation is updated when feedbacks are received.
// Feedbacks which show an increasing delay cause the estimation to be reduced.
TEST_F(CongestionControllerTest, UpdatesDelayBasedEstimate) {
TargetBitrateTrackingSetup();
const int64_t kRunTimeMs = 6000;
uint16_t seq_num = 0;
// The test must run and insert packets/feedback long enough that the
// BWE computes a valid estimate. This is first done in an environment which
// simulates no bandwidth limitation, and therefore not built-up delay.
PacketTransmissionAndFeedbackBlock(&seq_num, kRunTimeMs, 0);
ASSERT_TRUE(target_bitrate_bps_);
// Repeat, but this time with a building delay, and make sure that the
// estimation is adjusted downwards.
uint32_t bitrate_before_delay = *target_bitrate_bps_;
PacketTransmissionAndFeedbackBlock(&seq_num, kRunTimeMs, 50);
EXPECT_LT(*target_bitrate_bps_, bitrate_before_delay);
}
} // namespace test
} // namespace webrtc

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2017 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/congestion_controller/congestion_controller_unittests_helper.h"
#include "webrtc/base/checks.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
void ComparePacketFeedbackVectors(const std::vector<PacketFeedback>& truth,
const std::vector<PacketFeedback>& input) {
ASSERT_EQ(truth.size(), input.size());
size_t len = truth.size();
// truth contains the input data for the test, and input is what will be
// sent to the bandwidth estimator. truth.arrival_tims_ms is used to
// populate the transport feedback messages. As these times may be changed
// (because of resolution limits in the packets, and because of the time
// base adjustment performed by the TransportFeedbackAdapter at the first
// packet, the truth[x].arrival_time and input[x].arrival_time may not be
// equal. However, the difference must be the same for all x.
int64_t arrival_time_delta =
truth[0].arrival_time_ms - input[0].arrival_time_ms;
for (size_t i = 0; i < len; ++i) {
RTC_CHECK(truth[i].arrival_time_ms != PacketFeedback::kNotReceived);
if (input[i].arrival_time_ms != PacketFeedback::kNotReceived) {
EXPECT_EQ(truth[i].arrival_time_ms,
input[i].arrival_time_ms + arrival_time_delta);
}
EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms);
EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number);
EXPECT_EQ(truth[i].payload_size, input[i].payload_size);
EXPECT_EQ(truth[i].pacing_info, input[i].pacing_info);
}
}
} // namespace webrtc

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2017 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_CONGESTION_CONTROLLER_CONGESTION_CONTROLLER_UNITTESTS_HELPER_H_
#define WEBRTC_MODULES_CONGESTION_CONTROLLER_CONGESTION_CONTROLLER_UNITTESTS_HELPER_H_
#include <vector>
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
namespace webrtc {
void ComparePacketFeedbackVectors(const std::vector<PacketFeedback>& truth,
const std::vector<PacketFeedback>& input);
} // namespace webrtc
#endif // WEBRTC_MODULES_CONGESTION_CONTROLLER_CONGESTION_CONTROLLER_UNITTESTS_HELPER_H_

View File

@ -16,12 +16,14 @@
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
#include "webrtc/modules/congestion_controller/transport_feedback_adapter.h"
#include "webrtc/modules/include/module.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/pacing/packet_router.h"
#include "webrtc/modules/pacing/paced_sender.h"
#include "webrtc/modules/pacing/packet_router.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h"
namespace rtc {
@ -37,9 +39,10 @@ class RateLimiter;
class RemoteBitrateEstimator;
class RemoteBitrateObserver;
class RtcEventLog;
class TransportFeedbackObserver;
class CongestionController : public CallStatsObserver, public Module {
class CongestionController : public CallStatsObserver,
public Module,
public TransportFeedbackObserver {
public:
// Observer class for bitrate changes announced due to change in bandwidth
// estimate or due to that the send pacer is full. Fraction loss and rtt is
@ -91,7 +94,6 @@ class CongestionController : public CallStatsObserver, public Module {
// TODO(nisse): Delete this accessor function. The pacer should be
// internal to the congestion controller.
virtual PacedSender* pacer() { return pacer_.get(); }
virtual TransportFeedbackObserver* GetTransportFeedbackObserver();
RateLimiter* GetRetransmissionRateLimiter();
void EnablePeriodicAlrProbing(bool enable);
@ -117,6 +119,13 @@ class CongestionController : public CallStatsObserver, public Module {
int64_t TimeUntilNextProcess() override;
void Process() override;
// Implements TransportFeedbackObserver.
void AddPacket(uint16_t sequence_number,
size_t length,
const PacedPacketInfo& pacing_info) override;
void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override;
std::vector<PacketFeedback> GetTransportFeedbackVector() const override;
private:
class WrappingBitrateEstimator : public RemoteBitrateEstimator {
public:
@ -165,6 +174,7 @@ class CongestionController : public CallStatsObserver, public Module {
int64_t rtt);
Clock* const clock_;
Observer* const observer_;
RtcEventLog* const event_log_;
PacketRouter* const packet_router_;
const std::unique_ptr<PacedSender> pacer_;
const std::unique_ptr<BitrateController> bitrate_controller_;
@ -175,11 +185,15 @@ class CongestionController : public CallStatsObserver, public Module {
TransportFeedbackAdapter transport_feedback_adapter_;
int min_bitrate_bps_;
int max_bitrate_bps_;
rtc::CriticalSection critsect_;
uint32_t last_reported_bitrate_bps_ GUARDED_BY(critsect_);
uint8_t last_reported_fraction_loss_ GUARDED_BY(critsect_);
int64_t last_reported_rtt_ GUARDED_BY(critsect_);
NetworkState network_state_ GUARDED_BY(critsect_);
rtc::CriticalSection network_state_lock_;
uint32_t last_reported_bitrate_bps_ GUARDED_BY(network_state_lock_);
uint8_t last_reported_fraction_loss_ GUARDED_BY(network_state_lock_);
int64_t last_reported_rtt_ GUARDED_BY(network_state_lock_);
NetworkState network_state_ GUARDED_BY(network_state_lock_);
rtc::CriticalSection bwe_lock_;
std::unique_ptr<DelayBasedBwe> delay_based_bwe_ GUARDED_BY(bwe_lock_);
rtc::ThreadChecker worker_thread_checker_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CongestionController);
};

View File

@ -10,17 +10,11 @@
#include "webrtc/modules/congestion_controller/transport_feedback_adapter.h"
#include <algorithm>
#include <limits>
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/mod_ops.h"
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "webrtc/modules/utility/include/process_thread.h"
#include "webrtc/system_wrappers/include/field_trial.h"
namespace webrtc {
@ -31,27 +25,17 @@ const int64_t kBaseTimestampScaleFactor =
rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 8);
const int64_t kBaseTimestampRangeSizeUs = kBaseTimestampScaleFactor * (1 << 24);
TransportFeedbackAdapter::TransportFeedbackAdapter(
RtcEventLog* event_log,
Clock* clock,
BitrateController* bitrate_controller)
TransportFeedbackAdapter::TransportFeedbackAdapter(Clock* clock)
: send_side_bwe_with_overhead_(
webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
transport_overhead_bytes_per_packet_(0),
send_time_history_(clock, kSendTimeHistoryWindowMs),
event_log_(event_log),
clock_(clock),
current_offset_ms_(kNoTimestamp),
last_timestamp_us_(kNoTimestamp),
bitrate_controller_(bitrate_controller) {}
last_timestamp_us_(kNoTimestamp) {}
TransportFeedbackAdapter::~TransportFeedbackAdapter() {}
void TransportFeedbackAdapter::InitBwe() {
rtc::CritScope cs(&bwe_lock_);
delay_based_bwe_.reset(new DelayBasedBwe(event_log_, clock_));
}
void TransportFeedbackAdapter::AddPacket(uint16_t sequence_number,
size_t length,
const PacedPacketInfo& pacing_info) {
@ -68,27 +52,12 @@ void TransportFeedbackAdapter::OnSentPacket(uint16_t sequence_number,
send_time_history_.OnSentPacket(sequence_number, send_time_ms);
}
void TransportFeedbackAdapter::SetStartBitrate(int start_bitrate_bps) {
rtc::CritScope cs(&bwe_lock_);
delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
}
void TransportFeedbackAdapter::SetMinBitrate(int min_bitrate_bps) {
rtc::CritScope cs(&bwe_lock_);
delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
}
void TransportFeedbackAdapter::SetTransportOverhead(
int transport_overhead_bytes_per_packet) {
rtc::CritScope cs(&lock_);
transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
}
int64_t TransportFeedbackAdapter::GetProbingIntervalMs() const {
rtc::CritScope cs(&bwe_lock_);
return delay_based_bwe_->GetProbingIntervalMs();
}
void TransportFeedbackAdapter::ClearSendTimeHistory() {
rtc::CritScope cs(&lock_);
send_time_history_.Clear();
@ -172,25 +141,10 @@ std::vector<PacketFeedback> TransportFeedbackAdapter::GetPacketFeedbackVector(
void TransportFeedbackAdapter::OnTransportFeedback(
const rtcp::TransportFeedback& feedback) {
last_packet_feedback_vector_ = GetPacketFeedbackVector(feedback);
DelayBasedBwe::Result result;
{
rtc::CritScope cs(&bwe_lock_);
result = delay_based_bwe_->IncomingPacketFeedbackVector(
last_packet_feedback_vector_);
}
if (result.updated)
bitrate_controller_->OnDelayBasedBweResult(result);
}
std::vector<PacketFeedback>
TransportFeedbackAdapter::GetTransportFeedbackVector() const {
return last_packet_feedback_vector_;
}
void TransportFeedbackAdapter::OnRttUpdate(int64_t avg_rtt_ms,
int64_t max_rtt_ms) {
rtc::CritScope cs(&bwe_lock_);
delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
}
} // namespace webrtc

View File

@ -11,52 +11,38 @@
#ifndef WEBRTC_MODULES_CONGESTION_CONTROLLER_TRANSPORT_FEEDBACK_ADAPTER_H_
#define WEBRTC_MODULES_CONGESTION_CONTROLLER_TRANSPORT_FEEDBACK_ADAPTER_H_
#include <memory>
#include <vector>
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
#include "webrtc/system_wrappers/include/clock.h"
namespace webrtc {
class BitrateController;
class RtcEventLog;
class ProcessThread;
namespace rtcp {
class TransportFeedback;
} // namespace rtcp
class TransportFeedbackAdapter : public TransportFeedbackObserver,
public CallStatsObserver {
class TransportFeedbackAdapter {
public:
TransportFeedbackAdapter(RtcEventLog* event_log,
Clock* clock,
BitrateController* bitrate_controller);
explicit TransportFeedbackAdapter(Clock* clock);
virtual ~TransportFeedbackAdapter();
void InitBwe();
// Implements TransportFeedbackObserver.
void AddPacket(uint16_t sequence_number,
size_t length,
const PacedPacketInfo& pacing_info) override;
const PacedPacketInfo& pacing_info);
void OnSentPacket(uint16_t sequence_number, int64_t send_time_ms);
// TODO(holmer): This method should return DelayBasedBwe::Result so that we
// can get rid of the dependency on BitrateController. Requires changes
// to the CongestionController interface.
void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override;
std::vector<PacketFeedback> GetTransportFeedbackVector() const override;
void OnTransportFeedback(const rtcp::TransportFeedback& feedback);
std::vector<PacketFeedback> GetTransportFeedbackVector() const;
// Implements CallStatsObserver.
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
void SetStartBitrate(int start_bitrate_bps);
void SetMinBitrate(int min_bitrate_bps);
void SetTransportOverhead(int transport_overhead_bytes_per_packet);
int64_t GetProbingIntervalMs() const;
void ClearSendTimeHistory();
private:
@ -65,15 +51,11 @@ class TransportFeedbackAdapter : public TransportFeedbackObserver,
const bool send_side_bwe_with_overhead_;
rtc::CriticalSection lock_;
rtc::CriticalSection bwe_lock_;
int transport_overhead_bytes_per_packet_ GUARDED_BY(&lock_);
SendTimeHistory send_time_history_ GUARDED_BY(&lock_);
std::unique_ptr<DelayBasedBwe> delay_based_bwe_ GUARDED_BY(&bwe_lock_);
RtcEventLog* const event_log_;
Clock* const clock_;
const Clock* const clock_;
int64_t current_offset_ms_;
int64_t last_timestamp_us_;
BitrateController* const bitrate_controller_;
std::vector<PacketFeedback> last_packet_feedback_vector_;
};

View File

@ -15,6 +15,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/safe_conversions.h"
#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
#include "webrtc/modules/congestion_controller/congestion_controller_unittests_helper.h"
#include "webrtc/modules/congestion_controller/transport_feedback_adapter.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
@ -39,69 +40,23 @@ namespace test {
class TransportFeedbackAdapterTest : public ::testing::Test {
public:
TransportFeedbackAdapterTest()
: clock_(0), bitrate_controller_(this), target_bitrate_bps_(0) {}
TransportFeedbackAdapterTest() : clock_(0) {}
virtual ~TransportFeedbackAdapterTest() {}
virtual void SetUp() {
adapter_.reset(
new TransportFeedbackAdapter(nullptr, &clock_, &bitrate_controller_));
adapter_->InitBwe();
adapter_->SetStartBitrate(300000);
adapter_.reset(new TransportFeedbackAdapter(&clock_));
}
virtual void TearDown() { adapter_.reset(); }
protected:
// Proxy class used since TransportFeedbackAdapter will own the instance
// passed at construction.
class MockBitrateControllerAdapter : public MockBitrateController {
public:
explicit MockBitrateControllerAdapter(TransportFeedbackAdapterTest* owner)
: MockBitrateController(), owner_(owner) {}
~MockBitrateControllerAdapter() override {}
void OnDelayBasedBweResult(const DelayBasedBwe::Result& result) override {
owner_->target_bitrate_bps_ = result.target_bitrate_bps;
}
TransportFeedbackAdapterTest* const owner_;
};
void OnReceivedEstimatedBitrate(uint32_t bitrate) {}
void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
int64_t rtt,
int64_t now_ms) {}
void ComparePacketVectors(const std::vector<PacketFeedback>& truth,
const std::vector<PacketFeedback>& input) {
ASSERT_EQ(truth.size(), input.size());
size_t len = truth.size();
// truth contains the input data for the test, and input is what will be
// sent to the bandwidth estimator. truth.arrival_tims_ms is used to
// populate the transport feedback messages. As these times may be changed
// (because of resolution limits in the packets, and because of the time
// base adjustment performed by the TransportFeedbackAdapter at the first
// packet, the truth[x].arrival_time and input[x].arrival_time may not be
// equal. However, the difference must be the same for all x.
int64_t arrival_time_delta =
truth[0].arrival_time_ms - input[0].arrival_time_ms;
for (size_t i = 0; i < len; ++i) {
RTC_CHECK(truth[i].arrival_time_ms != PacketFeedback::kNotReceived);
if (input[i].arrival_time_ms != PacketFeedback::kNotReceived) {
EXPECT_EQ(truth[i].arrival_time_ms,
input[i].arrival_time_ms + arrival_time_delta);
}
EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms);
EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number);
EXPECT_EQ(truth[i].payload_size, input[i].payload_size);
EXPECT_EQ(truth[i].pacing_info, input[i].pacing_info);
}
}
void OnSentPacket(const PacketFeedback& packet_feedback) {
adapter_->AddPacket(packet_feedback.sequence_number,
packet_feedback.payload_size,
@ -111,10 +66,7 @@ class TransportFeedbackAdapterTest : public ::testing::Test {
}
SimulatedClock clock_;
MockBitrateControllerAdapter bitrate_controller_;
std::unique_ptr<TransportFeedbackAdapter> adapter_;
uint32_t target_bitrate_bps_;
};
TEST_F(TransportFeedbackAdapterTest, AdaptsFeedbackAndPopulatesSendTimes) {
@ -140,7 +92,7 @@ TEST_F(TransportFeedbackAdapterTest, AdaptsFeedbackAndPopulatesSendTimes) {
feedback.Build();
adapter_->OnTransportFeedback(feedback);
ComparePacketVectors(packets, adapter_->GetTransportFeedbackVector());
ComparePacketFeedbackVectors(packets, adapter_->GetTransportFeedbackVector());
}
TEST_F(TransportFeedbackAdapterTest, FeedbackVectorReportsUnreceived) {
@ -175,91 +127,8 @@ TEST_F(TransportFeedbackAdapterTest, FeedbackVectorReportsUnreceived) {
feedback.Build();
adapter_->OnTransportFeedback(feedback);
ComparePacketVectors(sent_packets, adapter_->GetTransportFeedbackVector());
}
TEST_F(TransportFeedbackAdapterTest, LongFeedbackDelays) {
const int64_t kFeedbackTimeoutMs = 60001;
const int kMaxConsecutiveFailedLookups = 5;
for (int i = 0; i < kMaxConsecutiveFailedLookups; ++i) {
std::vector<PacketFeedback> packets;
packets.push_back(
PacketFeedback(i * 100, 2 * i * 100, 0, 1500, kPacingInfo0));
packets.push_back(
PacketFeedback(i * 100 + 10, 2 * i * 100 + 10, 1, 1500, kPacingInfo0));
packets.push_back(
PacketFeedback(i * 100 + 20, 2 * i * 100 + 20, 2, 1500, kPacingInfo0));
packets.push_back(
PacketFeedback(i * 100 + 30, 2 * i * 100 + 30, 3, 1500, kPacingInfo1));
packets.push_back(
PacketFeedback(i * 100 + 40, 2 * i * 100 + 40, 4, 1500, kPacingInfo1));
for (const PacketFeedback& packet : packets)
OnSentPacket(packet);
rtcp::TransportFeedback feedback;
feedback.SetBase(packets[0].sequence_number,
packets[0].arrival_time_ms * 1000);
for (const PacketFeedback& packet : packets) {
EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
packet.arrival_time_ms * 1000));
}
feedback.Build();
clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs);
PacketFeedback later_packet(kFeedbackTimeoutMs + i * 100 + 40,
kFeedbackTimeoutMs + i * 200 + 40, 5, 1500,
kPacingInfo1);
OnSentPacket(later_packet);
adapter_->OnTransportFeedback(feedback);
// Check that packets have timed out.
for (PacketFeedback& packet : packets) {
packet.send_time_ms = -1;
packet.payload_size = 0;
packet.pacing_info = PacedPacketInfo();
}
ComparePacketVectors(packets, adapter_->GetTransportFeedbackVector());
}
// Target bitrate should have halved due to feedback delays.
EXPECT_EQ(150000u, target_bitrate_bps_);
// Test with feedback that isn't late enough to time out.
{
std::vector<PacketFeedback> packets;
packets.push_back(PacketFeedback(100, 200, 0, 1500, kPacingInfo0));
packets.push_back(PacketFeedback(110, 210, 1, 1500, kPacingInfo0));
packets.push_back(PacketFeedback(120, 220, 2, 1500, kPacingInfo0));
packets.push_back(PacketFeedback(130, 230, 3, 1500, kPacingInfo1));
packets.push_back(PacketFeedback(140, 240, 4, 1500, kPacingInfo1));
for (const PacketFeedback& packet : packets)
OnSentPacket(packet);
rtcp::TransportFeedback feedback;
feedback.SetBase(packets[0].sequence_number,
packets[0].arrival_time_ms * 1000);
for (const PacketFeedback& packet : packets) {
EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
packet.arrival_time_ms * 1000));
}
feedback.Build();
clock_.AdvanceTimeMilliseconds(kFeedbackTimeoutMs - 1);
PacketFeedback later_packet(kFeedbackTimeoutMs + 140,
kFeedbackTimeoutMs + 240, 5, 1500,
kPacingInfo1);
OnSentPacket(later_packet);
adapter_->OnTransportFeedback(feedback);
ComparePacketVectors(packets, adapter_->GetTransportFeedbackVector());
}
ComparePacketFeedbackVectors(sent_packets,
adapter_->GetTransportFeedbackVector());
}
TEST_F(TransportFeedbackAdapterTest, HandlesDroppedPackets) {
@ -302,8 +171,8 @@ TEST_F(TransportFeedbackAdapterTest, HandlesDroppedPackets) {
}
adapter_->OnTransportFeedback(feedback);
ComparePacketVectors(expected_packets,
adapter_->GetTransportFeedbackVector());
ComparePacketFeedbackVectors(expected_packets,
adapter_->GetTransportFeedbackVector());
}
TEST_F(TransportFeedbackAdapterTest, SendTimeWrapsBothWays) {
@ -338,8 +207,8 @@ TEST_F(TransportFeedbackAdapterTest, SendTimeWrapsBothWays) {
expected_packets.push_back(packets[i]);
adapter_->OnTransportFeedback(*feedback.get());
ComparePacketVectors(expected_packets,
adapter_->GetTransportFeedbackVector());
ComparePacketFeedbackVectors(expected_packets,
adapter_->GetTransportFeedbackVector());
}
}
@ -367,7 +236,7 @@ TEST_F(TransportFeedbackAdapterTest, HandlesArrivalReordering) {
// assigned by the order of transmission). Reordering by some other criteria,
// eg. arrival time, is up to the observers.
adapter_->OnTransportFeedback(feedback);
ComparePacketVectors(packets, adapter_->GetTransportFeedbackVector());
ComparePacketFeedbackVectors(packets, adapter_->GetTransportFeedbackVector());
}
TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
@ -430,7 +299,8 @@ TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
EXPECT_TRUE(feedback.get() != nullptr);
adapter_->OnTransportFeedback(*feedback.get());
ComparePacketVectors(sent_packets, adapter_->GetTransportFeedbackVector());
ComparePacketFeedbackVectors(sent_packets,
adapter_->GetTransportFeedbackVector());
// Create a new feedback message and add the trailing item.
feedback.reset(new rtcp::TransportFeedback());
@ -447,39 +317,9 @@ TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
{
std::vector<PacketFeedback> expected_packets;
expected_packets.push_back(packet_feedback);
ComparePacketVectors(expected_packets,
adapter_->GetTransportFeedbackVector());
ComparePacketFeedbackVectors(expected_packets,
adapter_->GetTransportFeedbackVector());
}
}
TEST_F(TransportFeedbackAdapterTest, UpdatesDelayBasedEstimate) {
uint16_t seq_num = 0;
size_t kPayloadSize = 1000;
// The test must run and insert packets/feedback long enough that the
// BWE computes a valid estimate.
const int64_t kRunTimeMs = 6000;
int64_t start_time_ms = clock_.TimeInMilliseconds();
while (clock_.TimeInMilliseconds() - start_time_ms < kRunTimeMs) {
PacketFeedback packet(clock_.TimeInMilliseconds(),
clock_.TimeInMilliseconds(), seq_num, kPayloadSize,
PacedPacketInfo());
OnSentPacket(packet);
// Create expected feedback and send into adapter.
std::unique_ptr<rtcp::TransportFeedback> feedback(
new rtcp::TransportFeedback());
feedback->SetBase(packet.sequence_number, packet.arrival_time_ms * 1000);
EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number,
packet.arrival_time_ms * 1000));
rtc::Buffer raw_packet = feedback->Build();
feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(),
raw_packet.size());
EXPECT_TRUE(feedback.get() != nullptr);
adapter_->OnTransportFeedback(*feedback.get());
clock_.AdvanceTimeMilliseconds(50);
++seq_num;
}
EXPECT_GT(target_bitrate_bps_, 0u);
}
} // namespace test
} // namespace webrtc

View File

@ -24,7 +24,6 @@
#include "webrtc/call/audio_send_stream.h"
#include "webrtc/call/call.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
@ -1072,11 +1071,9 @@ void EventLogAnalyzer::CreateBweSimulationGraph(Plot* plot) {
RTC_DCHECK_EQ(clock.TimeInMicroseconds(), NextRtcpTime());
const LoggedRtcpPacket& rtcp = *rtcp_iterator->second;
if (rtcp.type == kRtcpTransportFeedback) {
TransportFeedbackObserver* observer = cc.GetTransportFeedbackObserver();
observer->OnTransportFeedback(*static_cast<rtcp::TransportFeedback*>(
rtcp.packet.get()));
std::vector<PacketFeedback> feedback =
observer->GetTransportFeedbackVector();
cc.OnTransportFeedback(
*static_cast<rtcp::TransportFeedback*>(rtcp.packet.get()));
std::vector<PacketFeedback> feedback = cc.GetTransportFeedbackVector();
SortPacketFeedbackVector(&feedback);
rtc::Optional<uint32_t> bitrate_bps;
if (!feedback.empty()) {
@ -1098,9 +1095,8 @@ void EventLogAnalyzer::CreateBweSimulationGraph(Plot* plot) {
const LoggedRtpPacket& rtp = *rtp_iterator->second;
if (rtp.header.extension.hasTransportSequenceNumber) {
RTC_DCHECK(rtp.header.extension.hasTransportSequenceNumber);
cc.GetTransportFeedbackObserver()->AddPacket(
rtp.header.extension.transportSequenceNumber, rtp.total_length,
PacedPacketInfo());
cc.AddPacket(rtp.header.extension.transportSequenceNumber,
rtp.total_length, PacedPacketInfo());
rtc::SentPacket sent_packet(
rtp.header.extension.transportSequenceNumber, rtp.timestamp / 1000);
cc.OnSentPacket(sent_packet);
@ -1130,34 +1126,6 @@ void EventLogAnalyzer::CreateBweSimulationGraph(Plot* plot) {
plot->SetTitle("Simulated BWE behavior");
}
// TODO(holmer): Remove once TransportFeedbackAdapter no longer needs a
// BitrateController.
class NullBitrateController : public BitrateController {
public:
~NullBitrateController() override {}
RtcpBandwidthObserver* CreateRtcpBandwidthObserver() override {
return nullptr;
}
void SetStartBitrate(int start_bitrate_bps) override {}
void SetMinMaxBitrate(int min_bitrate_bps, int max_bitrate_bps) override {}
void SetBitrates(int start_bitrate_bps,
int min_bitrate_bps,
int max_bitrate_bps) override {}
void ResetBitrates(int bitrate_bps,
int min_bitrate_bps,
int max_bitrate_bps) override {}
void OnDelayBasedBweResult(const DelayBasedBwe::Result& result) override {}
bool AvailableBandwidth(uint32_t* bandwidth) const override { return false; }
void SetReservedBitrate(uint32_t reserved_bitrate_bps) override {}
bool GetNetworkParameters(uint32_t* bitrate,
uint8_t* fraction_loss,
int64_t* rtt) override {
return false;
}
int64_t TimeUntilNextProcess() override { return 0; }
void Process() override {}
};
void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) {
std::map<uint64_t, const LoggedRtpPacket*> outgoing_rtp;
std::map<uint64_t, const LoggedRtcpPacket*> incoming_rtcp;
@ -1178,9 +1146,7 @@ void EventLogAnalyzer::CreateNetworkDelayFeedbackGraph(Plot* plot) {
}
SimulatedClock clock(0);
NullBitrateController null_controller;
TransportFeedbackAdapter feedback_adapter(nullptr, &clock, &null_controller);
feedback_adapter.InitBwe();
TransportFeedbackAdapter feedback_adapter(&clock);
TimeSeries time_series;
time_series.label = "Network Delay Change";

View File

@ -789,7 +789,7 @@ VideoSendStreamImpl::VideoSendStreamImpl(
config_->send_transport,
&encoder_feedback_,
bandwidth_observer_.get(),
congestion_controller_->GetTransportFeedbackObserver(),
congestion_controller_,
call_stats_->rtcp_rtt_stats(),
congestion_controller_->pacer(),
packet_router_,