You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			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
 |