From bf4a221187dc4a6c8168ab1090a72555164b0c41 Mon Sep 17 00:00:00 2001 From: Ivo Creusen Date: Wed, 24 Apr 2019 14:06:24 +0200 Subject: [PATCH] Implement newly standardized stats Several new audio stats have been added to the standard, and this CL implements those inside of NetEq. Exposing these metrics on the API will be done in a follow-up CL. Bug: webrtc:10442, webrtc:10443, webrtc:10444 Change-Id: Ia7aa5a6d76685fc0fdb446172a0a3fd0310f6cb7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133887 Reviewed-by: Minyue Li Commit-Queue: Ivo Creusen Cr-Commit-Position: refs/heads/master@{#27755} --- modules/audio_coding/neteq/include/neteq.h | 6 ++++- modules/audio_coding/neteq/neteq_impl.cc | 10 +++++++-- .../neteq/statistics_calculator.cc | 22 +++++++++++++------ .../neteq/statistics_calculator.h | 9 +++++--- .../neteq/tools/neteq_stats_getter.cc | 14 +++++------- .../audio_coding/neteq/tools/neteq_test.cc | 6 +++-- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/modules/audio_coding/neteq/include/neteq.h b/modules/audio_coding/neteq/include/neteq.h index 549d355ae0..8721663360 100644 --- a/modules/audio_coding/neteq/include/neteq.h +++ b/modules/audio_coding/neteq/include/neteq.h @@ -71,8 +71,12 @@ struct NetEqLifetimeStatistics { uint64_t concealment_events = 0; uint64_t jitter_buffer_delay_ms = 0; uint64_t jitter_buffer_emitted_count = 0; + uint64_t inserted_samples_for_deceleration = 0; + uint64_t removed_samples_for_acceleration = 0; + uint64_t silent_concealed_samples = 0; + uint64_t fec_packets_received = 0; + uint64_t fec_packets_discarded = 0; // Below stats are not part of the spec. - uint64_t voice_concealed_samples = 0; uint64_t delayed_packet_outage_samples = 0; // This is sum of relative packet arrival delays of received packets so far. // Since end-to-end delay of a packet is difficult to measure and is not diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc index b7f5579c9b..fcb09bebef 100644 --- a/modules/audio_coding/neteq/neteq_impl.cc +++ b/modules/audio_coding/neteq/neteq_impl.cc @@ -654,9 +654,13 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, } // Calculate the number of primary (non-FEC/RED) packets. - const int number_of_primary_packets = std::count_if( + const size_t number_of_primary_packets = std::count_if( parsed_packet_list.begin(), parsed_packet_list.end(), [](const Packet& in) { return in.priority.codec_level == 0; }); + if (number_of_primary_packets < parsed_packet_list.size()) { + stats_->SecondaryPacketsReceived(parsed_packet_list.size() - + number_of_primary_packets); + } // Insert packets in buffer. const int ret = packet_buffer_->InsertPacketList( @@ -763,7 +767,9 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, expand_uma_logger_.UpdateSampleCounter(lifetime_stats.concealed_samples, fs_hz_); speech_expand_uma_logger_.UpdateSampleCounter( - lifetime_stats.voice_concealed_samples, fs_hz_); + lifetime_stats.concealed_samples - + lifetime_stats.silent_concealed_samples, + fs_hz_); // Check for muted state. if (enable_muted_state_ && expand_->Muted() && packet_buffer_->Empty()) { diff --git a/modules/audio_coding/neteq/statistics_calculator.cc b/modules/audio_coding/neteq/statistics_calculator.cc index a0e9bca4b1..d0f37bc3fe 100644 --- a/modules/audio_coding/neteq/statistics_calculator.cc +++ b/modules/audio_coding/neteq/statistics_calculator.cc @@ -182,8 +182,8 @@ void StatisticsCalculator::ConcealedSamplesCorrection(int num_samples, // Store negative correction to subtract from future positive additions. // See also the function comment in the header file. concealed_samples_correction_ -= num_samples; - if (is_voice) { - voice_concealed_samples_correction_ -= num_samples; + if (!is_voice) { + silent_concealed_samples_correction_ -= num_samples; } return; } @@ -193,22 +193,25 @@ void StatisticsCalculator::ConcealedSamplesCorrection(int num_samples, concealed_samples_correction_ -= canceled_out; lifetime_stats_.concealed_samples += num_samples - canceled_out; - if (is_voice) { - const size_t voice_canceled_out = std::min( - static_cast(num_samples), voice_concealed_samples_correction_); - voice_concealed_samples_correction_ -= voice_canceled_out; - lifetime_stats_.voice_concealed_samples += num_samples - voice_canceled_out; + if (!is_voice) { + const size_t silent_canceled_out = std::min( + static_cast(num_samples), silent_concealed_samples_correction_); + silent_concealed_samples_correction_ -= silent_canceled_out; + lifetime_stats_.silent_concealed_samples += + num_samples - silent_canceled_out; } } void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) { preemptive_samples_ += num_samples; operations_and_state_.preemptive_samples += num_samples; + lifetime_stats_.inserted_samples_for_deceleration += num_samples; } void StatisticsCalculator::AcceleratedSamples(size_t num_samples) { accelerate_samples_ += num_samples; operations_and_state_.accelerate_samples += num_samples; + lifetime_stats_.removed_samples_for_acceleration += num_samples; } void StatisticsCalculator::AddZeros(size_t num_samples) { @@ -221,6 +224,11 @@ void StatisticsCalculator::PacketsDiscarded(size_t num_packets) { void StatisticsCalculator::SecondaryPacketsDiscarded(size_t num_packets) { discarded_secondary_packets_ += num_packets; + lifetime_stats_.fec_packets_discarded += num_packets; +} + +void StatisticsCalculator::SecondaryPacketsReceived(size_t num_packets) { + lifetime_stats_.fec_packets_received += num_packets; } void StatisticsCalculator::LostSamples(size_t num_samples) { diff --git a/modules/audio_coding/neteq/statistics_calculator.h b/modules/audio_coding/neteq/statistics_calculator.h index cb92f37f8f..4482812a75 100644 --- a/modules/audio_coding/neteq/statistics_calculator.h +++ b/modules/audio_coding/neteq/statistics_calculator.h @@ -63,8 +63,11 @@ class StatisticsCalculator { // Reports that |num_packets| packets were discarded. virtual void PacketsDiscarded(size_t num_packets); - // Reports that |num_packets| packets samples were discarded. - virtual void SecondaryPacketsDiscarded(size_t num_samples); + // Reports that |num_packets| secondary (FEC) packets were discarded. + virtual void SecondaryPacketsDiscarded(size_t num_packets); + + // Reports that |num_packets| secondary (FEC) packets were received. + virtual void SecondaryPacketsReceived(size_t num_packets); // Reports that |num_samples| were lost. void LostSamples(size_t num_samples); @@ -191,7 +194,7 @@ class StatisticsCalculator { NetEqLifetimeStatistics lifetime_stats_; NetEqOperationsAndState operations_and_state_; size_t concealed_samples_correction_ = 0; - size_t voice_concealed_samples_correction_ = 0; + size_t silent_concealed_samples_correction_ = 0; size_t preemptive_samples_; size_t accelerate_samples_; size_t added_zero_samples_; diff --git a/modules/audio_coding/neteq/tools/neteq_stats_getter.cc b/modules/audio_coding/neteq/tools/neteq_stats_getter.cc index 291fc24890..91dd47c37d 100644 --- a/modules/audio_coding/neteq/tools/neteq_stats_getter.cc +++ b/modules/audio_coding/neteq/tools/neteq_stats_getter.cc @@ -57,16 +57,16 @@ void NetEqStatsGetter::AfterGetAudio(int64_t time_now_ms, last_stats_query_time_ms_ = time_now_ms; } + const auto voice_concealed_samples = + lifetime_stat.concealed_samples - lifetime_stat.silent_concealed_samples; if (current_concealment_event_ != lifetime_stat.concealment_events && - voice_concealed_samples_until_last_event_ < - lifetime_stat.voice_concealed_samples) { + voice_concealed_samples_until_last_event_ < voice_concealed_samples) { if (last_event_end_time_ms_ > 0) { // Do not account for the first event to avoid start of the call // skewing. ConcealmentEvent concealment_event; uint64_t last_event_voice_concealed_samples = - lifetime_stat.voice_concealed_samples - - voice_concealed_samples_until_last_event_; + voice_concealed_samples - voice_concealed_samples_until_last_event_; RTC_CHECK_GT(last_event_voice_concealed_samples, 0); concealment_event.duration_ms = last_event_voice_concealed_samples / (audio_frame.sample_rate_hz_ / 1000); @@ -74,12 +74,10 @@ void NetEqStatsGetter::AfterGetAudio(int64_t time_now_ms, concealment_event.time_from_previous_event_end_ms = time_now_ms - last_event_end_time_ms_; concealment_events_.emplace_back(concealment_event); - voice_concealed_samples_until_last_event_ = - lifetime_stat.voice_concealed_samples; + voice_concealed_samples_until_last_event_ = voice_concealed_samples; } last_event_end_time_ms_ = time_now_ms; - voice_concealed_samples_until_last_event_ = - lifetime_stat.voice_concealed_samples; + voice_concealed_samples_until_last_event_ = voice_concealed_samples; current_concealment_event_ = lifetime_stat.concealment_events; } diff --git a/modules/audio_coding/neteq/tools/neteq_test.cc b/modules/audio_coding/neteq/tools/neteq_test.cc index 97e71bf21f..8a6a94a52d 100644 --- a/modules/audio_coding/neteq/tools/neteq_test.cc +++ b/modules/audio_coding/neteq/tools/neteq_test.cc @@ -224,8 +224,10 @@ NetEqTest::SimulationStepResult NetEqTest::RunToNextGetAudio() { (out_frame.speech_type_ == AudioFrame::SpeechType::kPLCCNG); const bool cng = out_frame.speech_type_ == AudioFrame::SpeechType::kCNG; const bool voice_concealed = - lifetime_stats.voice_concealed_samples > - prev_lifetime_stats_.voice_concealed_samples; + (lifetime_stats.concealed_samples - + lifetime_stats.silent_concealed_samples) > + (prev_lifetime_stats_.concealed_samples - + prev_lifetime_stats_.silent_concealed_samples); *text_log_ << "GetAudio - wallclock: " << std::setw(5) << time_now_ms << ", delta wc: " << std::setw(4) << (input_->NextEventTime().value_or(time_now_ms) -