1 /*
2 * Copyright (c) 2015 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 "api/audio_codecs/opus/audio_encoder_opus.h"
12
13 #include <array>
14 #include <memory>
15 #include <utility>
16
17 #include "common_audio/mocks/mock_smoothing_filter.h"
18 #include "modules/audio_coding/audio_network_adaptor/mock/mock_audio_network_adaptor.h"
19 #include "modules/audio_coding/codecs/opus/audio_encoder_opus.h"
20 #include "modules/audio_coding/codecs/opus/opus_interface.h"
21 #include "modules/audio_coding/neteq/tools/audio_loop.h"
22 #include "rtc_base/checks.h"
23 #include "rtc_base/fake_clock.h"
24 #include "test/field_trial.h"
25 #include "test/gmock.h"
26 #include "test/gtest.h"
27 #include "test/testsupport/file_utils.h"
28
29 namespace webrtc {
30 using ::testing::NiceMock;
31 using ::testing::Return;
32
33 namespace {
34
35 constexpr int kDefaultOpusPayloadType = 105;
36 constexpr int kDefaultOpusRate = 32000;
37 constexpr int kDefaultOpusPacSize = 960;
38 constexpr int64_t kInitialTimeUs = 12345678;
39
CreateConfigWithParameters(const SdpAudioFormat::Parameters & params)40 AudioEncoderOpusConfig CreateConfigWithParameters(
41 const SdpAudioFormat::Parameters& params) {
42 const SdpAudioFormat format("opus", 48000, 2, params);
43 return *AudioEncoderOpus::SdpToConfig(format);
44 }
45
46 struct AudioEncoderOpusStates {
47 MockAudioNetworkAdaptor* mock_audio_network_adaptor;
48 MockSmoothingFilter* mock_bitrate_smoother;
49 std::unique_ptr<AudioEncoderOpusImpl> encoder;
50 std::unique_ptr<rtc::ScopedFakeClock> fake_clock;
51 AudioEncoderOpusConfig config;
52 };
53
CreateCodec(int sample_rate_hz,size_t num_channels)54 std::unique_ptr<AudioEncoderOpusStates> CreateCodec(int sample_rate_hz,
55 size_t num_channels) {
56 std::unique_ptr<AudioEncoderOpusStates> states =
57 std::make_unique<AudioEncoderOpusStates>();
58 states->mock_audio_network_adaptor = nullptr;
59 states->fake_clock.reset(new rtc::ScopedFakeClock());
60 states->fake_clock->SetTime(Timestamp::Micros(kInitialTimeUs));
61
62 MockAudioNetworkAdaptor** mock_ptr = &states->mock_audio_network_adaptor;
63 AudioEncoderOpusImpl::AudioNetworkAdaptorCreator creator =
64 [mock_ptr](const std::string&, RtcEventLog* event_log) {
65 std::unique_ptr<MockAudioNetworkAdaptor> adaptor(
66 new NiceMock<MockAudioNetworkAdaptor>());
67 EXPECT_CALL(*adaptor, Die());
68 *mock_ptr = adaptor.get();
69 return adaptor;
70 };
71
72 AudioEncoderOpusConfig config;
73 config.frame_size_ms = rtc::CheckedDivExact(kDefaultOpusPacSize, 48);
74 config.sample_rate_hz = sample_rate_hz;
75 config.num_channels = num_channels;
76 config.bitrate_bps = kDefaultOpusRate;
77 config.application = num_channels == 1
78 ? AudioEncoderOpusConfig::ApplicationMode::kVoip
79 : AudioEncoderOpusConfig::ApplicationMode::kAudio;
80 config.supported_frame_lengths_ms.push_back(config.frame_size_ms);
81 states->config = config;
82
83 std::unique_ptr<MockSmoothingFilter> bitrate_smoother(
84 new MockSmoothingFilter());
85 states->mock_bitrate_smoother = bitrate_smoother.get();
86
87 states->encoder.reset(
88 new AudioEncoderOpusImpl(states->config, kDefaultOpusPayloadType, creator,
89 std::move(bitrate_smoother)));
90 return states;
91 }
92
CreateEncoderRuntimeConfig()93 AudioEncoderRuntimeConfig CreateEncoderRuntimeConfig() {
94 constexpr int kBitrate = 40000;
95 constexpr int kFrameLength = 60;
96 constexpr bool kEnableDtx = false;
97 constexpr size_t kNumChannels = 1;
98 AudioEncoderRuntimeConfig config;
99 config.bitrate_bps = kBitrate;
100 config.frame_length_ms = kFrameLength;
101 config.enable_dtx = kEnableDtx;
102 config.num_channels = kNumChannels;
103 return config;
104 }
105
CheckEncoderRuntimeConfig(const AudioEncoderOpusImpl * encoder,const AudioEncoderRuntimeConfig & config)106 void CheckEncoderRuntimeConfig(const AudioEncoderOpusImpl* encoder,
107 const AudioEncoderRuntimeConfig& config) {
108 EXPECT_EQ(*config.bitrate_bps, encoder->GetTargetBitrate());
109 EXPECT_EQ(*config.frame_length_ms, encoder->next_frame_length_ms());
110 EXPECT_EQ(*config.enable_dtx, encoder->GetDtx());
111 EXPECT_EQ(*config.num_channels, encoder->num_channels_to_encode());
112 }
113
114 // Create 10ms audio data blocks for a total packet size of "packet_size_ms".
Create10msAudioBlocks(const std::unique_ptr<AudioEncoderOpusImpl> & encoder,int packet_size_ms)115 std::unique_ptr<test::AudioLoop> Create10msAudioBlocks(
116 const std::unique_ptr<AudioEncoderOpusImpl>& encoder,
117 int packet_size_ms) {
118 const std::string file_name =
119 test::ResourcePath("audio_coding/testfile32kHz", "pcm");
120
121 std::unique_ptr<test::AudioLoop> speech_data(new test::AudioLoop());
122 int audio_samples_per_ms =
123 rtc::CheckedDivExact(encoder->SampleRateHz(), 1000);
124 if (!speech_data->Init(
125 file_name,
126 packet_size_ms * audio_samples_per_ms *
127 encoder->num_channels_to_encode(),
128 10 * audio_samples_per_ms * encoder->num_channels_to_encode()))
129 return nullptr;
130 return speech_data;
131 }
132
133 } // namespace
134
135 class AudioEncoderOpusTest : public ::testing::TestWithParam<int> {
136 protected:
137 int sample_rate_hz_{GetParam()};
138 };
139 INSTANTIATE_TEST_SUITE_P(Param,
140 AudioEncoderOpusTest,
141 ::testing::Values(16000, 48000));
142
TEST_P(AudioEncoderOpusTest,DefaultApplicationModeMono)143 TEST_P(AudioEncoderOpusTest, DefaultApplicationModeMono) {
144 auto states = CreateCodec(sample_rate_hz_, 1);
145 EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
146 states->encoder->application());
147 }
148
TEST_P(AudioEncoderOpusTest,DefaultApplicationModeStereo)149 TEST_P(AudioEncoderOpusTest, DefaultApplicationModeStereo) {
150 auto states = CreateCodec(sample_rate_hz_, 2);
151 EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kAudio,
152 states->encoder->application());
153 }
154
TEST_P(AudioEncoderOpusTest,ChangeApplicationMode)155 TEST_P(AudioEncoderOpusTest, ChangeApplicationMode) {
156 auto states = CreateCodec(sample_rate_hz_, 2);
157 EXPECT_TRUE(
158 states->encoder->SetApplication(AudioEncoder::Application::kSpeech));
159 EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
160 states->encoder->application());
161 }
162
TEST_P(AudioEncoderOpusTest,ResetWontChangeApplicationMode)163 TEST_P(AudioEncoderOpusTest, ResetWontChangeApplicationMode) {
164 auto states = CreateCodec(sample_rate_hz_, 2);
165
166 // Trigger a reset.
167 states->encoder->Reset();
168 // Verify that the mode is still kAudio.
169 EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kAudio,
170 states->encoder->application());
171
172 // Now change to kVoip.
173 EXPECT_TRUE(
174 states->encoder->SetApplication(AudioEncoder::Application::kSpeech));
175 EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
176 states->encoder->application());
177
178 // Trigger a reset again.
179 states->encoder->Reset();
180 // Verify that the mode is still kVoip.
181 EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
182 states->encoder->application());
183 }
184
TEST_P(AudioEncoderOpusTest,ToggleDtx)185 TEST_P(AudioEncoderOpusTest, ToggleDtx) {
186 auto states = CreateCodec(sample_rate_hz_, 2);
187 // Enable DTX
188 EXPECT_TRUE(states->encoder->SetDtx(true));
189 EXPECT_TRUE(states->encoder->GetDtx());
190 // Turn off DTX.
191 EXPECT_TRUE(states->encoder->SetDtx(false));
192 EXPECT_FALSE(states->encoder->GetDtx());
193 }
194
TEST_P(AudioEncoderOpusTest,OnReceivedUplinkBandwidthWithoutAudioNetworkAdaptor)195 TEST_P(AudioEncoderOpusTest,
196 OnReceivedUplinkBandwidthWithoutAudioNetworkAdaptor) {
197 auto states = CreateCodec(sample_rate_hz_, 1);
198 // Constants are replicated from audio_states->encoderopus.cc.
199 const int kMinBitrateBps = 6000;
200 const int kMaxBitrateBps = 510000;
201 // Set a too low bitrate.
202 states->encoder->OnReceivedUplinkBandwidth(kMinBitrateBps - 1, absl::nullopt);
203 EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());
204 // Set a too high bitrate.
205 states->encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps + 1, absl::nullopt);
206 EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
207 // Set the minimum rate.
208 states->encoder->OnReceivedUplinkBandwidth(kMinBitrateBps, absl::nullopt);
209 EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());
210 // Set the maximum rate.
211 states->encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps, absl::nullopt);
212 EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
213 // Set rates from kMaxBitrateBps up to 32000 bps.
214 for (int rate = kMinBitrateBps; rate <= 32000; rate += 1000) {
215 states->encoder->OnReceivedUplinkBandwidth(rate, absl::nullopt);
216 EXPECT_EQ(rate, states->encoder->GetTargetBitrate());
217 }
218 }
219
TEST_P(AudioEncoderOpusTest,SetReceiverFrameLengthRange)220 TEST_P(AudioEncoderOpusTest, SetReceiverFrameLengthRange) {
221 auto states = CreateCodec(sample_rate_hz_, 2);
222 // Before calling to |SetReceiverFrameLengthRange|,
223 // |supported_frame_lengths_ms| should contain only the frame length being
224 // used.
225 using ::testing::ElementsAre;
226 EXPECT_THAT(states->encoder->supported_frame_lengths_ms(),
227 ElementsAre(states->encoder->next_frame_length_ms()));
228 states->encoder->SetReceiverFrameLengthRange(0, 12345);
229 states->encoder->SetReceiverFrameLengthRange(21, 60);
230 EXPECT_THAT(states->encoder->supported_frame_lengths_ms(),
231 ElementsAre(40, 60));
232 states->encoder->SetReceiverFrameLengthRange(20, 59);
233 EXPECT_THAT(states->encoder->supported_frame_lengths_ms(),
234 ElementsAre(20, 40));
235 }
236
TEST_P(AudioEncoderOpusTest,InvokeAudioNetworkAdaptorOnReceivedUplinkPacketLossFraction)237 TEST_P(AudioEncoderOpusTest,
238 InvokeAudioNetworkAdaptorOnReceivedUplinkPacketLossFraction) {
239 auto states = CreateCodec(sample_rate_hz_, 2);
240 states->encoder->EnableAudioNetworkAdaptor("", nullptr);
241
242 auto config = CreateEncoderRuntimeConfig();
243 EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
244 .WillOnce(Return(config));
245
246 // Since using mock audio network adaptor, any packet loss fraction is fine.
247 constexpr float kUplinkPacketLoss = 0.1f;
248 EXPECT_CALL(*states->mock_audio_network_adaptor,
249 SetUplinkPacketLossFraction(kUplinkPacketLoss));
250 states->encoder->OnReceivedUplinkPacketLossFraction(kUplinkPacketLoss);
251
252 CheckEncoderRuntimeConfig(states->encoder.get(), config);
253 }
254
TEST_P(AudioEncoderOpusTest,InvokeAudioNetworkAdaptorOnReceivedUplinkBandwidth)255 TEST_P(AudioEncoderOpusTest,
256 InvokeAudioNetworkAdaptorOnReceivedUplinkBandwidth) {
257 test::ScopedFieldTrials override_field_trials(
258 "WebRTC-Audio-StableTargetAdaptation/Disabled/");
259 auto states = CreateCodec(sample_rate_hz_, 2);
260 states->encoder->EnableAudioNetworkAdaptor("", nullptr);
261
262 auto config = CreateEncoderRuntimeConfig();
263 EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
264 .WillOnce(Return(config));
265
266 // Since using mock audio network adaptor, any target audio bitrate is fine.
267 constexpr int kTargetAudioBitrate = 30000;
268 constexpr int64_t kProbingIntervalMs = 3000;
269 EXPECT_CALL(*states->mock_audio_network_adaptor,
270 SetTargetAudioBitrate(kTargetAudioBitrate));
271 EXPECT_CALL(*states->mock_bitrate_smoother,
272 SetTimeConstantMs(kProbingIntervalMs * 4));
273 EXPECT_CALL(*states->mock_bitrate_smoother, AddSample(kTargetAudioBitrate));
274 states->encoder->OnReceivedUplinkBandwidth(kTargetAudioBitrate,
275 kProbingIntervalMs);
276
277 CheckEncoderRuntimeConfig(states->encoder.get(), config);
278 }
279
TEST_P(AudioEncoderOpusTest,InvokeAudioNetworkAdaptorOnReceivedUplinkAllocation)280 TEST_P(AudioEncoderOpusTest,
281 InvokeAudioNetworkAdaptorOnReceivedUplinkAllocation) {
282 auto states = CreateCodec(sample_rate_hz_, 2);
283 states->encoder->EnableAudioNetworkAdaptor("", nullptr);
284
285 auto config = CreateEncoderRuntimeConfig();
286 EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
287 .WillOnce(Return(config));
288
289 BitrateAllocationUpdate update;
290 update.target_bitrate = DataRate::BitsPerSec(30000);
291 update.stable_target_bitrate = DataRate::BitsPerSec(20000);
292 update.bwe_period = TimeDelta::Millis(200);
293 EXPECT_CALL(*states->mock_audio_network_adaptor,
294 SetTargetAudioBitrate(update.target_bitrate.bps()));
295 EXPECT_CALL(*states->mock_audio_network_adaptor,
296 SetUplinkBandwidth(update.stable_target_bitrate.bps()));
297 states->encoder->OnReceivedUplinkAllocation(update);
298
299 CheckEncoderRuntimeConfig(states->encoder.get(), config);
300 }
301
TEST_P(AudioEncoderOpusTest,InvokeAudioNetworkAdaptorOnReceivedRtt)302 TEST_P(AudioEncoderOpusTest, InvokeAudioNetworkAdaptorOnReceivedRtt) {
303 auto states = CreateCodec(sample_rate_hz_, 2);
304 states->encoder->EnableAudioNetworkAdaptor("", nullptr);
305
306 auto config = CreateEncoderRuntimeConfig();
307 EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
308 .WillOnce(Return(config));
309
310 // Since using mock audio network adaptor, any rtt is fine.
311 constexpr int kRtt = 30;
312 EXPECT_CALL(*states->mock_audio_network_adaptor, SetRtt(kRtt));
313 states->encoder->OnReceivedRtt(kRtt);
314
315 CheckEncoderRuntimeConfig(states->encoder.get(), config);
316 }
317
TEST_P(AudioEncoderOpusTest,InvokeAudioNetworkAdaptorOnReceivedOverhead)318 TEST_P(AudioEncoderOpusTest, InvokeAudioNetworkAdaptorOnReceivedOverhead) {
319 auto states = CreateCodec(sample_rate_hz_, 2);
320 states->encoder->EnableAudioNetworkAdaptor("", nullptr);
321
322 auto config = CreateEncoderRuntimeConfig();
323 EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
324 .WillOnce(Return(config));
325
326 // Since using mock audio network adaptor, any overhead is fine.
327 constexpr size_t kOverhead = 64;
328 EXPECT_CALL(*states->mock_audio_network_adaptor, SetOverhead(kOverhead));
329 states->encoder->OnReceivedOverhead(kOverhead);
330
331 CheckEncoderRuntimeConfig(states->encoder.get(), config);
332 }
333
TEST_P(AudioEncoderOpusTest,PacketLossFractionSmoothedOnSetUplinkPacketLossFraction)334 TEST_P(AudioEncoderOpusTest,
335 PacketLossFractionSmoothedOnSetUplinkPacketLossFraction) {
336 auto states = CreateCodec(sample_rate_hz_, 2);
337
338 // The values are carefully chosen so that if no smoothing is made, the test
339 // will fail.
340 constexpr float kPacketLossFraction_1 = 0.02f;
341 constexpr float kPacketLossFraction_2 = 0.198f;
342 // |kSecondSampleTimeMs| is chosen to ease the calculation since
343 // 0.9999 ^ 6931 = 0.5.
344 constexpr int64_t kSecondSampleTimeMs = 6931;
345
346 // First time, no filtering.
347 states->encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_1);
348 EXPECT_FLOAT_EQ(0.02f, states->encoder->packet_loss_rate());
349
350 states->fake_clock->AdvanceTime(TimeDelta::Millis(kSecondSampleTimeMs));
351 states->encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_2);
352
353 // Now the output of packet loss fraction smoother should be
354 // (0.02 + 0.198) / 2 = 0.109.
355 EXPECT_NEAR(0.109f, states->encoder->packet_loss_rate(), 0.001);
356 }
357
TEST_P(AudioEncoderOpusTest,PacketLossRateUpperBounded)358 TEST_P(AudioEncoderOpusTest, PacketLossRateUpperBounded) {
359 auto states = CreateCodec(sample_rate_hz_, 2);
360
361 states->encoder->OnReceivedUplinkPacketLossFraction(0.5);
362 EXPECT_FLOAT_EQ(0.2f, states->encoder->packet_loss_rate());
363 }
364
TEST_P(AudioEncoderOpusTest,DoNotInvokeSetTargetBitrateIfOverheadUnknown)365 TEST_P(AudioEncoderOpusTest, DoNotInvokeSetTargetBitrateIfOverheadUnknown) {
366 test::ScopedFieldTrials override_field_trials(
367 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
368
369 auto states = CreateCodec(sample_rate_hz_, 2);
370
371 states->encoder->OnReceivedUplinkBandwidth(kDefaultOpusRate * 2,
372 absl::nullopt);
373
374 // Since |OnReceivedOverhead| has not been called, the codec bitrate should
375 // not change.
376 EXPECT_EQ(kDefaultOpusRate, states->encoder->GetTargetBitrate());
377 }
378
TEST_P(AudioEncoderOpusTest,OverheadRemovedFromTargetAudioBitrate)379 TEST_P(AudioEncoderOpusTest, OverheadRemovedFromTargetAudioBitrate) {
380 test::ScopedFieldTrials override_field_trials(
381 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
382
383 auto states = CreateCodec(sample_rate_hz_, 2);
384
385 constexpr size_t kOverheadBytesPerPacket = 64;
386 states->encoder->OnReceivedOverhead(kOverheadBytesPerPacket);
387
388 constexpr int kTargetBitrateBps = 40000;
389 states->encoder->OnReceivedUplinkBandwidth(kTargetBitrateBps, absl::nullopt);
390
391 int packet_rate = rtc::CheckedDivExact(48000, kDefaultOpusPacSize);
392 EXPECT_EQ(kTargetBitrateBps -
393 8 * static_cast<int>(kOverheadBytesPerPacket) * packet_rate,
394 states->encoder->GetTargetBitrate());
395 }
396
TEST_P(AudioEncoderOpusTest,BitrateBounded)397 TEST_P(AudioEncoderOpusTest, BitrateBounded) {
398 test::ScopedFieldTrials override_field_trials(
399 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
400
401 constexpr int kMinBitrateBps = 6000;
402 constexpr int kMaxBitrateBps = 510000;
403
404 auto states = CreateCodec(sample_rate_hz_, 2);
405
406 constexpr size_t kOverheadBytesPerPacket = 64;
407 states->encoder->OnReceivedOverhead(kOverheadBytesPerPacket);
408
409 int packet_rate = rtc::CheckedDivExact(48000, kDefaultOpusPacSize);
410
411 // Set a target rate that is smaller than |kMinBitrateBps| when overhead is
412 // subtracted. The eventual codec rate should be bounded by |kMinBitrateBps|.
413 int target_bitrate =
414 kOverheadBytesPerPacket * 8 * packet_rate + kMinBitrateBps - 1;
415 states->encoder->OnReceivedUplinkBandwidth(target_bitrate, absl::nullopt);
416 EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());
417
418 // Set a target rate that is greater than |kMaxBitrateBps| when overhead is
419 // subtracted. The eventual codec rate should be bounded by |kMaxBitrateBps|.
420 target_bitrate =
421 kOverheadBytesPerPacket * 8 * packet_rate + kMaxBitrateBps + 1;
422 states->encoder->OnReceivedUplinkBandwidth(target_bitrate, absl::nullopt);
423 EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
424 }
425
426 // Verifies that the complexity adaptation in the config works as intended.
TEST(AudioEncoderOpusTest,ConfigComplexityAdaptation)427 TEST(AudioEncoderOpusTest, ConfigComplexityAdaptation) {
428 AudioEncoderOpusConfig config;
429 config.low_rate_complexity = 8;
430 config.complexity = 6;
431
432 // Bitrate within hysteresis window. Expect empty output.
433 config.bitrate_bps = 12500;
434 EXPECT_EQ(absl::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));
435
436 // Bitrate below hysteresis window. Expect higher complexity.
437 config.bitrate_bps = 10999;
438 EXPECT_EQ(8, AudioEncoderOpusImpl::GetNewComplexity(config));
439
440 // Bitrate within hysteresis window. Expect empty output.
441 config.bitrate_bps = 12500;
442 EXPECT_EQ(absl::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));
443
444 // Bitrate above hysteresis window. Expect lower complexity.
445 config.bitrate_bps = 14001;
446 EXPECT_EQ(6, AudioEncoderOpusImpl::GetNewComplexity(config));
447 }
448
449 // Verifies that the bandwidth adaptation in the config works as intended.
TEST_P(AudioEncoderOpusTest,ConfigBandwidthAdaptation)450 TEST_P(AudioEncoderOpusTest, ConfigBandwidthAdaptation) {
451 AudioEncoderOpusConfig config;
452 const size_t opus_rate_khz = rtc::CheckedDivExact(sample_rate_hz_, 1000);
453 const std::vector<int16_t> silence(
454 opus_rate_khz * config.frame_size_ms * config.num_channels, 0);
455 constexpr size_t kMaxBytes = 1000;
456 uint8_t bitstream[kMaxBytes];
457
458 OpusEncInst* inst;
459 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(
460 &inst, config.num_channels,
461 config.application ==
462 AudioEncoderOpusConfig::ApplicationMode::kVoip
463 ? 0
464 : 1,
465 sample_rate_hz_));
466
467 // Bitrate below minmum wideband. Expect narrowband.
468 config.bitrate_bps = absl::optional<int>(7999);
469 auto bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
470 EXPECT_EQ(absl::optional<int>(OPUS_BANDWIDTH_NARROWBAND), bandwidth);
471 WebRtcOpus_SetBandwidth(inst, *bandwidth);
472 // It is necessary to encode here because Opus has some logic in the encoder
473 // that goes from the user-set bandwidth to the used and returned one.
474 WebRtcOpus_Encode(inst, silence.data(),
475 rtc::CheckedDivExact(silence.size(), config.num_channels),
476 kMaxBytes, bitstream);
477
478 // Bitrate not yet above maximum narrowband. Expect empty.
479 config.bitrate_bps = absl::optional<int>(9000);
480 bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
481 EXPECT_EQ(absl::optional<int>(), bandwidth);
482
483 // Bitrate above maximum narrowband. Expect wideband.
484 config.bitrate_bps = absl::optional<int>(9001);
485 bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
486 EXPECT_EQ(absl::optional<int>(OPUS_BANDWIDTH_WIDEBAND), bandwidth);
487 WebRtcOpus_SetBandwidth(inst, *bandwidth);
488 // It is necessary to encode here because Opus has some logic in the encoder
489 // that goes from the user-set bandwidth to the used and returned one.
490 WebRtcOpus_Encode(inst, silence.data(),
491 rtc::CheckedDivExact(silence.size(), config.num_channels),
492 kMaxBytes, bitstream);
493
494 // Bitrate not yet below minimum wideband. Expect empty.
495 config.bitrate_bps = absl::optional<int>(8000);
496 bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
497 EXPECT_EQ(absl::optional<int>(), bandwidth);
498
499 // Bitrate above automatic threshold. Expect automatic.
500 config.bitrate_bps = absl::optional<int>(12001);
501 bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
502 EXPECT_EQ(absl::optional<int>(OPUS_AUTO), bandwidth);
503
504 EXPECT_EQ(0, WebRtcOpus_EncoderFree(inst));
505 }
506
TEST_P(AudioEncoderOpusTest,EmptyConfigDoesNotAffectEncoderSettings)507 TEST_P(AudioEncoderOpusTest, EmptyConfigDoesNotAffectEncoderSettings) {
508 auto states = CreateCodec(sample_rate_hz_, 2);
509 states->encoder->EnableAudioNetworkAdaptor("", nullptr);
510
511 auto config = CreateEncoderRuntimeConfig();
512 AudioEncoderRuntimeConfig empty_config;
513
514 EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
515 .WillOnce(Return(config))
516 .WillOnce(Return(empty_config));
517
518 constexpr size_t kOverhead = 64;
519 EXPECT_CALL(*states->mock_audio_network_adaptor, SetOverhead(kOverhead))
520 .Times(2);
521 states->encoder->OnReceivedOverhead(kOverhead);
522 states->encoder->OnReceivedOverhead(kOverhead);
523
524 CheckEncoderRuntimeConfig(states->encoder.get(), config);
525 }
526
TEST_P(AudioEncoderOpusTest,UpdateUplinkBandwidthInAudioNetworkAdaptor)527 TEST_P(AudioEncoderOpusTest, UpdateUplinkBandwidthInAudioNetworkAdaptor) {
528 test::ScopedFieldTrials override_field_trials(
529 "WebRTC-Audio-StableTargetAdaptation/Disabled/");
530 auto states = CreateCodec(sample_rate_hz_, 2);
531 states->encoder->EnableAudioNetworkAdaptor("", nullptr);
532 const size_t opus_rate_khz = rtc::CheckedDivExact(sample_rate_hz_, 1000);
533 const std::vector<int16_t> audio(opus_rate_khz * 10 * 2, 0);
534 rtc::Buffer encoded;
535 EXPECT_CALL(*states->mock_bitrate_smoother, GetAverage())
536 .WillOnce(Return(50000));
537 EXPECT_CALL(*states->mock_audio_network_adaptor, SetUplinkBandwidth(50000));
538 states->encoder->Encode(
539 0, rtc::ArrayView<const int16_t>(audio.data(), audio.size()), &encoded);
540
541 // Repeat update uplink bandwidth tests.
542 for (int i = 0; i < 5; i++) {
543 // Don't update till it is time to update again.
544 states->fake_clock->AdvanceTime(TimeDelta::Millis(
545 states->config.uplink_bandwidth_update_interval_ms - 1));
546 states->encoder->Encode(
547 0, rtc::ArrayView<const int16_t>(audio.data(), audio.size()), &encoded);
548
549 // Update when it is time to update.
550 EXPECT_CALL(*states->mock_bitrate_smoother, GetAverage())
551 .WillOnce(Return(40000));
552 EXPECT_CALL(*states->mock_audio_network_adaptor, SetUplinkBandwidth(40000));
553 states->fake_clock->AdvanceTime(TimeDelta::Millis(1));
554 states->encoder->Encode(
555 0, rtc::ArrayView<const int16_t>(audio.data(), audio.size()), &encoded);
556 }
557 }
558
TEST_P(AudioEncoderOpusTest,EncodeAtMinBitrate)559 TEST_P(AudioEncoderOpusTest, EncodeAtMinBitrate) {
560 auto states = CreateCodec(sample_rate_hz_, 1);
561 constexpr int kNumPacketsToEncode = 2;
562 auto audio_frames =
563 Create10msAudioBlocks(states->encoder, kNumPacketsToEncode * 20);
564 ASSERT_TRUE(audio_frames) << "Create10msAudioBlocks failed";
565 rtc::Buffer encoded;
566 uint32_t rtp_timestamp = 12345; // Just a number not important to this test.
567
568 states->encoder->OnReceivedUplinkBandwidth(0, absl::nullopt);
569 for (int packet_index = 0; packet_index < kNumPacketsToEncode;
570 packet_index++) {
571 // Make sure we are not encoding before we have enough data for
572 // a 20ms packet.
573 for (int index = 0; index < 1; index++) {
574 states->encoder->Encode(rtp_timestamp, audio_frames->GetNextBlock(),
575 &encoded);
576 EXPECT_EQ(0u, encoded.size());
577 }
578
579 // Should encode now.
580 states->encoder->Encode(rtp_timestamp, audio_frames->GetNextBlock(),
581 &encoded);
582 EXPECT_GT(encoded.size(), 0u);
583 encoded.Clear();
584 }
585 }
586
TEST(AudioEncoderOpusTest,TestConfigDefaults)587 TEST(AudioEncoderOpusTest, TestConfigDefaults) {
588 const auto config_opt = AudioEncoderOpus::SdpToConfig({"opus", 48000, 2});
589 ASSERT_TRUE(config_opt);
590 EXPECT_EQ(48000, config_opt->max_playback_rate_hz);
591 EXPECT_EQ(1u, config_opt->num_channels);
592 EXPECT_FALSE(config_opt->fec_enabled);
593 EXPECT_FALSE(config_opt->dtx_enabled);
594 EXPECT_EQ(20, config_opt->frame_size_ms);
595 }
596
TEST(AudioEncoderOpusTest,TestConfigFromParams)597 TEST(AudioEncoderOpusTest, TestConfigFromParams) {
598 const auto config1 = CreateConfigWithParameters({{"stereo", "0"}});
599 EXPECT_EQ(1U, config1.num_channels);
600
601 const auto config2 = CreateConfigWithParameters({{"stereo", "1"}});
602 EXPECT_EQ(2U, config2.num_channels);
603
604 const auto config3 = CreateConfigWithParameters({{"useinbandfec", "0"}});
605 EXPECT_FALSE(config3.fec_enabled);
606
607 const auto config4 = CreateConfigWithParameters({{"useinbandfec", "1"}});
608 EXPECT_TRUE(config4.fec_enabled);
609
610 const auto config5 = CreateConfigWithParameters({{"usedtx", "0"}});
611 EXPECT_FALSE(config5.dtx_enabled);
612
613 const auto config6 = CreateConfigWithParameters({{"usedtx", "1"}});
614 EXPECT_TRUE(config6.dtx_enabled);
615
616 const auto config7 = CreateConfigWithParameters({{"cbr", "0"}});
617 EXPECT_FALSE(config7.cbr_enabled);
618
619 const auto config8 = CreateConfigWithParameters({{"cbr", "1"}});
620 EXPECT_TRUE(config8.cbr_enabled);
621
622 const auto config9 =
623 CreateConfigWithParameters({{"maxplaybackrate", "12345"}});
624 EXPECT_EQ(12345, config9.max_playback_rate_hz);
625
626 const auto config10 =
627 CreateConfigWithParameters({{"maxaveragebitrate", "96000"}});
628 EXPECT_EQ(96000, config10.bitrate_bps);
629
630 const auto config11 = CreateConfigWithParameters({{"maxptime", "40"}});
631 for (int frame_length : config11.supported_frame_lengths_ms) {
632 EXPECT_LE(frame_length, 40);
633 }
634
635 const auto config12 = CreateConfigWithParameters({{"minptime", "40"}});
636 for (int frame_length : config12.supported_frame_lengths_ms) {
637 EXPECT_GE(frame_length, 40);
638 }
639
640 const auto config13 = CreateConfigWithParameters({{"ptime", "40"}});
641 EXPECT_EQ(40, config13.frame_size_ms);
642
643 constexpr int kMinSupportedFrameLength = 10;
644 constexpr int kMaxSupportedFrameLength =
645 WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
646
647 const auto config14 = CreateConfigWithParameters({{"ptime", "1"}});
648 EXPECT_EQ(kMinSupportedFrameLength, config14.frame_size_ms);
649
650 const auto config15 = CreateConfigWithParameters({{"ptime", "2000"}});
651 EXPECT_EQ(kMaxSupportedFrameLength, config15.frame_size_ms);
652 }
653
TEST(AudioEncoderOpusTest,TestConfigFromInvalidParams)654 TEST(AudioEncoderOpusTest, TestConfigFromInvalidParams) {
655 const webrtc::SdpAudioFormat format("opus", 48000, 2);
656 const auto default_config = *AudioEncoderOpus::SdpToConfig(format);
657 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME
658 const std::vector<int> default_supported_frame_lengths_ms({20, 40, 60, 120});
659 #else
660 const std::vector<int> default_supported_frame_lengths_ms({20, 40, 60});
661 #endif
662
663 AudioEncoderOpusConfig config;
664 config = CreateConfigWithParameters({{"stereo", "invalid"}});
665 EXPECT_EQ(default_config.num_channels, config.num_channels);
666
667 config = CreateConfigWithParameters({{"useinbandfec", "invalid"}});
668 EXPECT_EQ(default_config.fec_enabled, config.fec_enabled);
669
670 config = CreateConfigWithParameters({{"usedtx", "invalid"}});
671 EXPECT_EQ(default_config.dtx_enabled, config.dtx_enabled);
672
673 config = CreateConfigWithParameters({{"cbr", "invalid"}});
674 EXPECT_EQ(default_config.dtx_enabled, config.dtx_enabled);
675
676 config = CreateConfigWithParameters({{"maxplaybackrate", "0"}});
677 EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz);
678
679 config = CreateConfigWithParameters({{"maxplaybackrate", "-23"}});
680 EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz);
681
682 config = CreateConfigWithParameters({{"maxplaybackrate", "not a number!"}});
683 EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz);
684
685 config = CreateConfigWithParameters({{"maxaveragebitrate", "0"}});
686 EXPECT_EQ(6000, config.bitrate_bps);
687
688 config = CreateConfigWithParameters({{"maxaveragebitrate", "-1000"}});
689 EXPECT_EQ(6000, config.bitrate_bps);
690
691 config = CreateConfigWithParameters({{"maxaveragebitrate", "1024000"}});
692 EXPECT_EQ(510000, config.bitrate_bps);
693
694 config = CreateConfigWithParameters({{"maxaveragebitrate", "not a number!"}});
695 EXPECT_EQ(default_config.bitrate_bps, config.bitrate_bps);
696
697 config = CreateConfigWithParameters({{"maxptime", "invalid"}});
698 EXPECT_EQ(default_supported_frame_lengths_ms,
699 config.supported_frame_lengths_ms);
700
701 config = CreateConfigWithParameters({{"minptime", "invalid"}});
702 EXPECT_EQ(default_supported_frame_lengths_ms,
703 config.supported_frame_lengths_ms);
704
705 config = CreateConfigWithParameters({{"ptime", "invalid"}});
706 EXPECT_EQ(default_supported_frame_lengths_ms,
707 config.supported_frame_lengths_ms);
708 }
709
710 // Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
711 // Also test that the "maxaveragebitrate" can't be set to values outside the
712 // range of 6000 and 510000
TEST(AudioEncoderOpusTest,SetSendCodecOpusMaxAverageBitrate)713 TEST(AudioEncoderOpusTest, SetSendCodecOpusMaxAverageBitrate) {
714 // Ignore if less than 6000.
715 const auto config1 = AudioEncoderOpus::SdpToConfig(
716 {"opus", 48000, 2, {{"maxaveragebitrate", "5999"}}});
717 EXPECT_EQ(6000, config1->bitrate_bps);
718
719 // Ignore if larger than 510000.
720 const auto config2 = AudioEncoderOpus::SdpToConfig(
721 {"opus", 48000, 2, {{"maxaveragebitrate", "510001"}}});
722 EXPECT_EQ(510000, config2->bitrate_bps);
723
724 const auto config3 = AudioEncoderOpus::SdpToConfig(
725 {"opus", 48000, 2, {{"maxaveragebitrate", "200000"}}});
726 EXPECT_EQ(200000, config3->bitrate_bps);
727 }
728
729 // Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
TEST(AudioEncoderOpusTest,SetMaxPlaybackRateNb)730 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateNb) {
731 auto config = CreateConfigWithParameters({{"maxplaybackrate", "8000"}});
732 EXPECT_EQ(8000, config.max_playback_rate_hz);
733 EXPECT_EQ(12000, config.bitrate_bps);
734
735 config = CreateConfigWithParameters(
736 {{"maxplaybackrate", "8000"}, {"stereo", "1"}});
737 EXPECT_EQ(8000, config.max_playback_rate_hz);
738 EXPECT_EQ(24000, config.bitrate_bps);
739 }
740
741 // Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
TEST(AudioEncoderOpusTest,SetMaxPlaybackRateMb)742 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateMb) {
743 auto config = CreateConfigWithParameters({{"maxplaybackrate", "8001"}});
744 EXPECT_EQ(8001, config.max_playback_rate_hz);
745 EXPECT_EQ(20000, config.bitrate_bps);
746
747 config = CreateConfigWithParameters(
748 {{"maxplaybackrate", "8001"}, {"stereo", "1"}});
749 EXPECT_EQ(8001, config.max_playback_rate_hz);
750 EXPECT_EQ(40000, config.bitrate_bps);
751 }
752
753 // Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
TEST(AudioEncoderOpusTest,SetMaxPlaybackRateWb)754 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateWb) {
755 auto config = CreateConfigWithParameters({{"maxplaybackrate", "12001"}});
756 EXPECT_EQ(12001, config.max_playback_rate_hz);
757 EXPECT_EQ(20000, config.bitrate_bps);
758
759 config = CreateConfigWithParameters(
760 {{"maxplaybackrate", "12001"}, {"stereo", "1"}});
761 EXPECT_EQ(12001, config.max_playback_rate_hz);
762 EXPECT_EQ(40000, config.bitrate_bps);
763 }
764
765 // Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
TEST(AudioEncoderOpusTest,SetMaxPlaybackRateSwb)766 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateSwb) {
767 auto config = CreateConfigWithParameters({{"maxplaybackrate", "16001"}});
768 EXPECT_EQ(16001, config.max_playback_rate_hz);
769 EXPECT_EQ(32000, config.bitrate_bps);
770
771 config = CreateConfigWithParameters(
772 {{"maxplaybackrate", "16001"}, {"stereo", "1"}});
773 EXPECT_EQ(16001, config.max_playback_rate_hz);
774 EXPECT_EQ(64000, config.bitrate_bps);
775 }
776
777 // Test 24000 < maxplaybackrate triggers Opus full band mode.
TEST(AudioEncoderOpusTest,SetMaxPlaybackRateFb)778 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateFb) {
779 auto config = CreateConfigWithParameters({{"maxplaybackrate", "24001"}});
780 EXPECT_EQ(24001, config.max_playback_rate_hz);
781 EXPECT_EQ(32000, config.bitrate_bps);
782
783 config = CreateConfigWithParameters(
784 {{"maxplaybackrate", "24001"}, {"stereo", "1"}});
785 EXPECT_EQ(24001, config.max_playback_rate_hz);
786 EXPECT_EQ(64000, config.bitrate_bps);
787 }
788
TEST_P(AudioEncoderOpusTest,OpusFlagDtxAsNonSpeech)789 TEST_P(AudioEncoderOpusTest, OpusFlagDtxAsNonSpeech) {
790 // Create encoder with DTX enabled.
791 AudioEncoderOpusConfig config;
792 config.dtx_enabled = true;
793 config.sample_rate_hz = sample_rate_hz_;
794 constexpr int payload_type = 17;
795 const auto encoder = AudioEncoderOpus::MakeAudioEncoder(config, payload_type);
796
797 // Open file containing speech and silence.
798 const std::string kInputFileName =
799 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
800 test::AudioLoop audio_loop;
801 // Use the file as if it were sampled at our desired input rate.
802 const size_t max_loop_length_samples =
803 sample_rate_hz_ * 10; // Max 10 second loop.
804 const size_t input_block_size_samples =
805 10 * sample_rate_hz_ / 1000; // 10 ms.
806 EXPECT_TRUE(audio_loop.Init(kInputFileName, max_loop_length_samples,
807 input_block_size_samples));
808
809 // Encode.
810 AudioEncoder::EncodedInfo info;
811 rtc::Buffer encoded(500);
812 int nonspeech_frames = 0;
813 int max_nonspeech_frames = 0;
814 int dtx_frames = 0;
815 int max_dtx_frames = 0;
816 uint32_t rtp_timestamp = 0u;
817 for (size_t i = 0; i < 500; ++i) {
818 encoded.Clear();
819
820 // Every second call to the encoder will generate an Opus packet.
821 for (int j = 0; j < 2; j++) {
822 info =
823 encoder->Encode(rtp_timestamp, audio_loop.GetNextBlock(), &encoded);
824 rtp_timestamp += input_block_size_samples;
825 }
826
827 // Bookkeeping of number of DTX frames.
828 if (info.encoded_bytes <= 2) {
829 ++dtx_frames;
830 } else {
831 if (dtx_frames > max_dtx_frames)
832 max_dtx_frames = dtx_frames;
833 dtx_frames = 0;
834 }
835
836 // Bookkeeping of number of non-speech frames.
837 if (info.speech == 0) {
838 ++nonspeech_frames;
839 } else {
840 if (nonspeech_frames > max_nonspeech_frames)
841 max_nonspeech_frames = nonspeech_frames;
842 nonspeech_frames = 0;
843 }
844 }
845
846 // Maximum number of consecutive non-speech packets should exceed 15.
847 EXPECT_GT(max_nonspeech_frames, 15);
848 }
849
850 } // namespace webrtc
851