Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc

Issue 1702943002: Pass ownership of external encoders to the ACM (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 16 matching lines...) Expand all
27 namespace { 27 namespace {
28 static const size_t kMockMaxEncodedBytes = 1000; 28 static const size_t kMockMaxEncodedBytes = 1000;
29 static const size_t kMaxNumSamples = 48 * 10 * 2; // 10 ms @ 48 kHz stereo. 29 static const size_t kMaxNumSamples = 48 * 10 * 2; // 10 ms @ 48 kHz stereo.
30 static const size_t kMockReturnEncodedBytes = 17; 30 static const size_t kMockReturnEncodedBytes = 17;
31 static const int kCngPayloadType = 18; 31 static const int kCngPayloadType = 18;
32 } 32 }
33 33
34 class AudioEncoderCngTest : public ::testing::Test { 34 class AudioEncoderCngTest : public ::testing::Test {
35 protected: 35 protected:
36 AudioEncoderCngTest() 36 AudioEncoderCngTest()
37 : mock_vad_(new MockVad), 37 : mock_encoder_owner_(new MockAudioEncoder),
38 mock_encoder_(mock_encoder_owner_.get()),
39 mock_vad_(new MockVad),
38 timestamp_(4711), 40 timestamp_(4711),
39 num_audio_samples_10ms_(0), 41 num_audio_samples_10ms_(0),
40 sample_rate_hz_(8000) { 42 sample_rate_hz_(8000) {
41 memset(audio_, 0, kMaxNumSamples * 2); 43 memset(audio_, 0, kMaxNumSamples * 2);
42 config_.speech_encoder = &mock_encoder_; 44 EXPECT_CALL(*mock_encoder_, NumChannels()).WillRepeatedly(Return(1));
43 EXPECT_CALL(mock_encoder_, NumChannels()).WillRepeatedly(Return(1)); 45 EXPECT_CALL(*mock_encoder_, Die()).Times(1);
44 // Let the AudioEncoderCng object use a MockVad instead of its internally
45 // created Vad object.
46 config_.vad = mock_vad_;
47 config_.payload_type = kCngPayloadType;
48 } 46 }
49 47
50 void TearDown() override { 48 void TearDown() override {
51 EXPECT_CALL(*mock_vad_, Die()).Times(1); 49 EXPECT_CALL(*mock_vad_, Die()).Times(1);
52 cng_.reset(); 50 cng_.reset();
53 // Don't expect the cng_ object to delete the AudioEncoder object. But it
54 // will be deleted with the test fixture. This is why we explicitly delete
55 // the cng_ object above, and set expectations on mock_encoder_ afterwards.
56 EXPECT_CALL(mock_encoder_, Die()).Times(1);
57 } 51 }
58 52
59 void CreateCng() { 53 AudioEncoderCng::Config MakeCngConfig() {
60 // The config_ parameters may be changed by the TEST_Fs up until CreateCng() 54 AudioEncoderCng::Config config;
61 // is called, thus we cannot use the values until now. 55 config.speech_encoder = std::move(mock_encoder_owner_);
56 EXPECT_TRUE(config.speech_encoder);
57
58 // Let the AudioEncoderCng object use a MockVad instead of its internally
59 // created Vad object.
60 config.vad = mock_vad_;
61 config.payload_type = kCngPayloadType;
62
63 return config;
64 }
65
66 void CreateCng(AudioEncoderCng::Config&& config) {
62 num_audio_samples_10ms_ = static_cast<size_t>(10 * sample_rate_hz_ / 1000); 67 num_audio_samples_10ms_ = static_cast<size_t>(10 * sample_rate_hz_ / 1000);
63 ASSERT_LE(num_audio_samples_10ms_, kMaxNumSamples); 68 ASSERT_LE(num_audio_samples_10ms_, kMaxNumSamples);
64 EXPECT_CALL(mock_encoder_, SampleRateHz()) 69 if (config.speech_encoder) {
65 .WillRepeatedly(Return(sample_rate_hz_)); 70 EXPECT_CALL(*mock_encoder_, SampleRateHz())
66 // Max10MsFramesInAPacket() is just used to verify that the SID frame period 71 .WillRepeatedly(Return(sample_rate_hz_));
67 // is not too small. The return value does not matter that much, as long as 72 // Max10MsFramesInAPacket() is just used to verify that the SID frame
68 // it is smaller than 10. 73 // period is not too small. The return value does not matter that much,
69 EXPECT_CALL(mock_encoder_, Max10MsFramesInAPacket()).WillOnce(Return(1u)); 74 // as long as it is smaller than 10.
70 EXPECT_CALL(mock_encoder_, MaxEncodedBytes()) 75 EXPECT_CALL(*mock_encoder_, Max10MsFramesInAPacket())
71 .WillRepeatedly(Return(kMockMaxEncodedBytes)); 76 .WillOnce(Return(1u));
72 cng_.reset(new AudioEncoderCng(config_)); 77 EXPECT_CALL(*mock_encoder_, MaxEncodedBytes())
78 .WillRepeatedly(Return(kMockMaxEncodedBytes));
79 }
80 cng_.reset(new AudioEncoderCng(std::move(config)));
73 } 81 }
74 82
75 void Encode() { 83 void Encode() {
76 ASSERT_TRUE(cng_) << "Must call CreateCng() first."; 84 ASSERT_TRUE(cng_) << "Must call CreateCng() first.";
77 encoded_info_ = cng_->Encode( 85 encoded_info_ = cng_->Encode(
78 timestamp_, 86 timestamp_,
79 rtc::ArrayView<const int16_t>(audio_, num_audio_samples_10ms_), 87 rtc::ArrayView<const int16_t>(audio_, num_audio_samples_10ms_),
80 &encoded_); 88 &encoded_);
81 timestamp_ += static_cast<uint32_t>(num_audio_samples_10ms_); 89 timestamp_ += static_cast<uint32_t>(num_audio_samples_10ms_);
82 } 90 }
83 91
84 // Expect |num_calls| calls to the encoder, all successful. The last call 92 // Expect |num_calls| calls to the encoder, all successful. The last call
85 // claims to have encoded |kMockMaxEncodedBytes| bytes, and all the preceding 93 // claims to have encoded |kMockMaxEncodedBytes| bytes, and all the preceding
86 // ones 0 bytes. 94 // ones 0 bytes.
87 void ExpectEncodeCalls(size_t num_calls) { 95 void ExpectEncodeCalls(size_t num_calls) {
88 InSequence s; 96 InSequence s;
89 AudioEncoder::EncodedInfo info; 97 AudioEncoder::EncodedInfo info;
90 for (size_t j = 0; j < num_calls - 1; ++j) { 98 for (size_t j = 0; j < num_calls - 1; ++j) {
91 EXPECT_CALL(mock_encoder_, EncodeImpl(_, _, _)) 99 EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
92 .WillOnce(Return(info)); 100 .WillOnce(Return(info));
93 } 101 }
94 info.encoded_bytes = kMockReturnEncodedBytes; 102 info.encoded_bytes = kMockReturnEncodedBytes;
95 EXPECT_CALL(mock_encoder_, EncodeImpl(_, _, _)) 103 EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
96 .WillOnce(Invoke( 104 .WillOnce(
97 MockAudioEncoder::FakeEncoding(kMockReturnEncodedBytes))); 105 Invoke(MockAudioEncoder::FakeEncoding(kMockReturnEncodedBytes)));
98 } 106 }
99 107
100 // Verifies that the cng_ object waits until it has collected 108 // Verifies that the cng_ object waits until it has collected
101 // |blocks_per_frame| blocks of audio, and then dispatches all of them to 109 // |blocks_per_frame| blocks of audio, and then dispatches all of them to
102 // the underlying codec (speech or cng). 110 // the underlying codec (speech or cng).
103 void CheckBlockGrouping(size_t blocks_per_frame, bool active_speech) { 111 void CheckBlockGrouping(size_t blocks_per_frame, bool active_speech) {
104 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 112 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
105 .WillRepeatedly(Return(blocks_per_frame)); 113 .WillRepeatedly(Return(blocks_per_frame));
106 CreateCng(); 114 auto config = MakeCngConfig();
115 const int num_cng_coefficients = config.num_cng_coefficients;
116 CreateCng(std::move(config));
107 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 117 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
108 .WillRepeatedly(Return(active_speech ? Vad::kActive : Vad::kPassive)); 118 .WillRepeatedly(Return(active_speech ? Vad::kActive : Vad::kPassive));
109 119
110 // Don't expect any calls to the encoder yet. 120 // Don't expect any calls to the encoder yet.
111 EXPECT_CALL(mock_encoder_, EncodeImpl(_, _, _)).Times(0); 121 EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _)).Times(0);
112 for (size_t i = 0; i < blocks_per_frame - 1; ++i) { 122 for (size_t i = 0; i < blocks_per_frame - 1; ++i) {
113 Encode(); 123 Encode();
114 EXPECT_EQ(0u, encoded_info_.encoded_bytes); 124 EXPECT_EQ(0u, encoded_info_.encoded_bytes);
115 } 125 }
116 if (active_speech) 126 if (active_speech)
117 ExpectEncodeCalls(blocks_per_frame); 127 ExpectEncodeCalls(blocks_per_frame);
118 Encode(); 128 Encode();
119 if (active_speech) { 129 if (active_speech) {
120 EXPECT_EQ(kMockReturnEncodedBytes, encoded_info_.encoded_bytes); 130 EXPECT_EQ(kMockReturnEncodedBytes, encoded_info_.encoded_bytes);
121 } else { 131 } else {
122 EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients + 1), 132 EXPECT_EQ(static_cast<size_t>(num_cng_coefficients + 1),
123 encoded_info_.encoded_bytes); 133 encoded_info_.encoded_bytes);
124 } 134 }
125 } 135 }
126 136
127 // Verifies that the audio is partitioned into larger blocks before calling 137 // Verifies that the audio is partitioned into larger blocks before calling
128 // the VAD. 138 // the VAD.
129 void CheckVadInputSize(int input_frame_size_ms, 139 void CheckVadInputSize(int input_frame_size_ms,
130 int expected_first_block_size_ms, 140 int expected_first_block_size_ms,
131 int expected_second_block_size_ms) { 141 int expected_second_block_size_ms) {
132 const size_t blocks_per_frame = 142 const size_t blocks_per_frame =
133 static_cast<size_t>(input_frame_size_ms / 10); 143 static_cast<size_t>(input_frame_size_ms / 10);
134 144
135 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 145 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
136 .WillRepeatedly(Return(blocks_per_frame)); 146 .WillRepeatedly(Return(blocks_per_frame));
137 147
138 // Expect nothing to happen before the last block is sent to cng_. 148 // Expect nothing to happen before the last block is sent to cng_.
139 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)).Times(0); 149 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)).Times(0);
140 for (size_t i = 0; i < blocks_per_frame - 1; ++i) { 150 for (size_t i = 0; i < blocks_per_frame - 1; ++i) {
141 Encode(); 151 Encode();
142 } 152 }
143 153
144 // Let the VAD decision be passive, since an active decision may lead to 154 // Let the VAD decision be passive, since an active decision may lead to
145 // early termination of the decision loop. 155 // early termination of the decision loop.
(...skipping 14 matching lines...) Expand all
160 Encode(); 170 Encode();
161 } 171 }
162 172
163 // Tests a frame with both active and passive speech. Returns true if the 173 // Tests a frame with both active and passive speech. Returns true if the
164 // decision was active speech, false if it was passive. 174 // decision was active speech, false if it was passive.
165 bool CheckMixedActivePassive(Vad::Activity first_type, 175 bool CheckMixedActivePassive(Vad::Activity first_type,
166 Vad::Activity second_type) { 176 Vad::Activity second_type) {
167 // Set the speech encoder frame size to 60 ms, to ensure that the VAD will 177 // Set the speech encoder frame size to 60 ms, to ensure that the VAD will
168 // be called twice. 178 // be called twice.
169 const size_t blocks_per_frame = 6; 179 const size_t blocks_per_frame = 6;
170 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 180 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
171 .WillRepeatedly(Return(blocks_per_frame)); 181 .WillRepeatedly(Return(blocks_per_frame));
172 InSequence s; 182 InSequence s;
173 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 183 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
174 .WillOnce(Return(first_type)); 184 .WillOnce(Return(first_type));
175 if (first_type == Vad::kPassive) { 185 if (first_type == Vad::kPassive) {
176 // Expect a second call to the VAD only if the first frame was passive. 186 // Expect a second call to the VAD only if the first frame was passive.
177 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 187 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
178 .WillOnce(Return(second_type)); 188 .WillOnce(Return(second_type));
179 } 189 }
180 encoded_info_.payload_type = 0; 190 encoded_info_.payload_type = 0;
181 for (size_t i = 0; i < blocks_per_frame; ++i) { 191 for (size_t i = 0; i < blocks_per_frame; ++i) {
182 Encode(); 192 Encode();
183 } 193 }
184 return encoded_info_.payload_type != kCngPayloadType; 194 return encoded_info_.payload_type != kCngPayloadType;
185 } 195 }
186 196
187 AudioEncoderCng::Config config_;
188 std::unique_ptr<AudioEncoderCng> cng_; 197 std::unique_ptr<AudioEncoderCng> cng_;
189 MockAudioEncoder mock_encoder_; 198 std::unique_ptr<MockAudioEncoder> mock_encoder_owner_;
199 MockAudioEncoder* mock_encoder_;
190 MockVad* mock_vad_; // Ownership is transferred to |cng_|. 200 MockVad* mock_vad_; // Ownership is transferred to |cng_|.
191 uint32_t timestamp_; 201 uint32_t timestamp_;
192 int16_t audio_[kMaxNumSamples]; 202 int16_t audio_[kMaxNumSamples];
193 size_t num_audio_samples_10ms_; 203 size_t num_audio_samples_10ms_;
194 rtc::Buffer encoded_; 204 rtc::Buffer encoded_;
195 AudioEncoder::EncodedInfo encoded_info_; 205 AudioEncoder::EncodedInfo encoded_info_;
196 int sample_rate_hz_; 206 int sample_rate_hz_;
207
208 RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderCngTest);
197 }; 209 };
198 210
199 TEST_F(AudioEncoderCngTest, CreateAndDestroy) { 211 TEST_F(AudioEncoderCngTest, CreateAndDestroy) {
200 CreateCng(); 212 CreateCng(MakeCngConfig());
201 } 213 }
202 214
203 TEST_F(AudioEncoderCngTest, CheckFrameSizePropagation) { 215 TEST_F(AudioEncoderCngTest, CheckFrameSizePropagation) {
204 CreateCng(); 216 CreateCng(MakeCngConfig());
205 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()).WillOnce(Return(17U)); 217 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
218 .WillOnce(Return(17U));
206 EXPECT_EQ(17U, cng_->Num10MsFramesInNextPacket()); 219 EXPECT_EQ(17U, cng_->Num10MsFramesInNextPacket());
207 } 220 }
208 221
209 TEST_F(AudioEncoderCngTest, CheckChangeBitratePropagation) { 222 TEST_F(AudioEncoderCngTest, CheckChangeBitratePropagation) {
210 CreateCng(); 223 CreateCng(MakeCngConfig());
211 EXPECT_CALL(mock_encoder_, SetTargetBitrate(4711)); 224 EXPECT_CALL(*mock_encoder_, SetTargetBitrate(4711));
212 cng_->SetTargetBitrate(4711); 225 cng_->SetTargetBitrate(4711);
213 } 226 }
214 227
215 TEST_F(AudioEncoderCngTest, CheckProjectedPacketLossRatePropagation) { 228 TEST_F(AudioEncoderCngTest, CheckProjectedPacketLossRatePropagation) {
216 CreateCng(); 229 CreateCng(MakeCngConfig());
217 EXPECT_CALL(mock_encoder_, SetProjectedPacketLossRate(0.5)); 230 EXPECT_CALL(*mock_encoder_, SetProjectedPacketLossRate(0.5));
218 cng_->SetProjectedPacketLossRate(0.5); 231 cng_->SetProjectedPacketLossRate(0.5);
219 } 232 }
220 233
221 TEST_F(AudioEncoderCngTest, EncodeCallsVad) { 234 TEST_F(AudioEncoderCngTest, EncodeCallsVad) {
222 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 235 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
223 .WillRepeatedly(Return(1U)); 236 .WillRepeatedly(Return(1U));
224 CreateCng(); 237 CreateCng(MakeCngConfig());
225 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 238 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
226 .WillOnce(Return(Vad::kPassive)); 239 .WillOnce(Return(Vad::kPassive));
227 Encode(); 240 Encode();
228 } 241 }
229 242
230 TEST_F(AudioEncoderCngTest, EncodeCollects1BlockPassiveSpeech) { 243 TEST_F(AudioEncoderCngTest, EncodeCollects1BlockPassiveSpeech) {
231 CheckBlockGrouping(1, false); 244 CheckBlockGrouping(1, false);
232 } 245 }
233 246
234 TEST_F(AudioEncoderCngTest, EncodeCollects2BlocksPassiveSpeech) { 247 TEST_F(AudioEncoderCngTest, EncodeCollects2BlocksPassiveSpeech) {
(...skipping 11 matching lines...) Expand all
246 TEST_F(AudioEncoderCngTest, EncodeCollects2BlocksActiveSpeech) { 259 TEST_F(AudioEncoderCngTest, EncodeCollects2BlocksActiveSpeech) {
247 CheckBlockGrouping(2, true); 260 CheckBlockGrouping(2, true);
248 } 261 }
249 262
250 TEST_F(AudioEncoderCngTest, EncodeCollects3BlocksActiveSpeech) { 263 TEST_F(AudioEncoderCngTest, EncodeCollects3BlocksActiveSpeech) {
251 CheckBlockGrouping(3, true); 264 CheckBlockGrouping(3, true);
252 } 265 }
253 266
254 TEST_F(AudioEncoderCngTest, EncodePassive) { 267 TEST_F(AudioEncoderCngTest, EncodePassive) {
255 const size_t kBlocksPerFrame = 3; 268 const size_t kBlocksPerFrame = 3;
256 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 269 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
257 .WillRepeatedly(Return(kBlocksPerFrame)); 270 .WillRepeatedly(Return(kBlocksPerFrame));
258 CreateCng(); 271 auto config = MakeCngConfig();
272 const auto sid_frame_interval_ms = config.sid_frame_interval_ms;
273 const auto num_cng_coefficients = config.num_cng_coefficients;
274 CreateCng(std::move(config));
259 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 275 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
260 .WillRepeatedly(Return(Vad::kPassive)); 276 .WillRepeatedly(Return(Vad::kPassive));
261 // Expect no calls at all to the speech encoder mock. 277 // Expect no calls at all to the speech encoder mock.
262 EXPECT_CALL(mock_encoder_, EncodeImpl(_, _, _)).Times(0); 278 EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _)).Times(0);
263 uint32_t expected_timestamp = timestamp_; 279 uint32_t expected_timestamp = timestamp_;
264 for (size_t i = 0; i < 100; ++i) { 280 for (size_t i = 0; i < 100; ++i) {
265 Encode(); 281 Encode();
266 // Check if it was time to call the cng encoder. This is done once every 282 // Check if it was time to call the cng encoder. This is done once every
267 // |kBlocksPerFrame| calls. 283 // |kBlocksPerFrame| calls.
268 if ((i + 1) % kBlocksPerFrame == 0) { 284 if ((i + 1) % kBlocksPerFrame == 0) {
269 // Now check if a SID interval has elapsed. 285 // Now check if a SID interval has elapsed.
270 if ((i % (config_.sid_frame_interval_ms / 10)) < kBlocksPerFrame) { 286 if ((i % (sid_frame_interval_ms / 10)) < kBlocksPerFrame) {
271 // If so, verify that we got a CNG encoding. 287 // If so, verify that we got a CNG encoding.
272 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 288 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type);
273 EXPECT_FALSE(encoded_info_.speech); 289 EXPECT_FALSE(encoded_info_.speech);
274 EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients) + 1, 290 EXPECT_EQ(static_cast<size_t>(num_cng_coefficients) + 1,
275 encoded_info_.encoded_bytes); 291 encoded_info_.encoded_bytes);
276 EXPECT_EQ(expected_timestamp, encoded_info_.encoded_timestamp); 292 EXPECT_EQ(expected_timestamp, encoded_info_.encoded_timestamp);
277 } 293 }
278 expected_timestamp += kBlocksPerFrame * num_audio_samples_10ms_; 294 expected_timestamp += kBlocksPerFrame * num_audio_samples_10ms_;
279 } else { 295 } else {
280 // Otherwise, expect no output. 296 // Otherwise, expect no output.
281 EXPECT_EQ(0u, encoded_info_.encoded_bytes); 297 EXPECT_EQ(0u, encoded_info_.encoded_bytes);
282 } 298 }
283 } 299 }
284 } 300 }
285 301
286 // Verifies that the correct action is taken for frames with both active and 302 // Verifies that the correct action is taken for frames with both active and
287 // passive speech. 303 // passive speech.
288 TEST_F(AudioEncoderCngTest, MixedActivePassive) { 304 TEST_F(AudioEncoderCngTest, MixedActivePassive) {
289 CreateCng(); 305 CreateCng(MakeCngConfig());
290 306
291 // All of the frame is active speech. 307 // All of the frame is active speech.
292 ExpectEncodeCalls(6); 308 ExpectEncodeCalls(6);
293 EXPECT_TRUE(CheckMixedActivePassive(Vad::kActive, Vad::kActive)); 309 EXPECT_TRUE(CheckMixedActivePassive(Vad::kActive, Vad::kActive));
294 EXPECT_TRUE(encoded_info_.speech); 310 EXPECT_TRUE(encoded_info_.speech);
295 311
296 // First half of the frame is active speech. 312 // First half of the frame is active speech.
297 ExpectEncodeCalls(6); 313 ExpectEncodeCalls(6);
298 EXPECT_TRUE(CheckMixedActivePassive(Vad::kActive, Vad::kPassive)); 314 EXPECT_TRUE(CheckMixedActivePassive(Vad::kActive, Vad::kPassive));
299 EXPECT_TRUE(encoded_info_.speech); 315 EXPECT_TRUE(encoded_info_.speech);
300 316
301 // Second half of the frame is active speech. 317 // Second half of the frame is active speech.
302 ExpectEncodeCalls(6); 318 ExpectEncodeCalls(6);
303 EXPECT_TRUE(CheckMixedActivePassive(Vad::kPassive, Vad::kActive)); 319 EXPECT_TRUE(CheckMixedActivePassive(Vad::kPassive, Vad::kActive));
304 EXPECT_TRUE(encoded_info_.speech); 320 EXPECT_TRUE(encoded_info_.speech);
305 321
306 // All of the frame is passive speech. Expect no calls to |mock_encoder_|. 322 // All of the frame is passive speech. Expect no calls to |mock_encoder_|.
307 EXPECT_FALSE(CheckMixedActivePassive(Vad::kPassive, Vad::kPassive)); 323 EXPECT_FALSE(CheckMixedActivePassive(Vad::kPassive, Vad::kPassive));
308 EXPECT_FALSE(encoded_info_.speech); 324 EXPECT_FALSE(encoded_info_.speech);
309 } 325 }
310 326
311 // These tests verify that the audio is partitioned into larger blocks before 327 // These tests verify that the audio is partitioned into larger blocks before
312 // calling the VAD. 328 // calling the VAD.
313 // The parameters for CheckVadInputSize are: 329 // The parameters for CheckVadInputSize are:
314 // CheckVadInputSize(frame_size, expected_first_block_size, 330 // CheckVadInputSize(frame_size, expected_first_block_size,
315 // expected_second_block_size); 331 // expected_second_block_size);
316 TEST_F(AudioEncoderCngTest, VadInputSize10Ms) { 332 TEST_F(AudioEncoderCngTest, VadInputSize10Ms) {
317 CreateCng(); 333 CreateCng(MakeCngConfig());
318 CheckVadInputSize(10, 10, 0); 334 CheckVadInputSize(10, 10, 0);
319 } 335 }
320 TEST_F(AudioEncoderCngTest, VadInputSize20Ms) { 336 TEST_F(AudioEncoderCngTest, VadInputSize20Ms) {
321 CreateCng(); 337 CreateCng(MakeCngConfig());
322 CheckVadInputSize(20, 20, 0); 338 CheckVadInputSize(20, 20, 0);
323 } 339 }
324 TEST_F(AudioEncoderCngTest, VadInputSize30Ms) { 340 TEST_F(AudioEncoderCngTest, VadInputSize30Ms) {
325 CreateCng(); 341 CreateCng(MakeCngConfig());
326 CheckVadInputSize(30, 30, 0); 342 CheckVadInputSize(30, 30, 0);
327 } 343 }
328 TEST_F(AudioEncoderCngTest, VadInputSize40Ms) { 344 TEST_F(AudioEncoderCngTest, VadInputSize40Ms) {
329 CreateCng(); 345 CreateCng(MakeCngConfig());
330 CheckVadInputSize(40, 20, 20); 346 CheckVadInputSize(40, 20, 20);
331 } 347 }
332 TEST_F(AudioEncoderCngTest, VadInputSize50Ms) { 348 TEST_F(AudioEncoderCngTest, VadInputSize50Ms) {
333 CreateCng(); 349 CreateCng(MakeCngConfig());
334 CheckVadInputSize(50, 30, 20); 350 CheckVadInputSize(50, 30, 20);
335 } 351 }
336 TEST_F(AudioEncoderCngTest, VadInputSize60Ms) { 352 TEST_F(AudioEncoderCngTest, VadInputSize60Ms) {
337 CreateCng(); 353 CreateCng(MakeCngConfig());
338 CheckVadInputSize(60, 30, 30); 354 CheckVadInputSize(60, 30, 30);
339 } 355 }
340 356
341 // Verifies that the correct payload type is set when CNG is encoded. 357 // Verifies that the correct payload type is set when CNG is encoded.
342 TEST_F(AudioEncoderCngTest, VerifyCngPayloadType) { 358 TEST_F(AudioEncoderCngTest, VerifyCngPayloadType) {
343 CreateCng(); 359 CreateCng(MakeCngConfig());
344 EXPECT_CALL(mock_encoder_, EncodeImpl(_, _, _)).Times(0); 360 EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _)).Times(0);
345 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()).WillOnce(Return(1U)); 361 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket()).WillOnce(Return(1U));
346 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 362 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
347 .WillOnce(Return(Vad::kPassive)); 363 .WillOnce(Return(Vad::kPassive));
348 encoded_info_.payload_type = 0; 364 encoded_info_.payload_type = 0;
349 Encode(); 365 Encode();
350 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 366 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type);
351 } 367 }
352 368
353 // Verifies that a SID frame is encoded immediately as the signal changes from 369 // Verifies that a SID frame is encoded immediately as the signal changes from
354 // active speech to passive. 370 // active speech to passive.
355 TEST_F(AudioEncoderCngTest, VerifySidFrameAfterSpeech) { 371 TEST_F(AudioEncoderCngTest, VerifySidFrameAfterSpeech) {
356 CreateCng(); 372 auto config = MakeCngConfig();
357 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 373 const auto num_cng_coefficients = config.num_cng_coefficients;
374 CreateCng(std::move(config));
375 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
358 .WillRepeatedly(Return(1U)); 376 .WillRepeatedly(Return(1U));
359 // Start with encoding noise. 377 // Start with encoding noise.
360 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 378 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
361 .Times(2) 379 .Times(2)
362 .WillRepeatedly(Return(Vad::kPassive)); 380 .WillRepeatedly(Return(Vad::kPassive));
363 Encode(); 381 Encode();
364 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 382 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type);
365 EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients) + 1, 383 EXPECT_EQ(static_cast<size_t>(num_cng_coefficients) + 1,
366 encoded_info_.encoded_bytes); 384 encoded_info_.encoded_bytes);
367 // Encode again, and make sure we got no frame at all (since the SID frame 385 // Encode again, and make sure we got no frame at all (since the SID frame
368 // period is 100 ms by default). 386 // period is 100 ms by default).
369 Encode(); 387 Encode();
370 EXPECT_EQ(0u, encoded_info_.encoded_bytes); 388 EXPECT_EQ(0u, encoded_info_.encoded_bytes);
371 389
372 // Now encode active speech. 390 // Now encode active speech.
373 encoded_info_.payload_type = 0; 391 encoded_info_.payload_type = 0;
374 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 392 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
375 .WillOnce(Return(Vad::kActive)); 393 .WillOnce(Return(Vad::kActive));
376 EXPECT_CALL(mock_encoder_, EncodeImpl(_, _, _)).WillOnce( 394 EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
377 Invoke(MockAudioEncoder::FakeEncoding(kMockReturnEncodedBytes))); 395 .WillOnce(
396 Invoke(MockAudioEncoder::FakeEncoding(kMockReturnEncodedBytes)));
378 Encode(); 397 Encode();
379 EXPECT_EQ(kMockReturnEncodedBytes, encoded_info_.encoded_bytes); 398 EXPECT_EQ(kMockReturnEncodedBytes, encoded_info_.encoded_bytes);
380 399
381 // Go back to noise again, and verify that a SID frame is emitted. 400 // Go back to noise again, and verify that a SID frame is emitted.
382 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 401 EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _))
383 .WillOnce(Return(Vad::kPassive)); 402 .WillOnce(Return(Vad::kPassive));
384 Encode(); 403 Encode();
385 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 404 EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type);
386 EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients) + 1, 405 EXPECT_EQ(static_cast<size_t>(num_cng_coefficients) + 1,
387 encoded_info_.encoded_bytes); 406 encoded_info_.encoded_bytes);
388 } 407 }
389 408
390 // Resetting the CNG should reset both the VAD and the encoder. 409 // Resetting the CNG should reset both the VAD and the encoder.
391 TEST_F(AudioEncoderCngTest, Reset) { 410 TEST_F(AudioEncoderCngTest, Reset) {
392 CreateCng(); 411 CreateCng(MakeCngConfig());
393 EXPECT_CALL(mock_encoder_, Reset()).Times(1); 412 EXPECT_CALL(*mock_encoder_, Reset()).Times(1);
394 EXPECT_CALL(*mock_vad_, Reset()).Times(1); 413 EXPECT_CALL(*mock_vad_, Reset()).Times(1);
395 cng_->Reset(); 414 cng_->Reset();
396 } 415 }
397 416
398 #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 417 #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
399 418
400 // This test fixture tests various error conditions that makes the 419 // This test fixture tests various error conditions that makes the
401 // AudioEncoderCng die via CHECKs. 420 // AudioEncoderCng die via CHECKs.
402 class AudioEncoderCngDeathTest : public AudioEncoderCngTest { 421 class AudioEncoderCngDeathTest : public AudioEncoderCngTest {
403 protected: 422 protected:
404 AudioEncoderCngDeathTest() : AudioEncoderCngTest() { 423 AudioEncoderCngDeathTest() : AudioEncoderCngTest() {
405 // Don't provide a Vad mock object, since it will leak when the test dies.
406 config_.vad = NULL;
407 EXPECT_CALL(*mock_vad_, Die()).Times(1); 424 EXPECT_CALL(*mock_vad_, Die()).Times(1);
408 delete mock_vad_; 425 delete mock_vad_;
409 mock_vad_ = NULL; 426 mock_vad_ = nullptr;
410 } 427 }
411 428
412 // Override AudioEncoderCngTest::TearDown, since that one expects a call to 429 // Override AudioEncoderCngTest::TearDown, since that one expects a call to
413 // the destructor of |mock_vad_|. In this case, that object is already 430 // the destructor of |mock_vad_|. In this case, that object is already
414 // deleted. 431 // deleted.
415 void TearDown() override { 432 void TearDown() override {
416 cng_.reset(); 433 cng_.reset();
417 // Don't expect the cng_ object to delete the AudioEncoder object. But it 434 }
418 // will be deleted with the test fixture. This is why we explicitly delete 435
419 // the cng_ object above, and set expectations on mock_encoder_ afterwards. 436 AudioEncoderCng::Config MakeCngConfig() {
420 EXPECT_CALL(mock_encoder_, Die()).Times(1); 437 // Don't provide a Vad mock object, since it would leak when the test dies.
438 auto config = AudioEncoderCngTest::MakeCngConfig();
439 config.vad = nullptr;
440 return config;
441 }
442
443 void TryWrongNumCoefficients(int num) {
444 EXPECT_DEATH(
445 [&] {
446 auto config = MakeCngConfig();
447 config.num_cng_coefficients = num;
448 CreateCng(std::move(config));
449 }(),
450 "Invalid configuration");
421 } 451 }
422 }; 452 };
423 453
424 TEST_F(AudioEncoderCngDeathTest, WrongFrameSize) { 454 TEST_F(AudioEncoderCngDeathTest, WrongFrameSize) {
425 CreateCng(); 455 CreateCng(MakeCngConfig());
426 num_audio_samples_10ms_ *= 2; // 20 ms frame. 456 num_audio_samples_10ms_ *= 2; // 20 ms frame.
427 EXPECT_DEATH(Encode(), ""); 457 EXPECT_DEATH(Encode(), "");
428 num_audio_samples_10ms_ = 0; // Zero samples. 458 num_audio_samples_10ms_ = 0; // Zero samples.
429 EXPECT_DEATH(Encode(), ""); 459 EXPECT_DEATH(Encode(), "");
430 } 460 }
431 461
432 TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficients) { 462 TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficientsA) {
433 config_.num_cng_coefficients = -1; 463 TryWrongNumCoefficients(-1);
434 EXPECT_DEATH(CreateCng(), "Invalid configuration"); 464 }
435 config_.num_cng_coefficients = 0; 465
436 EXPECT_DEATH(CreateCng(), "Invalid configuration"); 466 TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficientsB) {
437 config_.num_cng_coefficients = 13; 467 TryWrongNumCoefficients(0);
438 EXPECT_DEATH(CreateCng(), "Invalid configuration"); 468 }
469
470 TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficientsC) {
471 TryWrongNumCoefficients(13);
439 } 472 }
440 473
441 TEST_F(AudioEncoderCngDeathTest, NullSpeechEncoder) { 474 TEST_F(AudioEncoderCngDeathTest, NullSpeechEncoder) {
442 config_.speech_encoder = NULL; 475 auto config = MakeCngConfig();
443 EXPECT_DEATH(CreateCng(), "Invalid configuration"); 476 config.speech_encoder = nullptr;
477 EXPECT_DEATH(CreateCng(std::move(config)), "");
444 } 478 }
445 479
446 TEST_F(AudioEncoderCngDeathTest, Stereo) { 480 TEST_F(AudioEncoderCngDeathTest, StereoEncoder) {
447 EXPECT_CALL(mock_encoder_, NumChannels()).WillRepeatedly(Return(2)); 481 EXPECT_CALL(*mock_encoder_, NumChannels()).WillRepeatedly(Return(2));
448 EXPECT_DEATH(CreateCng(), "Invalid configuration"); 482 EXPECT_DEATH(CreateCng(MakeCngConfig()), "Invalid configuration");
449 config_.num_channels = 2; 483 }
450 EXPECT_DEATH(CreateCng(), "Invalid configuration"); 484
485 TEST_F(AudioEncoderCngDeathTest, StereoConfig) {
486 EXPECT_DEATH(
487 [&] {
488 auto config = MakeCngConfig();
489 config.num_channels = 2;
490 CreateCng(std::move(config));
491 }(),
492 "Invalid configuration");
451 } 493 }
452 494
453 TEST_F(AudioEncoderCngDeathTest, EncoderFrameSizeTooLarge) { 495 TEST_F(AudioEncoderCngDeathTest, EncoderFrameSizeTooLarge) {
454 CreateCng(); 496 CreateCng(MakeCngConfig());
455 EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 497 EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
456 .WillRepeatedly(Return(7U)); 498 .WillRepeatedly(Return(7U));
457 for (int i = 0; i < 6; ++i) 499 for (int i = 0; i < 6; ++i)
458 Encode(); 500 Encode();
459 EXPECT_DEATH(Encode(), 501 EXPECT_DEATH(Encode(),
460 "Frame size cannot be larger than 60 ms when using VAD/CNG."); 502 "Frame size cannot be larger than 60 ms when using VAD/CNG.");
461 } 503 }
462 504
463 #endif // GTEST_HAS_DEATH_TEST 505 #endif // GTEST_HAS_DEATH_TEST
464 506
465 } // namespace webrtc 507 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698