From 3ef3bfc2aafa707985c9e9dcd4cfb6ccbc525628 Mon Sep 17 00:00:00 2001 From: Henrik Lundin Date: Tue, 10 Apr 2018 15:10:26 +0200 Subject: [PATCH] Add new histograms WebRTC.Audio.(Speech)ExpandRatePercent These two new histograms relate to the packet-loss concealment that happens when audio packets are lost or late for decoding, and the NetEq must resort to extrapolating audio from the previously decoded data. Bug: webrtc:9126 Change-Id: I99cc97e653169fb742da0092653ab99fd10e5d7b Reviewed-on: https://webrtc-review.googlesource.com/67861 Commit-Queue: Henrik Lundin Reviewed-by: Ivo Creusen Cr-Commit-Position: refs/heads/master@{#22812} --- modules/audio_coding/BUILD.gn | 2 + .../audio_coding/neteq/expand_uma_logger.cc | 69 +++++++++++++++++++ .../audio_coding/neteq/expand_uma_logger.h | 54 +++++++++++++++ modules/audio_coding/neteq/neteq_impl.cc | 13 +++- modules/audio_coding/neteq/neteq_impl.h | 3 + 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 modules/audio_coding/neteq/expand_uma_logger.cc create mode 100644 modules/audio_coding/neteq/expand_uma_logger.h diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index efa43ea01a..f6c6920f90 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -1039,6 +1039,8 @@ rtc_static_library("neteq") { "neteq/dtmf_tone_generator.h", "neteq/expand.cc", "neteq/expand.h", + "neteq/expand_uma_logger.cc", + "neteq/expand_uma_logger.h", "neteq/include/neteq.h", "neteq/merge.cc", "neteq/merge.h", diff --git a/modules/audio_coding/neteq/expand_uma_logger.cc b/modules/audio_coding/neteq/expand_uma_logger.cc new file mode 100644 index 0000000000..c656eede6a --- /dev/null +++ b/modules/audio_coding/neteq/expand_uma_logger.cc @@ -0,0 +1,69 @@ +/* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/audio_coding/neteq/expand_uma_logger.h" +#include "rtc_base/checks.h" +#include "system_wrappers/include/metrics.h" + +namespace webrtc { +namespace { +std::unique_ptr GetNewCountdown( + const TickTimer& tick_timer, + int logging_period_s) { + return tick_timer.GetNewCountdown((logging_period_s * 1000) / + tick_timer.ms_per_tick()); +} +} // namespace + +ExpandUmaLogger::ExpandUmaLogger(std::string uma_name, + int logging_period_s, + const TickTimer* tick_timer) + : uma_name_(uma_name), + logging_period_s_(logging_period_s), + tick_timer_(*tick_timer), + timer_(GetNewCountdown(tick_timer_, logging_period_s_)) { + RTC_DCHECK(tick_timer); + RTC_DCHECK_GT(logging_period_s_, 0); +} + +ExpandUmaLogger::~ExpandUmaLogger() = default; + +void ExpandUmaLogger::UpdateSampleCounter(uint64_t samples, + int sample_rate_hz) { + if ((last_logged_value_ && *last_logged_value_ > samples) || + sample_rate_hz_ != sample_rate_hz) { + // Sanity checks. The incremental counter moved backwards, or sample rate + // changed. + last_logged_value_.reset(); + } + last_value_ = samples; + sample_rate_hz_ = sample_rate_hz; + if (!last_logged_value_) { + last_logged_value_ = rtc::Optional(samples); + } + + if (!timer_->Finished()) { + // Not yet time to log. + return; + } + + RTC_DCHECK(last_logged_value_); + RTC_DCHECK_GE(last_value_, *last_logged_value_); + const uint64_t diff = last_value_ - *last_logged_value_; + last_logged_value_ = rtc::Optional(last_value_); + // Calculate rate in percent. + RTC_DCHECK_GT(sample_rate_hz, 0); + const int rate = (100 * diff) / (sample_rate_hz * logging_period_s_); + RTC_DCHECK_GE(rate, 0); + RTC_DCHECK_LE(rate, 100); + RTC_HISTOGRAM_PERCENTAGE_SPARSE(uma_name_, rate); + timer_ = GetNewCountdown(tick_timer_, logging_period_s_); +} + +} // namespace webrtc diff --git a/modules/audio_coding/neteq/expand_uma_logger.h b/modules/audio_coding/neteq/expand_uma_logger.h new file mode 100644 index 0000000000..70af39beb2 --- /dev/null +++ b/modules/audio_coding/neteq/expand_uma_logger.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MODULES_AUDIO_CODING_NETEQ_EXPAND_UMA_LOGGER_H_ +#define MODULES_AUDIO_CODING_NETEQ_EXPAND_UMA_LOGGER_H_ + +#include +#include + +#include "api/optional.h" +#include "modules/audio_coding/neteq/tick_timer.h" +#include "rtc_base/constructormagic.h" + +namespace webrtc { + +// This class is used to periodically log values to a UMA histogram. The caller +// is expected to update this class with an incremental sample counter which +// counts expand samples. At the end of each logging period, the class will +// calculate the fraction of samples that were expand samples during that period +// and report that in percent. The logging period must be strictly positive. +// Does not take ownership of tick_timer and the pointer must refer to a valid +// object that outlives the one constructed. +class ExpandUmaLogger { + public: + ExpandUmaLogger(std::string uma_name, + int logging_period_s, + const TickTimer* tick_timer); + + ~ExpandUmaLogger(); + + // In this call, value should be an incremental sample counter. The sample + // rate must be strictly positive. + void UpdateSampleCounter(uint64_t value, int sample_rate_hz); + + private: + const std::string uma_name_; + const int logging_period_s_; + const TickTimer& tick_timer_; + std::unique_ptr timer_; + rtc::Optional last_logged_value_; + uint64_t last_value_ = 0; + int sample_rate_hz_ = 0; + + RTC_DISALLOW_COPY_AND_ASSIGN(ExpandUmaLogger); +}; + +} // namespace webrtc +#endif // MODULES_AUDIO_CODING_NETEQ_EXPAND_UMA_LOGGER_H_ diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc index 4e780c3f2f..6ce6a12637 100644 --- a/modules/audio_coding/neteq/neteq_impl.cc +++ b/modules/audio_coding/neteq/neteq_impl.cc @@ -106,7 +106,13 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, playout_mode_(config.playout_mode), enable_fast_accelerate_(config.enable_fast_accelerate), nack_enabled_(false), - enable_muted_state_(config.enable_muted_state) { + enable_muted_state_(config.enable_muted_state), + expand_uma_logger_("WebRTC.Audio.ExpandRatePercent", + 10, // Report once every 10 s. + tick_timer_.get()), + speech_expand_uma_logger_("WebRTC.Audio.SpeechExpandRatePercent", + 10, // Report once every 10 s. + tick_timer_.get()) { RTC_LOG(LS_INFO) << "NetEq config: " << config.ToString(); int fs = config.sample_rate_hz; if (fs != 8000 && fs != 16000 && fs != 32000 && fs != 48000) { @@ -837,6 +843,11 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, bool* muted) { last_decoded_timestamps_.clear(); tick_timer_->Increment(); stats_.IncreaseCounter(output_size_samples_, fs_hz_); + const auto lifetime_stats = stats_.GetLifetimeStatistics(); + expand_uma_logger_.UpdateSampleCounter(lifetime_stats.concealed_samples, + fs_hz_); + speech_expand_uma_logger_.UpdateSampleCounter( + lifetime_stats.voice_concealed_samples, fs_hz_); // Check for muted state. if (enable_muted_state_ && expand_->Muted() && packet_buffer_->Empty()) { diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h index bdeb0206d6..3b7070f9f7 100644 --- a/modules/audio_coding/neteq/neteq_impl.h +++ b/modules/audio_coding/neteq/neteq_impl.h @@ -17,6 +17,7 @@ #include "api/optional.h" #include "modules/audio_coding/neteq/audio_multi_vector.h" #include "modules/audio_coding/neteq/defines.h" +#include "modules/audio_coding/neteq/expand_uma_logger.h" #include "modules/audio_coding/neteq/include/neteq.h" #include "modules/audio_coding/neteq/packet.h" // Declare PacketList. #include "modules/audio_coding/neteq/random_vector.h" @@ -440,6 +441,8 @@ class NetEqImpl : public webrtc::NetEq { std::unique_ptr generated_noise_stopwatch_ RTC_GUARDED_BY(crit_sect_); std::vector last_decoded_timestamps_ RTC_GUARDED_BY(crit_sect_); + ExpandUmaLogger expand_uma_logger_ RTC_GUARDED_BY(crit_sect_); + ExpandUmaLogger speech_expand_uma_logger_ RTC_GUARDED_BY(crit_sect_); private: RTC_DISALLOW_COPY_AND_ASSIGN(NetEqImpl);