Replace interfaces for sending RTCP with std::functions in ReceiveSideCongestionController
Logic for throttling how often REMB messages are sent is added to ReceiveSideCongestionController as well as a new method SetMaxDesiredReceiveBitrate. These are based on the logic in PacketRouter. The logic for throttling REMB and setting the max REMB will be removed from PacketRouter in a follow up cl. The purpose is to eventually decouple PacketRouter from sending RTCP messages when RtcpTransceiver is used. Bug: webrtc:12693 Change-Id: I9fb5cbcd14bb17d977e76d329a906fc0a9abc276 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215685 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Per Kjellander <perkj@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33801}
This commit is contained in:
parent
1585587c57
commit
898f091eeb
@ -22,12 +22,17 @@ rtc_library("congestion_controller") {
|
||||
sources = [
|
||||
"include/receive_side_congestion_controller.h",
|
||||
"receive_side_congestion_controller.cc",
|
||||
"remb_throttler.cc",
|
||||
"remb_throttler.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"..:module_api",
|
||||
"../../api/transport:field_trial_based_config",
|
||||
"../../api/transport:network_control",
|
||||
"../../api/units:data_rate",
|
||||
"../../api/units:time_delta",
|
||||
"../../api/units:timestamp",
|
||||
"../../rtc_base/synchronization:mutex",
|
||||
"../pacing",
|
||||
"../remote_bitrate_estimator",
|
||||
@ -43,11 +48,17 @@ if (rtc_include_tests && !build_with_chromium) {
|
||||
rtc_library("congestion_controller_unittests") {
|
||||
testonly = true
|
||||
|
||||
sources = [ "receive_side_congestion_controller_unittest.cc" ]
|
||||
sources = [
|
||||
"receive_side_congestion_controller_unittest.cc",
|
||||
"remb_throttler_unittest.cc",
|
||||
]
|
||||
deps = [
|
||||
":congestion_controller",
|
||||
"../../api/test/network_emulation",
|
||||
"../../api/test/network_emulation:create_cross_traffic",
|
||||
"../../api/units:data_rate",
|
||||
"../../api/units:time_delta",
|
||||
"../../api/units:timestamp",
|
||||
"../../system_wrappers",
|
||||
"../../test:test_support",
|
||||
"../../test/scenario",
|
||||
|
||||
@ -16,7 +16,10 @@
|
||||
|
||||
#include "api/transport/field_trial_based_config.h"
|
||||
#include "api/transport/network_control.h"
|
||||
#include "api/units/data_rate.h"
|
||||
#include "modules/congestion_controller/remb_throttler.h"
|
||||
#include "modules/include/module.h"
|
||||
#include "modules/pacing/packet_router.h"
|
||||
#include "modules/remote_bitrate_estimator/remote_estimator_proxy.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
|
||||
@ -32,12 +35,20 @@ class RemoteBitrateObserver;
|
||||
class ReceiveSideCongestionController : public CallStatsObserver,
|
||||
public Module {
|
||||
public:
|
||||
// TODO(bugs.webrtc.org/12693): Deprecate
|
||||
ReceiveSideCongestionController(Clock* clock, PacketRouter* packet_router);
|
||||
// TODO(bugs.webrtc.org/12693): Deprecate
|
||||
ReceiveSideCongestionController(
|
||||
Clock* clock,
|
||||
PacketRouter* packet_router,
|
||||
NetworkStateEstimator* network_state_estimator);
|
||||
|
||||
ReceiveSideCongestionController(
|
||||
Clock* clock,
|
||||
RemoteEstimatorProxy::TransportFeedbackSender feedback_sender,
|
||||
RembThrottler::RembSender remb_sender,
|
||||
NetworkStateEstimator* network_state_estimator);
|
||||
|
||||
~ReceiveSideCongestionController() override {}
|
||||
|
||||
virtual void OnReceivedPacket(int64_t arrival_time_ms,
|
||||
@ -56,6 +67,10 @@ class ReceiveSideCongestionController : public CallStatsObserver,
|
||||
// This is send bitrate, used to control the rate of feedback messages.
|
||||
void OnBitrateChanged(int bitrate_bps);
|
||||
|
||||
// Ensures the remote party is notified of the receive bitrate no larger than
|
||||
// |bitrate| using RTCP REMB.
|
||||
void SetMaxDesiredReceiveBitrate(DataRate bitrate);
|
||||
|
||||
// Implements Module.
|
||||
int64_t TimeUntilNextProcess() override;
|
||||
void Process() override;
|
||||
@ -103,6 +118,7 @@ class ReceiveSideCongestionController : public CallStatsObserver,
|
||||
};
|
||||
|
||||
const FieldTrialBasedConfig field_trial_config_;
|
||||
RembThrottler remb_throttler_;
|
||||
WrappingBitrateEstimator remote_bitrate_estimator_;
|
||||
RemoteEstimatorProxy remote_estimator_proxy_;
|
||||
};
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "modules/congestion_controller/include/receive_side_congestion_controller.h"
|
||||
|
||||
#include "api/units/data_rate.h"
|
||||
#include "modules/pacing/packet_router.h"
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
@ -127,9 +128,26 @@ ReceiveSideCongestionController::ReceiveSideCongestionController(
|
||||
Clock* clock,
|
||||
PacketRouter* packet_router,
|
||||
NetworkStateEstimator* network_state_estimator)
|
||||
: remote_bitrate_estimator_(packet_router, clock),
|
||||
: remb_throttler_([](auto...) {}, clock),
|
||||
remote_bitrate_estimator_(packet_router, clock),
|
||||
remote_estimator_proxy_(
|
||||
clock,
|
||||
[packet_router](
|
||||
std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets) {
|
||||
packet_router->SendCombinedRtcpPacket(std::move(packets));
|
||||
},
|
||||
&field_trial_config_,
|
||||
network_state_estimator) {}
|
||||
|
||||
ReceiveSideCongestionController::ReceiveSideCongestionController(
|
||||
Clock* clock,
|
||||
RemoteEstimatorProxy::TransportFeedbackSender feedback_sender,
|
||||
RembThrottler::RembSender remb_sender,
|
||||
NetworkStateEstimator* network_state_estimator)
|
||||
: remb_throttler_(std::move(remb_sender), clock),
|
||||
remote_bitrate_estimator_(&remb_throttler_, clock),
|
||||
remote_estimator_proxy_(clock,
|
||||
packet_router,
|
||||
std::move(feedback_sender),
|
||||
&field_trial_config_,
|
||||
network_state_estimator) {}
|
||||
|
||||
@ -186,4 +204,9 @@ void ReceiveSideCongestionController::Process() {
|
||||
remote_bitrate_estimator_.Process();
|
||||
}
|
||||
|
||||
void ReceiveSideCongestionController::SetMaxDesiredReceiveBitrate(
|
||||
DataRate bitrate) {
|
||||
remb_throttler_.SetMaxDesiredReceiveBitrate(bitrate);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -20,10 +20,8 @@
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::AtLeast;
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
using ::testing::SaveArg;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::MockFunction;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -37,34 +35,28 @@ uint32_t AbsSendTime(int64_t t, int64_t denom) {
|
||||
return (((t << 18) + (denom >> 1)) / denom) & 0x00fffffful;
|
||||
}
|
||||
|
||||
class MockPacketRouter : public PacketRouter {
|
||||
public:
|
||||
MOCK_METHOD(void,
|
||||
OnReceiveBitrateChanged,
|
||||
(const std::vector<uint32_t>& ssrcs, uint32_t bitrate),
|
||||
(override));
|
||||
};
|
||||
|
||||
const uint32_t kInitialBitrateBps = 60000;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace test {
|
||||
|
||||
TEST(ReceiveSideCongestionControllerTest, OnReceivedPacketWithAbsSendTime) {
|
||||
StrictMock<MockPacketRouter> packet_router;
|
||||
TEST(ReceiveSideCongestionControllerTest, SendsRembWithAbsSendTime) {
|
||||
MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)>
|
||||
feedback_sender;
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
SimulatedClock clock_(123456);
|
||||
|
||||
ReceiveSideCongestionController controller(&clock_, &packet_router);
|
||||
ReceiveSideCongestionController controller(
|
||||
&clock_, feedback_sender.AsStdFunction(), remb_sender.AsStdFunction(),
|
||||
nullptr);
|
||||
|
||||
size_t payload_size = 1000;
|
||||
RTPHeader header;
|
||||
header.ssrc = 0x11eb21c;
|
||||
header.extension.hasAbsoluteSendTime = true;
|
||||
|
||||
std::vector<unsigned int> ssrcs;
|
||||
EXPECT_CALL(packet_router, OnReceiveBitrateChanged(_, _))
|
||||
.WillRepeatedly(SaveArg<0>(&ssrcs));
|
||||
EXPECT_CALL(remb_sender, Call(_, ElementsAre(header.ssrc))).Times(AtLeast(1));
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
clock_.AdvanceTimeMilliseconds((1000 * payload_size) / kInitialBitrateBps);
|
||||
@ -72,9 +64,20 @@ TEST(ReceiveSideCongestionControllerTest, OnReceivedPacketWithAbsSendTime) {
|
||||
header.extension.absoluteSendTime = AbsSendTime(now_ms, 1000);
|
||||
controller.OnReceivedPacket(now_ms, payload_size, header);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ(1u, ssrcs.size());
|
||||
EXPECT_EQ(header.ssrc, ssrcs[0]);
|
||||
TEST(ReceiveSideCongestionControllerTest,
|
||||
SendsRembAfterSetMaxDesiredReceiveBitrate) {
|
||||
MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)>
|
||||
feedback_sender;
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
SimulatedClock clock_(123456);
|
||||
|
||||
ReceiveSideCongestionController controller(
|
||||
&clock_, feedback_sender.AsStdFunction(), remb_sender.AsStdFunction(),
|
||||
nullptr);
|
||||
EXPECT_CALL(remb_sender, Call(123, _));
|
||||
controller.SetMaxDesiredReceiveBitrate(DataRate::BitsPerSec(123));
|
||||
}
|
||||
|
||||
TEST(ReceiveSideCongestionControllerTest, ConvergesToCapacity) {
|
||||
|
||||
63
modules/congestion_controller/remb_throttler.cc
Normal file
63
modules/congestion_controller/remb_throttler.cc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "modules/congestion_controller/remb_throttler.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
constexpr TimeDelta kRembSendInterval = TimeDelta::Millis(200);
|
||||
} // namespace
|
||||
|
||||
RembThrottler::RembThrottler(RembSender remb_sender, Clock* clock)
|
||||
: remb_sender_(std::move(remb_sender)),
|
||||
clock_(clock),
|
||||
last_remb_time_(Timestamp::MinusInfinity()),
|
||||
last_send_remb_bitrate_(DataRate::PlusInfinity()),
|
||||
max_remb_bitrate_(DataRate::PlusInfinity()) {}
|
||||
|
||||
void RembThrottler::OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
|
||||
uint32_t bitrate_bps) {
|
||||
DataRate receive_bitrate = DataRate::BitsPerSec(bitrate_bps);
|
||||
Timestamp now = clock_->CurrentTime();
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
// % threshold for if we should send a new REMB asap.
|
||||
const int64_t kSendThresholdPercent = 103;
|
||||
if (receive_bitrate * kSendThresholdPercent / 100 >
|
||||
last_send_remb_bitrate_ &&
|
||||
now < last_remb_time_ + kRembSendInterval) {
|
||||
return;
|
||||
}
|
||||
last_remb_time_ = now;
|
||||
last_send_remb_bitrate_ = receive_bitrate;
|
||||
receive_bitrate = std::min(last_send_remb_bitrate_, max_remb_bitrate_);
|
||||
}
|
||||
remb_sender_(receive_bitrate.bps(), ssrcs);
|
||||
}
|
||||
|
||||
void RembThrottler::SetMaxDesiredReceiveBitrate(DataRate bitrate) {
|
||||
Timestamp now = clock_->CurrentTime();
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
max_remb_bitrate_ = bitrate;
|
||||
if (now - last_remb_time_ < kRembSendInterval &&
|
||||
!last_send_remb_bitrate_.IsZero() &&
|
||||
last_send_remb_bitrate_ <= max_remb_bitrate_) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
remb_sender_(bitrate.bps(), /*ssrcs=*/{});
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
54
modules/congestion_controller/remb_throttler.h
Normal file
54
modules/congestion_controller/remb_throttler.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 MODULES_CONGESTION_CONTROLLER_REMB_THROTTLER_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_REMB_THROTTLER_H_
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "modules/remote_bitrate_estimator/remote_estimator_proxy.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// RembThrottler is a helper class used for throttling RTCP REMB messages.
|
||||
// Throttles small changes to the received BWE within 200ms.
|
||||
class RembThrottler : public RemoteBitrateObserver {
|
||||
public:
|
||||
using RembSender =
|
||||
std::function<void(int64_t bitrate_bps, std::vector<uint32_t> ssrcs)>;
|
||||
RembThrottler(RembSender remb_sender, Clock* clock);
|
||||
|
||||
// Ensures the remote party is notified of the receive bitrate no larger than
|
||||
// |bitrate| using RTCP REMB.
|
||||
void SetMaxDesiredReceiveBitrate(DataRate bitrate);
|
||||
|
||||
// Implements RemoteBitrateObserver;
|
||||
// Called every time there is a new bitrate estimate for a receive channel
|
||||
// group. This call will trigger a new RTCP REMB packet if the bitrate
|
||||
// estimate has decreased or if no RTCP REMB packet has been sent for
|
||||
// a certain time interval.
|
||||
void OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
|
||||
uint32_t bitrate_bps) override;
|
||||
|
||||
private:
|
||||
const RembSender remb_sender_;
|
||||
Clock* const clock_;
|
||||
mutable Mutex mutex_;
|
||||
Timestamp last_remb_time_ RTC_GUARDED_BY(mutex_);
|
||||
DataRate last_send_remb_bitrate_ RTC_GUARDED_BY(mutex_);
|
||||
DataRate max_remb_bitrate_ RTC_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_REMB_THROTTLER_H_
|
||||
100
modules/congestion_controller/remb_throttler_unittest.cc
Normal file
100
modules/congestion_controller/remb_throttler_unittest.cc
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "modules/congestion_controller/remb_throttler.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::MockFunction;
|
||||
|
||||
TEST(RembThrottlerTest, CallRembSenderOnFirstReceiveBitrateChange) {
|
||||
SimulatedClock clock(Timestamp::Zero());
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
RembThrottler remb_throttler(remb_sender.AsStdFunction(), &clock);
|
||||
|
||||
EXPECT_CALL(remb_sender, Call(12345, std::vector<uint32_t>({1, 2, 3})));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/12345);
|
||||
}
|
||||
|
||||
TEST(RembThrottlerTest, ThrottlesSmallReceiveBitrateDecrease) {
|
||||
SimulatedClock clock(Timestamp::Zero());
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
RembThrottler remb_throttler(remb_sender.AsStdFunction(), &clock);
|
||||
|
||||
EXPECT_CALL(remb_sender, Call);
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/12346);
|
||||
clock.AdvanceTime(TimeDelta::Millis(100));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/12345);
|
||||
|
||||
EXPECT_CALL(remb_sender, Call(12345, _));
|
||||
clock.AdvanceTime(TimeDelta::Millis(101));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/12345);
|
||||
}
|
||||
|
||||
TEST(RembThrottlerTest, DoNotThrottleLargeReceiveBitrateDecrease) {
|
||||
SimulatedClock clock(Timestamp::Zero());
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
RembThrottler remb_throttler(remb_sender.AsStdFunction(), &clock);
|
||||
|
||||
EXPECT_CALL(remb_sender, Call(2345, _));
|
||||
EXPECT_CALL(remb_sender, Call(1234, _));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/2345);
|
||||
clock.AdvanceTime(TimeDelta::Millis(1));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/1234);
|
||||
}
|
||||
|
||||
TEST(RembThrottlerTest, ThrottlesReceiveBitrateIncrease) {
|
||||
SimulatedClock clock(Timestamp::Zero());
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
RembThrottler remb_throttler(remb_sender.AsStdFunction(), &clock);
|
||||
|
||||
EXPECT_CALL(remb_sender, Call);
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/1234);
|
||||
clock.AdvanceTime(TimeDelta::Millis(100));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/2345);
|
||||
|
||||
// Updates 200ms after previous callback is not throttled.
|
||||
EXPECT_CALL(remb_sender, Call(2345, _));
|
||||
clock.AdvanceTime(TimeDelta::Millis(101));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/2345);
|
||||
}
|
||||
|
||||
TEST(RembThrottlerTest, CallRembSenderOnSetMaxDesiredReceiveBitrate) {
|
||||
SimulatedClock clock(Timestamp::Zero());
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
RembThrottler remb_throttler(remb_sender.AsStdFunction(), &clock);
|
||||
EXPECT_CALL(remb_sender, Call(1234, _));
|
||||
remb_throttler.SetMaxDesiredReceiveBitrate(DataRate::BitsPerSec(1234));
|
||||
}
|
||||
|
||||
TEST(RembThrottlerTest, CallRembSenderWithMinOfMaxDesiredAndOnReceivedBitrate) {
|
||||
SimulatedClock clock(Timestamp::Zero());
|
||||
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
|
||||
RembThrottler remb_throttler(remb_sender.AsStdFunction(), &clock);
|
||||
|
||||
EXPECT_CALL(remb_sender, Call(1234, _));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/1234);
|
||||
clock.AdvanceTime(TimeDelta::Millis(1));
|
||||
remb_throttler.SetMaxDesiredReceiveBitrate(DataRate::BitsPerSec(4567));
|
||||
|
||||
clock.AdvanceTime(TimeDelta::Millis(200));
|
||||
EXPECT_CALL(remb_sender, Call(4567, _));
|
||||
remb_throttler.OnReceiveBitrateChanged({1, 2, 3}, /*bitrate_bps=*/5678);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -38,6 +38,7 @@ class RemoteBitrateObserver {
|
||||
virtual ~RemoteBitrateObserver() {}
|
||||
};
|
||||
|
||||
// TODO(bugs.webrtc.org/12693): Deprecate
|
||||
class TransportFeedbackSenderInterface {
|
||||
public:
|
||||
virtual ~TransportFeedbackSenderInterface() = default;
|
||||
|
||||
@ -33,11 +33,11 @@ static constexpr int64_t kMaxTimeMs =
|
||||
|
||||
RemoteEstimatorProxy::RemoteEstimatorProxy(
|
||||
Clock* clock,
|
||||
TransportFeedbackSenderInterface* feedback_sender,
|
||||
TransportFeedbackSender feedback_sender,
|
||||
const WebRtcKeyValueConfig* key_value_config,
|
||||
NetworkStateEstimator* network_state_estimator)
|
||||
: clock_(clock),
|
||||
feedback_sender_(feedback_sender),
|
||||
feedback_sender_(std::move(feedback_sender)),
|
||||
send_config_(key_value_config),
|
||||
last_process_time_ms_(-1),
|
||||
network_state_estimator_(network_state_estimator),
|
||||
@ -217,7 +217,7 @@ void RemoteEstimatorProxy::SendPeriodicFeedbacks() {
|
||||
}
|
||||
packets.push_back(std::move(feedback_packet));
|
||||
|
||||
feedback_sender_->SendCombinedRtcpPacket(std::move(packets));
|
||||
feedback_sender_(std::move(packets));
|
||||
// Note: Don't erase items from packet_arrival_times_ after sending, in case
|
||||
// they need to be re-sent after a reordering. Removal will be handled
|
||||
// by OnPacketArrival once packets are too old.
|
||||
@ -250,7 +250,7 @@ void RemoteEstimatorProxy::SendFeedbackOnRequest(
|
||||
RTC_DCHECK(feedback_sender_ != nullptr);
|
||||
std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets;
|
||||
packets.push_back(std::move(feedback_packet));
|
||||
feedback_sender_->SendCombinedRtcpPacket(std::move(packets));
|
||||
feedback_sender_(std::move(packets));
|
||||
}
|
||||
|
||||
int64_t RemoteEstimatorProxy::BuildFeedbackPacket(
|
||||
|
||||
@ -11,7 +11,9 @@
|
||||
#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_ESTIMATOR_PROXY_H_
|
||||
#define MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_ESTIMATOR_PROXY_H_
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/transport/network_control.h"
|
||||
@ -24,7 +26,6 @@
|
||||
namespace webrtc {
|
||||
|
||||
class Clock;
|
||||
class PacketRouter;
|
||||
namespace rtcp {
|
||||
class TransportFeedback;
|
||||
}
|
||||
@ -32,11 +33,14 @@ class TransportFeedback;
|
||||
// Class used when send-side BWE is enabled: This proxy is instantiated on the
|
||||
// receive side. It buffers a number of receive timestamps and then sends
|
||||
// transport feedback messages back too the send side.
|
||||
|
||||
class RemoteEstimatorProxy : public RemoteBitrateEstimator {
|
||||
public:
|
||||
// Used for sending transport feedback messages when send side
|
||||
// BWE is used.
|
||||
using TransportFeedbackSender = std::function<void(
|
||||
std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets)>;
|
||||
RemoteEstimatorProxy(Clock* clock,
|
||||
TransportFeedbackSenderInterface* feedback_sender,
|
||||
TransportFeedbackSender feedback_sender,
|
||||
const WebRtcKeyValueConfig* key_value_config,
|
||||
NetworkStateEstimator* network_state_estimator);
|
||||
~RemoteEstimatorProxy() override;
|
||||
@ -88,7 +92,7 @@ class RemoteEstimatorProxy : public RemoteBitrateEstimator {
|
||||
rtcp::TransportFeedback* feedback_packet);
|
||||
|
||||
Clock* const clock_;
|
||||
TransportFeedbackSenderInterface* const feedback_sender_;
|
||||
const TransportFeedbackSender feedback_sender_;
|
||||
const TransportWideFeedbackConfig send_config_;
|
||||
int64_t last_process_time_ms_;
|
||||
|
||||
|
||||
@ -16,8 +16,8 @@
|
||||
#include "api/transport/field_trial_based_config.h"
|
||||
#include "api/transport/network_types.h"
|
||||
#include "api/transport/test/mock_network_control.h"
|
||||
#include "modules/pacing/packet_router.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
@ -25,6 +25,7 @@
|
||||
using ::testing::_;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::MockFunction;
|
||||
using ::testing::Return;
|
||||
using ::testing::SizeIs;
|
||||
|
||||
@ -63,20 +64,12 @@ std::vector<int64_t> TimestampsMs(
|
||||
return timestamps;
|
||||
}
|
||||
|
||||
class MockTransportFeedbackSender : public TransportFeedbackSenderInterface {
|
||||
public:
|
||||
MOCK_METHOD(bool,
|
||||
SendCombinedRtcpPacket,
|
||||
(std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets),
|
||||
(override));
|
||||
};
|
||||
|
||||
class RemoteEstimatorProxyTest : public ::testing::Test {
|
||||
public:
|
||||
RemoteEstimatorProxyTest()
|
||||
: clock_(0),
|
||||
proxy_(&clock_,
|
||||
&router_,
|
||||
feedback_sender_.AsStdFunction(),
|
||||
&field_trial_config_,
|
||||
&network_state_estimator_) {}
|
||||
|
||||
@ -113,7 +106,8 @@ class RemoteEstimatorProxyTest : public ::testing::Test {
|
||||
|
||||
FieldTrialBasedConfig field_trial_config_;
|
||||
SimulatedClock clock_;
|
||||
::testing::StrictMock<MockTransportFeedbackSender> router_;
|
||||
MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)>
|
||||
feedback_sender_;
|
||||
::testing::NiceMock<MockNetworkStateEstimator> network_state_estimator_;
|
||||
RemoteEstimatorProxy proxy_;
|
||||
};
|
||||
@ -121,7 +115,7 @@ class RemoteEstimatorProxyTest : public ::testing::Test {
|
||||
TEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) {
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -134,7 +128,6 @@ TEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) {
|
||||
ElementsAre(kBaseSeq));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -144,7 +137,7 @@ TEST_F(RemoteEstimatorProxyTest, DuplicatedPackets) {
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs);
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs + 1000);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -167,13 +160,13 @@ TEST_F(RemoteEstimatorProxyTest, FeedbackWithMissingStart) {
|
||||
// First feedback.
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs);
|
||||
IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1000);
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket).WillOnce(Return(true));
|
||||
EXPECT_CALL(feedback_sender_, Call);
|
||||
Process();
|
||||
|
||||
// Second feedback starts with a missing packet (DROP kBaseSeq + 2).
|
||||
IncomingPacket(kBaseSeq + 3, kBaseTimeMs + 3000);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -186,7 +179,6 @@ TEST_F(RemoteEstimatorProxyTest, FeedbackWithMissingStart) {
|
||||
ElementsAre(kBaseSeq + 3));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs + 3000));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -197,7 +189,7 @@ TEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) {
|
||||
IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
|
||||
IncomingPacket(kBaseSeq + 2, kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -211,7 +203,6 @@ TEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) {
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs, kBaseTimeMs + kMaxSmallDeltaMs,
|
||||
kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -224,7 +215,7 @@ TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs);
|
||||
IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kTooLargeDelta);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -237,7 +228,6 @@ TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
|
||||
ElementsAre(kBaseSeq));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs));
|
||||
return true;
|
||||
}))
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
@ -251,7 +241,6 @@ TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
|
||||
ElementsAre(kBaseSeq + 1));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs + kTooLargeDelta));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -263,7 +252,7 @@ TEST_F(RemoteEstimatorProxyTest, HandlesReorderingAndWrap) {
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs);
|
||||
IncomingPacket(kLargeSeq, kBaseTimeMs + kDeltaMs);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -274,7 +263,6 @@ TEST_F(RemoteEstimatorProxyTest, HandlesReorderingAndWrap) {
|
||||
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs + kDeltaMs, kBaseTimeMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -293,7 +281,7 @@ TEST_F(RemoteEstimatorProxyTest, HandlesMalformedSequenceNumbers) {
|
||||
}
|
||||
|
||||
// Only expect feedback for the last two packets.
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -306,7 +294,6 @@ TEST_F(RemoteEstimatorProxyTest, HandlesMalformedSequenceNumbers) {
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs + 28 * kDeltaMs,
|
||||
kBaseTimeMs + 29 * kDeltaMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -324,7 +311,7 @@ TEST_F(RemoteEstimatorProxyTest, HandlesBackwardsWrappingSequenceNumbers) {
|
||||
}
|
||||
|
||||
// Only expect feedback for the first two packets.
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -336,7 +323,6 @@ TEST_F(RemoteEstimatorProxyTest, HandlesBackwardsWrappingSequenceNumbers) {
|
||||
ElementsAre(kBaseSeq + 40000, kBaseSeq));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs + kDeltaMs, kBaseTimeMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -346,7 +332,7 @@ TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs);
|
||||
IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -359,14 +345,13 @@ TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
|
||||
ElementsAre(kBaseSeq, kBaseSeq + 2));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs, kBaseTimeMs + 2));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
|
||||
IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -379,7 +364,6 @@ TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
|
||||
ElementsAre(kBaseSeq + 1, kBaseSeq + 2));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs + 1, kBaseTimeMs + 2));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -390,7 +374,7 @@ TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
|
||||
|
||||
IncomingPacket(kBaseSeq + 2, kBaseTimeMs);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -400,14 +384,13 @@ TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
|
||||
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
|
||||
IncomingPacket(kBaseSeq + 3, kTimeoutTimeMs); // kBaseSeq + 2 times out here.
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -417,7 +400,6 @@ TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
|
||||
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kTimeoutTimeMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -427,7 +409,7 @@ TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs - 1);
|
||||
IncomingPacket(kBaseSeq + 1, kTimeoutTimeMs - 1);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -440,7 +422,6 @@ TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs - 1, kTimeoutTimeMs - 1,
|
||||
kTimeoutTimeMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
Process();
|
||||
@ -496,7 +477,7 @@ TEST_F(RemoteEstimatorProxyOnRequestTest, TimeUntilNextProcessIsHigh) {
|
||||
TEST_F(RemoteEstimatorProxyOnRequestTest, ProcessDoesNotSendFeedback) {
|
||||
proxy_.SetSendPeriodicFeedback(false);
|
||||
IncomingPacket(kBaseSeq, kBaseTimeMs);
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket).Times(0);
|
||||
EXPECT_CALL(feedback_sender_, Call).Times(0);
|
||||
Process();
|
||||
}
|
||||
|
||||
@ -506,7 +487,7 @@ TEST_F(RemoteEstimatorProxyOnRequestTest, RequestSinglePacketFeedback) {
|
||||
IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
|
||||
IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2 * kMaxSmallDeltaMs);
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -519,7 +500,6 @@ TEST_F(RemoteEstimatorProxyOnRequestTest, RequestSinglePacketFeedback) {
|
||||
ElementsAre(kBaseSeq + 3));
|
||||
EXPECT_THAT(TimestampsMs(*feedback_packet),
|
||||
ElementsAre(kBaseTimeMs + 3 * kMaxSmallDeltaMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
constexpr FeedbackRequest kSinglePacketFeedbackRequest = {
|
||||
@ -535,7 +515,7 @@ TEST_F(RemoteEstimatorProxyOnRequestTest, RequestLastFivePacketFeedback) {
|
||||
IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs);
|
||||
}
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -553,7 +533,6 @@ TEST_F(RemoteEstimatorProxyOnRequestTest, RequestLastFivePacketFeedback) {
|
||||
kBaseTimeMs + 8 * kMaxSmallDeltaMs,
|
||||
kBaseTimeMs + 9 * kMaxSmallDeltaMs,
|
||||
kBaseTimeMs + 10 * kMaxSmallDeltaMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
|
||||
@ -571,7 +550,7 @@ TEST_F(RemoteEstimatorProxyOnRequestTest,
|
||||
IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs);
|
||||
}
|
||||
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
EXPECT_CALL(feedback_sender_, Call)
|
||||
.WillOnce(Invoke(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
rtcp::TransportFeedback* feedback_packet =
|
||||
@ -586,7 +565,6 @@ TEST_F(RemoteEstimatorProxyOnRequestTest,
|
||||
ElementsAre(kBaseTimeMs + 6 * kMaxSmallDeltaMs,
|
||||
kBaseTimeMs + 8 * kMaxSmallDeltaMs,
|
||||
kBaseTimeMs + 10 * kMaxSmallDeltaMs));
|
||||
return true;
|
||||
}));
|
||||
|
||||
constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
|
||||
@ -658,13 +636,7 @@ TEST_F(RemoteEstimatorProxyTest, SendTransportFeedbackAndNetworkStateUpdate) {
|
||||
AbsoluteSendTime::MsTo24Bits(kBaseTimeMs - 1)));
|
||||
EXPECT_CALL(network_state_estimator_, GetCurrentEstimate())
|
||||
.WillOnce(Return(NetworkStateEstimate()));
|
||||
EXPECT_CALL(router_, SendCombinedRtcpPacket)
|
||||
.WillOnce(
|
||||
[](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
|
||||
EXPECT_THAT(feedback_packets, SizeIs(2));
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(feedback_sender_, Call(SizeIs(2)));
|
||||
Process();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user