Remove dependency to NetworkStateEstimator from TransportSequenceNumberFeedbackGenerator

NetworkStateEstimator is not used by WebRTC from receive side.

ReceiveSidesCongestionController::SetTransportOverhead is not needed either since NetworkStateEstimator is removed.
Note, CongestionControlFeedbackGenerator is used with RFC 8888 only and feedback frequency will be refactored in later cl.


Bug: webrtc:42220808
Change-Id: I08980aa19117e1de7a9b7896d05d07715dd9f962
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375460
Auto-Submit: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43821}
This commit is contained in:
Per K 2025-01-29 08:32:42 +00:00 committed by WebRTC LUCI CQ
parent 3155346f66
commit eb688d6e80
15 changed files with 57 additions and 246 deletions

View file

@ -733,8 +733,7 @@ Call::Call(CallConfig config,
absl::bind_front(&PacketRouter::SendCombinedRtcpPacket, absl::bind_front(&PacketRouter::SendCombinedRtcpPacket,
transport_send->packet_router()), transport_send->packet_router()),
absl::bind_front(&PacketRouter::SendRemb, absl::bind_front(&PacketRouter::SendRemb,
transport_send->packet_router()), transport_send->packet_router())),
/*network_state_estimator=*/nullptr),
receive_time_calculator_( receive_time_calculator_(
ReceiveTimeCalculator::CreateFromFieldTrial(env_.field_trials())), ReceiveTimeCalculator::CreateFromFieldTrial(env_.field_trials())),
video_send_delay_stats_(new SendDelayStats(&env_.clock())), video_send_delay_stats_(new SendDelayStats(&env_.clock())),

View file

@ -36,6 +36,7 @@ rtc_library("congestion_controller") {
"../remote_bitrate_estimator:congestion_control_feedback_generator", "../remote_bitrate_estimator:congestion_control_feedback_generator",
"../remote_bitrate_estimator:transport_sequence_number_feedback_generator", "../remote_bitrate_estimator:transport_sequence_number_feedback_generator",
"../rtp_rtcp:rtp_rtcp_format", "../rtp_rtcp:rtp_rtcp_format",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:nullability", "//third_party/abseil-cpp/absl/base:nullability",
] ]
} }

View file

