Start counting NetEq stats after first packet is decoded.
A slight behavior change is that we only increment total samples received when GetAudio is successful. Bug: webrtc:370424996 Change-Id: I8607418c179ca3bc22963b98792a9e8b9af2d451 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/364220 Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org> Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org> Reviewed-by: Jakob Ivarsson <jakobi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43139}
This commit is contained in:
parent
57ec58b82d
commit
09c043a4bb
@ -201,6 +201,7 @@ int NetEqImpl::GetAudio(AudioFrame* audio_frame,
|
|||||||
if (GetAudioInternal(audio_frame, action_override) != 0) {
|
if (GetAudioInternal(audio_frame, action_override) != 0) {
|
||||||
return kFail;
|
return kFail;
|
||||||
}
|
}
|
||||||
|
stats_->IncreaseCounter(output_size_samples_, fs_hz_);
|
||||||
RTC_DCHECK_EQ(
|
RTC_DCHECK_EQ(
|
||||||
audio_frame->sample_rate_hz_,
|
audio_frame->sample_rate_hz_,
|
||||||
rtc::dchecked_cast<int>(audio_frame->samples_per_channel_ * 100));
|
rtc::dchecked_cast<int>(audio_frame->samples_per_channel_ * 100));
|
||||||
@ -733,7 +734,6 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame,
|
|||||||
bool play_dtmf;
|
bool play_dtmf;
|
||||||
last_decoded_packet_infos_.clear();
|
last_decoded_packet_infos_.clear();
|
||||||
tick_timer_->Increment();
|
tick_timer_->Increment();
|
||||||
stats_->IncreaseCounter(output_size_samples_, fs_hz_);
|
|
||||||
|
|
||||||
// Check for muted state.
|
// Check for muted state.
|
||||||
if (enable_muted_state_ && expand_->Muted() && packet_buffer_->Empty()) {
|
if (enable_muted_state_ && expand_->Muted() && packet_buffer_->Empty()) {
|
||||||
|
|||||||
@ -384,6 +384,35 @@ TEST_F(NetEqImplTest, InsertPacket) {
|
|||||||
/*receive_time=*/clock_.CurrentTime());
|
/*receive_time=*/clock_.CurrentTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(NetEqImplTest, CountStatsAfterFirstDecodedPacket) {
|
||||||
|
UseNoMocks();
|
||||||
|
CreateInstance();
|
||||||
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
||||||
|
EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
|
||||||
|
SdpAudioFormat("l16", 8000, 1)));
|
||||||
|
const size_t kPayloadLengthSamples = 80;
|
||||||
|
const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
|
||||||
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
||||||
|
RTPHeader rtp_header;
|
||||||
|
rtp_header.payloadType = kPayloadType;
|
||||||
|
rtp_header.sequenceNumber = 0x1234;
|
||||||
|
rtp_header.timestamp = 0x12345678;
|
||||||
|
rtp_header.ssrc = 0x87654321;
|
||||||
|
AudioFrame frame;
|
||||||
|
// Get audio a couple of times to make sure that samples received remains
|
||||||
|
// zero.
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
neteq_->GetAudio(&frame);
|
||||||
|
EXPECT_EQ(neteq_->GetLifetimeStatistics().concealed_samples, 0u);
|
||||||
|
EXPECT_EQ(neteq_->GetLifetimeStatistics().total_samples_received, 0u);
|
||||||
|
}
|
||||||
|
neteq_->InsertPacket(rtp_header, payload, clock_.CurrentTime());
|
||||||
|
neteq_->GetAudio(&frame);
|
||||||
|
EXPECT_EQ(neteq_->GetLifetimeStatistics().concealed_samples, 0u);
|
||||||
|
EXPECT_EQ(neteq_->GetLifetimeStatistics().total_samples_received,
|
||||||
|
kPayloadLengthSamples);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
|
TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
|
||||||
UseNoMocks();
|
UseNoMocks();
|
||||||
CreateInstance();
|
CreateInstance();
|
||||||
|
|||||||
@ -81,7 +81,7 @@ TEST_F(NetEqDecodingTest, MAYBE_TestOpusBitExactness) {
|
|||||||
"cefd2de4adfa8f6a9b66a3639ad63c2f6779d0cd";
|
"cefd2de4adfa8f6a9b66a3639ad63c2f6779d0cd";
|
||||||
|
|
||||||
const std::string network_stats_checksum =
|
const std::string network_stats_checksum =
|
||||||
"5f2c8e3dff9cff55dd7a9f4167939de001566d95|"
|
"06f6b9a86aeae6317fd25a36edf9ed16f35e798f|"
|
||||||
"80ab17c17da030d4f2dfbf314ac44aacdadd7f0c";
|
"80ab17c17da030d4f2dfbf314ac44aacdadd7f0c";
|
||||||
|
|
||||||
DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum,
|
DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum,
|
||||||
@ -103,7 +103,7 @@ TEST_F(NetEqDecodingTest, MAYBE_TestOpusDtxBitExactness) {
|
|||||||
"5d13affec87bf4cc8c7667f0cd0d25e1ad09c7c3";
|
"5d13affec87bf4cc8c7667f0cd0d25e1ad09c7c3";
|
||||||
|
|
||||||
const std::string network_stats_checksum =
|
const std::string network_stats_checksum =
|
||||||
"92b0fdcbf8bb9354d40140b7312f2fb76a078555";
|
"6af74a713749cc4343464718b6af54f1e5b06ad9";
|
||||||
|
|
||||||
DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum,
|
DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum,
|
||||||
absl::GetFlag(FLAGS_gen_ref));
|
absl::GetFlag(FLAGS_gen_ref));
|
||||||
@ -660,7 +660,7 @@ TEST_F(NetEqDecodingTestWithMutedState, MutedState) {
|
|||||||
// NetEqNetworkStatistics::expand_rate tells the fraction of samples that were
|
// NetEqNetworkStatistics::expand_rate tells the fraction of samples that were
|
||||||
// concealment samples, in Q14 (16384 = 100%) .The vast majority should be
|
// concealment samples, in Q14 (16384 = 100%) .The vast majority should be
|
||||||
// concealment samples in this test.
|
// concealment samples in this test.
|
||||||
EXPECT_GT(stats.expand_rate, 14000);
|
EXPECT_GT(stats.expand_rate, 13000);
|
||||||
// And, it should be greater than the speech_expand_rate.
|
// And, it should be greater than the speech_expand_rate.
|
||||||
EXPECT_GT(stats.expand_rate, stats.speech_expand_rate);
|
EXPECT_GT(stats.expand_rate, stats.speech_expand_rate);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -155,6 +155,9 @@ void StatisticsCalculator::ResetMcu() {
|
|||||||
|
|
||||||
void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples,
|
void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples,
|
||||||
bool is_new_concealment_event) {
|
bool is_new_concealment_event) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
expanded_speech_samples_ += num_samples;
|
expanded_speech_samples_ += num_samples;
|
||||||
ConcealedSamplesCorrection(rtc::dchecked_cast<int>(num_samples), true);
|
ConcealedSamplesCorrection(rtc::dchecked_cast<int>(num_samples), true);
|
||||||
lifetime_stats_.concealment_events += is_new_concealment_event;
|
lifetime_stats_.concealment_events += is_new_concealment_event;
|
||||||
@ -162,18 +165,27 @@ void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples,
|
|||||||
|
|
||||||
void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples,
|
void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples,
|
||||||
bool is_new_concealment_event) {
|
bool is_new_concealment_event) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
expanded_noise_samples_ += num_samples;
|
expanded_noise_samples_ += num_samples;
|
||||||
ConcealedSamplesCorrection(rtc::dchecked_cast<int>(num_samples), false);
|
ConcealedSamplesCorrection(rtc::dchecked_cast<int>(num_samples), false);
|
||||||
lifetime_stats_.concealment_events += is_new_concealment_event;
|
lifetime_stats_.concealment_events += is_new_concealment_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::ExpandedVoiceSamplesCorrection(int num_samples) {
|
void StatisticsCalculator::ExpandedVoiceSamplesCorrection(int num_samples) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
expanded_speech_samples_ =
|
expanded_speech_samples_ =
|
||||||
AddIntToSizeTWithLowerCap(num_samples, expanded_speech_samples_);
|
AddIntToSizeTWithLowerCap(num_samples, expanded_speech_samples_);
|
||||||
ConcealedSamplesCorrection(num_samples, true);
|
ConcealedSamplesCorrection(num_samples, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::ExpandedNoiseSamplesCorrection(int num_samples) {
|
void StatisticsCalculator::ExpandedNoiseSamplesCorrection(int num_samples) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
expanded_noise_samples_ =
|
expanded_noise_samples_ =
|
||||||
AddIntToSizeTWithLowerCap(num_samples, expanded_noise_samples_);
|
AddIntToSizeTWithLowerCap(num_samples, expanded_noise_samples_);
|
||||||
ConcealedSamplesCorrection(num_samples, false);
|
ConcealedSamplesCorrection(num_samples, false);
|
||||||
@ -184,6 +196,9 @@ void StatisticsCalculator::DecodedOutputPlayed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::EndExpandEvent(int fs_hz) {
|
void StatisticsCalculator::EndExpandEvent(int fs_hz) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
RTC_DCHECK_GE(lifetime_stats_.concealed_samples,
|
RTC_DCHECK_GE(lifetime_stats_.concealed_samples,
|
||||||
concealed_samples_at_event_end_);
|
concealed_samples_at_event_end_);
|
||||||
const int event_duration_ms =
|
const int event_duration_ms =
|
||||||
@ -201,6 +216,9 @@ void StatisticsCalculator::EndExpandEvent(int fs_hz) {
|
|||||||
|
|
||||||
void StatisticsCalculator::ConcealedSamplesCorrection(int num_samples,
|
void StatisticsCalculator::ConcealedSamplesCorrection(int num_samples,
|
||||||
bool is_voice) {
|
bool is_voice) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (num_samples < 0) {
|
if (num_samples < 0) {
|
||||||
// Store negative correction to subtract from future positive additions.
|
// Store negative correction to subtract from future positive additions.
|
||||||
// See also the function comment in the header file.
|
// See also the function comment in the header file.
|
||||||
@ -226,18 +244,27 @@ void StatisticsCalculator::ConcealedSamplesCorrection(int num_samples,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) {
|
void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
preemptive_samples_ += num_samples;
|
preemptive_samples_ += num_samples;
|
||||||
operations_and_state_.preemptive_samples += num_samples;
|
operations_and_state_.preemptive_samples += num_samples;
|
||||||
lifetime_stats_.inserted_samples_for_deceleration += num_samples;
|
lifetime_stats_.inserted_samples_for_deceleration += num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::AcceleratedSamples(size_t num_samples) {
|
void StatisticsCalculator::AcceleratedSamples(size_t num_samples) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
accelerate_samples_ += num_samples;
|
accelerate_samples_ += num_samples;
|
||||||
operations_and_state_.accelerate_samples += num_samples;
|
operations_and_state_.accelerate_samples += num_samples;
|
||||||
lifetime_stats_.removed_samples_for_acceleration += num_samples;
|
lifetime_stats_.removed_samples_for_acceleration += num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::GeneratedNoiseSamples(size_t num_samples) {
|
void StatisticsCalculator::GeneratedNoiseSamples(size_t num_samples) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
lifetime_stats_.generated_noise_samples += num_samples;
|
lifetime_stats_.generated_noise_samples += num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,6 +282,9 @@ void StatisticsCalculator::SecondaryPacketsReceived(size_t num_packets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) {
|
void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) {
|
||||||
|
if (!decoded_output_played_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const int time_step_ms =
|
const int time_step_ms =
|
||||||
rtc::CheckedDivExact(static_cast<int>(1000 * num_samples), fs_hz);
|
rtc::CheckedDivExact(static_cast<int>(1000 * num_samples), fs_hz);
|
||||||
delayed_packet_outage_counter_.AdvanceClock(time_step_ms);
|
delayed_packet_outage_counter_.AdvanceClock(time_step_ms);
|
||||||
@ -268,10 +298,14 @@ void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) {
|
|||||||
lifetime_stats_.total_samples_received += num_samples;
|
lifetime_stats_.total_samples_received += num_samples;
|
||||||
expand_uma_logger_.UpdateSampleCounter(lifetime_stats_.concealed_samples,
|
expand_uma_logger_.UpdateSampleCounter(lifetime_stats_.concealed_samples,
|
||||||
fs_hz);
|
fs_hz);
|
||||||
speech_expand_uma_logger_.UpdateSampleCounter(
|
uint64_t speech_concealed_samples = 0;
|
||||||
lifetime_stats_.concealed_samples -
|
if (lifetime_stats_.concealed_samples >
|
||||||
lifetime_stats_.silent_concealed_samples,
|
lifetime_stats_.silent_concealed_samples) {
|
||||||
fs_hz);
|
speech_concealed_samples = lifetime_stats_.concealed_samples -
|
||||||
|
lifetime_stats_.silent_concealed_samples;
|
||||||
|
}
|
||||||
|
speech_expand_uma_logger_.UpdateSampleCounter(speech_concealed_samples,
|
||||||
|
fs_hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::JitterBufferDelay(size_t num_samples,
|
void StatisticsCalculator::JitterBufferDelay(size_t num_samples,
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace webrtc {
|
|||||||
TEST(LifetimeStatistics, TotalSamplesReceived) {
|
TEST(LifetimeStatistics, TotalSamplesReceived) {
|
||||||
TickTimer timer;
|
TickTimer timer;
|
||||||
StatisticsCalculator stats(&timer);
|
StatisticsCalculator stats(&timer);
|
||||||
|
stats.DecodedOutputPlayed();
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
stats.IncreaseCounter(480, 48000); // 10 ms at 48 kHz.
|
stats.IncreaseCounter(480, 48000); // 10 ms at 48 kHz.
|
||||||
}
|
}
|
||||||
@ -26,6 +27,7 @@ TEST(LifetimeStatistics, TotalSamplesReceived) {
|
|||||||
TEST(LifetimeStatistics, SamplesConcealed) {
|
TEST(LifetimeStatistics, SamplesConcealed) {
|
||||||
TickTimer timer;
|
TickTimer timer;
|
||||||
StatisticsCalculator stats(&timer);
|
StatisticsCalculator stats(&timer);
|
||||||
|
stats.DecodedOutputPlayed();
|
||||||
stats.ExpandedVoiceSamples(100, false);
|
stats.ExpandedVoiceSamples(100, false);
|
||||||
stats.ExpandedNoiseSamples(17, false);
|
stats.ExpandedNoiseSamples(17, false);
|
||||||
EXPECT_EQ(100u + 17u, stats.GetLifetimeStatistics().concealed_samples);
|
EXPECT_EQ(100u + 17u, stats.GetLifetimeStatistics().concealed_samples);
|
||||||
@ -38,6 +40,7 @@ TEST(LifetimeStatistics, SamplesConcealed) {
|
|||||||
TEST(LifetimeStatistics, SamplesConcealedCorrection) {
|
TEST(LifetimeStatistics, SamplesConcealedCorrection) {
|
||||||
TickTimer timer;
|
TickTimer timer;
|
||||||
StatisticsCalculator stats(&timer);
|
StatisticsCalculator stats(&timer);
|
||||||
|
stats.DecodedOutputPlayed();
|
||||||
stats.ExpandedVoiceSamples(100, false);
|
stats.ExpandedVoiceSamples(100, false);
|
||||||
EXPECT_EQ(100u, stats.GetLifetimeStatistics().concealed_samples);
|
EXPECT_EQ(100u, stats.GetLifetimeStatistics().concealed_samples);
|
||||||
stats.ExpandedVoiceSamplesCorrection(-10);
|
stats.ExpandedVoiceSamplesCorrection(-10);
|
||||||
@ -60,6 +63,7 @@ TEST(LifetimeStatistics, SamplesConcealedCorrection) {
|
|||||||
TEST(LifetimeStatistics, NoUpdateOnTimeStretch) {
|
TEST(LifetimeStatistics, NoUpdateOnTimeStretch) {
|
||||||
TickTimer timer;
|
TickTimer timer;
|
||||||
StatisticsCalculator stats(&timer);
|
StatisticsCalculator stats(&timer);
|
||||||
|
stats.DecodedOutputPlayed();
|
||||||
stats.ExpandedVoiceSamples(100, false);
|
stats.ExpandedVoiceSamples(100, false);
|
||||||
stats.AcceleratedSamples(4711);
|
stats.AcceleratedSamples(4711);
|
||||||
stats.PreemptiveExpandedSamples(17);
|
stats.PreemptiveExpandedSamples(17);
|
||||||
@ -70,6 +74,7 @@ TEST(LifetimeStatistics, NoUpdateOnTimeStretch) {
|
|||||||
TEST(StatisticsCalculator, ExpandedSamplesCorrection) {
|
TEST(StatisticsCalculator, ExpandedSamplesCorrection) {
|
||||||
TickTimer timer;
|
TickTimer timer;
|
||||||
StatisticsCalculator stats(&timer);
|
StatisticsCalculator stats(&timer);
|
||||||
|
stats.DecodedOutputPlayed();
|
||||||
NetEqNetworkStatistics stats_output;
|
NetEqNetworkStatistics stats_output;
|
||||||
constexpr int kSampleRateHz = 48000;
|
constexpr int kSampleRateHz = 48000;
|
||||||
constexpr int k10MsSamples = kSampleRateHz / 100;
|
constexpr int k10MsSamples = kSampleRateHz / 100;
|
||||||
@ -243,4 +248,19 @@ TEST(StatisticsCalculator, JitterBufferDelay) {
|
|||||||
EXPECT_EQ(lts.jitter_buffer_emitted_count, 960ul);
|
EXPECT_EQ(lts.jitter_buffer_emitted_count, 960ul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(StatisticsCalculator, CountStatsAfterFirstDecodedPacket) {
|
||||||
|
TickTimer timer;
|
||||||
|
StatisticsCalculator stats(&timer);
|
||||||
|
stats.IncreaseCounter(/*num_samples=*/480, /*fs_hz=*/48000);
|
||||||
|
stats.ExpandedVoiceSamples(/*num_samples=*/480,
|
||||||
|
/*is_new_concealment_event=*/true);
|
||||||
|
NetEqLifetimeStatistics lts = stats.GetLifetimeStatistics();
|
||||||
|
EXPECT_EQ(lts.total_samples_received, 0u);
|
||||||
|
EXPECT_EQ(lts.concealed_samples, 0u);
|
||||||
|
stats.DecodedOutputPlayed();
|
||||||
|
stats.IncreaseCounter(/*num_samples=*/480, /*fs_hz=*/48000);
|
||||||
|
lts = stats.GetLifetimeStatistics();
|
||||||
|
EXPECT_EQ(lts.total_samples_received, 480u);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user