xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/statistics_calculator_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2017 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 "modules/audio_coding/neteq/statistics_calculator.h"
12 
13 #include "test/gtest.h"
14 
15 namespace webrtc {
16 
TEST(LifetimeStatistics,TotalSamplesReceived)17 TEST(LifetimeStatistics, TotalSamplesReceived) {
18   StatisticsCalculator stats;
19   for (int i = 0; i < 10; ++i) {
20     stats.IncreaseCounter(480, 48000);  // 10 ms at 48 kHz.
21   }
22   EXPECT_EQ(10 * 480u, stats.GetLifetimeStatistics().total_samples_received);
23 }
24 
TEST(LifetimeStatistics,SamplesConcealed)25 TEST(LifetimeStatistics, SamplesConcealed) {
26   StatisticsCalculator stats;
27   stats.ExpandedVoiceSamples(100, false);
28   stats.ExpandedNoiseSamples(17, false);
29   EXPECT_EQ(100u + 17u, stats.GetLifetimeStatistics().concealed_samples);
30 }
31 
32 // This test verifies that a negative correction of concealed_samples does not
33 // result in a decrease in the stats value (because stats-consuming applications
34 // would not expect the value to decrease). Instead, the correction should be
35 // made to future increments to the stat.
TEST(LifetimeStatistics,SamplesConcealedCorrection)36 TEST(LifetimeStatistics, SamplesConcealedCorrection) {
37   StatisticsCalculator stats;
38   stats.ExpandedVoiceSamples(100, false);
39   EXPECT_EQ(100u, stats.GetLifetimeStatistics().concealed_samples);
40   stats.ExpandedVoiceSamplesCorrection(-10);
41   // Do not subtract directly, but keep the correction for later.
42   EXPECT_EQ(100u, stats.GetLifetimeStatistics().concealed_samples);
43   stats.ExpandedVoiceSamplesCorrection(20);
44   // The total correction is 20 - 10.
45   EXPECT_EQ(110u, stats.GetLifetimeStatistics().concealed_samples);
46 
47   // Also test correction done to the next ExpandedVoiceSamples call.
48   stats.ExpandedVoiceSamplesCorrection(-17);
49   EXPECT_EQ(110u, stats.GetLifetimeStatistics().concealed_samples);
50   stats.ExpandedVoiceSamples(100, false);
51   EXPECT_EQ(110u + 100u - 17u, stats.GetLifetimeStatistics().concealed_samples);
52 }
53 
54 // This test verifies that neither "accelerate" nor "pre-emptive expand" reults
55 // in a modification to concealed_samples stats. Only PLC operations (i.e.,
56 // "expand" and "merge") should affect the stat.
TEST(LifetimeStatistics,NoUpdateOnTimeStretch)57 TEST(LifetimeStatistics, NoUpdateOnTimeStretch) {
58   StatisticsCalculator stats;
59   stats.ExpandedVoiceSamples(100, false);
60   stats.AcceleratedSamples(4711);
61   stats.PreemptiveExpandedSamples(17);
62   stats.ExpandedVoiceSamples(100, false);
63   EXPECT_EQ(200u, stats.GetLifetimeStatistics().concealed_samples);
64 }
65 
TEST(StatisticsCalculator,ExpandedSamplesCorrection)66 TEST(StatisticsCalculator, ExpandedSamplesCorrection) {
67   StatisticsCalculator stats;
68   NetEqNetworkStatistics stats_output;
69   constexpr int kSampleRateHz = 48000;
70   constexpr int k10MsSamples = kSampleRateHz / 100;
71   constexpr int kPacketSizeMs = 20;
72   constexpr size_t kSamplesPerPacket = kPacketSizeMs * kSampleRateHz / 1000;
73 
74   // Advance time by 10 ms.
75   stats.IncreaseCounter(k10MsSamples, kSampleRateHz);
76 
77   stats.GetNetworkStatistics(kSamplesPerPacket, &stats_output);
78 
79   EXPECT_EQ(0u, stats_output.expand_rate);
80   EXPECT_EQ(0u, stats_output.speech_expand_rate);
81 
82   // Correct with a negative value.
83   stats.ExpandedVoiceSamplesCorrection(-100);
84   stats.ExpandedNoiseSamplesCorrection(-100);
85   stats.IncreaseCounter(k10MsSamples, kSampleRateHz);
86   stats.GetNetworkStatistics(kSamplesPerPacket, &stats_output);
87   // Expect no change, since negative values are disallowed.
88   EXPECT_EQ(0u, stats_output.expand_rate);
89   EXPECT_EQ(0u, stats_output.speech_expand_rate);
90 
91   // Correct with a positive value.
92   stats.ExpandedVoiceSamplesCorrection(50);
93   stats.ExpandedNoiseSamplesCorrection(200);
94   stats.IncreaseCounter(k10MsSamples, kSampleRateHz);
95   stats.GetNetworkStatistics(kSamplesPerPacket, &stats_output);
96   // Calculate expected rates in Q14. Expand rate is noise + voice, while
97   // speech expand rate is only voice.
98   EXPECT_EQ(((50u + 200u) << 14) / k10MsSamples, stats_output.expand_rate);
99   EXPECT_EQ((50u << 14) / k10MsSamples, stats_output.speech_expand_rate);
100 }
101 
TEST(StatisticsCalculator,RelativePacketArrivalDelay)102 TEST(StatisticsCalculator, RelativePacketArrivalDelay) {
103   StatisticsCalculator stats;
104 
105   stats.RelativePacketArrivalDelay(50);
106   NetEqLifetimeStatistics stats_output = stats.GetLifetimeStatistics();
107   EXPECT_EQ(50u, stats_output.relative_packet_arrival_delay_ms);
108 
109   stats.RelativePacketArrivalDelay(20);
110   stats_output = stats.GetLifetimeStatistics();
111   EXPECT_EQ(70u, stats_output.relative_packet_arrival_delay_ms);
112 }
113 
TEST(StatisticsCalculator,ReceivedPacket)114 TEST(StatisticsCalculator, ReceivedPacket) {
115   StatisticsCalculator stats;
116 
117   stats.ReceivedPacket();
118   NetEqLifetimeStatistics stats_output = stats.GetLifetimeStatistics();
119   EXPECT_EQ(1u, stats_output.jitter_buffer_packets_received);
120 
121   stats.ReceivedPacket();
122   stats_output = stats.GetLifetimeStatistics();
123   EXPECT_EQ(2u, stats_output.jitter_buffer_packets_received);
124 }
125 
TEST(StatisticsCalculator,InterruptionCounter)126 TEST(StatisticsCalculator, InterruptionCounter) {
127   constexpr int fs_khz = 48;
128   constexpr int fs_hz = fs_khz * 1000;
129   StatisticsCalculator stats;
130   stats.DecodedOutputPlayed();
131   stats.EndExpandEvent(fs_hz);
132   auto lts = stats.GetLifetimeStatistics();
133   EXPECT_EQ(0, lts.interruption_count);
134   EXPECT_EQ(0, lts.total_interruption_duration_ms);
135 
136   // Add an event that is shorter than 150 ms. Should not be logged.
137   stats.ExpandedVoiceSamples(10 * fs_khz, false);   // 10 ms.
138   stats.ExpandedNoiseSamples(139 * fs_khz, false);  // 139 ms.
139   stats.EndExpandEvent(fs_hz);
140   lts = stats.GetLifetimeStatistics();
141   EXPECT_EQ(0, lts.interruption_count);
142 
143   // Add an event that is longer than 150 ms. Should be logged.
144   stats.ExpandedVoiceSamples(140 * fs_khz, false);  // 140 ms.
145   stats.ExpandedNoiseSamples(11 * fs_khz, false);   // 11 ms.
146   stats.EndExpandEvent(fs_hz);
147   lts = stats.GetLifetimeStatistics();
148   EXPECT_EQ(1, lts.interruption_count);
149   EXPECT_EQ(151, lts.total_interruption_duration_ms);
150 
151   // Add one more long event.
152   stats.ExpandedVoiceSamples(100 * fs_khz, false);   // 100 ms.
153   stats.ExpandedNoiseSamples(5000 * fs_khz, false);  // 5000 ms.
154   stats.EndExpandEvent(fs_hz);
155   lts = stats.GetLifetimeStatistics();
156   EXPECT_EQ(2, lts.interruption_count);
157   EXPECT_EQ(5100 + 151, lts.total_interruption_duration_ms);
158 }
159 
TEST(StatisticsCalculator,InterruptionCounterDoNotLogBeforeDecoding)160 TEST(StatisticsCalculator, InterruptionCounterDoNotLogBeforeDecoding) {
161   constexpr int fs_khz = 48;
162   constexpr int fs_hz = fs_khz * 1000;
163   StatisticsCalculator stats;
164 
165   // Add an event that is longer than 150 ms. Should normally be logged, but we
166   // have not called DecodedOutputPlayed() yet, so it shouldn't this time.
167   stats.ExpandedVoiceSamples(151 * fs_khz, false);  // 151 ms.
168   stats.EndExpandEvent(fs_hz);
169   auto lts = stats.GetLifetimeStatistics();
170   EXPECT_EQ(0, lts.interruption_count);
171 
172   // Call DecodedOutputPlayed(). Logging should happen after this.
173   stats.DecodedOutputPlayed();
174 
175   // Add one more long event.
176   stats.ExpandedVoiceSamples(151 * fs_khz, false);  // 151 ms.
177   stats.EndExpandEvent(fs_hz);
178   lts = stats.GetLifetimeStatistics();
179   EXPECT_EQ(1, lts.interruption_count);
180 }
181 
TEST(StatisticsCalculator,DiscardedPackets)182 TEST(StatisticsCalculator, DiscardedPackets) {
183   StatisticsCalculator statistics_calculator;
184   EXPECT_EQ(0u,
185             statistics_calculator.GetLifetimeStatistics().packets_discarded);
186 
187   statistics_calculator.PacketsDiscarded(1);
188   EXPECT_EQ(1u,
189             statistics_calculator.GetLifetimeStatistics().packets_discarded);
190 
191   statistics_calculator.PacketsDiscarded(10);
192   EXPECT_EQ(11u,
193             statistics_calculator.GetLifetimeStatistics().packets_discarded);
194 
195   // Calling `SecondaryPacketsDiscarded` does not modify `packets_discarded`.
196   statistics_calculator.SecondaryPacketsDiscarded(1);
197   EXPECT_EQ(11u,
198             statistics_calculator.GetLifetimeStatistics().packets_discarded);
199 
200   // Calling `FlushedPacketBuffer` does not modify `packets_discarded`.
201   statistics_calculator.FlushedPacketBuffer();
202   EXPECT_EQ(11u,
203             statistics_calculator.GetLifetimeStatistics().packets_discarded);
204 }
205 
206 }  // namespace webrtc
207