Audio encoder tests: Create audio encoders the new way
Specifically, don't expect the ACM to be able to create encoders; we
have to give it an encoder that we make ourselves.
The new way of creating encoders used a 32 kbit/s bitrate
unconditionally for iSAC; I had to change it to 32 kbit/s for 16 kHz
and 56 kbit/s for 32 kHz, which is what the old way of creating
encoders has used since forever.
I also had to change some test expectations on Opus, because the new
way defaults to 32 kbit/s for mono and 64 kbit/s for stereo (which I
believe to be correct), while the old way defaults to 64 kbit/s in
both cases.
Bug: webrtc:8396
Change-Id: I3aab944175a8e27f4c63380e822b27e839bba7f2
Reviewed-on: https://webrtc-review.googlesource.com/94540
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24375}
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index 2829db4..de2aeb7 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -1406,8 +1406,10 @@
"../../api/audio:audio_frame_api",
"../../rtc_base:checks",
":audio_coding",
+ ":audio_format_conversion",
":neteq_tools",
"../../api/audio_codecs:builtin_audio_decoder_factory",
+ "../../api/audio_codecs:builtin_audio_encoder_factory",
"../../api/audio_codecs:audio_codecs_api",
"../../rtc_base:rtc_base_approved",
"../../test:test_support",
diff --git a/modules/audio_coding/acm2/acm_send_test.cc b/modules/audio_coding/acm2/acm_send_test.cc
index b1a3e98..c5e010c 100644
--- a/modules/audio_coding/acm2/acm_send_test.cc
+++ b/modules/audio_coding/acm2/acm_send_test.cc
@@ -16,10 +16,13 @@
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/audio_codecs/builtin_audio_encoder_factory.h"
+#include "modules/audio_coding/codecs/audio_format_conversion.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "modules/audio_coding/neteq/tools/packet.h"
#include "rtc_base/checks.h"
+#include "rtc_base/stringencode.h"
#include "test/gtest.h"
namespace webrtc {
@@ -65,20 +68,26 @@
sampling_freq_hz, channels));
codec.pltype = payload_type;
codec.pacsize = frame_size_samples;
- codec_registered_ = (acm_->RegisterSendCodec(codec) == 0);
+ auto factory = CreateBuiltinAudioEncoderFactory();
+ SdpAudioFormat format = CodecInstToSdp(codec);
+ format.parameters["ptime"] = rtc::ToString(rtc::CheckedDivExact(
+ frame_size_samples, rtc::CheckedDivExact(sampling_freq_hz, 1000)));
+ acm_->SetEncoder(
+ factory->MakeAudioEncoder(payload_type, format, absl::nullopt));
+ codec_registered_ = true;
input_frame_.num_channels_ = channels;
assert(input_block_size_samples_ * input_frame_.num_channels_ <=
AudioFrame::kMaxDataSizeSamples);
return codec_registered_;
}
-bool AcmSendTestOldApi::RegisterExternalCodec(
- AudioEncoder* external_speech_encoder) {
- acm_->RegisterExternalSendCodec(external_speech_encoder);
+void AcmSendTestOldApi::RegisterExternalCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder) {
input_frame_.num_channels_ = external_speech_encoder->NumChannels();
+ acm_->SetEncoder(std::move(external_speech_encoder));
assert(input_block_size_samples_ * input_frame_.num_channels_ <=
AudioFrame::kMaxDataSizeSamples);
- return codec_registered_ = true;
+ codec_registered_ = true;
}
std::unique_ptr<Packet> AcmSendTestOldApi::NextPacket() {
diff --git a/modules/audio_coding/acm2/acm_send_test.h b/modules/audio_coding/acm2/acm_send_test.h
index 68ba9e1..3479de0 100644
--- a/modules/audio_coding/acm2/acm_send_test.h
+++ b/modules/audio_coding/acm2/acm_send_test.h
@@ -42,8 +42,9 @@
int payload_type,
int frame_size_samples);
- // Registers an external send codec. Returns true on success, false otherwise.
- bool RegisterExternalCodec(AudioEncoder* external_speech_encoder);
+ // Registers an external send codec.
+ void RegisterExternalCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder);
// Inherited from PacketSource.
std::unique_ptr<Packet> NextPacket() override;
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index 01f83a7..924a4a6 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -1148,13 +1148,14 @@
payload_type, frame_size_samples);
}
- bool RegisterExternalSendCodec(AudioEncoder* external_speech_encoder,
- int payload_type) {
+ void RegisterExternalSendCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder,
+ int payload_type) {
payload_type_ = payload_type;
frame_size_rtp_timestamps_ = rtc::checked_cast<uint32_t>(
external_speech_encoder->Num10MsFramesInNextPacket() *
external_speech_encoder->RtpTimestampRateHz() / 100);
- return send_test_->RegisterExternalCodec(external_speech_encoder);
+ send_test_->RegisterExternalCodec(std::move(external_speech_encoder));
}
// Runs the test. SetUpSender() and RegisterSendCodec() must have been called
@@ -1249,11 +1250,11 @@
codec_frame_size_rtp_timestamps));
}
- void SetUpTestExternalEncoder(AudioEncoder* external_speech_encoder,
- int payload_type) {
+ void SetUpTestExternalEncoder(
+ std::unique_ptr<AudioEncoder> external_speech_encoder,
+ int payload_type) {
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(
- RegisterExternalSendCodec(external_speech_encoder, payload_type));
+ RegisterExternalSendCodec(std::move(external_speech_encoder), payload_type);
}
std::unique_ptr<test::AcmSendTestOldApi> send_test_;
@@ -1460,8 +1461,8 @@
TEST_F(AcmSenderBitExactnessNewApi, MAYBE_OpusFromFormat_stereo_20ms) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 120);
- ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(encoder.get(), 120));
+ ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(
+ AudioEncoderOpus::MakeAudioEncoder(*config, 120), 120));
Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
"3e285b74510e62062fbd8142dacd16e9",
"3e285b74510e62062fbd8142dacd16e9",
@@ -1499,8 +1500,8 @@
TEST_F(AcmSenderBitExactnessNewApi, OpusFromFormat_stereo_20ms_voip) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 120);
- ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(encoder.get(), 120));
+ ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(
+ AudioEncoderOpus::MakeAudioEncoder(*config, 120), 120));
// If not set, default will be kAudio in case of stereo.
EXPECT_EQ(0, send_test_->acm()->SetOpusApplication(kVoip));
Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
@@ -1550,9 +1551,10 @@
payload_type, frame_size_samples);
}
- bool RegisterExternalSendCodec(AudioEncoder* external_speech_encoder,
- int payload_type) {
- return send_test_->RegisterExternalCodec(external_speech_encoder);
+ void RegisterExternalSendCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder,
+ int payload_type) {
+ send_test_->RegisterExternalCodec(std::move(external_speech_encoder));
}
void RunInner(int min_expected_total_bits, int max_expected_total_bits) {
@@ -1611,9 +1613,9 @@
TEST_F(AcmSetBitRateNewApi, OpusFromFormat_48khz_20ms_10kbps) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "10000"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 107);
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(RegisterExternalSendCodec(encoder.get(), 107));
+ RegisterExternalSendCodec(AudioEncoderOpus::MakeAudioEncoder(*config, 107),
+ 107);
RunInner(8000, 12000);
}
@@ -1625,9 +1627,9 @@
TEST_F(AcmSetBitRateNewApi, OpusFromFormat_48khz_20ms_50kbps) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "50000"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 107);
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(RegisterExternalSendCodec(encoder.get(), 107));
+ RegisterExternalSendCodec(AudioEncoderOpus::MakeAudioEncoder(*config, 107),
+ 107);
RunInner(40000, 60000);
}
@@ -1650,9 +1652,9 @@
TEST_F(AcmSetBitRateNewApi, MAYBE_OpusFromFormat_48khz_20ms_100kbps) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "100000"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 107);
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(RegisterExternalSendCodec(encoder.get(), 107));
+ RegisterExternalSendCodec(AudioEncoderOpus::MakeAudioEncoder(*config, 107),
+ 107);
RunInner(80000, 120000);
}
@@ -1724,17 +1726,17 @@
TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_10kbps_2) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
- Run(10000, 32200, 5208);
+ Run(10000, 14096, 4232);
}
TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_50kbps_2) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
- Run(50000, 32200, 23928);
+ Run(50000, 14096, 22552);
}
TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_100kbps_2) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
- Run(100000, 32200, 50448);
+ Run(100000, 14096, 49472);
}
// These next 2 tests ensure that the SetBitRate function has no effect on PCM
@@ -1754,36 +1756,33 @@
codec_inst.pacsize = 160;
codec_inst.pltype = 0;
AudioEncoderPcmU encoder(codec_inst);
- MockAudioEncoder mock_encoder;
+ auto mock_encoder = absl::make_unique<MockAudioEncoder>();
// Set expectations on the mock encoder and also delegate the calls to the
// real encoder.
- EXPECT_CALL(mock_encoder, SampleRateHz())
+ EXPECT_CALL(*mock_encoder, SampleRateHz())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SampleRateHz));
- EXPECT_CALL(mock_encoder, NumChannels())
+ EXPECT_CALL(*mock_encoder, NumChannels())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::NumChannels));
- EXPECT_CALL(mock_encoder, RtpTimestampRateHz())
+ EXPECT_CALL(*mock_encoder, RtpTimestampRateHz())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::RtpTimestampRateHz));
- EXPECT_CALL(mock_encoder, Num10MsFramesInNextPacket())
+ EXPECT_CALL(*mock_encoder, Num10MsFramesInNextPacket())
.Times(AtLeast(1))
.WillRepeatedly(
Invoke(&encoder, &AudioEncoderPcmU::Num10MsFramesInNextPacket));
- EXPECT_CALL(mock_encoder, GetTargetBitrate())
+ EXPECT_CALL(*mock_encoder, GetTargetBitrate())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::GetTargetBitrate));
- EXPECT_CALL(mock_encoder, EncodeImpl(_, _, _))
+ EXPECT_CALL(*mock_encoder, EncodeImpl(_, _, _))
.Times(AtLeast(1))
.WillRepeatedly(Invoke(
&encoder, static_cast<AudioEncoder::EncodedInfo (AudioEncoder::*)(
uint32_t, rtc::ArrayView<const int16_t>, rtc::Buffer*)>(
&AudioEncoderPcmU::Encode)));
- EXPECT_CALL(mock_encoder, SetFec(_))
- .Times(AtLeast(1))
- .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SetFec));
ASSERT_NO_FATAL_FAILURE(
- SetUpTestExternalEncoder(&mock_encoder, codec_inst.pltype));
+ SetUpTestExternalEncoder(std::move(mock_encoder), codec_inst.pltype));
Run("81a9d4c0bb72e9becc43aef124c981e9", "8f9b8750bd80fe26b6cbf6659b89f0f9",
50, test::AcmReceiveTestOldApi::kMonoOutput);
}