Add field trial to control network socket receive buffer size.

In some very high-bandwidth application there have been observations of
packet loss in the socket implementation (not on the network itself) due
to large bursts of packets arriving. Allocating too big buffers can of
course lead to issue as well, so this flag is intended to find a good
tradeoff.

Bug: webrtc:15585
Change-Id: I63eccb1a9f34d852d80c286fc27bffd17818f0ef
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324021
Auto-Submit: Erik Språng <sprang@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40963}
This commit is contained in:
Erik Språng 2023-10-18 14:25:33 +02:00 committed by WebRTC LUCI CQ
parent 81be76aac6
commit 665e6817d1
4 changed files with 60 additions and 2 deletions

View file

@ -715,6 +715,9 @@ POLICY_EXEMPT_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
FieldTrial('WebRTC-SendBufferSizeBytes',
'webrtc:11905',
date(2024, 4, 1)),
FieldTrial('WebRTC-ReceiveBufferSize',
'webrtc:15585',
date(2024, 4, 1)),
FieldTrial('WebRTC-SendNackDelayMs',
'webrtc:9953',
date(2024, 4, 1)),

View file

@ -745,6 +745,19 @@ void ExtractCodecInformation(
}
}
int ParseReceiveBufferSize(const webrtc::FieldTrialsView& trials) {
webrtc::FieldTrialParameter<int> size_bytes("size_bytes",
kVideoRtpRecvBufferSize);
webrtc::ParseFieldTrial({&size_bytes},
trials.Lookup("WebRTC-ReceiveBufferSize"));
if (size_bytes.Get() < 10'000 || size_bytes.Get() > 10'000'000) {
RTC_LOG(LS_WARNING) << "WebRTC-ReceiveBufferSize out of bounds: "
<< size_bytes.Get();
return kVideoRtpRecvBufferSize;
}
return size_bytes.Get();
}
} // namespace
// --------------- WebRtcVideoEngine ---------------------------
@ -2585,7 +2598,8 @@ WebRtcVideoReceiveChannel::WebRtcVideoReceiveChannel(
discard_unknown_ssrc_packets_(
IsEnabled(call_->trials(),
"WebRTC-Video-DiscardPacketsWithUnknownSsrc")),
crypto_options_(crypto_options) {
crypto_options_(crypto_options),
receive_buffer_size_(ParseReceiveBufferSize(call_->trials())) {
RTC_DCHECK_RUN_ON(&thread_checker_);
rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc;
recv_codecs_ = MapCodecs(GetPayloadTypesAndDefaultCodecs(
@ -3182,7 +3196,7 @@ void WebRtcVideoReceiveChannel::SetInterface(
MediaChannelUtil::SetInterface(iface);
// Set the RTP recv/send buffer to a bigger size.
MediaChannelUtil::SetOption(MediaChannelNetworkInterface::ST_RTP,
rtc::Socket::OPT_RCVBUF, kVideoRtpRecvBufferSize);
rtc::Socket::OPT_RCVBUF, receive_buffer_size_);
}
void WebRtcVideoReceiveChannel::SetFrameDecryptor(

View file

@ -891,6 +891,8 @@ class WebRtcVideoReceiveChannel : public MediaChannelUtil,
// Callback invoked whenever the list of SSRCs changes.
absl::AnyInvocable<void(const std::set<uint32_t>&)>
ssrc_list_changed_callback_;
const int receive_buffer_size_;
};
// Keeping the old name "WebRtcVideoChannel" around because some external

View file

@ -977,6 +977,45 @@ TEST_F(WebRtcVideoEngineTest, SendsFeedbackAfterUnsignaledRtxPacket) {
receive_channel->SetInterface(nullptr);
}
TEST_F(WebRtcVideoEngineTest, ReceiveBufferSizeViaFieldTrial) {
webrtc::test::ScopedKeyValueConfig override_field_trials(
field_trials_, "WebRTC-ReceiveBufferSize/size_bytes:10000/");
std::unique_ptr<VideoMediaReceiveChannelInterface> receive_channel =
engine_.CreateReceiveChannel(call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions());
cricket::FakeNetworkInterface network;
receive_channel->SetInterface(&network);
EXPECT_EQ(10000, network.recvbuf_size());
receive_channel->SetInterface(nullptr);
}
TEST_F(WebRtcVideoEngineTest, TooLowReceiveBufferSizeViaFieldTrial) {
// 10000001 is too high, it will revert to the default
// kVideoRtpRecvBufferSize.
webrtc::test::ScopedKeyValueConfig override_field_trials(
field_trials_, "WebRTC-ReceiveBufferSize/size_bytes:10000001/");
std::unique_ptr<VideoMediaReceiveChannelInterface> receive_channel =
engine_.CreateReceiveChannel(call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions());
cricket::FakeNetworkInterface network;
receive_channel->SetInterface(&network);
EXPECT_EQ(kVideoRtpRecvBufferSize, network.recvbuf_size());
receive_channel->SetInterface(nullptr);
}
TEST_F(WebRtcVideoEngineTest, TooHighReceiveBufferSizeViaFieldTrial) {
// 9999 is too low, it will revert to the default kVideoRtpRecvBufferSize.
webrtc::test::ScopedKeyValueConfig override_field_trials(
field_trials_, "WebRTC-ReceiveBufferSize/size_bytes:9999/");
std::unique_ptr<VideoMediaReceiveChannelInterface> receive_channel =
engine_.CreateReceiveChannel(call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions());
cricket::FakeNetworkInterface network;
receive_channel->SetInterface(&network);
EXPECT_EQ(kVideoRtpRecvBufferSize, network.recvbuf_size());
receive_channel->SetInterface(nullptr);
}
TEST_F(WebRtcVideoEngineTest, UpdatesUnsignaledRtxSsrcAndRecoversPayload) {
// Setup a channel with VP8, RTX and transport sequence number header
// extension. Receive stream is not explicitly configured.