diff --git a/modules/audio_coding/neteq/neteq_impl_unittest.cc b/modules/audio_coding/neteq/neteq_impl_unittest.cc index 0e087c847f..784c63c28f 100644 --- a/modules/audio_coding/neteq/neteq_impl_unittest.cc +++ b/modules/audio_coding/neteq/neteq_impl_unittest.cc @@ -10,6 +10,7 @@ #include +#include "absl/memory/memory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "common_types.h" // NOLINT(build/include) #include "modules/audio_coding/neteq/accelerate.h" @@ -28,6 +29,7 @@ #include "modules/audio_coding/neteq/sync_buffer.h" #include "modules/audio_coding/neteq/timestamp_scaler.h" #include "rtc_base/numerics/safe_conversions.h" +#include "test/function_audio_decoder_factory.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/mock_audio_decoder.h" @@ -59,8 +61,10 @@ class NetEqImplTest : public ::testing::Test { protected: NetEqImplTest() { config_.sample_rate_hz = 8000; } - void CreateInstance() { - NetEqImpl::Dependencies deps(config_, CreateBuiltinAudioDecoderFactory()); + void CreateInstance( + const rtc::scoped_refptr& decoder_factory) { + ASSERT_TRUE(decoder_factory); + NetEqImpl::Dependencies deps(config_, decoder_factory); // Get a local pointer to NetEq's TickTimer object. tick_timer_ = deps.tick_timer.get(); @@ -137,6 +141,8 @@ class NetEqImplTest : public ::testing::Test { ASSERT_TRUE(neteq_ != NULL); } + void CreateInstance() { CreateInstance(CreateBuiltinAudioDecoderFactory()); } + void UseNoMocks() { ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance"; use_mock_buffer_level_filter_ = false; @@ -1328,13 +1334,17 @@ class NetEqImplTest120ms : public NetEqImplTest { void CreateInstanceNoMocks() { UseNoMocks(); - CreateInstance(); + CreateInstance(decoder_factory_); + EXPECT_TRUE(neteq_->RegisterPayloadType( + kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}}))); } void CreateInstanceWithDelayManagerMock() { UseNoMocks(); use_mock_delay_manager_ = true; - CreateInstance(); + CreateInstance(decoder_factory_); + EXPECT_TRUE(neteq_->RegisterPayloadType( + kPayloadType, SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}}))); } uint32_t timestamp_diff_between_packets() const { @@ -1364,14 +1374,18 @@ class NetEqImplTest120ms : public NetEqImplTest { } void Register120msCodec(AudioDecoder::SpeechType speech_type) { - decoder_.reset(new Decoder120ms(kSamplingFreq_, speech_type)); - ASSERT_EQ(2u, decoder_->Channels()); - EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( - decoder_.get(), NetEqDecoder::kDecoderOpus_2ch, - "120ms codec", kPayloadType)); + const uint32_t sampling_freq = kSamplingFreq_; + decoder_factory_ = + new rtc::RefCountedObject( + [sampling_freq, speech_type]() { + std::unique_ptr decoder = + absl::make_unique(sampling_freq, speech_type); + RTC_CHECK_EQ(2, decoder->Channels()); + return decoder; + }); } - std::unique_ptr decoder_; + rtc::scoped_refptr decoder_factory_; AudioFrame output_; const uint32_t kPayloadType = 17; const uint32_t kSamplingFreq_ = 48000; @@ -1379,8 +1393,8 @@ class NetEqImplTest120ms : public NetEqImplTest { }; TEST_F(NetEqImplTest120ms, CodecInternalCng) { - CreateInstanceNoMocks(); Register120msCodec(AudioDecoder::kComfortNoise); + CreateInstanceNoMocks(); InsertPacket(first_timestamp()); GetFirstPacket(); @@ -1391,8 +1405,8 @@ TEST_F(NetEqImplTest120ms, CodecInternalCng) { } TEST_F(NetEqImplTest120ms, Normal) { - CreateInstanceNoMocks(); Register120msCodec(AudioDecoder::kSpeech); + CreateInstanceNoMocks(); InsertPacket(first_timestamp()); GetFirstPacket(); @@ -1401,9 +1415,9 @@ TEST_F(NetEqImplTest120ms, Normal) { } TEST_F(NetEqImplTest120ms, Merge) { + Register120msCodec(AudioDecoder::kSpeech); CreateInstanceWithDelayManagerMock(); - Register120msCodec(AudioDecoder::kSpeech); InsertPacket(first_timestamp()); GetFirstPacket(); @@ -1420,8 +1434,8 @@ TEST_F(NetEqImplTest120ms, Merge) { } TEST_F(NetEqImplTest120ms, Expand) { - CreateInstanceNoMocks(); Register120msCodec(AudioDecoder::kSpeech); + CreateInstanceNoMocks(); InsertPacket(first_timestamp()); GetFirstPacket(); @@ -1432,8 +1446,8 @@ TEST_F(NetEqImplTest120ms, Expand) { } TEST_F(NetEqImplTest120ms, FastAccelerate) { - CreateInstanceWithDelayManagerMock(); Register120msCodec(AudioDecoder::kSpeech); + CreateInstanceWithDelayManagerMock(); InsertPacket(first_timestamp()); GetFirstPacket(); @@ -1450,8 +1464,8 @@ TEST_F(NetEqImplTest120ms, FastAccelerate) { } TEST_F(NetEqImplTest120ms, PreemptiveExpand) { - CreateInstanceWithDelayManagerMock(); Register120msCodec(AudioDecoder::kSpeech); + CreateInstanceWithDelayManagerMock(); InsertPacket(first_timestamp()); GetFirstPacket(); @@ -1469,8 +1483,8 @@ TEST_F(NetEqImplTest120ms, PreemptiveExpand) { } TEST_F(NetEqImplTest120ms, Accelerate) { - CreateInstanceWithDelayManagerMock(); Register120msCodec(AudioDecoder::kSpeech); + CreateInstanceWithDelayManagerMock(); InsertPacket(first_timestamp()); GetFirstPacket(); diff --git a/test/BUILD.gn b/test/BUILD.gn index 70e53f5d2c..1557af2513 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -830,6 +830,7 @@ rtc_source_set("test_renderer_generic") { rtc_source_set("audio_codec_mocks") { testonly = true sources = [ + "function_audio_decoder_factory.h", "mock_audio_decoder.cc", "mock_audio_decoder.h", "mock_audio_decoder_factory.h", @@ -843,7 +844,9 @@ rtc_source_set("audio_codec_mocks") { "../api:array_view", "../api/audio_codecs:audio_codecs_api", "../api/audio_codecs:builtin_audio_decoder_factory", + "../rtc_base:checks", "../rtc_base:rtc_base_approved", + "//third_party/abseil-cpp/absl/memory", ] } diff --git a/test/function_audio_decoder_factory.h b/test/function_audio_decoder_factory.h new file mode 100644 index 0000000000..a5ee593a7a --- /dev/null +++ b/test/function_audio_decoder_factory.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef TEST_FUNCTION_AUDIO_DECODER_FACTORY_H_ +#define TEST_FUNCTION_AUDIO_DECODER_FACTORY_H_ + +#include +#include +#include +#include + +#include "absl/memory/memory.h" +#include "api/audio_codecs/audio_decoder_factory.h" +#include "api/audio_codecs/audio_format.h" +#include "rtc_base/checks.h" + +namespace webrtc { +namespace test { + +// A decoder factory producing decoders by calling a supplied create function. +class FunctionAudioDecoderFactory : public AudioDecoderFactory { + public: + explicit FunctionAudioDecoderFactory( + std::function()> create) + : create_([create](const SdpAudioFormat&, + absl::optional codec_pair_id) { + return create(); + }) {} + explicit FunctionAudioDecoderFactory( + std::function( + const SdpAudioFormat&, + absl::optional codec_pair_id)> create) + : create_(std::move(create)) {} + + // Unused by tests. + std::vector GetSupportedDecoders() override { + RTC_NOTREACHED(); + return {}; + } + + bool IsSupportedDecoder(const SdpAudioFormat& format) override { + return true; + } + + std::unique_ptr MakeAudioDecoder( + const SdpAudioFormat& format, + absl::optional codec_pair_id) override { + return create_(format, codec_pair_id); + } + + private: + const std::function( + const SdpAudioFormat&, + absl::optional codec_pair_id)> + create_; +}; + +} // namespace test +} // namespace webrtc + +#endif // TEST_FUNCTION_AUDIO_DECODER_FACTORY_H_