mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-01 05:55:18 +00:00
171 lines
5.2 KiB
C++
171 lines
5.2 KiB
C++
|
/*
|
||
|
* Copyright (c) 2013 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 "webrtc/modules/audio_coding/neteq/statistics_calculator.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <string.h> // memset
|
||
|
|
||
|
#include "webrtc/modules/audio_coding/neteq/decision_logic.h"
|
||
|
#include "webrtc/modules/audio_coding/neteq/delay_manager.h"
|
||
|
|
||
|
namespace webrtc {
|
||
|
|
||
|
StatisticsCalculator::StatisticsCalculator()
|
||
|
: preemptive_samples_(0),
|
||
|
accelerate_samples_(0),
|
||
|
added_zero_samples_(0),
|
||
|
expanded_voice_samples_(0),
|
||
|
expanded_noise_samples_(0),
|
||
|
discarded_packets_(0),
|
||
|
lost_timestamps_(0),
|
||
|
last_report_timestamp_(0),
|
||
|
len_waiting_times_(0),
|
||
|
next_waiting_time_index_(0) {
|
||
|
memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::Reset() {
|
||
|
preemptive_samples_ = 0;
|
||
|
accelerate_samples_ = 0;
|
||
|
added_zero_samples_ = 0;
|
||
|
expanded_voice_samples_ = 0;
|
||
|
expanded_noise_samples_ = 0;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::ResetMcu() {
|
||
|
discarded_packets_ = 0;
|
||
|
lost_timestamps_ = 0;
|
||
|
last_report_timestamp_ = 0;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::ResetWaitingTimeStatistics() {
|
||
|
memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
|
||
|
len_waiting_times_ = 0;
|
||
|
next_waiting_time_index_ = 0;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) {
|
||
|
expanded_voice_samples_ += num_samples;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) {
|
||
|
expanded_noise_samples_ += num_samples;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) {
|
||
|
preemptive_samples_ += num_samples;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::AcceleratedSamples(int num_samples) {
|
||
|
accelerate_samples_ += num_samples;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::AddZeros(int num_samples) {
|
||
|
added_zero_samples_ += num_samples;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::PacketsDiscarded(int num_packets) {
|
||
|
discarded_packets_ += num_packets;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::LostSamples(int num_samples) {
|
||
|
lost_timestamps_ += num_samples;
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::IncreaseCounter(int num_samples, int fs_hz) {
|
||
|
last_report_timestamp_ += num_samples;
|
||
|
if (last_report_timestamp_ >
|
||
|
static_cast<uint32_t>(fs_hz * kMaxReportPeriod)) {
|
||
|
lost_timestamps_ = 0;
|
||
|
last_report_timestamp_ = 0;
|
||
|
discarded_packets_ = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) {
|
||
|
assert(next_waiting_time_index_ < kLenWaitingTimes);
|
||
|
waiting_times_[next_waiting_time_index_] = waiting_time_ms;
|
||
|
next_waiting_time_index_++;
|
||
|
if (next_waiting_time_index_ >= kLenWaitingTimes) {
|
||
|
next_waiting_time_index_ = 0;
|
||
|
}
|
||
|
if (len_waiting_times_ < kLenWaitingTimes) {
|
||
|
len_waiting_times_++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::GetNetworkStatistics(
|
||
|
int fs_hz,
|
||
|
int num_samples_in_buffers,
|
||
|
int samples_per_packet,
|
||
|
const DelayManager& delay_manager,
|
||
|
const DecisionLogic& decision_logic,
|
||
|
NetEqNetworkStatistics *stats) {
|
||
|
if (fs_hz <= 0 || !stats) {
|
||
|
assert(false);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
stats->added_zero_samples = added_zero_samples_;
|
||
|
stats->current_buffer_size_ms = num_samples_in_buffers * 1000 / fs_hz;
|
||
|
const int ms_per_packet = 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 = delay_manager.AverageIAT();
|
||
|
|
||
|
stats->packet_loss_rate = CalculateQ14Ratio(lost_timestamps_,
|
||
|
last_report_timestamp_);
|
||
|
|
||
|
const unsigned discarded_samples = discarded_packets_ * samples_per_packet;
|
||
|
stats->packet_discard_rate = CalculateQ14Ratio(discarded_samples,
|
||
|
last_report_timestamp_);
|
||
|
|
||
|
stats->accelerate_rate = CalculateQ14Ratio(accelerate_samples_,
|
||
|
last_report_timestamp_);
|
||
|
|
||
|
stats->preemptive_rate = CalculateQ14Ratio(preemptive_samples_,
|
||
|
last_report_timestamp_);
|
||
|
|
||
|
stats->expand_rate = CalculateQ14Ratio(expanded_voice_samples_ +
|
||
|
expanded_noise_samples_,
|
||
|
last_report_timestamp_);
|
||
|
|
||
|
// Reset counters.
|
||
|
ResetMcu();
|
||
|
Reset();
|
||
|
}
|
||
|
|
||
|
void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) {
|
||
|
if (!waiting_times) {
|
||
|
return;
|
||
|
}
|
||
|
waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_);
|
||
|
ResetWaitingTimeStatistics();
|
||
|
}
|
||
|
|
||
|
int StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator,
|
||
|
uint32_t denominator) {
|
||
|
if (numerator == 0) {
|
||
|
return 0;
|
||
|
} else if (numerator < denominator) {
|
||
|
// Ratio must be smaller than 1 in Q14.
|
||
|
assert((numerator << 14) / denominator < (1 << 14));
|
||
|
return (numerator << 14) / denominator;
|
||
|
} else {
|
||
|
// Will not produce a ratio larger than 1, since this is probably an error.
|
||
|
return 1 << 14;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // namespace webrtc
|