1 /*
2 * Copyright (c) 2012 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 // Unit tests for DecisionLogic class and derived classes.
12
13 #include "modules/audio_coding/neteq/decision_logic.h"
14
15 #include "api/neteq/neteq_controller.h"
16 #include "api/neteq/tick_timer.h"
17 #include "modules/audio_coding/neteq/buffer_level_filter.h"
18 #include "modules/audio_coding/neteq/delay_manager.h"
19 #include "modules/audio_coding/neteq/mock/mock_buffer_level_filter.h"
20 #include "modules/audio_coding/neteq/mock/mock_delay_manager.h"
21 #include "test/field_trial.h"
22 #include "test/gtest.h"
23
24 namespace webrtc {
25
26 namespace {
27
28 constexpr int kSampleRate = 8000;
29 constexpr int kSamplesPerMs = kSampleRate / 1000;
30 constexpr int kOutputSizeSamples = kSamplesPerMs * 10;
31 constexpr int kMinTimescaleInterval = 5;
32
CreateNetEqStatus(NetEq::Mode last_mode,int current_delay_ms)33 NetEqController::NetEqStatus CreateNetEqStatus(NetEq::Mode last_mode,
34 int current_delay_ms) {
35 NetEqController::NetEqStatus status;
36 status.play_dtmf = false;
37 status.last_mode = last_mode;
38 status.target_timestamp = 1234;
39 status.generated_noise_samples = 0;
40 status.expand_mutefactor = 0;
41 status.packet_buffer_info.num_samples = current_delay_ms * kSamplesPerMs;
42 status.packet_buffer_info.span_samples = current_delay_ms * kSamplesPerMs;
43 status.packet_buffer_info.span_samples_no_dtx =
44 current_delay_ms * kSamplesPerMs;
45 status.packet_buffer_info.dtx_or_cng = false;
46 status.next_packet = {status.target_timestamp, false, false};
47 return status;
48 }
49
50 using ::testing::Return;
51
52 } // namespace
53
54 class DecisionLogicTest : public ::testing::Test {
55 protected:
DecisionLogicTest()56 DecisionLogicTest() {
57 test::ScopedFieldTrials field_trial(
58 "WebRTC-Audio-NetEqDecisionLogicSettings/"
59 "estimate_dtx_delay:true,time_stretch_cn:true/");
60
61 NetEqController::Config config;
62 config.tick_timer = &tick_timer_;
63 config.allow_time_stretching = true;
64 std::unique_ptr<Histogram> histogram =
65 std::make_unique<Histogram>(200, 12345, 2);
66 auto delay_manager = std::make_unique<MockDelayManager>(
67 200, 0, 12300, absl::nullopt, 2000, config.tick_timer,
68 std::move(histogram));
69 mock_delay_manager_ = delay_manager.get();
70 auto buffer_level_filter = std::make_unique<MockBufferLevelFilter>();
71 mock_buffer_level_filter_ = buffer_level_filter.get();
72 decision_logic_ = std::make_unique<DecisionLogic>(
73 config, std::move(delay_manager), std::move(buffer_level_filter));
74 decision_logic_->SetSampleRate(kSampleRate, kOutputSizeSamples);
75 }
76
77 TickTimer tick_timer_;
78 std::unique_ptr<DecisionLogic> decision_logic_;
79 MockDelayManager* mock_delay_manager_;
80 MockBufferLevelFilter* mock_buffer_level_filter_;
81 };
82
TEST_F(DecisionLogicTest,NormalOperation)83 TEST_F(DecisionLogicTest, NormalOperation) {
84 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
85 .WillRepeatedly(Return(100));
86 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
87 .WillRepeatedly(Return(90 * kSamplesPerMs));
88
89 bool reset_decoder = false;
90 tick_timer_.Increment(kMinTimescaleInterval + 1);
91 EXPECT_EQ(decision_logic_->GetDecision(
92 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
93 NetEq::Operation::kNormal);
94 EXPECT_FALSE(reset_decoder);
95 }
96
TEST_F(DecisionLogicTest,Accelerate)97 TEST_F(DecisionLogicTest, Accelerate) {
98 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
99 .WillRepeatedly(Return(100));
100 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
101 .WillRepeatedly(Return(110 * kSamplesPerMs));
102
103 bool reset_decoder = false;
104 tick_timer_.Increment(kMinTimescaleInterval + 1);
105 EXPECT_EQ(decision_logic_->GetDecision(
106 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
107 NetEq::Operation::kAccelerate);
108 EXPECT_FALSE(reset_decoder);
109 }
110
TEST_F(DecisionLogicTest,FastAccelerate)111 TEST_F(DecisionLogicTest, FastAccelerate) {
112 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
113 .WillRepeatedly(Return(100));
114 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
115 .WillRepeatedly(Return(400 * kSamplesPerMs));
116
117 bool reset_decoder = false;
118 tick_timer_.Increment(kMinTimescaleInterval + 1);
119 EXPECT_EQ(decision_logic_->GetDecision(
120 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
121 NetEq::Operation::kFastAccelerate);
122 EXPECT_FALSE(reset_decoder);
123 }
124
TEST_F(DecisionLogicTest,PreemptiveExpand)125 TEST_F(DecisionLogicTest, PreemptiveExpand) {
126 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
127 .WillRepeatedly(Return(100));
128 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
129 .WillRepeatedly(Return(50 * kSamplesPerMs));
130
131 bool reset_decoder = false;
132 tick_timer_.Increment(kMinTimescaleInterval + 1);
133 EXPECT_EQ(decision_logic_->GetDecision(
134 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
135 NetEq::Operation::kPreemptiveExpand);
136 EXPECT_FALSE(reset_decoder);
137 }
138
TEST_F(DecisionLogicTest,DecelerationTargetLevelOffset)139 TEST_F(DecisionLogicTest, DecelerationTargetLevelOffset) {
140 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
141 .WillRepeatedly(Return(500));
142 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
143 .WillRepeatedly(Return(400 * kSamplesPerMs));
144
145 bool reset_decoder = false;
146 tick_timer_.Increment(kMinTimescaleInterval + 1);
147 EXPECT_EQ(decision_logic_->GetDecision(
148 CreateNetEqStatus(NetEq::Mode::kNormal, 400), &reset_decoder),
149 NetEq::Operation::kPreemptiveExpand);
150 EXPECT_FALSE(reset_decoder);
151 }
152
TEST_F(DecisionLogicTest,PostponeDecodeAfterExpand)153 TEST_F(DecisionLogicTest, PostponeDecodeAfterExpand) {
154 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
155 .WillRepeatedly(Return(500));
156
157 // Below 50% target delay threshold.
158 bool reset_decoder = false;
159 EXPECT_EQ(decision_logic_->GetDecision(
160 CreateNetEqStatus(NetEq::Mode::kExpand, 200), &reset_decoder),
161 NetEq::Operation::kExpand);
162 EXPECT_FALSE(reset_decoder);
163
164 // Above 50% target delay threshold.
165 EXPECT_EQ(decision_logic_->GetDecision(
166 CreateNetEqStatus(NetEq::Mode::kExpand, 250), &reset_decoder),
167 NetEq::Operation::kNormal);
168 EXPECT_FALSE(reset_decoder);
169 }
170
TEST_F(DecisionLogicTest,TimeStrechComfortNoise)171 TEST_F(DecisionLogicTest, TimeStrechComfortNoise) {
172 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
173 .WillRepeatedly(Return(500));
174
175 {
176 bool reset_decoder = false;
177 // Below target window.
178 auto status = CreateNetEqStatus(NetEq::Mode::kCodecInternalCng, 400);
179 status.generated_noise_samples = 400 * kSamplesPerMs;
180 status.next_packet->timestamp =
181 status.target_timestamp + 400 * kSamplesPerMs;
182 EXPECT_EQ(decision_logic_->GetDecision(status, &reset_decoder),
183 NetEq::Operation::kCodecInternalCng);
184 EXPECT_FALSE(reset_decoder);
185 }
186
187 {
188 bool reset_decoder = false;
189 // Above target window.
190 auto status = CreateNetEqStatus(NetEq::Mode::kCodecInternalCng, 600);
191 status.generated_noise_samples = 200 * kSamplesPerMs;
192 status.next_packet->timestamp =
193 status.target_timestamp + 400 * kSamplesPerMs;
194 EXPECT_EQ(decision_logic_->GetDecision(status, &reset_decoder),
195 NetEq::Operation::kNormal);
196 EXPECT_FALSE(reset_decoder);
197
198 // The buffer level filter should be adjusted with the number of samples
199 // that was skipped.
200 int timestamp_leap = status.next_packet->timestamp -
201 status.target_timestamp -
202 status.generated_noise_samples;
203 EXPECT_CALL(*mock_buffer_level_filter_,
204 Update(400 * kSamplesPerMs, timestamp_leap));
205 EXPECT_EQ(decision_logic_->GetDecision(
206 CreateNetEqStatus(NetEq::Mode::kNormal, 400), &reset_decoder),
207 NetEq::Operation::kNormal);
208 EXPECT_FALSE(reset_decoder);
209 }
210 }
211
212 } // namespace webrtc
213