@ -14,13 +14,13 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include "absl/base/attributes.h"
#include "absl/base/nullability.h" #include "absl/base/nullability.h"
#include "api/environment/environment.h" #include "api/environment/environment.h"
#include "api/media_types.h" #include "api/media_types.h"
#include "api/sequence_checker.h" #include "api/sequence_checker.h"
#include "api/transport/network_control.h" #include "api/transport/network_control.h"
#include "api/units/data_rate.h" #include "api/units/data_rate.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "modules/congestion_controller/remb_throttler.h" #include "modules/congestion_controller/remb_throttler.h"
#include "modules/include/module_common_types.h" #include "modules/include/module_common_types.h"
@ -40,11 +40,17 @@ class RemoteBitrateEstimator;
// send our results back to the sender. // send our results back to the sender.
class ReceiveSideCongestionController : public CallStatsObserver { class ReceiveSideCongestionController : public CallStatsObserver {
public: public:
ABSL_DEPRECATED("Use the constructor without NetworkStateEstimator.")
ReceiveSideCongestionController( ReceiveSideCongestionController(
const Environment& env, const Environment& env,
TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender, TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender,
RembThrottler::RembSender remb_sender, RembThrottler::RembSender remb_sender,
absl::Nullable<NetworkStateEstimator*> network_state_estimator); absl::Nullable<NetworkStateEstimator*> unused);
ReceiveSideCongestionController(
const Environment& env,
TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender,
RembThrottler::RembSender remb_sender);
~ReceiveSideCongestionController() override = default; ~ReceiveSideCongestionController() override = default;
@ -62,8 +68,6 @@ class ReceiveSideCongestionController : public CallStatsObserver {
// `bitrate` using RTCP REMB. // `bitrate` using RTCP REMB.
void SetMaxDesiredReceiveBitrate(DataRate bitrate); void SetMaxDesiredReceiveBitrate(DataRate bitrate);
void SetTransportOverhead(DataSize overhead_per_packet);
// Returns latest receive side bandwidth estimation. // Returns latest receive side bandwidth estimation.
// Returns zero if receive side bandwidth estimation is unavailable. // Returns zero if receive side bandwidth estimation is unavailable.
DataRate LatestReceiveSideEstimate() const; DataRate LatestReceiveSideEstimate() const;

View file

@ -21,7 +21,6 @@
#include "api/sequence_checker.h" #include "api/sequence_checker.h"
#include "api/transport/network_control.h" #include "api/transport/network_control.h"
#include "api/units/data_rate.h" #include "api/units/data_rate.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "api/units/timestamp.h" #include "api/units/timestamp.h"
#include "modules/congestion_controller/remb_throttler.h" #include "modules/congestion_controller/remb_throttler.h"
@ -89,11 +88,16 @@ ReceiveSideCongestionController::ReceiveSideCongestionController(
const Environment& env, const Environment& env,
TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender, TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender,
RembThrottler::RembSender remb_sender, RembThrottler::RembSender remb_sender,
absl::Nullable<NetworkStateEstimator*> network_state_estimator) absl::Nullable<NetworkStateEstimator*> /* unused */)
: ReceiveSideCongestionController(env, feedback_sender, remb_sender) {}
ReceiveSideCongestionController::ReceiveSideCongestionController(
const Environment& env,
TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender,
RembThrottler::RembSender remb_sender)
: env_(env), : env_(env),
remb_throttler_(std::move(remb_sender), &env_.clock()), remb_throttler_(std::move(remb_sender), &env_.clock()),
transport_sequence_number_feedback_generator_(feedback_sender, transport_sequence_number_feedback_generator_(feedback_sender),
network_state_estimator),
congestion_control_feedback_generator_(env, feedback_sender), congestion_control_feedback_generator_(env, feedback_sender),
rbe_(std::make_unique<RemoteBitrateEstimatorSingleStream>( rbe_(std::make_unique<RemoteBitrateEstimatorSingleStream>(
env_, env_,
@ -184,13 +188,4 @@ void ReceiveSideCongestionController::SetMaxDesiredReceiveBitrate(
remb_throttler_.SetMaxDesiredReceiveBitrate(bitrate); remb_throttler_.SetMaxDesiredReceiveBitrate(bitrate);
} }
void ReceiveSideCongestionController::SetTransportOverhead(
DataSize overhead_per_packet) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
transport_sequence_number_feedback_generator_.SetTransportOverhead(
overhead_per_packet);
congestion_control_feedback_generator_.SetTransportOverhead(
overhead_per_packet);
}
} // namespace webrtc } // namespace webrtc

View file

@ -55,9 +55,9 @@ TEST(ReceiveSideCongestionControllerTest, SendsRembWithAbsSendTime) {
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
SimulatedClock clock(123456); SimulatedClock clock(123456);
ReceiveSideCongestionController controller( ReceiveSideCongestionController controller(CreateEnvironment(&clock),
CreateEnvironment(&clock), feedback_sender.AsStdFunction(), feedback_sender.AsStdFunction(),
remb_sender.AsStdFunction(), nullptr); remb_sender.AsStdFunction());
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<AbsoluteSendTime>(1); extensions.Register<AbsoluteSendTime>(1);
@ -85,9 +85,9 @@ TEST(ReceiveSideCongestionControllerTest,
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
SimulatedClock clock(123456); SimulatedClock clock(123456);
ReceiveSideCongestionController controller( ReceiveSideCongestionController controller(CreateEnvironment(&clock),
CreateEnvironment(&clock), feedback_sender.AsStdFunction(), feedback_sender.AsStdFunction(),
remb_sender.AsStdFunction(), nullptr); remb_sender.AsStdFunction());
EXPECT_CALL(remb_sender, Call(123, _)); EXPECT_CALL(remb_sender, Call(123, _));
controller.SetMaxDesiredReceiveBitrate(DataRate::BitsPerSec(123)); controller.SetMaxDesiredReceiveBitrate(DataRate::BitsPerSec(123));
} }
@ -112,7 +112,7 @@ TEST(ReceiveSideCongestionControllerTest, SendsRfc8888FeedbackIfForced) {
SimulatedClock clock(123456); SimulatedClock clock(123456);
ReceiveSideCongestionController controller( ReceiveSideCongestionController controller(
CreateEnvironment(&clock, &field_trials), rtcp_sender.AsStdFunction(), CreateEnvironment(&clock, &field_trials), rtcp_sender.AsStdFunction(),
remb_sender.AsStdFunction(), nullptr); remb_sender.AsStdFunction());
// Expect that RTCP feedback is sent. // Expect that RTCP feedback is sent.
EXPECT_CALL(rtcp_sender, Call) EXPECT_CALL(rtcp_sender, Call)
@ -136,9 +136,9 @@ TEST(ReceiveSideCongestionControllerTest, SendsRfc8888FeedbackIfEnabled) {
rtcp_sender; rtcp_sender;
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
SimulatedClock clock(123456); SimulatedClock clock(123456);
ReceiveSideCongestionController controller( ReceiveSideCongestionController controller(CreateEnvironment(&clock),
CreateEnvironment(&clock), rtcp_sender.AsStdFunction(), rtcp_sender.AsStdFunction(),
remb_sender.AsStdFunction(), nullptr); remb_sender.AsStdFunction());
controller.EnableSendCongestionControlFeedbackAccordingToRfc8888(); controller.EnableSendCongestionControlFeedbackAccordingToRfc8888();
// Expect that RTCP feedback is sent. // Expect that RTCP feedback is sent.
@ -164,9 +164,9 @@ TEST(ReceiveSideCongestionControllerTest,
rtcp_sender; rtcp_sender;
MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender; MockFunction<void(uint64_t, std::vector<uint32_t>)> remb_sender;
SimulatedClock clock(123456); SimulatedClock clock(123456);
ReceiveSideCongestionController controller( ReceiveSideCongestionController controller(CreateEnvironment(&clock),
CreateEnvironment(&clock), rtcp_sender.AsStdFunction(), rtcp_sender.AsStdFunction(),
remb_sender.AsStdFunction(), nullptr); remb_sender.AsStdFunction());
// No Transport feedback is sent because received packet does not have // No Transport feedback is sent because received packet does not have
// transport sequence number rtp header extension. // transport sequence number rtp header extension.

View file

@ -83,6 +83,7 @@ rtc_library("transport_sequence_number_feedback_generator") {
"../../api/units:timestamp", "../../api/units:timestamp",
"../../rtc_base:checks", "../../rtc_base:checks",
"../../rtc_base:logging", "../../rtc_base:logging",
"../../rtc_base:macromagic",
"../../rtc_base:rtc_numerics", "../../rtc_base:rtc_numerics",
"../../rtc_base:safe_minmax", "../../rtc_base:safe_minmax",
"../../rtc_base/synchronization:mutex", "../../rtc_base/synchronization:mutex",
@ -169,6 +170,7 @@ if (rtc_include_tests) {
":remote_bitrate_estimator", ":remote_bitrate_estimator",
":transport_sequence_number_feedback_generator", ":transport_sequence_number_feedback_generator",
"..:module_api_public", "..:module_api_public",
"../../api:rtp_headers",
"../../api/environment:environment_factory", "../../api/environment:environment_factory",
"../../api/transport:mock_network_control", "../../api/transport:mock_network_control",
"../../api/transport:network_control", "../../api/transport:network_control",

View file

@ -89,12 +89,6 @@ void CongestionControlFeedbackGenerator::OnSendBandwidthEstimateChanged(
max_feedback_rate_ = estimate * 0.05; max_feedback_rate_ = estimate * 0.05;
} }
void CongestionControlFeedbackGenerator::SetTransportOverhead(
DataSize overhead_per_packet) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
packet_overhead_ = overhead_per_packet;
}
void CongestionControlFeedbackGenerator::SendFeedback(Timestamp now) { void CongestionControlFeedbackGenerator::SendFeedback(Timestamp now) {
uint32_t compact_ntp = uint32_t compact_ntp =
CompactNtp(env_.clock().ConvertTimestampToNtpTime(now)); CompactNtp(env_.clock().ConvertTimestampToNtpTime(now));
@ -121,7 +115,7 @@ void CongestionControlFeedbackGenerator::CalculateNextPossibleSendTime(
DataSize debt_payed = time_since_last_sent * max_feedback_rate_; DataSize debt_payed = time_since_last_sent * max_feedback_rate_;
send_rate_debt_ = debt_payed > send_rate_debt_ ? DataSize::Zero() send_rate_debt_ = debt_payed > send_rate_debt_ ? DataSize::Zero()
: send_rate_debt_ - debt_payed; : send_rate_debt_ - debt_payed;
send_rate_debt_ += feedback_size + packet_overhead_; send_rate_debt_ += feedback_size;
last_feedback_sent_time_ = now; last_feedback_sent_time_ = now;
next_possible_feedback_send_time_ = next_possible_feedback_send_time_ =
now + std::clamp(max_feedback_rate_.IsZero() now + std::clamp(max_feedback_rate_.IsZero()

View file

@ -54,8 +54,6 @@ class CongestionControlFeedbackGenerator
TimeDelta Process(Timestamp now) override; TimeDelta Process(Timestamp now) override;
void SetTransportOverhead(DataSize overhead_per_packet) override;
private: private:
Timestamp NextFeedbackTime() const RTC_RUN_ON(sequence_checker_); Timestamp NextFeedbackTime() const RTC_RUN_ON(sequence_checker_);

View file

@ -142,9 +142,7 @@ TEST(CongestionControlFeedbackGeneratorTest,
rtcp_sender.AsStdFunction()); rtcp_sender.AsStdFunction());
const DataRate kSendBandwidthEstimate = DataRate::BytesPerSec(10'000); const DataRate kSendBandwidthEstimate = DataRate::BytesPerSec(10'000);
const DataSize kPacketOverHead = DataSize::Bytes(25);
generator.OnSendBandwidthEstimateChanged(kSendBandwidthEstimate); generator.OnSendBandwidthEstimateChanged(kSendBandwidthEstimate);
generator.SetTransportOverhead(kPacketOverHead);
TimeDelta time_to_next_process = generator.Process(clock.CurrentTime()); TimeDelta time_to_next_process = generator.Process(clock.CurrentTime());
clock.AdvanceTime(kSmallTimeInterval); clock.AdvanceTime(kSmallTimeInterval);
time_to_next_process -= kSmallTimeInterval; time_to_next_process -= kSmallTimeInterval;
@ -166,8 +164,7 @@ TEST(CongestionControlFeedbackGeneratorTest,
// Expect at most 5% of send bandwidth to be used. This decide the // Expect at most 5% of send bandwidth to be used. This decide the
// time to next feedback. // time to next feedback.
expected_feedback_time += expected_feedback_time +=
(DataSize::Bytes(rtcp_len) + kPacketOverHead) / DataSize::Bytes(rtcp_len) / (0.05 * kSendBandwidthEstimate);
(0.05 * kSendBandwidthEstimate);
}); });
generator.OnReceivedPacket( generator.OnReceivedPacket(
CreatePacket(clock.CurrentTime(), /*marker=*/true)); CreatePacket(clock.CurrentTime(), /*marker=*/true));

View file

@ -11,13 +11,14 @@
#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_RTP_TRANSPORT_FEEDBACK_GENERATOR_H_ #ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_RTP_TRANSPORT_FEEDBACK_GENERATOR_H_
#define MODULES_REMOTE_BITRATE_ESTIMATOR_RTP_TRANSPORT_FEEDBACK_GENERATOR_H_ #define MODULES_REMOTE_BITRATE_ESTIMATOR_RTP_TRANSPORT_FEEDBACK_GENERATOR_H_
#include <functional>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "api/units/data_rate.h" #include "api/units/data_rate.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "api/units/timestamp.h" #include "api/units/timestamp.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h"
namespace webrtc { namespace webrtc {
@ -37,9 +38,6 @@ class RtpTransportFeedbackGenerator {
virtual TimeDelta Process(Timestamp now) = 0; virtual TimeDelta Process(Timestamp now) = 0;
virtual void OnSendBandwidthEstimateChanged(DataRate estimate) = 0; virtual void OnSendBandwidthEstimateChanged(DataRate estimate) = 0;
// Overhead from transport layers below RTP. Ie, IP, SRTP.
virtual void SetTransportOverhead(DataSize overhead_per_packet) = 0;
}; };
} // namespace webrtc } // namespace webrtc

View file

@ -12,20 +12,24 @@
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include <limits>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <utility> #include <utility>
#include <vector>
#include "api/rtp_headers.h"
#include "api/units/data_rate.h"
#include "api/units/data_size.h" #include "api/units/data_size.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "modules/rtp_rtcp/source/rtcp_packet/remote_estimate.h" #include "api/units/timestamp.h"
#include "modules/remote_bitrate_estimator/packet_arrival_map.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_minmax.h" #include "rtc_base/synchronization/mutex.h"
#include "system_wrappers/include/clock.h"
namespace webrtc { namespace webrtc {
namespace { namespace {
@ -35,37 +39,16 @@ constexpr TimeDelta kMinInterval = TimeDelta::Millis(50);
constexpr TimeDelta kMaxInterval = TimeDelta::Millis(250); constexpr TimeDelta kMaxInterval = TimeDelta::Millis(250);
constexpr TimeDelta kDefaultInterval = TimeDelta::Millis(100); constexpr TimeDelta kDefaultInterval = TimeDelta::Millis(100);
TimeDelta GetAbsoluteSendTimeDelta(uint32_t new_sendtime,
uint32_t previous_sendtime) {
static constexpr uint32_t kWrapAroundPeriod = 0x0100'0000;
RTC_DCHECK_LT(new_sendtime, kWrapAroundPeriod);
RTC_DCHECK_LT(previous_sendtime, kWrapAroundPeriod);
uint32_t delta = (new_sendtime - previous_sendtime) % kWrapAroundPeriod;
if (delta >= kWrapAroundPeriod / 2) {
// absolute send time wraps around, thus treat deltas larger than half of
// the wrap around period as negative.
delta = (previous_sendtime - new_sendtime) % kWrapAroundPeriod;
return TimeDelta::Micros(int64_t{delta} * -1'000'000 / (1 << 18));
}
return TimeDelta::Micros(int64_t{delta} * 1'000'000 / (1 << 18));
}
} // namespace } // namespace
TransportSequenceNumberFeedbackGenenerator:: TransportSequenceNumberFeedbackGenenerator::
TransportSequenceNumberFeedbackGenenerator( TransportSequenceNumberFeedbackGenenerator(RtcpSender feedback_sender)
RtcpSender feedback_sender,
NetworkStateEstimator* network_state_estimator)
: feedback_sender_(std::move(feedback_sender)), : feedback_sender_(std::move(feedback_sender)),
last_process_time_(Timestamp::MinusInfinity()), last_process_time_(Timestamp::MinusInfinity()),
network_state_estimator_(network_state_estimator),
media_ssrc_(0), media_ssrc_(0),
feedback_packet_count_(0), feedback_packet_count_(0),
packet_overhead_(DataSize::Zero()),
send_interval_(kDefaultInterval), send_interval_(kDefaultInterval),
send_periodic_feedback_(true), send_periodic_feedback_(true) {
previous_abs_send_time_(0),
abs_send_timestamp_(Timestamp::Zero()),
last_arrival_time_with_abs_send_time_(Timestamp::MinusInfinity()) {
RTC_LOG(LS_INFO) RTC_LOG(LS_INFO)
<< "Maximum interval between transport feedback RTCP messages: " << "Maximum interval between transport feedback RTCP messages: "
<< kMaxInterval; << kMaxInterval;
@ -138,27 +121,6 @@ void TransportSequenceNumberFeedbackGenenerator::OnReceivedPacket(
// Send feedback packet immediately. // Send feedback packet immediately.
SendFeedbackOnRequest(seq, *feedback_request); SendFeedbackOnRequest(seq, *feedback_request);
} }
std::optional<uint32_t> absolute_send_time_24bits =
packet.GetExtension<AbsoluteSendTime>();
if (network_state_estimator_ && absolute_send_time_24bits.has_value()) {
PacketResult packet_result;
packet_result.receive_time = packet.arrival_time();
if (packet.arrival_time() - last_arrival_time_with_abs_send_time_ <
TimeDelta::Seconds(10)) {
abs_send_timestamp_ += GetAbsoluteSendTimeDelta(
*absolute_send_time_24bits, previous_abs_send_time_);
} else {
abs_send_timestamp_ = packet.arrival_time();
}
last_arrival_time_with_abs_send_time_ = packet.arrival_time();
previous_abs_send_time_ = *absolute_send_time_24bits;
packet_result.sent_packet.send_time = abs_send_timestamp_;
packet_result.sent_packet.size =
DataSize::Bytes(packet.size()) + packet_overhead_;
packet_result.sent_packet.sequence_number = seq;
network_state_estimator_->OnReceivedPacket(packet_result);
}
} }
TimeDelta TransportSequenceNumberFeedbackGenenerator::Process(Timestamp now) { TimeDelta TransportSequenceNumberFeedbackGenenerator::Process(Timestamp now) {
@ -202,12 +164,6 @@ void TransportSequenceNumberFeedbackGenenerator::OnSendBandwidthEstimateChanged(
send_interval_ = send_interval; send_interval_ = send_interval;
} }
void TransportSequenceNumberFeedbackGenenerator::SetTransportOverhead(
DataSize overhead_per_packet) {
MutexLock lock(&lock_);
packet_overhead_ = overhead_per_packet;
}
void TransportSequenceNumberFeedbackGenenerator::SendPeriodicFeedbacks() { void TransportSequenceNumberFeedbackGenenerator::SendPeriodicFeedbacks() {
// `periodic_window_start_seq_` is the first sequence number to include in // `periodic_window_start_seq_` is the first sequence number to include in
// the current feedback packet. Some older may still be in the map, in case // the current feedback packet. Some older may still be in the map, in case
@ -215,16 +171,6 @@ void TransportSequenceNumberFeedbackGenenerator::SendPeriodicFeedbacks() {
if (!periodic_window_start_seq_) if (!periodic_window_start_seq_)
return; return;
std::unique_ptr<rtcp::RemoteEstimate> remote_estimate;
if (network_state_estimator_) {
std::optional<NetworkStateEstimate> state_estimate =
network_state_estimator_->GetCurrentEstimate();
if (state_estimate) {
remote_estimate = std::make_unique<rtcp::RemoteEstimate>();
remote_estimate->SetEstimate(state_estimate.value());
}
}
int64_t packet_arrival_times_end_seq = int64_t packet_arrival_times_end_seq =
packet_arrival_times_.end_sequence_number(); packet_arrival_times_.end_sequence_number();
while (periodic_window_start_seq_ < packet_arrival_times_end_seq) { while (periodic_window_start_seq_ < packet_arrival_times_end_seq) {
@ -238,13 +184,8 @@ void TransportSequenceNumberFeedbackGenenerator::SendPeriodicFeedbacks() {
} }
RTC_DCHECK(feedback_sender_ != nullptr); RTC_DCHECK(feedback_sender_ != nullptr);
std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets; std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets;
if (remote_estimate) {
packets.push_back(std::move(remote_estimate));
}
packets.push_back(std::move(feedback_packet)); packets.push_back(std::move(feedback_packet));
feedback_sender_(std::move(packets)); feedback_sender_(std::move(packets));
// Note: Don't erase items from packet_arrival_times_ after sending, in // 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 // case they need to be re-sent after a reordering. Removal will be

View file

@ -11,26 +11,21 @@
#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TRANSPORT_SEQUENCE_NUMBER_FEEDBACK_GENERATOR_H_ #ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TRANSPORT_SEQUENCE_NUMBER_FEEDBACK_GENERATOR_H_
#define MODULES_REMOTE_BITRATE_ESTIMATOR_TRANSPORT_SEQUENCE_NUMBER_FEEDBACK_GENERATOR_H_ #define MODULES_REMOTE_BITRATE_ESTIMATOR_TRANSPORT_SEQUENCE_NUMBER_FEEDBACK_GENERATOR_H_
#include <deque> #include <cstdint>
#include <functional>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <vector>
#include "api/field_trials_view.h"
#include "api/rtp_headers.h" #include "api/rtp_headers.h"
#include "api/transport/network_control.h"
#include "api/units/data_rate.h" #include "api/units/data_rate.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "api/units/timestamp.h" #include "api/units/timestamp.h"
#include "modules/remote_bitrate_estimator/packet_arrival_map.h" #include "modules/remote_bitrate_estimator/packet_arrival_map.h"
#include "modules/remote_bitrate_estimator/rtp_transport_feedback_generator.h" #include "modules/remote_bitrate_estimator/rtp_transport_feedback_generator.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/numerics/sequence_number_unwrapper.h" #include "rtc_base/numerics/sequence_number_unwrapper.h"
#include "rtc_base/synchronization/mutex.h" #include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.h"
namespace webrtc { namespace webrtc {
@ -45,8 +40,7 @@ class TransportSequenceNumberFeedbackGenenerator
: public RtpTransportFeedbackGenerator { : public RtpTransportFeedbackGenerator {
public: public:
TransportSequenceNumberFeedbackGenenerator( TransportSequenceNumberFeedbackGenenerator(
RtpTransportFeedbackGenerator::RtcpSender feedback_sender, RtpTransportFeedbackGenerator::RtcpSender feedback_sender);
NetworkStateEstimator* network_state_estimator);
~TransportSequenceNumberFeedbackGenenerator(); ~TransportSequenceNumberFeedbackGenenerator();
void OnReceivedPacket(const RtpPacketReceived& packet) override; void OnReceivedPacket(const RtpPacketReceived& packet) override;
@ -54,8 +48,6 @@ class TransportSequenceNumberFeedbackGenenerator
TimeDelta Process(Timestamp now) override; TimeDelta Process(Timestamp now) override;
void SetTransportOverhead(DataSize overhead_per_packet) override;
private: private:
void MaybeCullOldPackets(int64_t sequence_number, Timestamp arrival_time) void MaybeCullOldPackets(int64_t sequence_number, Timestamp arrival_time)
RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_); RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_);
@ -86,13 +78,9 @@ class TransportSequenceNumberFeedbackGenenerator
Timestamp last_process_time_; Timestamp last_process_time_;
Mutex lock_; Mutex lock_;
// `network_state_estimator_` may be null.
NetworkStateEstimator* const network_state_estimator_
RTC_PT_GUARDED_BY(&lock_);
uint32_t media_ssrc_ RTC_GUARDED_BY(&lock_); uint32_t media_ssrc_ RTC_GUARDED_BY(&lock_);
uint8_t feedback_packet_count_ RTC_GUARDED_BY(&lock_); uint8_t feedback_packet_count_ RTC_GUARDED_BY(&lock_);
SeqNumUnwrapper<uint16_t> unwrapper_ RTC_GUARDED_BY(&lock_); SeqNumUnwrapper<uint16_t> unwrapper_ RTC_GUARDED_BY(&lock_);
DataSize packet_overhead_ RTC_GUARDED_BY(&lock_);
// The next sequence number that should be the start sequence number during // The next sequence number that should be the start sequence number during
// periodic reporting. Will be std::nullopt before the first seen packet. // periodic reporting. Will be std::nullopt before the first seen packet.
@ -103,11 +91,6 @@ class TransportSequenceNumberFeedbackGenenerator
TimeDelta send_interval_ RTC_GUARDED_BY(&lock_); TimeDelta send_interval_ RTC_GUARDED_BY(&lock_);
bool send_periodic_feedback_ RTC_GUARDED_BY(&lock_); bool send_periodic_feedback_ RTC_GUARDED_BY(&lock_);
// Unwraps absolute send times.
uint32_t previous_abs_send_time_ RTC_GUARDED_BY(&lock_);
Timestamp abs_send_timestamp_ RTC_GUARDED_BY(&lock_);
Timestamp last_arrival_time_with_abs_send_time_ RTC_GUARDED_BY(&lock_);
}; };
} // namespace webrtc } // namespace webrtc

View file

@ -13,13 +13,15 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <utility> #include <vector>
#include "api/transport/test/mock_network_control.h" #include "api/rtp_headers.h"
#include "api/units/data_rate.h" #include "api/units/data_rate.h"
#include "api/units/data_size.h" #include "api/units/data_size.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "api/units/timestamp.h" #include "api/units/timestamp.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h"
@ -79,9 +81,7 @@ std::vector<Timestamp> Timestamps(
class TransportSequenceNumberFeedbackGeneneratorTest : public ::testing::Test { class TransportSequenceNumberFeedbackGeneneratorTest : public ::testing::Test {
public: public:
TransportSequenceNumberFeedbackGeneneratorTest() TransportSequenceNumberFeedbackGeneneratorTest()
: clock_(0), : clock_(0), feedback_generator_(feedback_sender_.AsStdFunction()) {}
feedback_generator_(feedback_sender_.AsStdFunction(),
&network_state_estimator_) {}
protected: protected:
void IncomingPacket(uint16_t seq, void IncomingPacket(uint16_t seq,
@ -120,7 +120,6 @@ class TransportSequenceNumberFeedbackGeneneratorTest : public ::testing::Test {
SimulatedClock clock_; SimulatedClock clock_;
MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)> MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)>
feedback_sender_; feedback_sender_;
::testing::NiceMock<MockNetworkStateEstimator> network_state_estimator_;
TransportSequenceNumberFeedbackGenenerator feedback_generator_; TransportSequenceNumberFeedbackGenenerator feedback_generator_;
}; };
@ -596,104 +595,5 @@ TEST_F(RemoteEstimatorProxyOnRequestTest,
kFivePacketsFeedbackRequest); kFivePacketsFeedbackRequest);
} }
TEST_F(TransportSequenceNumberFeedbackGeneneratorTest,
ReportsIncomingPacketToNetworkStateEstimator) {
const DataSize kPacketOverhead = DataSize::Bytes(38);
feedback_generator_.SetTransportOverhead(kPacketOverhead);
EXPECT_CALL(network_state_estimator_, OnReceivedPacket)
.WillOnce([&](const PacketResult& packet) {
EXPECT_EQ(packet.receive_time, kBaseTime);
EXPECT_GT(packet.sent_packet.size, kPacketOverhead);
// Expect first send time to be equal to the arrival time.
EXPECT_EQ(packet.sent_packet.send_time, kBaseTime);
});
IncomingPacket(kBaseSeq, kBaseTime, AbsoluteSendTime::To24Bits(kBaseTime));
}
TEST_F(TransportSequenceNumberFeedbackGeneneratorTest,
IncomingPacketHandlesWrapInAbsSendTime) {
// abs send time use 24bit precision.
const uint32_t kFirstAbsSendTime =
AbsoluteSendTime::To24Bits(Timestamp::Millis((1 << 24) - 30));
// Second abs send time has wrapped.
const uint32_t kSecondAbsSendTime =
AbsoluteSendTime::To24Bits(Timestamp::Millis(1 << 24));
const TimeDelta kExpectedAbsSendTimeDelta = TimeDelta::Millis(30);
Timestamp first_send_timestamp = Timestamp::Zero();
EXPECT_CALL(network_state_estimator_, OnReceivedPacket)
.WillOnce([&](const PacketResult& packet) {
EXPECT_EQ(packet.receive_time, kBaseTime);
first_send_timestamp = packet.sent_packet.send_time;
});
IncomingPacket(kBaseSeq, kBaseTime, kFirstAbsSendTime);
EXPECT_CALL(network_state_estimator_, OnReceivedPacket)
.WillOnce([&](const PacketResult& packet) {
EXPECT_EQ(packet.receive_time, kBaseTime + TimeDelta::Millis(123));
EXPECT_EQ(packet.sent_packet.send_time.ms(),
(first_send_timestamp + kExpectedAbsSendTimeDelta).ms());
});
IncomingPacket(kBaseSeq + 1, kBaseTime + TimeDelta::Millis(123),
kSecondAbsSendTime);
}
TEST_F(TransportSequenceNumberFeedbackGeneneratorTest,
IncomingPacketHandlesReorderedPackets) {
const uint32_t kFirstAbsSendTime =
AbsoluteSendTime::To24Bits(Timestamp::Millis((1 << 12)));
Timestamp first_send_timestamp = Timestamp::Zero();
EXPECT_CALL(network_state_estimator_, OnReceivedPacket)
.WillOnce([&](const PacketResult& packet) {
EXPECT_EQ(packet.receive_time, kBaseTime);
first_send_timestamp = packet.sent_packet.send_time;
});
IncomingPacket(kBaseSeq + 1, kBaseTime, kFirstAbsSendTime);
const TimeDelta kExpectedAbsSendTimeDelta = -TimeDelta::Millis(30);
const uint32_t kSecondAbsSendTime = AbsoluteSendTime::To24Bits(
Timestamp::Millis(1 << 12) + kExpectedAbsSendTimeDelta);
EXPECT_CALL(network_state_estimator_, OnReceivedPacket)
.WillOnce([&](const PacketResult& packet) {
EXPECT_EQ(packet.sent_packet.send_time.ms(),
(first_send_timestamp + kExpectedAbsSendTimeDelta).ms());
});
IncomingPacket(kBaseSeq, kBaseTime + TimeDelta::Millis(123),
kSecondAbsSendTime);
}
TEST_F(TransportSequenceNumberFeedbackGeneneratorTest,
IncomingPacketResetSendTimeToArrivalTimeAfterLargeArrivaltimeDelta) {
const uint32_t kFirstAbsSendTime =
AbsoluteSendTime::To24Bits(Timestamp::Millis((1 << 12)));
EXPECT_CALL(network_state_estimator_, OnReceivedPacket)
.WillOnce([&](const PacketResult& packet) {
EXPECT_EQ(packet.receive_time, kBaseTime);
EXPECT_EQ(packet.sent_packet.send_time, kBaseTime);
});
IncomingPacket(kBaseSeq + 1, kBaseTime, kFirstAbsSendTime);
EXPECT_CALL(network_state_estimator_, OnReceivedPacket)
.WillOnce([&](const PacketResult& packet) {
EXPECT_EQ(packet.receive_time, kBaseTime + TimeDelta::Seconds(20));
EXPECT_EQ(packet.sent_packet.send_time,
kBaseTime + TimeDelta::Seconds(20));
});
IncomingPacket(kBaseSeq, kBaseTime + TimeDelta::Seconds(20),
kFirstAbsSendTime + 123);
}
TEST_F(TransportSequenceNumberFeedbackGeneneratorTest,
SendTransportFeedbackAndNetworkStateUpdate) {
IncomingPacket(kBaseSeq, kBaseTime,
AbsoluteSendTime::To24Bits(kBaseTime - TimeDelta::Millis(1)));
EXPECT_CALL(network_state_estimator_, GetCurrentEstimate())
.WillOnce(Return(NetworkStateEstimate()));
EXPECT_CALL(feedback_sender_, Call(SizeIs(2)));
Process();
}
} // namespace } // namespace
} // namespace webrtc } // namespace webrtc

View file

@ -1972,7 +1972,7 @@ void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) const {
RembInterceptor remb_interceptor; RembInterceptor remb_interceptor;
ReceiveSideCongestionController rscc( ReceiveSideCongestionController rscc(
CreateEnvironment(&clock), [](auto...) {}, CreateEnvironment(&clock), [](auto...) {},
absl::bind_front(&RembInterceptor::SendRemb, &remb_interceptor), nullptr); absl::bind_front(&RembInterceptor::SendRemb, &remb_interceptor));
// TODO(holmer): Log the call config and use that here instead. // TODO(holmer): Log the call config and use that here instead.
// static const uint32_t kDefaultStartBitrateBps = 300000; // static const uint32_t kDefaultStartBitrateBps = 300000;
// rscc.SetBweBitrates(0, kDefaultStartBitrateBps, -1); // rscc.SetBweBitrates(0, kDefaultStartBitrateBps, -1);

View file

@ -31,8 +31,7 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
ReceiveSideCongestionController cc( ReceiveSideCongestionController cc(
CreateEnvironment(&clock), CreateEnvironment(&clock),
/*feedback_sender=*/[](auto...) {}, /*feedback_sender=*/[](auto...) {},
/*remb_sender=*/[](auto...) {}, /*remb_sender=*/[](auto...) {});
/*network_state_estimator=*/nullptr);
RtpHeaderExtensionMap extensions; RtpHeaderExtensionMap extensions;
extensions.Register<TransmissionOffset>(1); extensions.Register<TransmissionOffset>(1);
extensions.Register<AbsoluteSendTime>(2); extensions.Register<AbsoluteSendTime>(2);