Remove legacy delay manger field trial and update default config.
Bug: webrtc:10333 Change-Id: I20e55d8d111d93657d1afe556fe3a325337c074c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232820 Reviewed-by: Ivo Creusen <ivoc@webrtc.org> Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35321}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
28c7180999
commit
93849d4b2a
@ -20,6 +20,7 @@
|
||||
|
||||
#include "modules/include/module_common_types_public.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/experiments/struct_parameters_parser.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
#include "rtc_base/numerics/safe_minmax.h"
|
||||
@ -45,9 +46,17 @@ std::unique_ptr<ReorderOptimizer> MaybeCreateReorderOptimizer(
|
||||
} // namespace
|
||||
|
||||
DelayManager::Config::Config() {
|
||||
Parser()->Parse(webrtc::field_trial::FindFullName(
|
||||
"WebRTC-Audio-NetEqDelayManagerConfig"));
|
||||
MaybeUpdateFromLegacyFieldTrial();
|
||||
StructParametersParser::Create( //
|
||||
"quantile", &quantile, //
|
||||
"forget_factor", &forget_factor, //
|
||||
"start_forget_weight", &start_forget_weight, //
|
||||
"resample_interval_ms", &resample_interval_ms, //
|
||||
"max_history_ms", &max_history_ms, //
|
||||
"use_reorder_optimizer", &use_reorder_optimizer, //
|
||||
"reorder_forget_factor", &reorder_forget_factor, //
|
||||
"ms_per_loss_percent", &ms_per_loss_percent)
|
||||
->Parse(webrtc::field_trial::FindFullName(
|
||||
"WebRTC-Audio-NetEqDelayManagerConfig"));
|
||||
}
|
||||
|
||||
void DelayManager::Config::Log() {
|
||||
@ -63,42 +72,6 @@ void DelayManager::Config::Log() {
|
||||
<< " ms_per_loss_percent=" << ms_per_loss_percent;
|
||||
}
|
||||
|
||||
std::unique_ptr<StructParametersParser> DelayManager::Config::Parser() {
|
||||
return StructParametersParser::Create( //
|
||||
"quantile", &quantile, //
|
||||
"forget_factor", &forget_factor, //
|
||||
"start_forget_weight", &start_forget_weight, //
|
||||
"resample_interval_ms", &resample_interval_ms, //
|
||||
"max_history_ms", &max_history_ms, //
|
||||
"use_reorder_optimizer", &use_reorder_optimizer, //
|
||||
"reorder_forget_factor", &reorder_forget_factor, //
|
||||
"ms_per_loss_percent", &ms_per_loss_percent);
|
||||
}
|
||||
|
||||
// TODO(jakobi): remove legacy field trial.
|
||||
void DelayManager::Config::MaybeUpdateFromLegacyFieldTrial() {
|
||||
constexpr char kDelayHistogramFieldTrial[] =
|
||||
"WebRTC-Audio-NetEqDelayHistogram";
|
||||
if (!webrtc::field_trial::IsEnabled(kDelayHistogramFieldTrial)) {
|
||||
return;
|
||||
}
|
||||
const auto field_trial_string =
|
||||
webrtc::field_trial::FindFullName(kDelayHistogramFieldTrial);
|
||||
double percentile = -1.0;
|
||||
double forget_factor = -1.0;
|
||||
double start_forget_weight = -1.0;
|
||||
if (sscanf(field_trial_string.c_str(), "Enabled-%lf-%lf-%lf", &percentile,
|
||||
&forget_factor, &start_forget_weight) >= 2 &&
|
||||
percentile >= 0.0 && percentile <= 100.0 && forget_factor >= 0.0 &&
|
||||
forget_factor <= 1.0) {
|
||||
this->quantile = percentile / 100;
|
||||
this->forget_factor = forget_factor;
|
||||
this->start_forget_weight = start_forget_weight >= 1
|
||||
? absl::make_optional(start_forget_weight)
|
||||
: absl::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
DelayManager::DelayManager(const Config& config, const TickTimer* tick_timer)
|
||||
: max_packets_in_buffer_(config.max_packets_in_buffer),
|
||||
underrun_optimizer_(tick_timer,
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
#include "modules/audio_coding/neteq/reorder_optimizer.h"
|
||||
#include "modules/audio_coding/neteq/underrun_optimizer.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
#include "rtc_base/experiments/struct_parameters_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -34,10 +33,10 @@ class DelayManager {
|
||||
void Log();
|
||||
|
||||
// Options that can be configured via field trial.
|
||||
double quantile = 0.97;
|
||||
double forget_factor = 0.9993;
|
||||
double quantile = 0.95;
|
||||
double forget_factor = 0.983;
|
||||
absl::optional<double> start_forget_weight = 2;
|
||||
absl::optional<int> resample_interval_ms;
|
||||
absl::optional<int> resample_interval_ms = 500;
|
||||
int max_history_ms = 2000;
|
||||
|
||||
bool use_reorder_optimizer = true;
|
||||
@ -47,12 +46,6 @@ class DelayManager {
|
||||
// Options that are externally populated.
|
||||
int max_packets_in_buffer = 200;
|
||||
int base_minimum_delay_ms = 0;
|
||||
|
||||
private:
|
||||
std::unique_ptr<StructParametersParser> Parser();
|
||||
|
||||
// TODO(jakobi): remove legacy field trial.
|
||||
void MaybeUpdateFromLegacyFieldTrial();
|
||||
};
|
||||
|
||||
DelayManager(const Config& config, const TickTimer* tick_timer);
|
||||
|
||||
@ -44,8 +44,8 @@ class DelayManagerTest : public ::testing::Test {
|
||||
absl::optional<int> InsertNextPacket();
|
||||
void IncreaseTime(int inc_ms);
|
||||
|
||||
DelayManager dm_;
|
||||
TickTimer tick_timer_;
|
||||
DelayManager dm_;
|
||||
uint32_t ts_;
|
||||
};
|
||||
|
||||
@ -74,39 +74,18 @@ TEST_F(DelayManagerTest, CreateAndDestroy) {
|
||||
}
|
||||
|
||||
TEST_F(DelayManagerTest, UpdateNormal) {
|
||||
// First packet arrival.
|
||||
InsertNextPacket();
|
||||
// Advance time by one frame size.
|
||||
IncreaseTime(kFrameSizeMs);
|
||||
// Second packet arrival.
|
||||
InsertNextPacket();
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
InsertNextPacket();
|
||||
IncreaseTime(kFrameSizeMs);
|
||||
}
|
||||
EXPECT_EQ(20, dm_.TargetDelayMs());
|
||||
}
|
||||
|
||||
TEST_F(DelayManagerTest, UpdateLongInterArrivalTime) {
|
||||
// First packet arrival.
|
||||
InsertNextPacket();
|
||||
// Advance time by two frame size.
|
||||
IncreaseTime(2 * kFrameSizeMs);
|
||||
// Second packet arrival.
|
||||
InsertNextPacket();
|
||||
EXPECT_EQ(40, dm_.TargetDelayMs());
|
||||
}
|
||||
|
||||
TEST_F(DelayManagerTest, MaxDelay) {
|
||||
const int kExpectedTarget = 5 * kFrameSizeMs;
|
||||
// First packet arrival.
|
||||
InsertNextPacket();
|
||||
// Second packet arrival.
|
||||
IncreaseTime(kExpectedTarget);
|
||||
InsertNextPacket();
|
||||
|
||||
// No limit is set.
|
||||
EXPECT_EQ(kExpectedTarget, dm_.TargetDelayMs());
|
||||
|
||||
const int kMaxDelayMs = 3 * kFrameSizeMs;
|
||||
const int kMaxDelayMs = 60;
|
||||
EXPECT_GT(dm_.TargetDelayMs(), kMaxDelayMs);
|
||||
EXPECT_TRUE(dm_.SetMaximumDelay(kMaxDelayMs));
|
||||
IncreaseTime(kFrameSizeMs);
|
||||
InsertNextPacket();
|
||||
EXPECT_EQ(kMaxDelayMs, dm_.TargetDelayMs());
|
||||
|
||||
@ -115,17 +94,9 @@ TEST_F(DelayManagerTest, MaxDelay) {
|
||||
}
|
||||
|
||||
TEST_F(DelayManagerTest, MinDelay) {
|
||||
const int kExpectedTarget = 5 * kFrameSizeMs;
|
||||
// First packet arrival.
|
||||
InsertNextPacket();
|
||||
// Second packet arrival.
|
||||
IncreaseTime(kExpectedTarget);
|
||||
InsertNextPacket();
|
||||
|
||||
// No limit is applied.
|
||||
EXPECT_EQ(kExpectedTarget, dm_.TargetDelayMs());
|
||||
|
||||
int kMinDelayMs = 7 * kFrameSizeMs;
|
||||
EXPECT_LT(dm_.TargetDelayMs(), kMinDelayMs);
|
||||
dm_.SetMinimumDelay(kMinDelayMs);
|
||||
IncreaseTime(kFrameSizeMs);
|
||||
InsertNextPacket();
|
||||
@ -251,48 +222,11 @@ TEST_F(DelayManagerTest, MinimumDelayMemorization) {
|
||||
}
|
||||
|
||||
TEST_F(DelayManagerTest, BaseMinimumDelay) {
|
||||
const int kExpectedTarget = 5 * kFrameSizeMs;
|
||||
// First packet arrival.
|
||||
InsertNextPacket();
|
||||
// Second packet arrival.
|
||||
IncreaseTime(kExpectedTarget);
|
||||
InsertNextPacket();
|
||||
|
||||
// No limit is applied.
|
||||
EXPECT_EQ(kExpectedTarget, dm_.TargetDelayMs());
|
||||
|
||||
constexpr int kBaseMinimumDelayMs = 7 * kFrameSizeMs;
|
||||
EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
|
||||
EXPECT_EQ(dm_.GetBaseMinimumDelay(), kBaseMinimumDelayMs);
|
||||
|
||||
IncreaseTime(kFrameSizeMs);
|
||||
InsertNextPacket();
|
||||
EXPECT_EQ(dm_.GetBaseMinimumDelay(), kBaseMinimumDelayMs);
|
||||
EXPECT_EQ(kBaseMinimumDelayMs, dm_.TargetDelayMs());
|
||||
}
|
||||
|
||||
TEST_F(DelayManagerTest, BaseMinimumDelayAffectsTargetDelay) {
|
||||
const int kExpectedTarget = 5;
|
||||
const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
|
||||
// First packet arrival.
|
||||
InsertNextPacket();
|
||||
// Second packet arrival.
|
||||
IncreaseTime(kTimeIncrement);
|
||||
InsertNextPacket();
|
||||
|
||||
// No limit is applied.
|
||||
EXPECT_EQ(kTimeIncrement, dm_.TargetDelayMs());
|
||||
|
||||
// Minimum delay is lower than base minimum delay, that is why base minimum
|
||||
// delay is used to calculate target level.
|
||||
constexpr int kMinimumDelayPackets = kExpectedTarget + 1;
|
||||
constexpr int kBaseMinimumDelayPackets = kExpectedTarget + 2;
|
||||
|
||||
constexpr int kMinimumDelayMs = kMinimumDelayPackets * kFrameSizeMs;
|
||||
constexpr int kBaseMinimumDelayMs = kBaseMinimumDelayPackets * kFrameSizeMs;
|
||||
|
||||
EXPECT_TRUE(kMinimumDelayMs < kBaseMinimumDelayMs);
|
||||
EXPECT_TRUE(dm_.SetMinimumDelay(kMinimumDelayMs));
|
||||
EXPECT_LT(dm_.TargetDelayMs(), kBaseMinimumDelayMs);
|
||||
EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
|
||||
EXPECT_EQ(dm_.GetBaseMinimumDelay(), kBaseMinimumDelayMs);
|
||||
|
||||
|
||||
@ -1370,7 +1370,7 @@ int NetEqImpl::GetDecision(Operation* operation,
|
||||
}
|
||||
}
|
||||
|
||||
timestamp_ = end_timestamp;
|
||||
timestamp_ = sync_buffer_->end_timestamp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1026,22 +1026,37 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
|
||||
EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
|
||||
.WillRepeatedly(Return(rtc::checked_cast<int>(kPayloadLengthSamples)));
|
||||
|
||||
// Pointee(x) verifies that first byte of the payload equals x, this makes it
|
||||
// possible to verify that the correct payload is fed to Decode().
|
||||
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
|
||||
kSampleRateKhz * 1000, _, _))
|
||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
||||
dummy_output + kPayloadLengthSamples),
|
||||
SetArgPointee<4>(AudioDecoder::kSpeech),
|
||||
Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
|
||||
EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
|
||||
SdpAudioFormat("opus", 48000, 2)));
|
||||
|
||||
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
|
||||
kSampleRateKhz * 1000, _, _))
|
||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
||||
dummy_output + kPayloadLengthSamples),
|
||||
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
||||
Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
|
||||
struct Packet {
|
||||
int sequence_number_delta;
|
||||
int timestamp_delta;
|
||||
AudioDecoder::SpeechType decoder_output_type;
|
||||
};
|
||||
std::vector<Packet> packets = {
|
||||
{0, 0, AudioDecoder::kSpeech},
|
||||
{1, kPayloadLengthSamples, AudioDecoder::kComfortNoise},
|
||||
{2, 2 * kPayloadLengthSamples, AudioDecoder::kSpeech},
|
||||
{1, kPayloadLengthSamples, AudioDecoder::kSpeech}};
|
||||
|
||||
for (size_t i = 0; i < packets.size(); ++i) {
|
||||
rtp_header.sequenceNumber += packets[i].sequence_number_delta;
|
||||
rtp_header.timestamp += packets[i].timestamp_delta;
|
||||
payload[0] = i;
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
|
||||
|
||||
// Pointee(x) verifies that first byte of the payload equals x, this makes
|
||||
// it possible to verify that the correct payload is fed to Decode().
|
||||
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(i), kPayloadLengthBytes,
|
||||
kSampleRateKhz * 1000, _, _))
|
||||
.WillOnce(DoAll(SetArrayArgument<3>(
|
||||
dummy_output, dummy_output + kPayloadLengthSamples),
|
||||
SetArgPointee<4>(packets[i].decoder_output_type),
|
||||
Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
|
||||
}
|
||||
|
||||
// Expect comfort noise to be returned by the decoder.
|
||||
EXPECT_CALL(mock_decoder,
|
||||
DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
|
||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
||||
@ -1049,87 +1064,24 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
|
||||
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
||||
Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
|
||||
|
||||
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
|
||||
kSampleRateKhz * 1000, _, _))
|
||||
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
||||
dummy_output + kPayloadLengthSamples),
|
||||
SetArgPointee<4>(AudioDecoder::kSpeech),
|
||||
Return(rtc::checked_cast<int>(kPayloadLengthSamples))));
|
||||
std::vector<AudioFrame::SpeechType> expected_output = {
|
||||
AudioFrame::kNormalSpeech, AudioFrame::kCNG, AudioFrame::kNormalSpeech};
|
||||
size_t output_index = 0;
|
||||
|
||||
EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
|
||||
SdpAudioFormat("opus", 48000, 2)));
|
||||
|
||||
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
|
||||
AudioFrame output;
|
||||
AudioFrame::SpeechType expected_type[8] = {
|
||||
AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech, AudioFrame::kCNG,
|
||||
AudioFrame::kCNG, AudioFrame::kCNG, AudioFrame::kCNG,
|
||||
AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech};
|
||||
int expected_timestamp_increment[8] = {
|
||||
-1, // will not be used.
|
||||
10 * kSampleRateKhz,
|
||||
-1,
|
||||
-1, // timestamp will be empty during CNG mode; indicated by -1 here.
|
||||
-1,
|
||||
-1,
|
||||
50 * kSampleRateKhz,
|
||||
10 * kSampleRateKhz};
|
||||
|
||||
// Insert one packet (decoder will return speech).
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
|
||||
|
||||
bool muted;
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
|
||||
absl::optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
|
||||
ASSERT_TRUE(last_timestamp);
|
||||
|
||||
// Insert second packet (decoder will return CNG).
|
||||
payload[0] = 1;
|
||||
rtp_header.sequenceNumber++;
|
||||
rtp_header.timestamp += kPayloadLengthSamples;
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
|
||||
|
||||
// Lambda for verifying the timestamps.
|
||||
auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
|
||||
absl::optional<uint32_t> ts, size_t i) {
|
||||
if (expected_timestamp_increment[i] == -1) {
|
||||
// Expect to get an empty timestamp value during CNG and PLC.
|
||||
EXPECT_FALSE(ts) << "i = " << i;
|
||||
int timeout_counter = 0;
|
||||
while (!packet_buffer_->Empty()) {
|
||||
ASSERT_LT(timeout_counter++, 20) << "Test timed out";
|
||||
AudioFrame output;
|
||||
bool muted;
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
|
||||
if (output_index + 1 < expected_output.size() &&
|
||||
output.speech_type_ == expected_output[output_index + 1]) {
|
||||
++output_index;
|
||||
} else {
|
||||
ASSERT_TRUE(ts) << "i = " << i;
|
||||
EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
|
||||
<< "i = " << i;
|
||||
last_timestamp = ts;
|
||||
EXPECT_EQ(output.speech_type_, expected_output[output_index]);
|
||||
}
|
||||
};
|
||||
|
||||
for (size_t i = 1; i < 6; ++i) {
|
||||
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
||||
EXPECT_EQ(1u, output.num_channels_);
|
||||
EXPECT_EQ(expected_type[i - 1], output.speech_type_);
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
|
||||
SCOPED_TRACE("");
|
||||
verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
|
||||
}
|
||||
|
||||
// Insert third packet, which leaves a gap from last packet.
|
||||
payload[0] = 2;
|
||||
rtp_header.sequenceNumber += 2;
|
||||
rtp_header.timestamp += 2 * kPayloadLengthSamples;
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
|
||||
|
||||
for (size_t i = 6; i < 8; ++i) {
|
||||
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
||||
EXPECT_EQ(1u, output.num_channels_);
|
||||
EXPECT_EQ(expected_type[i - 1], output.speech_type_);
|
||||
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
|
||||
SCOPED_TRACE("");
|
||||
verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
|
||||
}
|
||||
|
||||
// Now check the packet buffer, and make sure it is empty.
|
||||
EXPECT_TRUE(packet_buffer_->Empty());
|
||||
|
||||
EXPECT_CALL(mock_decoder, Die());
|
||||
}
|
||||
|
||||
|
||||
@ -274,7 +274,7 @@ class NetEqNetworkStatsTest {
|
||||
|
||||
// Next we introduce packet losses.
|
||||
SetPacketLossRate(0.1);
|
||||
expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 1065;
|
||||
expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 898;
|
||||
RunTest(50, expects);
|
||||
|
||||
// Next we enable FEC.
|
||||
|
||||
@ -82,17 +82,17 @@ TEST_F(NetEqDecodingTest, MAYBE_TestBitExactness) {
|
||||
const std::string input_rtp_file =
|
||||
webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp");
|
||||
|
||||
const std::string output_checksum = PlatformChecksum(
|
||||
"6c35140ce4d75874bdd60aa1872400b05fd05ca2",
|
||||
"ab451bb8301d9a92fbf4de91556b56f1ea38b4ce", "not used",
|
||||
"6c35140ce4d75874bdd60aa1872400b05fd05ca2",
|
||||
"64b46bb3c1165537a880ae8404afce2efba456c0");
|
||||
const std::string output_checksum =
|
||||
PlatformChecksum("ba4fae83a52f5e9d95b0910f05d540114285697b",
|
||||
"aa557f30f7fdcebbbbf99d7f235ccba3a1c98983", "not used",
|
||||
"ba4fae83a52f5e9d95b0910f05d540114285697b",
|
||||
"64b46bb3c1165537a880ae8404afce2efba456c0");
|
||||
|
||||
const std::string network_stats_checksum = PlatformChecksum(
|
||||
"90594d85fa31d3d9584d79293bf7aa4ee55ed751",
|
||||
"77b9c3640b81aff6a38d69d07dd782d39c15321d", "not used",
|
||||
"90594d85fa31d3d9584d79293bf7aa4ee55ed751",
|
||||
"90594d85fa31d3d9584d79293bf7aa4ee55ed751");
|
||||
const std::string network_stats_checksum =
|
||||
PlatformChecksum("fa878a8464ef1cb3d01503b7f927c3e2ce6f02c4",
|
||||
"300ccc2aaee7ed1971afb2f9a20247ed8760441d", "not used",
|
||||
"fa878a8464ef1cb3d01503b7f927c3e2ce6f02c4",
|
||||
"fa878a8464ef1cb3d01503b7f927c3e2ce6f02c4");
|
||||
|
||||
DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum,
|
||||
absl::GetFlag(FLAGS_gen_ref));
|
||||
@ -531,11 +531,16 @@ TEST_F(NetEqDecodingTest, DiscardDuplicateCng) {
|
||||
out_frame_.timestamp_ + out_frame_.samples_per_channel_);
|
||||
}
|
||||
|
||||
// Insert speech again.
|
||||
++seq_no;
|
||||
timestamp += kCngPeriodSamples;
|
||||
PopulateRtpInfo(seq_no, timestamp, &rtp_info);
|
||||
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload));
|
||||
uint32_t first_speech_timestamp = timestamp;
|
||||
// Insert speech again.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
PopulateRtpInfo(seq_no, timestamp, &rtp_info);
|
||||
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload));
|
||||
++seq_no;
|
||||
timestamp += kSamples;
|
||||
}
|
||||
|
||||
// Pull audio once and verify that the output is speech again.
|
||||
ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
|
||||
@ -543,7 +548,7 @@ TEST_F(NetEqDecodingTest, DiscardDuplicateCng) {
|
||||
EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
|
||||
absl::optional<uint32_t> playout_timestamp = neteq_->GetPlayoutTimestamp();
|
||||
ASSERT_TRUE(playout_timestamp);
|
||||
EXPECT_EQ(timestamp + kSamples - algorithmic_delay_samples,
|
||||
EXPECT_EQ(first_speech_timestamp + kSamples - algorithmic_delay_samples,
|
||||
*playout_timestamp);
|
||||
}
|
||||
|
||||
@ -1263,7 +1268,7 @@ TEST(NetEqOutputDelayTest, RunTestWithFieldTrial) {
|
||||
// The base delay values are taken from the resuts of the non-delayed case in
|
||||
// NetEqOutputDelayTest.RunTest above.
|
||||
EXPECT_EQ(20 + kExpectedDelayMs, result.target_delay_ms);
|
||||
EXPECT_EQ(24 + kExpectedDelayMs, result.filtered_current_delay_ms);
|
||||
EXPECT_EQ(60 + kExpectedDelayMs, result.filtered_current_delay_ms);
|
||||
}
|
||||
|
||||
// Set a non-multiple-of-10 value in the field trial, and verify that we don't
|
||||
@ -1278,7 +1283,7 @@ TEST(NetEqOutputDelayTest, RunTestWithFieldTrialOddValue) {
|
||||
// The base delay values are taken from the resuts of the non-delayed case in
|
||||
// NetEqOutputDelayTest.RunTest above.
|
||||
EXPECT_EQ(20 + kRoundedDelayMs, result.target_delay_ms);
|
||||
EXPECT_EQ(24 + kRoundedDelayMs, result.filtered_current_delay_ms);
|
||||
EXPECT_EQ(60 + kRoundedDelayMs, result.filtered_current_delay_ms);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
||||
@ -49,7 +49,7 @@ absl::optional<int> RelativeArrivalDelayTracker::Update(uint32_t timestamp,
|
||||
|
||||
void RelativeArrivalDelayTracker::Reset() {
|
||||
delay_history_.clear();
|
||||
packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch();
|
||||
packet_iat_stopwatch_.reset();
|
||||
newest_timestamp_ = absl::nullopt;
|
||||
last_timestamp_ = absl::nullopt;
|
||||
}
|
||||
|
||||
@ -245,15 +245,9 @@ void NetEqDecodingTest::WrapTest(uint16_t start_seq_no,
|
||||
NetEqNetworkStatistics network_stats;
|
||||
ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats));
|
||||
|
||||
// Due to internal NetEq logic, preferred buffer-size is about 4 times the
|
||||
// packet size for first few packets. Therefore we refrain from checking
|
||||
// the criteria.
|
||||
if (packets_inserted > 4) {
|
||||
// Expect preferred and actual buffer size to be no more than 2 frames.
|
||||
EXPECT_LE(network_stats.preferred_buffer_size_ms, kFrameSizeMs * 2);
|
||||
EXPECT_LE(network_stats.current_buffer_size_ms,
|
||||
kFrameSizeMs * 2 + algorithmic_delay_ms_);
|
||||
}
|
||||
EXPECT_LE(network_stats.preferred_buffer_size_ms, 80);
|
||||
EXPECT_LE(network_stats.current_buffer_size_ms,
|
||||
80 + algorithmic_delay_ms_);
|
||||
last_seq_no = seq_no;
|
||||
last_timestamp = timestamp;
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ void UnderrunOptimizer::Update(int relative_delay_ms) {
|
||||
|
||||
void UnderrunOptimizer::Reset() {
|
||||
histogram_.Reset();
|
||||
resample_stopwatch_ = tick_timer_->GetNewStopwatch();
|
||||
resample_stopwatch_.reset();
|
||||
max_delay_in_interval_ms_ = 0;
|
||||
optimal_delay_ms_.reset();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user