Add PeerConnectionInterface::ReconfigureBandwidthEstimation

Using the Api, BWE components are recreated and new settings can be
applied. Initially, the only configuration available is allowing BWE probes without media".


Note that BWE components are created when transport first becomes writable. So calling this method before a PeerConnection is connected is cheap and only changes configuration.

Integration test in https://webrtc-review.googlesource.com/c/src/+/337322

Bug: webrtc:14928
Change-Id: If2c848489bf94a1f7a5ebf90d2886d90c202c7c3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336240
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41687}
This commit is contained in:
Per K 2024-02-07 14:16:20 +01:00 committed by WebRTC LUCI CQ
parent 22b6564d77
commit 39ac25d6ec
17 changed files with 120 additions and 17 deletions

View file

@ -355,6 +355,7 @@ rtc_library("libjingle_peerconnection_api") {
"neteq:neteq_api",
"rtc_event_log",
"task_queue",
"transport:bandwidth_estimation_settings",
"transport:bitrate_settings",
"transport:enums",
"transport:network_control",

View file

@ -112,6 +112,7 @@
#include "api/set_remote_description_observer_interface.h"
#include "api/stats/rtc_stats_collector_callback.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/transport/bandwidth_estimation_settings.h"
#include "api/transport/bitrate_settings.h"
#include "api/transport/enums.h"
#include "api/transport/network_control.h"
@ -1133,6 +1134,13 @@ class RTC_EXPORT PeerConnectionInterface : public webrtc::RefCountInterface {
// to the provided value.
virtual RTCError SetBitrate(const BitrateSettings& bitrate) = 0;
// Allows an application to reconfigure bandwidth estimation.
// The method can be called both before and after estimation has started.
// Estimation starts when the first RTP packet is sent.
// Estimation will be restarted if already started.
virtual void ReconfigureBandwidthEstimation(
const BandwidthEstimationSettings& settings) {}
// Enable/disable playout of received audio streams. Enabled by default. Note
// that even if playout is enabled, streams will only be played out if the
// appropriate SDP is also applied. Setting `playout` to false will stop

View file

@ -177,6 +177,10 @@ class MockPeerConnectionInterface : public webrtc::PeerConnectionInterface {
(const std::vector<cricket::Candidate>&),
(override));
MOCK_METHOD(RTCError, SetBitrate, (const BitrateSettings&), (override));
MOCK_METHOD(void,
ReconfigureBandwidthEstimation,
(const BandwidthEstimationSettings&),
(override));
MOCK_METHOD(void, SetAudioPlayout, (bool), (override));
MOCK_METHOD(void, SetAudioRecording, (bool), (override));
MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>,

View file

@ -18,6 +18,12 @@ rtc_library("bitrate_settings") {
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("bandwidth_estimation_settings") {
visibility = [ "*" ]
sources = [ "bandwidth_estimation_settings.h" ]
deps = [ "../../rtc_base/system:rtc_export" ]
}
rtc_source_set("enums") {
visibility = [ "*" ]
sources = [ "enums.h" ]

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2024 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 API_TRANSPORT_BANDWIDTH_ESTIMATION_SETTINGS_H_
#define API_TRANSPORT_BANDWIDTH_ESTIMATION_SETTINGS_H_
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// Configuration settings affecting bandwidth estimation.
// These settings can be set and changed by an application.
struct RTC_EXPORT BandwidthEstimationSettings {
// A bandwith estimation probe may be sent using a RtpTransceiver with
// direction SendOnly or SendRecv that supports RTX. The probe can be sent
// without first sending media packets in which case Rtp padding packets are
// used.
bool allow_probe_without_media = false;
};
} // namespace webrtc
#endif // API_TRANSPORT_BANDWIDTH_ESTIMATION_SETTINGS_H_

View file

@ -117,6 +117,7 @@ rtc_library("rtp_interfaces") {
"../api/crypto:options",
"../api/environment",
"../api/rtc_event_log",
"../api/transport:bandwidth_estimation_settings",
"../api/transport:bitrate_settings",
"../api/transport:network_control",
"../api/units:time_delta",

View file

@ -38,10 +38,6 @@ struct RtpTransportConfig {
// The burst interval of the pacer, see TaskQueuePacedSender constructor.
absl::optional<TimeDelta> pacer_burst_interval;
// A bandwith estimation probe may be sent on a writable Rtp stream that have
// RTX configured. It can be sent without first sending media packets.
bool allow_bandwidth_estimation_probe_without_media = false;
};
} // namespace webrtc

View file

@ -70,8 +70,6 @@ bool IsRelayed(const rtc::NetworkRoute& route) {
RtpTransportControllerSend::RtpTransportControllerSend(
const RtpTransportConfig& config)
: env_(config.env),
allow_bandwidth_estimation_probe_without_media_(
config.allow_bandwidth_estimation_probe_without_media),
task_queue_(TaskQueueBase::Current()),
bitrate_configurator_(config.bitrate_config),
pacer_started_(false),
@ -168,7 +166,7 @@ void RtpTransportControllerSend::RegisterSendingRtpStream(
packet_router_.AddSendRtpModule(&rtp_module,
/*remb_candidate=*/true);
pacer_.SetAllowProbeWithoutMediaPacket(
allow_bandwidth_estimation_probe_without_media_ &&
bwe_settings_.allow_probe_without_media &&
packet_router_.SupportsRtxPayloadPadding());
}
@ -188,7 +186,7 @@ void RtpTransportControllerSend::DeRegisterSendingRtpStream(
pacer_.RemovePacketsForSsrc(*rtp_module.FlexfecSsrc());
}
pacer_.SetAllowProbeWithoutMediaPacket(
allow_bandwidth_estimation_probe_without_media_ &&
bwe_settings_.allow_probe_without_media &&
packet_router_.SupportsRtxPayloadPadding());
}
@ -257,6 +255,29 @@ RtpTransportControllerSend::GetStreamFeedbackProvider() {
return &feedback_demuxer_;
}
void RtpTransportControllerSend::ReconfigureBandwidthEstimation(
const BandwidthEstimationSettings& settings) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
bwe_settings_ = settings;
if (controller_) {
// Recreate the controller and handler.
control_handler_ = nullptr;
controller_ = nullptr;
// The BWE controller is created when/if the network is available.
MaybeCreateControllers();
if (controller_) {
BitrateConstraints constraints = bitrate_configurator_.GetConfig();
UpdateBitrateConstraints(constraints);
UpdateStreamsConfig();
UpdateNetworkAvailability();
}
}
pacer_.SetAllowProbeWithoutMediaPacket(
bwe_settings_.allow_probe_without_media &&
packet_router_.SupportsRtxPayloadPadding());
}
void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
TargetTransferRateObserver* observer) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
@ -358,9 +379,6 @@ void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_LOG(LS_VERBOSE) << "SignalNetworkState "
<< (network_available ? "Up" : "Down");
NetworkAvailability msg;
msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds());
msg.network_available = network_available;
network_available_ = network_available;
if (network_available) {
pacer_.Resume();
@ -373,11 +391,7 @@ void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
if (!controller_) {
MaybeCreateControllers();
}
if (controller_) {
control_handler_->SetNetworkAvailability(network_available);
PostUpdates(controller_->OnNetworkAvailability(msg));
UpdateControlState();
}
UpdateNetworkAvailability();
for (auto& rtp_sender : video_rtp_senders_) {
rtp_sender->OnNetworkAvailability(network_available);
}
@ -620,6 +634,18 @@ void RtpTransportControllerSend::MaybeCreateControllers() {
StartProcessPeriodicTasks();
}
void RtpTransportControllerSend::UpdateNetworkAvailability() {
if (!controller_) {
return;
}
NetworkAvailability msg;
msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds());
msg.network_available = network_available_;
control_handler_->SetNetworkAvailability(network_available_);
PostUpdates(controller_->OnNetworkAvailability(msg));
UpdateControlState();
}
void RtpTransportControllerSend::UpdateInitialConstraints(
TargetRateConstraints new_contraints) {
if (!new_contraints.starting_rate)

View file

@ -84,6 +84,8 @@ class RtpTransportControllerSend final
RtpPacketSender* packet_sender() override;
void SetAllocatedSendBitrateLimits(BitrateAllocationLimits limits) override;
void ReconfigureBandwidthEstimation(
const BandwidthEstimationSettings& settings) override;
void SetPacingFactor(float pacing_factor) override;
void SetQueueTimeLimit(int limit_ms) override;
@ -127,6 +129,7 @@ class RtpTransportControllerSend final
private:
void MaybeCreateControllers() RTC_RUN_ON(sequence_checker_);
void UpdateNetworkAvailability() RTC_RUN_ON(sequence_checker_);
void UpdateInitialConstraints(TargetRateConstraints new_contraints)
RTC_RUN_ON(sequence_checker_);
@ -150,7 +153,6 @@ class RtpTransportControllerSend final
const Environment env_;
SequenceChecker sequence_checker_;
const bool allow_bandwidth_estimation_probe_without_media_;
TaskQueueBase* task_queue_;
PacketRouter packet_router_;
std::vector<std::unique_ptr<RtpVideoSenderInterface>> video_rtp_senders_
@ -158,6 +160,7 @@ class RtpTransportControllerSend final
RtpBitrateConfigurator bitrate_configurator_;
std::map<std::string, rtc::NetworkRoute> network_routes_
RTC_GUARDED_BY(sequence_checker_);
BandwidthEstimationSettings bwe_settings_ RTC_GUARDED_BY(sequence_checker_);
bool pacer_started_ RTC_GUARDED_BY(sequence_checker_);
TaskQueuePacedSender pacer_;

View file

@ -24,6 +24,7 @@
#include "api/fec_controller.h"
#include "api/frame_transformer_interface.h"
#include "api/rtc_event_log/rtc_event_log.h"
#include "api/transport/bandwidth_estimation_settings.h"
#include "api/transport/bitrate_settings.h"
#include "api/units/timestamp.h"
#include "call/rtp_config.h"
@ -125,6 +126,9 @@ class RtpTransportControllerSendInterface {
virtual void SetAllocatedSendBitrateLimits(
BitrateAllocationLimits limits) = 0;
virtual void ReconfigureBandwidthEstimation(
const BandwidthEstimationSettings& settings) = 0;
virtual void SetPacingFactor(float pacing_factor) = 0;
virtual void SetQueueTimeLimit(int limit_ms) = 0;

View file

@ -69,6 +69,10 @@ class MockRtpTransportControllerSend
SetAllocatedSendBitrateLimits,
(BitrateAllocationLimits),
(override));
MOCK_METHOD(void,
ReconfigureBandwidthEstimation,
(const BandwidthEstimationSettings&),
(override));
MOCK_METHOD(void, SetPacingFactor, (float), (override));
MOCK_METHOD(void, SetQueueTimeLimit, (int), (override));
MOCK_METHOD(StreamFeedbackProvider*,

View file

@ -426,6 +426,7 @@ rtc_source_set("peer_connection_proxy") {
deps = [
":proxy",
"../api:libjingle_peerconnection_api",
"../api/transport:bandwidth_estimation_settings",
]
}

View file

@ -1681,6 +1681,15 @@ RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
return RTCError::OK();
}
void PeerConnection::ReconfigureBandwidthEstimation(
const BandwidthEstimationSettings& settings) {
worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, settings]() {
RTC_DCHECK_RUN_ON(worker_thread());
call_->GetTransportControllerSend()->ReconfigureBandwidthEstimation(
settings);
}));
}
void PeerConnection::SetAudioPlayout(bool playout) {
if (!worker_thread()->IsCurrent()) {
worker_thread()->BlockingCall(

View file

@ -236,6 +236,8 @@ class PeerConnection : public PeerConnectionInternal,
const std::vector<cricket::Candidate>& candidates) override;
RTCError SetBitrate(const BitrateSettings& bitrate) override;
void ReconfigureBandwidthEstimation(
const BandwidthEstimationSettings& settings) override;
void SetAudioPlayout(bool playout) override;
void SetAudioRecording(bool recording) override;

View file

@ -16,6 +16,7 @@
#include <vector>
#include "api/peer_connection_interface.h"
#include "api/transport/bandwidth_estimation_settings.h"
#include "pc/proxy.h"
namespace webrtc {
@ -137,6 +138,9 @@ PROXY_METHOD2(void,
std::function<void(RTCError)>)
PROXY_METHOD1(bool, RemoveIceCandidates, const std::vector<cricket::Candidate>&)
PROXY_METHOD1(RTCError, SetBitrate, const BitrateSettings&)
PROXY_METHOD1(void,
ReconfigureBandwidthEstimation,
const BandwidthEstimationSettings&)
PROXY_METHOD1(void, SetAudioPlayout, bool)
PROXY_METHOD1(void, SetAudioRecording, bool)
// This method will be invoked on the network thread. See

View file

@ -197,6 +197,9 @@ class FakePeerConnectionBase : public PeerConnectionInternal {
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
}
void ReconfigureBandwidthEstimation(
const BandwidthEstimationSettings& settings) override {}
void SetAudioPlayout(bool playout) override {}
void SetAudioRecording(bool recording) override {}

View file

@ -170,6 +170,10 @@ class MockPeerConnectionInternal : public PeerConnectionInternal {
(const std::vector<cricket::Candidate>&),
(override));
MOCK_METHOD(RTCError, SetBitrate, (const BitrateSettings&), (override));
MOCK_METHOD(void,
ReconfigureBandwidthEstimation,
(const BandwidthEstimationSettings&),
(override));
MOCK_METHOD(void, SetAudioPlayout, (bool), (override));
MOCK_METHOD(void, SetAudioRecording, (bool), (override));
MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>,