Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / statistics_calculator.cc
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include "webrtc/modules/audio_coding/neteq/statistics_calculator.h"
12
13 #include <assert.h>
14 #include <string.h>  // memset
15
16 #include "webrtc/modules/audio_coding/neteq/decision_logic.h"
17 #include "webrtc/modules/audio_coding/neteq/delay_manager.h"
18
19 namespace webrtc {
20
21 StatisticsCalculator::StatisticsCalculator()
22     : preemptive_samples_(0),
23       accelerate_samples_(0),
24       added_zero_samples_(0),
25       expanded_voice_samples_(0),
26       expanded_noise_samples_(0),
27       discarded_packets_(0),
28       lost_timestamps_(0),
29       last_report_timestamp_(0),
30       len_waiting_times_(0),
31       next_waiting_time_index_(0) {
32   memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
33 }
34
35 void StatisticsCalculator::Reset() {
36   preemptive_samples_ = 0;
37   accelerate_samples_ = 0;
38   added_zero_samples_ = 0;
39   expanded_voice_samples_ = 0;
40   expanded_noise_samples_ = 0;
41 }
42
43 void StatisticsCalculator::ResetMcu() {
44   discarded_packets_ = 0;
45   lost_timestamps_ = 0;
46   last_report_timestamp_ = 0;
47 }
48
49 void StatisticsCalculator::ResetWaitingTimeStatistics() {
50   memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
51   len_waiting_times_ = 0;
52   next_waiting_time_index_ = 0;
53 }
54
55 void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) {
56   expanded_voice_samples_ += num_samples;
57 }
58
59 void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) {
60   expanded_noise_samples_ += num_samples;
61 }
62
63 void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) {
64   preemptive_samples_ += num_samples;
65 }
66
67 void StatisticsCalculator::AcceleratedSamples(int num_samples) {
68   accelerate_samples_ += num_samples;
69 }
70
71 void StatisticsCalculator::AddZeros(int num_samples) {
72   added_zero_samples_ += num_samples;
73 }
74
75 void StatisticsCalculator::PacketsDiscarded(int num_packets) {
76   discarded_packets_ += num_packets;
77 }
78
79 void StatisticsCalculator::LostSamples(int num_samples) {
80   lost_timestamps_ += num_samples;
81 }
82
83 void StatisticsCalculator::IncreaseCounter(int num_samples, int fs_hz) {
84   last_report_timestamp_ += num_samples;
85   if (last_report_timestamp_ >
86       static_cast<uint32_t>(fs_hz * kMaxReportPeriod)) {
87     lost_timestamps_ = 0;
88     last_report_timestamp_ = 0;
89     discarded_packets_ = 0;
90   }
91 }
92
93 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) {
94   assert(next_waiting_time_index_ < kLenWaitingTimes);
95   waiting_times_[next_waiting_time_index_] = waiting_time_ms;
96   next_waiting_time_index_++;
97   if (next_waiting_time_index_ >= kLenWaitingTimes) {
98     next_waiting_time_index_ = 0;
99   }
100   if (len_waiting_times_ < kLenWaitingTimes) {
101     len_waiting_times_++;
102   }
103 }
104
105 void StatisticsCalculator::GetNetworkStatistics(
106     int fs_hz,
107     int num_samples_in_buffers,
108     int samples_per_packet,
109     const DelayManager& delay_manager,
110     const DecisionLogic& decision_logic,
111     NetEqNetworkStatistics *stats) {
112   if (fs_hz <= 0 || !stats) {
113     assert(false);
114     return;
115   }
116
117   stats->added_zero_samples = added_zero_samples_;
118   stats->current_buffer_size_ms = num_samples_in_buffers * 1000 / fs_hz;
119   const int ms_per_packet = decision_logic.packet_length_samples() /
120       (fs_hz / 1000);
121   stats->preferred_buffer_size_ms = (delay_manager.TargetLevel() >> 8) *
122       ms_per_packet;
123   stats->jitter_peaks_found = delay_manager.PeakFound();
124   stats->clockdrift_ppm = delay_manager.AverageIAT();
125
126   stats->packet_loss_rate = CalculateQ14Ratio(lost_timestamps_,
127                                               last_report_timestamp_);
128
129   const unsigned discarded_samples = discarded_packets_ * samples_per_packet;
130   stats->packet_discard_rate = CalculateQ14Ratio(discarded_samples,
131                                                  last_report_timestamp_);
132
133   stats->accelerate_rate = CalculateQ14Ratio(accelerate_samples_,
134                                              last_report_timestamp_);
135
136   stats->preemptive_rate = CalculateQ14Ratio(preemptive_samples_,
137                                              last_report_timestamp_);
138
139   stats->expand_rate = CalculateQ14Ratio(expanded_voice_samples_ +
140                                          expanded_noise_samples_,
141                                          last_report_timestamp_);
142
143   // Reset counters.
144   ResetMcu();
145   Reset();
146 }
147
148 void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) {
149   if (!waiting_times) {
150     return;
151   }
152   waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_);
153   ResetWaitingTimeStatistics();
154 }
155
156 int StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator,
157                                             uint32_t denominator) {
158   if (numerator == 0) {
159     return 0;
160   } else if (numerator < denominator) {
161     // Ratio must be smaller than 1 in Q14.
162     assert((numerator << 14) / denominator < (1 << 14));
163     return (numerator << 14) / denominator;
164   } else {
165     // Will not produce a ratio larger than 1, since this is probably an error.
166     return 1 << 14;
167   }
168 }
169
170 }  // namespace webrtc