Propagate field trials into audio NackTracker
Bug: webrtc:42220378
Change-Id: Ibf831e15b5931925a9efa9099178f71b1a23c147
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/359280
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42769}
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index 15eb29c..e96a40a 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -711,6 +711,7 @@
":webrtc_cng",
"..:module_api_public",
"../../api:array_view",
+ "../../api:field_trials_view",
"../../api:rtp_headers",
"../../api:rtp_packet_info",
"../../api:scoped_refptr",
diff --git a/modules/audio_coding/neteq/nack_tracker.cc b/modules/audio_coding/neteq/nack_tracker.cc
index 71c6fc3..a1e973b 100644
--- a/modules/audio_coding/neteq/nack_tracker.cc
+++ b/modules/audio_coding/neteq/nack_tracker.cc
@@ -13,10 +13,10 @@
#include <cstdint>
#include <utility>
+#include "api/field_trials_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/struct_parameters_parser.h"
#include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
namespace webrtc {
namespace {
@@ -28,14 +28,13 @@
} // namespace
-NackTracker::Config::Config() {
+NackTracker::Config::Config(const FieldTrialsView& field_trials) {
auto parser = StructParametersParser::Create(
"packet_loss_forget_factor", &packet_loss_forget_factor,
"ms_per_loss_percent", &ms_per_loss_percent, "never_nack_multiple_times",
&never_nack_multiple_times, "require_valid_rtt", &require_valid_rtt,
"max_loss_rate", &max_loss_rate);
- parser->Parse(
- webrtc::field_trial::FindFullName(kNackTrackerConfigFieldTrial));
+ parser->Parse(field_trials.Lookup(kNackTrackerConfigFieldTrial));
RTC_LOG(LS_INFO) << "Nack tracker config:"
" packet_loss_forget_factor="
<< packet_loss_forget_factor
@@ -45,8 +44,9 @@
<< " max_loss_rate=" << max_loss_rate;
}
-NackTracker::NackTracker()
- : sequence_num_last_received_rtp_(0),
+NackTracker::NackTracker(const FieldTrialsView& field_trials)
+ : config_(field_trials),
+ sequence_num_last_received_rtp_(0),
timestamp_last_received_rtp_(0),
any_rtp_received_(false),
sequence_num_last_decoded_rtp_(0),
diff --git a/modules/audio_coding/neteq/nack_tracker.h b/modules/audio_coding/neteq/nack_tracker.h
index d9005da..c95496d 100644
--- a/modules/audio_coding/neteq/nack_tracker.h
+++ b/modules/audio_coding/neteq/nack_tracker.h
@@ -18,6 +18,7 @@
#include <vector>
#include "absl/types/optional.h"
+#include "api/field_trials_view.h"
#include "modules/include/module_common_types_public.h"
#include "rtc_base/gtest_prod_util.h"
@@ -54,7 +55,7 @@
// A limit for the size of the NACK list.
static const size_t kNackListSizeLimit = 500; // 10 seconds for 20 ms frame
// packets.
- NackTracker();
+ explicit NackTracker(const FieldTrialsView& field_trials);
~NackTracker();
// Set a maximum for the size of the NACK list. If the last received packet
@@ -99,7 +100,7 @@
// Options that can be configured via field trial.
struct Config {
- Config();
+ explicit Config(const FieldTrialsView& field_trials);
// The exponential decay factor used to estimate the packet loss rate.
double packet_loss_forget_factor = 0.996;
diff --git a/modules/audio_coding/neteq/nack_tracker_unittest.cc b/modules/audio_coding/neteq/nack_tracker_unittest.cc
index a843425..89d3555 100644
--- a/modules/audio_coding/neteq/nack_tracker_unittest.cc
+++ b/modules/audio_coding/neteq/nack_tracker_unittest.cc
@@ -16,12 +16,14 @@
#include <memory>
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
-#include "test/field_trial.h"
+#include "test/explicit_key_value_config.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
+using test::ExplicitKeyValueConfig;
+
const int kSampleRateHz = 16000;
const int kPacketSizeMs = 30;
const uint32_t kTimestampIncrement = 480; // 30 ms.
@@ -54,7 +56,8 @@
} // namespace
TEST(NackTrackerTest, EmptyListWhenNoPacketLoss) {
- NackTracker nack;
+ ExplicitKeyValueConfig field_trials("");
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
int seq_num = 1;
@@ -72,12 +75,13 @@
}
TEST(NackTrackerTest, LatePacketsMovedToNackThenNackListDoesNotChange) {
+ ExplicitKeyValueConfig field_trials("");
const uint16_t kSequenceNumberLostPackets[] = {2, 3, 4, 5, 6, 7, 8, 9};
static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) /
sizeof(kSequenceNumberLostPackets[0]);
for (int k = 0; k < 2; k++) { // Two iteration with/without wrap around.
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
uint16_t sequence_num_lost_packets[kNumAllLostPackets];
@@ -119,12 +123,13 @@
}
TEST(NackTrackerTest, ArrivedPacketsAreRemovedFromNackList) {
+ ExplicitKeyValueConfig field_trials("");
const uint16_t kSequenceNumberLostPackets[] = {2, 3, 4, 5, 6, 7, 8, 9};
static const int kNumAllLostPackets = sizeof(kSequenceNumberLostPackets) /
sizeof(kSequenceNumberLostPackets[0]);
for (int k = 0; k < 2; ++k) { // Two iteration with/without wrap around.
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
uint16_t sequence_num_lost_packets[kNumAllLostPackets];
@@ -180,13 +185,14 @@
// Assess if estimation of timestamps and time-to-play is correct. Introduce all
// combinations that timestamps and sequence numbers might have wrap around.
TEST(NackTrackerTest, EstimateTimestampAndTimeToPlay) {
+ ExplicitKeyValueConfig field_trials("");
const uint16_t kLostPackets[] = {2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15};
static const int kNumAllLostPackets =
sizeof(kLostPackets) / sizeof(kLostPackets[0]);
for (int k = 0; k < 4; ++k) {
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
// Sequence number wrap around if `k` is 2 or 3;
@@ -243,9 +249,10 @@
TEST(NackTrackerTest,
MissingPacketsPriorToLastDecodedRtpShouldNotBeInNackList) {
+ ExplicitKeyValueConfig field_trials("");
for (int m = 0; m < 2; ++m) {
uint16_t seq_num_offset = (m == 0) ? 0 : 65531; // Wrap around if `m` is 1.
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
// Two consecutive packets to have a correct estimate of timestamp increase.
@@ -296,7 +303,8 @@
}
TEST(NackTrackerTest, Reset) {
- NackTracker nack;
+ ExplicitKeyValueConfig field_trials("");
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
// Two consecutive packets to have a correct estimate of timestamp increase.
@@ -320,10 +328,11 @@
}
TEST(NackTrackerTest, ListSizeAppliedFromBeginning) {
+ ExplicitKeyValueConfig field_trials("");
const size_t kNackListSize = 10;
for (int m = 0; m < 2; ++m) {
uint16_t seq_num_offset = (m == 0) ? 0 : 65525; // Wrap around if `m` is 1.
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
@@ -344,10 +353,11 @@
}
TEST(NackTrackerTest, ChangeOfListSizeAppliedAndOldElementsRemoved) {
+ ExplicitKeyValueConfig field_trials("");
const size_t kNackListSize = 10;
for (int m = 0; m < 2; ++m) {
uint16_t seq_num_offset = (m == 0) ? 0 : 65525; // Wrap around if `m` is 1.
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
uint16_t seq_num = seq_num_offset;
@@ -399,8 +409,9 @@
}
TEST(NackTrackerTest, RoudTripTimeIsApplied) {
+ ExplicitKeyValueConfig field_trials("");
const int kNackListSize = 200;
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
@@ -430,12 +441,12 @@
// Set never_nack_multiple_times to true with a field trial and verify that
// packets are not nacked multiple times.
TEST(NackTrackerTest, DoNotNackMultipleTimes) {
- test::ScopedFieldTrials field_trials(
+ ExplicitKeyValueConfig field_trials(
"WebRTC-Audio-NetEqNackTrackerConfig/"
"packet_loss_forget_factor:0.996,ms_per_loss_percent:20,"
"never_nack_multiple_times:true/");
const int kNackListSize = 200;
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
@@ -461,8 +472,9 @@
// Test if estimated packet loss rate is correct.
TEST(NackTrackerTest, PacketLossRateCorrect) {
+ ExplicitKeyValueConfig field_trials("");
const int kNackListSize = 200;
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
uint16_t seq_num = 0;
@@ -487,8 +499,9 @@
}
TEST(NackTrackerTest, DoNotNackAfterDtx) {
+ ExplicitKeyValueConfig field_trials("");
const int kNackListSize = 200;
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
uint16_t seq_num = 0;
@@ -502,10 +515,10 @@
}
TEST(NackTrackerTest, DoNotNackIfLossRateIsTooHigh) {
- test::ScopedFieldTrials field_trials(
+ ExplicitKeyValueConfig field_trials(
"WebRTC-Audio-NetEqNackTrackerConfig/max_loss_rate:0.4/");
const int kNackListSize = 200;
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
uint16_t seq_num = 0;
@@ -527,10 +540,10 @@
}
TEST(NackTrackerTest, OnlyNackIfRttIsValid) {
- test::ScopedFieldTrials field_trials(
+ ExplicitKeyValueConfig field_trials(
"WebRTC-Audio-NetEqNackTrackerConfig/require_valid_rtt:true/");
const int kNackListSize = 200;
- NackTracker nack;
+ NackTracker nack(field_trials);
nack.UpdateSampleRate(kSampleRateHz);
nack.SetMaxNackListSize(kNackListSize);
uint16_t seq_num = 0;
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index 5ea78e3..01a4d7f 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -424,7 +424,7 @@
void NetEqImpl::EnableNack(size_t max_nack_list_size) {
MutexLock lock(&mutex_);
if (!nack_enabled_) {
- nack_ = std::make_unique<NackTracker>();
+ nack_ = std::make_unique<NackTracker>(env_.field_trials());
nack_enabled_ = true;
nack_->UpdateSampleRate(fs_hz_);
}