NetEq: Simplify the dependencies of GetNetworkStatistics
Adds a new method PopulateDelayManagerStats which takes care of the fields that needed information from the DelayManager. Also adds a new test for StatisticsCalculator made practically feasible by the refactoring. Bug: webrtc:7554 Change-Id: Iff5cb5e209c276bd2784f2ccf73be8f619b1d955 Reviewed-on: https://webrtc-review.googlesource.com/3181 Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org> Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19957}
This commit is contained in:
committed by
Commit Bot
parent
13b668222a
commit
dccfc405a6
@ -374,9 +374,11 @@ int NetEqImpl::NetworkStatistics(NetEqNetworkStatistics* stats) {
|
||||
sync_buffer_->FutureLength();
|
||||
assert(delay_manager_.get());
|
||||
assert(decision_logic_.get());
|
||||
const int ms_per_packet = rtc::dchecked_cast<int>(
|
||||
decision_logic_->packet_length_samples() / (fs_hz_ / 1000));
|
||||
stats_.PopulateDelayManagerStats(ms_per_packet, *delay_manager_.get(), stats);
|
||||
stats_.GetNetworkStatistics(fs_hz_, total_samples_in_buffers,
|
||||
decoder_frame_length_, *delay_manager_.get(),
|
||||
*decision_logic_.get(), stats);
|
||||
decoder_frame_length_, stats);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include <string.h> // memset
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/audio_coding/neteq/decision_logic.h"
|
||||
#include "modules/audio_coding/neteq/delay_manager.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/safe_conversions.h"
|
||||
@ -255,24 +254,13 @@ void StatisticsCalculator::GetNetworkStatistics(
|
||||
int fs_hz,
|
||||
size_t num_samples_in_buffers,
|
||||
size_t samples_per_packet,
|
||||
const DelayManager& delay_manager,
|
||||
const DecisionLogic& decision_logic,
|
||||
NetEqNetworkStatistics *stats) {
|
||||
if (fs_hz <= 0 || !stats) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
RTC_DCHECK_GT(fs_hz, 0);
|
||||
RTC_DCHECK(stats);
|
||||
|
||||
stats->added_zero_samples = added_zero_samples_;
|
||||
stats->current_buffer_size_ms =
|
||||
static_cast<uint16_t>(num_samples_in_buffers * 1000 / fs_hz);
|
||||
const int ms_per_packet = rtc::dchecked_cast<int>(
|
||||
decision_logic.packet_length_samples() / (fs_hz / 1000));
|
||||
stats->preferred_buffer_size_ms = (delay_manager.TargetLevel() >> 8) *
|
||||
ms_per_packet;
|
||||
stats->jitter_peaks_found = delay_manager.PeakFound();
|
||||
stats->clockdrift_ppm =
|
||||
rtc::saturated_cast<int32_t>(delay_manager.EstimatedClockDriftPpm());
|
||||
|
||||
stats->packet_loss_rate =
|
||||
CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_);
|
||||
@ -331,6 +319,18 @@ void StatisticsCalculator::GetNetworkStatistics(
|
||||
Reset();
|
||||
}
|
||||
|
||||
void StatisticsCalculator::PopulateDelayManagerStats(
|
||||
int ms_per_packet,
|
||||
const DelayManager& delay_manager,
|
||||
NetEqNetworkStatistics* stats) {
|
||||
RTC_DCHECK(stats);
|
||||
stats->preferred_buffer_size_ms =
|
||||
(delay_manager.TargetLevel() >> 8) * ms_per_packet;
|
||||
stats->jitter_peaks_found = delay_manager.PeakFound();
|
||||
stats->clockdrift_ppm =
|
||||
rtc::saturated_cast<int32_t>(delay_manager.EstimatedClockDriftPpm());
|
||||
}
|
||||
|
||||
NetEqLifetimeStatistics StatisticsCalculator::GetLifetimeStatistics() const {
|
||||
return lifetime_stats_;
|
||||
}
|
||||
|
||||
@ -20,8 +20,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Forward declarations.
|
||||
class DecisionLogic;
|
||||
class DelayManager;
|
||||
|
||||
// This class handles various network statistics in NetEq.
|
||||
@ -91,14 +89,22 @@ class StatisticsCalculator {
|
||||
// Returns the current network statistics in |stats|. The current sample rate
|
||||
// is |fs_hz|, the total number of samples in packet buffer and sync buffer
|
||||
// yet to play out is |num_samples_in_buffers|, and the number of samples per
|
||||
// packet is |samples_per_packet|.
|
||||
// packet is |samples_per_packet|. The method does not populate
|
||||
// |preferred_buffer_size_ms|, |jitter_peaks_found| or |clockdrift_ppm|; use
|
||||
// the PopulateDelayManagerStats method for those.
|
||||
void GetNetworkStatistics(int fs_hz,
|
||||
size_t num_samples_in_buffers,
|
||||
size_t samples_per_packet,
|
||||
const DelayManager& delay_manager,
|
||||
const DecisionLogic& decision_logic,
|
||||
NetEqNetworkStatistics *stats);
|
||||
|
||||
// Populates |preferred_buffer_size_ms|, |jitter_peaks_found| and
|
||||
// |clockdrift_ppm| in |stats|. This is a convenience method, and does not
|
||||
// strictly have to be in the StatisticsCalculator class, but it makes sense
|
||||
// since all other stats fields are populated by that class.
|
||||
static void PopulateDelayManagerStats(int ms_per_packet,
|
||||
const DelayManager& delay_manager,
|
||||
NetEqNetworkStatistics* stats);
|
||||
|
||||
// Returns a copy of this class's lifetime statistics. These statistics are
|
||||
// never reset.
|
||||
NetEqLifetimeStatistics GetLifetimeStatistics() const;
|
||||
|
||||
@ -63,4 +63,45 @@ TEST(LifetimeStatistics, NoUpdateOnTimeStretch) {
|
||||
EXPECT_EQ(200u, stats.GetLifetimeStatistics().concealed_samples);
|
||||
}
|
||||
|
||||
TEST(StatisticsCalculator, ExpandedSamplesCorrection) {
|
||||
StatisticsCalculator stats;
|
||||
NetEqNetworkStatistics stats_output;
|
||||
constexpr int kSampleRateHz = 48000;
|
||||
constexpr int k10MsSamples = kSampleRateHz / 100;
|
||||
constexpr int kPacketSizeMs = 20;
|
||||
constexpr size_t kSamplesPerPacket = kPacketSizeMs * kSampleRateHz / 1000;
|
||||
// Assume 2 packets in the buffer.
|
||||
constexpr size_t kNumSamplesInBuffer = 2 * kSamplesPerPacket;
|
||||
|
||||
// Advance time by 10 ms.
|
||||
stats.IncreaseCounter(k10MsSamples, kSampleRateHz);
|
||||
|
||||
stats.GetNetworkStatistics(kSampleRateHz, kNumSamplesInBuffer,
|
||||
kSamplesPerPacket, &stats_output);
|
||||
|
||||
EXPECT_EQ(0u, stats_output.expand_rate);
|
||||
EXPECT_EQ(0u, stats_output.speech_expand_rate);
|
||||
|
||||
// Correct with a negative value.
|
||||
stats.ExpandedVoiceSamplesCorrection(-100);
|
||||
stats.ExpandedNoiseSamplesCorrection(-100);
|
||||
stats.IncreaseCounter(k10MsSamples, kSampleRateHz);
|
||||
stats.GetNetworkStatistics(kSampleRateHz, kNumSamplesInBuffer,
|
||||
kSamplesPerPacket, &stats_output);
|
||||
// Expect no change, since negative values are disallowed.
|
||||
EXPECT_EQ(0u, stats_output.expand_rate);
|
||||
EXPECT_EQ(0u, stats_output.speech_expand_rate);
|
||||
|
||||
// Correct with a positive value.
|
||||
stats.ExpandedVoiceSamplesCorrection(50);
|
||||
stats.ExpandedNoiseSamplesCorrection(200);
|
||||
stats.IncreaseCounter(k10MsSamples, kSampleRateHz);
|
||||
stats.GetNetworkStatistics(kSampleRateHz, kNumSamplesInBuffer,
|
||||
kSamplesPerPacket, &stats_output);
|
||||
// Calculate expected rates in Q14. Expand rate is noise + voice, while
|
||||
// speech expand rate is only voice.
|
||||
EXPECT_EQ(((50u + 200u) << 14) / k10MsSamples, stats_output.expand_rate);
|
||||
EXPECT_EQ((50u << 14) / k10MsSamples, stats_output.speech_expand_rate);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Reference in New Issue
Block a user