From 1a610f15c3f5cb88b119551cc5d5f5c23884afc7 Mon Sep 17 00:00:00 2001 From: charujain Date: Sun, 18 Jun 2017 02:38:58 -0700 Subject: [PATCH] Revert of Opus implementation of the AudioEncoderFactoryTemplate API (patchset #4 id:80001 of https://codereview.webrtc.org/2930243003/ ) Reason for revert: Breaking google3 projects Original issue's description: > Opus implementation of the AudioEncoderFactoryTemplate API > > Now the templated AudioEncoderFactory can create Opus encoders! > > BUG=webrtc:7831 > > Review-Url: https://codereview.webrtc.org/2930243003 > Cr-Commit-Position: refs/heads/master@{#18645} > Committed: https://chromium.googlesource.com/external/webrtc/+/fe1aa82c63380c2f79c60cbe1f50ed13144a093f TBR=ossu@webrtc.org,solenberg@webrtc.org,kwiberg@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:7831 Review-Url: https://codereview.webrtc.org/2947563002 Cr-Commit-Position: refs/heads/master@{#18649} --- webrtc/api/audio_codecs/opus/BUILD.gn | 43 --- .../audio_codecs/opus/audio_encoder_opus.cc | 52 ---- .../audio_codecs/opus/audio_encoder_opus.h | 40 --- .../opus/audio_encoder_opus_config.cc | 67 ----- .../opus/audio_encoder_opus_config.h | 63 ---- webrtc/api/audio_codecs/test/BUILD.gn | 1 - ...audio_encoder_factory_template_unittest.cc | 23 -- webrtc/modules/audio_coding/BUILD.gn | 7 +- .../acm2/audio_coding_module_unittest.cc | 10 +- .../modules/audio_coding/acm2/rent_a_codec.cc | 2 +- .../builtin_audio_encoder_factory_internal.cc | 2 +- .../codecs/opus/audio_encoder_opus.cc | 271 ++++++++++-------- .../codecs/opus/audio_encoder_opus.h | 83 ++++-- .../opus/audio_encoder_opus_unittest.cc | 177 ++++++------ .../codecs/opus/opus_complexity_unittest.cc | 17 +- .../neteq/audio_decoder_unittest.cc | 16 +- 16 files changed, 316 insertions(+), 558 deletions(-) delete mode 100644 webrtc/api/audio_codecs/opus/BUILD.gn delete mode 100644 webrtc/api/audio_codecs/opus/audio_encoder_opus.cc delete mode 100644 webrtc/api/audio_codecs/opus/audio_encoder_opus.h delete mode 100644 webrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc delete mode 100644 webrtc/api/audio_codecs/opus/audio_encoder_opus_config.h diff --git a/webrtc/api/audio_codecs/opus/BUILD.gn b/webrtc/api/audio_codecs/opus/BUILD.gn deleted file mode 100644 index 426403003e..0000000000 --- a/webrtc/api/audio_codecs/opus/BUILD.gn +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2017 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. - -import("../../../webrtc.gni") -if (is_android) { - import("//build/config/android/config.gni") - import("//build/config/android/rules.gni") -} - -rtc_static_library("audio_encoder_opus_config") { - sources = [ - "audio_encoder_opus_config.cc", - "audio_encoder_opus_config.h", - ] - deps = [ - "../../../base:rtc_base_approved", - ] - defines = [] - if (rtc_opus_variable_complexity) { - defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=1" ] - } else { - defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=0" ] - } -} - -rtc_static_library("audio_encoder_opus") { - sources = [ - "audio_encoder_opus.cc", - "audio_encoder_opus.h", - ] - deps = [ - ":audio_encoder_opus_config", - "..:audio_codecs_api", - "../../../base:protobuf_utils", # TODO(kwiberg): Why is this needed? - "../../../base:rtc_base_approved", - "../../../modules/audio_coding:webrtc_opus", - ] -} diff --git a/webrtc/api/audio_codecs/opus/audio_encoder_opus.cc b/webrtc/api/audio_codecs/opus/audio_encoder_opus.cc deleted file mode 100644 index 0969561ed1..0000000000 --- a/webrtc/api/audio_codecs/opus/audio_encoder_opus.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#include "webrtc/api/audio_codecs/opus/audio_encoder_opus.h" - -#include -#include - -#include "webrtc/base/ptr_util.h" -#include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" - -namespace webrtc { - -rtc::Optional AudioEncoderOpus::SdpToConfig( - const SdpAudioFormat& format) { - return AudioEncoderOpusImpl::SdpToConfig(format); -} - -void AudioEncoderOpus::AppendSupportedEncoders( - std::vector* specs) { - const SdpAudioFormat fmt = { - "opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}}; - const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt)); - specs->push_back({fmt, info}); -} - -AudioCodecInfo AudioEncoderOpus::QueryAudioEncoder( - const AudioEncoderOpusConfig& config) { - RTC_DCHECK(config.IsOk()); - AudioCodecInfo info(48000, config.num_channels, config.bitrate_bps, - AudioEncoderOpusConfig::kMinBitrateBps, - AudioEncoderOpusConfig::kMaxBitrateBps); - info.allow_comfort_noise = false; - info.supports_network_adaption = true; - return info; -} - -std::unique_ptr AudioEncoderOpus::MakeAudioEncoder( - const AudioEncoderOpusConfig& config, - int payload_type) { - RTC_DCHECK(config.IsOk()); - return rtc::MakeUnique(config, payload_type); -} - -} // namespace webrtc diff --git a/webrtc/api/audio_codecs/opus/audio_encoder_opus.h b/webrtc/api/audio_codecs/opus/audio_encoder_opus.h deleted file mode 100644 index e5bee31646..0000000000 --- a/webrtc/api/audio_codecs/opus/audio_encoder_opus.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2017 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 WEBRTC_API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_ -#define WEBRTC_API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_ - -#include -#include - -#include "webrtc/api/audio_codecs/audio_encoder.h" -#include "webrtc/api/audio_codecs/audio_format.h" -#include "webrtc/api/audio_codecs/opus/audio_encoder_opus_config.h" -#include "webrtc/base/optional.h" - -namespace webrtc { - -// Opus encoder API for use as a template parameter to -// CreateAudioEncoderFactory<...>(). -// -// NOTE: This struct is still under development and may change without notice. -struct AudioEncoderOpus { - static rtc::Optional SdpToConfig( - const SdpAudioFormat& audio_format); - static void AppendSupportedEncoders(std::vector* specs); - static AudioCodecInfo QueryAudioEncoder(const AudioEncoderOpusConfig& config); - static std::unique_ptr MakeAudioEncoder( - const AudioEncoderOpusConfig&, - int payload_type); -}; - -} // namespace webrtc - -#endif // WEBRTC_API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_ diff --git a/webrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc b/webrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc deleted file mode 100644 index d4e12e8ce8..0000000000 --- a/webrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#include "webrtc/api/audio_codecs/opus/audio_encoder_opus_config.h" - -namespace webrtc { - -namespace { - -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) || defined(WEBRTC_ARCH_ARM) -// If we are on Android, iOS and/or ARM, use a lower complexity setting by -// default, to save encoder complexity. -constexpr int kDefaultComplexity = 5; -#else -constexpr int kDefaultComplexity = 9; -#endif - -constexpr int kDefaultLowRateComplexity = - WEBRTC_OPUS_VARIABLE_COMPLEXITY ? 9 : kDefaultComplexity; - -} // namespace - -constexpr int AudioEncoderOpusConfig::kDefaultFrameSizeMs; -constexpr int AudioEncoderOpusConfig::kMinBitrateBps; -constexpr int AudioEncoderOpusConfig::kMaxBitrateBps; - -AudioEncoderOpusConfig::AudioEncoderOpusConfig() - : frame_size_ms(kDefaultFrameSizeMs), - num_channels(1), - application(ApplicationMode::kVoip), - bitrate_bps(32000), - fec_enabled(false), - cbr_enabled(false), - max_playback_rate_hz(48000), - complexity(kDefaultComplexity), - low_rate_complexity(kDefaultLowRateComplexity), - complexity_threshold_bps(12500), - complexity_threshold_window_bps(1500), - dtx_enabled(false), - uplink_bandwidth_update_interval_ms(200) {} -AudioEncoderOpusConfig::AudioEncoderOpusConfig(const AudioEncoderOpusConfig&) = - default; -AudioEncoderOpusConfig::~AudioEncoderOpusConfig() = default; -AudioEncoderOpusConfig& AudioEncoderOpusConfig::operator=( - const AudioEncoderOpusConfig&) = default; - -bool AudioEncoderOpusConfig::IsOk() const { - if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) - return false; - if (num_channels != 1 && num_channels != 2) - return false; - if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps) - return false; - if (complexity < 0 || complexity > 10) - return false; - if (low_rate_complexity < 0 || low_rate_complexity > 10) - return false; - return true; -} -} // namespace webrtc diff --git a/webrtc/api/audio_codecs/opus/audio_encoder_opus_config.h b/webrtc/api/audio_codecs/opus/audio_encoder_opus_config.h deleted file mode 100644 index 1726c69d6e..0000000000 --- a/webrtc/api/audio_codecs/opus/audio_encoder_opus_config.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2017 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 WEBRTC_API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_CONFIG_H_ -#define WEBRTC_API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_CONFIG_H_ - -#include - -#include - -namespace webrtc { - -// NOTE: This struct is still under development and may change without notice. -struct AudioEncoderOpusConfig { - static constexpr int kDefaultFrameSizeMs = 20; - - // Opus API allows a min bitrate of 500bps, but Opus documentation suggests - // bitrate should be in the range of 6000 to 510000, inclusive. - static constexpr int kMinBitrateBps = 6000; - static constexpr int kMaxBitrateBps = 510000; - - AudioEncoderOpusConfig(); - AudioEncoderOpusConfig(const AudioEncoderOpusConfig&); - ~AudioEncoderOpusConfig(); - AudioEncoderOpusConfig& operator=(const AudioEncoderOpusConfig&); - - bool IsOk() const; // Checks if the values are currently OK. - - int frame_size_ms; - size_t num_channels; - enum class ApplicationMode { kVoip, kAudio }; - ApplicationMode application; - int bitrate_bps; - bool fec_enabled; - bool cbr_enabled; - int max_playback_rate_hz; - - // |complexity| is used when the bitrate goes above - // |complexity_threshold_bps| + |complexity_threshold_window_bps|; - // |low_rate_complexity| is used when the bitrate falls below - // |complexity_threshold_bps| - |complexity_threshold_window_bps|. In the - // interval in the middle, we keep using the most recent of the two - // complexity settings. - int complexity; - int low_rate_complexity; - int complexity_threshold_bps; - int complexity_threshold_window_bps; - - bool dtx_enabled; - std::vector supported_frame_lengths_ms; - int uplink_bandwidth_update_interval_ms; -}; - -} // namespace webrtc - -#endif // WEBRTC_API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_CONFIG_H_ diff --git a/webrtc/api/audio_codecs/test/BUILD.gn b/webrtc/api/audio_codecs/test/BUILD.gn index 3a48a33b53..08d527d2b0 100644 --- a/webrtc/api/audio_codecs/test/BUILD.gn +++ b/webrtc/api/audio_codecs/test/BUILD.gn @@ -26,7 +26,6 @@ if (rtc_include_tests) { "../../../test:test_support", "../g722:audio_decoder_g722", "../g722:audio_encoder_g722", - "../opus:audio_encoder_opus", "//testing/gmock", ] } diff --git a/webrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc b/webrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc index 4a7e291ed4..abca96852b 100644 --- a/webrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc +++ b/webrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc @@ -10,7 +10,6 @@ #include "webrtc/api/audio_codecs/audio_encoder_factory_template.h" #include "webrtc/api/audio_codecs/g722/audio_encoder_g722.h" -#include "webrtc/api/audio_codecs/opus/audio_encoder_opus.h" #include "webrtc/base/ptr_util.h" #include "webrtc/test/gmock.h" #include "webrtc/test/gtest.h" @@ -134,26 +133,4 @@ TEST(AudioEncoderFactoryTemplateTest, G722) { EXPECT_EQ(16000, enc->SampleRateHz()); } -TEST(AudioEncoderFactoryTemplateTest, Opus) { - auto factory = CreateAudioEncoderFactory(); - AudioCodecInfo info = {48000, 1, 32000, 6000, 510000}; - info.allow_comfort_noise = false; - info.supports_network_adaption = true; - EXPECT_THAT( - factory->GetSupportedEncoders(), - testing::ElementsAre(AudioCodecSpec{ - {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}}, - info})); - EXPECT_EQ(rtc::Optional(), - factory->QueryAudioEncoder({"foo", 8000, 1})); - EXPECT_EQ( - rtc::Optional(info), - factory->QueryAudioEncoder( - {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}})); - EXPECT_EQ(nullptr, factory->MakeAudioEncoder(17, {"bar", 16000, 1})); - auto enc = factory->MakeAudioEncoder(17, {"opus", 48000, 2}); - ASSERT_NE(nullptr, enc); - EXPECT_EQ(48000, enc->SampleRateHz()); -} - } // namespace webrtc diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index c0da0e36c9..afd2720f39 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -828,7 +828,6 @@ rtc_static_library("webrtc_opus") { ":audio_network_adaptor", "../..:webrtc_common", "../../api/audio_codecs:audio_codecs_api", - "../../api/audio_codecs/opus:audio_encoder_opus_config", "../../base:protobuf_utils", "../../base:rtc_base_approved", "../../base:rtc_numerics", @@ -840,6 +839,11 @@ rtc_static_library("webrtc_opus") { ] defines = audio_codec_defines + if (rtc_opus_variable_complexity) { + defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=1" ] + } else { + defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=0" ] + } if (rtc_build_opus) { public_deps += [ rtc_opus_dir ] @@ -1480,7 +1484,6 @@ if (rtc_include_tests) { ":neteq", ":neteq_tools", "../../api/audio_codecs:audio_codecs_api", - "../../api/audio_codecs/opus:audio_encoder_opus", "../../base:protobuf_utils", "../../common_audio", "../../test:test_main", diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc index 0dc89dcd94..236501a6f9 100644 --- a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc @@ -1501,7 +1501,7 @@ TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Opus_stereo_20ms) { TEST_F(AcmSenderBitExactnessNewApi, MAYBE_OpusFromFormat_stereo_20ms) { const SdpAudioFormat kOpusFormat("opus", 48000, 2, {{"stereo", "1"}}); - AudioEncoderOpusImpl encoder(120, kOpusFormat); + AudioEncoderOpus encoder(120, kOpusFormat); ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(&encoder, 120)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( "855041f2490b887302bce9d544731849", @@ -1547,7 +1547,7 @@ TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Opus_stereo_20ms_voip) { TEST_F(AcmSenderBitExactnessNewApi, MAYBE_OpusFromFormat_stereo_20ms_voip) { const SdpAudioFormat kOpusFormat("opus", 48000, 2, {{"stereo", "1"}}); - AudioEncoderOpusImpl encoder(120, kOpusFormat); + AudioEncoderOpus encoder(120, kOpusFormat); ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(&encoder, 120)); // If not set, default will be kAudio in case of stereo. EXPECT_EQ(0, send_test_->acm()->SetOpusApplication(kVoip)); @@ -1664,7 +1664,7 @@ TEST_F(AcmSetBitRateOldApi, MAYBE_Opus_48khz_20ms_10kbps) { } TEST_F(AcmSetBitRateNewApi, MAYBE_OpusFromFormat_48khz_20ms_10kbps) { - AudioEncoderOpusImpl encoder( + AudioEncoderOpus encoder( 107, SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "10000"}})); ASSERT_TRUE(SetUpSender()); ASSERT_TRUE(RegisterExternalSendCodec(&encoder, 107)); @@ -1693,7 +1693,7 @@ TEST_F(AcmSetBitRateOldApi, MAYBE_Opus_48khz_20ms_50kbps) { } TEST_F(AcmSetBitRateNewApi, MAYBE_OpusFromFormat_48khz_20ms_50kbps) { - AudioEncoderOpusImpl encoder( + AudioEncoderOpus encoder( 107, SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "50000"}})); ASSERT_TRUE(SetUpSender()); ASSERT_TRUE(RegisterExternalSendCodec(&encoder, 107)); @@ -1721,7 +1721,7 @@ TEST_F(AcmSetBitRateOldApi, MAYBE_Opus_48khz_20ms_100kbps) { } TEST_F(AcmSetBitRateNewApi, MAYBE_OpusFromFormat_48khz_20ms_100kbps) { - AudioEncoderOpusImpl encoder( + AudioEncoderOpus encoder( 107, SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "100000"}})); ASSERT_TRUE(SetUpSender()); ASSERT_TRUE(RegisterExternalSendCodec(&encoder, 107)); diff --git a/webrtc/modules/audio_coding/acm2/rent_a_codec.cc b/webrtc/modules/audio_coding/acm2/rent_a_codec.cc index bfac02d729..79491b83a6 100644 --- a/webrtc/modules/audio_coding/acm2/rent_a_codec.cc +++ b/webrtc/modules/audio_coding/acm2/rent_a_codec.cc @@ -163,7 +163,7 @@ std::unique_ptr CreateEncoder( #endif #ifdef WEBRTC_CODEC_OPUS if (STR_CASE_CMP(speech_inst.plname, "opus") == 0) - return std::unique_ptr(new AudioEncoderOpusImpl(speech_inst)); + return std::unique_ptr(new AudioEncoderOpus(speech_inst)); #endif if (STR_CASE_CMP(speech_inst.plname, "pcmu") == 0) return std::unique_ptr(new AudioEncoderPcmU(speech_inst)); diff --git a/webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.cc b/webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.cc index 9c3bfbd9d2..3f75cc8624 100644 --- a/webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.cc +++ b/webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.cc @@ -74,7 +74,7 @@ NamedEncoderFactory encoder_factories[] = { #endif #ifdef WEBRTC_CODEC_OPUS - NamedEncoderFactory::ForEncoder(), + NamedEncoderFactory::ForEncoder(), #endif NamedEncoderFactory::ForEncoder(), NamedEncoderFactory::ForEncoder(), diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc index a4ae2ca6d5..be32aef152 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc @@ -48,6 +48,11 @@ constexpr int kOpusBitrateNbBps = 12000; constexpr int kOpusBitrateWbBps = 20000; constexpr int kOpusBitrateFbBps = 32000; +// Opus API allows a min bitrate of 500bps, but Opus documentation suggests +// bitrate should be in the range of 6000 to 510000, inclusive. +constexpr int kOpusMinBitrateBps = 6000; +constexpr int kOpusMaxBitrateBps = 510000; + constexpr int kSampleRateHz = 48000; constexpr int kDefaultMaxPlaybackRate = 48000; @@ -128,8 +133,8 @@ int CalculateDefaultBitrate(int max_playback_rate, size_t num_channels) { return kOpusBitrateFbBps * rtc::dchecked_cast(num_channels); } }(); - RTC_DCHECK_GE(bitrate, AudioEncoderOpusConfig::kMinBitrateBps); - RTC_DCHECK_LE(bitrate, AudioEncoderOpusConfig::kMaxBitrateBps); + RTC_DCHECK_GE(bitrate, kOpusMinBitrateBps); + RTC_DCHECK_LE(bitrate, kOpusMaxBitrateBps); return bitrate; } @@ -145,8 +150,7 @@ int CalculateBitrate(int max_playback_rate_hz, const auto bitrate = rtc::StringToNumber(*bitrate_param); if (bitrate) { const int chosen_bitrate = - std::max(AudioEncoderOpusConfig::kMinBitrateBps, - std::min(*bitrate, AudioEncoderOpusConfig::kMaxBitrateBps)); + std::max(kOpusMinBitrateBps, std::min(*bitrate, kOpusMaxBitrateBps)); if (bitrate != chosen_bitrate) { LOG(LS_WARNING) << "Invalid maxaveragebitrate " << *bitrate << " clamped to " << chosen_bitrate; @@ -191,7 +195,7 @@ int GetFrameSizeMs(const SdpAudioFormat& format) { return *(std::end(kOpusSupportedFrameLengths) - 1); } - return AudioEncoderOpusConfig::kDefaultFrameSizeMs; + return AudioEncoderOpus::Config::kDefaultFrameSizeMs; } void FindSupportedFrameLengths(int min_frame_length_ms, @@ -207,14 +211,9 @@ void FindSupportedFrameLengths(int min_frame_length_ms, RTC_DCHECK(std::is_sorted(out->begin(), out->end())); } -int GetBitrateBps(const AudioEncoderOpusConfig& config) { - RTC_DCHECK(config.IsOk()); - return config.bitrate_bps; -} - } // namespace -rtc::Optional AudioEncoderOpusImpl::QueryAudioEncoder( +rtc::Optional AudioEncoderOpus::QueryAudioEncoder( const SdpAudioFormat& format) { if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0 && format.clockrate_hz == 48000 && format.num_channels == 2) { @@ -222,9 +221,8 @@ rtc::Optional AudioEncoderOpusImpl::QueryAudioEncoder( const int bitrate = CalculateBitrate(GetMaxPlaybackRate(format), num_channels, GetFormatParameter(format, "maxaveragebitrate")); - AudioCodecInfo info(48000, num_channels, bitrate, - AudioEncoderOpusConfig::kMinBitrateBps, - AudioEncoderOpusConfig::kMaxBitrateBps); + AudioCodecInfo info(48000, num_channels, bitrate, kOpusMinBitrateBps, + kOpusMaxBitrateBps); info.allow_comfort_noise = false; info.supports_network_adaption = true; @@ -233,44 +231,46 @@ rtc::Optional AudioEncoderOpusImpl::QueryAudioEncoder( return rtc::Optional(); } -AudioEncoderOpusConfig AudioEncoderOpusImpl::CreateConfig( +AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( const CodecInst& codec_inst) { - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); config.num_channels = codec_inst.channels; - config.bitrate_bps = codec_inst.rate; - config.application = config.num_channels == 1 - ? AudioEncoderOpusConfig::ApplicationMode::kVoip - : AudioEncoderOpusConfig::ApplicationMode::kAudio; + config.bitrate_bps = rtc::Optional(codec_inst.rate); + config.payload_type = codec_inst.pltype; + config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip + : AudioEncoderOpus::kAudio; config.supported_frame_lengths_ms.push_back(config.frame_size_ms); +#if WEBRTC_OPUS_VARIABLE_COMPLEXITY + config.low_rate_complexity = 9; +#endif return config; } -rtc::Optional AudioEncoderOpusImpl::SdpToConfig( +AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( + int payload_type, const SdpAudioFormat& format) { - if (STR_CASE_CMP(format.name.c_str(), "opus") != 0 || - format.clockrate_hz != 48000 || format.num_channels != 2) { - return rtc::Optional(); - } + AudioEncoderOpus::Config config; - AudioEncoderOpusConfig config; config.num_channels = GetChannelCount(format); config.frame_size_ms = GetFrameSizeMs(format); config.max_playback_rate_hz = GetMaxPlaybackRate(format); config.fec_enabled = (GetFormatParameter(format, "useinbandfec") == "1"); config.dtx_enabled = (GetFormatParameter(format, "usedtx") == "1"); config.cbr_enabled = (GetFormatParameter(format, "cbr") == "1"); - config.bitrate_bps = + config.bitrate_bps = rtc::Optional( CalculateBitrate(config.max_playback_rate_hz, config.num_channels, - GetFormatParameter(format, "maxaveragebitrate")); - config.application = config.num_channels == 1 - ? AudioEncoderOpusConfig::ApplicationMode::kVoip - : AudioEncoderOpusConfig::ApplicationMode::kAudio; + GetFormatParameter(format, "maxaveragebitrate"))); + config.payload_type = payload_type; + config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip + : AudioEncoderOpus::kAudio; +#if WEBRTC_OPUS_VARIABLE_COMPLEXITY + config.low_rate_complexity = 9; +#endif constexpr int kMinANAFrameLength = kANASupportedFrameLengths[0]; constexpr int kMaxANAFrameLength = kANASupportedFrameLengths[arraysize(kANASupportedFrameLengths) - 1]; - // For now, minptime and maxptime are only used with ANA. If ptime is outside // of this range, it will get adjusted once ANA takes hold. Ideally, we'd know // if ANA was to be used when setting up the config, and adjust accordingly. @@ -281,28 +281,10 @@ rtc::Optional AudioEncoderOpusImpl::SdpToConfig( FindSupportedFrameLengths(min_frame_length_ms, max_frame_length_ms, &config.supported_frame_lengths_ms); - RTC_DCHECK(config.IsOk()); - return rtc::Optional(config); + return config; } -rtc::Optional AudioEncoderOpusImpl::GetNewComplexity( - const AudioEncoderOpusConfig& config) { - RTC_DCHECK(config.IsOk()); - const int bitrate_bps = GetBitrateBps(config); - if (bitrate_bps >= config.complexity_threshold_bps - - config.complexity_threshold_window_bps && - bitrate_bps <= config.complexity_threshold_bps + - config.complexity_threshold_window_bps) { - // Within the hysteresis window; make no change. - return rtc::Optional(); - } else { - return rtc::Optional(bitrate_bps <= config.complexity_threshold_bps - ? config.low_rate_complexity - : config.complexity); - } -} - -class AudioEncoderOpusImpl::PacketLossFractionSmoother { +class AudioEncoderOpus::PacketLossFractionSmoother { public: explicit PacketLossFractionSmoother() : last_sample_time_ms_(rtc::TimeMillis()), @@ -329,13 +311,58 @@ class AudioEncoderOpusImpl::PacketLossFractionSmoother { rtc::ExpFilter smoother_; }; -AudioEncoderOpusImpl::AudioEncoderOpusImpl( - const AudioEncoderOpusConfig& config, - int payload_type, +AudioEncoderOpus::Config::Config() { +#if WEBRTC_OPUS_VARIABLE_COMPLEXITY + low_rate_complexity = 9; +#endif +} +AudioEncoderOpus::Config::Config(const Config&) = default; +AudioEncoderOpus::Config::~Config() = default; +auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default; + +bool AudioEncoderOpus::Config::IsOk() const { + if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) + return false; + if (num_channels != 1 && num_channels != 2) + return false; + if (bitrate_bps && + (*bitrate_bps < kOpusMinBitrateBps || *bitrate_bps > kOpusMaxBitrateBps)) + return false; + if (complexity < 0 || complexity > 10) + return false; + if (low_rate_complexity < 0 || low_rate_complexity > 10) + return false; + return true; +} + +int AudioEncoderOpus::Config::GetBitrateBps() const { + RTC_DCHECK(IsOk()); + if (bitrate_bps) + return *bitrate_bps; // Explicitly set value. + else + return num_channels == 1 ? 32000 : 64000; // Default value. +} + +rtc::Optional AudioEncoderOpus::Config::GetNewComplexity() const { + RTC_DCHECK(IsOk()); + const int bitrate_bps = GetBitrateBps(); + if (bitrate_bps >= + complexity_threshold_bps - complexity_threshold_window_bps && + bitrate_bps <= + complexity_threshold_bps + complexity_threshold_window_bps) { + // Within the hysteresis window; make no change. + return rtc::Optional(); + } + return bitrate_bps <= complexity_threshold_bps + ? rtc::Optional(low_rate_complexity) + : rtc::Optional(complexity); +} + +AudioEncoderOpus::AudioEncoderOpus( + const Config& config, AudioNetworkAdaptorCreator&& audio_network_adaptor_creator, std::unique_ptr bitrate_smoother) - : payload_type_(payload_type), - send_side_bwe_with_overhead_(webrtc::field_trial::IsEnabled( + : send_side_bwe_with_overhead_(webrtc::field_trial::IsEnabled( "WebRTC-SendSideBwe-WithOverhead")), packet_loss_rate_(0.0), inst_(nullptr), @@ -355,42 +382,42 @@ AudioEncoderOpusImpl::AudioEncoderOpusImpl( RTC_CHECK(RecreateEncoderInstance(config)); } -AudioEncoderOpusImpl::AudioEncoderOpusImpl(const CodecInst& codec_inst) - : AudioEncoderOpusImpl(CreateConfig(codec_inst), codec_inst.pltype) {} +AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) + : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {} -AudioEncoderOpusImpl::AudioEncoderOpusImpl(int payload_type, - const SdpAudioFormat& format) - : AudioEncoderOpusImpl(*SdpToConfig(format), payload_type) {} +AudioEncoderOpus::AudioEncoderOpus(int payload_type, + const SdpAudioFormat& format) + : AudioEncoderOpus(CreateConfig(payload_type, format), nullptr) {} -AudioEncoderOpusImpl::~AudioEncoderOpusImpl() { +AudioEncoderOpus::~AudioEncoderOpus() { RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); } -int AudioEncoderOpusImpl::SampleRateHz() const { +int AudioEncoderOpus::SampleRateHz() const { return kSampleRateHz; } -size_t AudioEncoderOpusImpl::NumChannels() const { +size_t AudioEncoderOpus::NumChannels() const { return config_.num_channels; } -size_t AudioEncoderOpusImpl::Num10MsFramesInNextPacket() const { +size_t AudioEncoderOpus::Num10MsFramesInNextPacket() const { return Num10msFramesPerPacket(); } -size_t AudioEncoderOpusImpl::Max10MsFramesInAPacket() const { +size_t AudioEncoderOpus::Max10MsFramesInAPacket() const { return Num10msFramesPerPacket(); } -int AudioEncoderOpusImpl::GetTargetBitrate() const { - return GetBitrateBps(config_); +int AudioEncoderOpus::GetTargetBitrate() const { + return config_.GetBitrateBps(); } -void AudioEncoderOpusImpl::Reset() { +void AudioEncoderOpus::Reset() { RTC_CHECK(RecreateEncoderInstance(config_)); } -bool AudioEncoderOpusImpl::SetFec(bool enable) { +bool AudioEncoderOpus::SetFec(bool enable) { if (enable) { RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); } else { @@ -400,7 +427,7 @@ bool AudioEncoderOpusImpl::SetFec(bool enable) { return true; } -bool AudioEncoderOpusImpl::SetDtx(bool enable) { +bool AudioEncoderOpus::SetDtx(bool enable) { if (enable) { RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); } else { @@ -410,30 +437,30 @@ bool AudioEncoderOpusImpl::SetDtx(bool enable) { return true; } -bool AudioEncoderOpusImpl::GetDtx() const { +bool AudioEncoderOpus::GetDtx() const { return config_.dtx_enabled; } -bool AudioEncoderOpusImpl::SetApplication(Application application) { +bool AudioEncoderOpus::SetApplication(Application application) { auto conf = config_; switch (application) { case Application::kSpeech: - conf.application = AudioEncoderOpusConfig::ApplicationMode::kVoip; + conf.application = AudioEncoderOpus::kVoip; break; case Application::kAudio: - conf.application = AudioEncoderOpusConfig::ApplicationMode::kAudio; + conf.application = AudioEncoderOpus::kAudio; break; } return RecreateEncoderInstance(conf); } -void AudioEncoderOpusImpl::SetMaxPlaybackRate(int frequency_hz) { +void AudioEncoderOpus::SetMaxPlaybackRate(int frequency_hz) { auto conf = config_; conf.max_playback_rate_hz = frequency_hz; RTC_CHECK(RecreateEncoderInstance(conf)); } -bool AudioEncoderOpusImpl::EnableAudioNetworkAdaptor( +bool AudioEncoderOpus::EnableAudioNetworkAdaptor( const std::string& config_string, RtcEventLog* event_log) { audio_network_adaptor_ = @@ -441,11 +468,11 @@ bool AudioEncoderOpusImpl::EnableAudioNetworkAdaptor( return audio_network_adaptor_.get() != nullptr; } -void AudioEncoderOpusImpl::DisableAudioNetworkAdaptor() { +void AudioEncoderOpus::DisableAudioNetworkAdaptor() { audio_network_adaptor_.reset(nullptr); } -void AudioEncoderOpusImpl::OnReceivedUplinkPacketLossFraction( +void AudioEncoderOpus::OnReceivedUplinkPacketLossFraction( float uplink_packet_loss_fraction) { if (!audio_network_adaptor_) { packet_loss_fraction_smoother_->AddSample(uplink_packet_loss_fraction); @@ -457,7 +484,7 @@ void AudioEncoderOpusImpl::OnReceivedUplinkPacketLossFraction( ApplyAudioNetworkAdaptor(); } -void AudioEncoderOpusImpl::OnReceivedUplinkRecoverablePacketLossFraction( +void AudioEncoderOpus::OnReceivedUplinkRecoverablePacketLossFraction( float uplink_recoverable_packet_loss_fraction) { if (!audio_network_adaptor_) return; @@ -466,7 +493,7 @@ void AudioEncoderOpusImpl::OnReceivedUplinkRecoverablePacketLossFraction( ApplyAudioNetworkAdaptor(); } -void AudioEncoderOpusImpl::OnReceivedUplinkBandwidth( +void AudioEncoderOpus::OnReceivedUplinkBandwidth( int target_audio_bitrate_bps, rtc::Optional probing_interval_ms) { if (audio_network_adaptor_) { @@ -490,30 +517,28 @@ void AudioEncoderOpusImpl::OnReceivedUplinkBandwidth( } else if (send_side_bwe_with_overhead_) { if (!overhead_bytes_per_packet_) { LOG(LS_INFO) - << "AudioEncoderOpusImpl: Overhead unknown, target audio bitrate " + << "AudioEncoderOpus: Overhead unknown, target audio bitrate " << target_audio_bitrate_bps << " bps is ignored."; return; } const int overhead_bps = static_cast( *overhead_bytes_per_packet_ * 8 * 100 / Num10MsFramesInNextPacket()); - SetTargetBitrate( - std::min(AudioEncoderOpusConfig::kMaxBitrateBps, - std::max(AudioEncoderOpusConfig::kMinBitrateBps, - target_audio_bitrate_bps - overhead_bps))); + SetTargetBitrate(std::min( + kOpusMaxBitrateBps, + std::max(kOpusMinBitrateBps, target_audio_bitrate_bps - overhead_bps))); } else { SetTargetBitrate(target_audio_bitrate_bps); } } -void AudioEncoderOpusImpl::OnReceivedRtt(int rtt_ms) { +void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) { if (!audio_network_adaptor_) return; audio_network_adaptor_->SetRtt(rtt_ms); ApplyAudioNetworkAdaptor(); } -void AudioEncoderOpusImpl::OnReceivedOverhead( - size_t overhead_bytes_per_packet) { +void AudioEncoderOpus::OnReceivedOverhead(size_t overhead_bytes_per_packet) { if (audio_network_adaptor_) { audio_network_adaptor_->SetOverhead(overhead_bytes_per_packet); ApplyAudioNetworkAdaptor(); @@ -523,9 +548,8 @@ void AudioEncoderOpusImpl::OnReceivedOverhead( } } -void AudioEncoderOpusImpl::SetReceiverFrameLengthRange( - int min_frame_length_ms, - int max_frame_length_ms) { +void AudioEncoderOpus::SetReceiverFrameLengthRange(int min_frame_length_ms, + int max_frame_length_ms) { // Ensure that |SetReceiverFrameLengthRange| is called before // |EnableAudioNetworkAdaptor|, otherwise we need to recreate // |audio_network_adaptor_|, which is not a needed use case. @@ -534,7 +558,7 @@ void AudioEncoderOpusImpl::SetReceiverFrameLengthRange( &config_.supported_frame_lengths_ms); } -AudioEncoder::EncodedInfo AudioEncoderOpusImpl::EncodeImpl( +AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( uint32_t rtp_timestamp, rtc::ArrayView audio, rtc::Buffer* encoded) { @@ -573,26 +597,26 @@ AudioEncoder::EncodedInfo AudioEncoderOpusImpl::EncodeImpl( config_.frame_size_ms = next_frame_length_ms_; info.encoded_timestamp = first_timestamp_in_buffer_; - info.payload_type = payload_type_; + info.payload_type = config_.payload_type; info.send_even_if_empty = true; // Allows Opus to send empty packets. info.speech = (info.encoded_bytes > 0); info.encoder_type = CodecType::kOpus; return info; } -size_t AudioEncoderOpusImpl::Num10msFramesPerPacket() const { +size_t AudioEncoderOpus::Num10msFramesPerPacket() const { return static_cast(rtc::CheckedDivExact(config_.frame_size_ms, 10)); } -size_t AudioEncoderOpusImpl::SamplesPer10msFrame() const { +size_t AudioEncoderOpus::SamplesPer10msFrame() const { return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels; } -size_t AudioEncoderOpusImpl::SufficientOutputBufferSize() const { +size_t AudioEncoderOpus::SufficientOutputBufferSize() const { // Calculate the number of bytes we expect the encoder to produce, // then multiply by two to give a wide margin for error. const size_t bytes_per_millisecond = - static_cast(GetBitrateBps(config_) / (1000 * 8) + 1); + static_cast(config_.GetBitrateBps() / (1000 * 8) + 1); const size_t approx_encoded_bytes = Num10msFramesPerPacket() * 10 * bytes_per_millisecond; return 2 * approx_encoded_bytes; @@ -601,8 +625,7 @@ size_t AudioEncoderOpusImpl::SufficientOutputBufferSize() const { // If the given config is OK, recreate the Opus encoder instance with those // settings, save the config, and return true. Otherwise, do nothing and return // false. -bool AudioEncoderOpusImpl::RecreateEncoderInstance( - const AudioEncoderOpusConfig& config) { +bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) { if (!config.IsOk()) return false; config_ = config; @@ -610,13 +633,9 @@ bool AudioEncoderOpusImpl::RecreateEncoderInstance( RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); input_buffer_.clear(); input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame()); - RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate( - &inst_, config.num_channels, - config.application == - AudioEncoderOpusConfig::ApplicationMode::kVoip - ? 0 - : 1)); - RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, GetBitrateBps(config))); + RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels, + config.application)); + RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.GetBitrateBps())); if (config.fec_enabled) { RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); } else { @@ -626,7 +645,7 @@ bool AudioEncoderOpusImpl::RecreateEncoderInstance( 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz)); // Use the default complexity if the start bitrate is within the hysteresis // window. - complexity_ = GetNewComplexity(config).value_or(config.complexity); + complexity_ = config.GetNewComplexity().value_or(config.complexity); RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); if (config.dtx_enabled) { RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); @@ -646,12 +665,11 @@ bool AudioEncoderOpusImpl::RecreateEncoderInstance( return true; } -void AudioEncoderOpusImpl::SetFrameLength(int frame_length_ms) { +void AudioEncoderOpus::SetFrameLength(int frame_length_ms) { next_frame_length_ms_ = frame_length_ms; } -void AudioEncoderOpusImpl::SetNumChannelsToEncode( - size_t num_channels_to_encode) { +void AudioEncoderOpus::SetNumChannelsToEncode(size_t num_channels_to_encode) { RTC_DCHECK_GT(num_channels_to_encode, 0); RTC_DCHECK_LE(num_channels_to_encode, config_.num_channels); @@ -662,7 +680,7 @@ void AudioEncoderOpusImpl::SetNumChannelsToEncode( num_channels_to_encode_ = num_channels_to_encode; } -void AudioEncoderOpusImpl::SetProjectedPacketLossRate(float fraction) { +void AudioEncoderOpus::SetProjectedPacketLossRate(float fraction) { float opt_loss_rate = OptimizePacketLossRate(fraction, packet_loss_rate_); if (packet_loss_rate_ != opt_loss_rate) { packet_loss_rate_ = opt_loss_rate; @@ -672,20 +690,19 @@ void AudioEncoderOpusImpl::SetProjectedPacketLossRate(float fraction) { } } -void AudioEncoderOpusImpl::SetTargetBitrate(int bits_per_second) { - config_.bitrate_bps = rtc::SafeClamp( - bits_per_second, AudioEncoderOpusConfig::kMinBitrateBps, - AudioEncoderOpusConfig::kMaxBitrateBps); +void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { + config_.bitrate_bps = rtc::Optional(rtc::SafeClamp( + bits_per_second, kOpusMinBitrateBps, kOpusMaxBitrateBps)); RTC_DCHECK(config_.IsOk()); - RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, GetBitrateBps(config_))); - const auto new_complexity = GetNewComplexity(config_); + RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); + const auto new_complexity = config_.GetNewComplexity(); if (new_complexity && complexity_ != *new_complexity) { complexity_ = *new_complexity; RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); } } -void AudioEncoderOpusImpl::ApplyAudioNetworkAdaptor() { +void AudioEncoderOpus::ApplyAudioNetworkAdaptor() { auto config = audio_network_adaptor_->GetEncoderRuntimeConfig(); RTC_DCHECK(!config.frame_length_ms || *config.frame_length_ms == 20 || *config.frame_length_ms == 60); @@ -705,20 +722,20 @@ void AudioEncoderOpusImpl::ApplyAudioNetworkAdaptor() { } std::unique_ptr -AudioEncoderOpusImpl::DefaultAudioNetworkAdaptorCreator( +AudioEncoderOpus::DefaultAudioNetworkAdaptorCreator( const ProtoString& config_string, RtcEventLog* event_log) const { AudioNetworkAdaptorImpl::Config config; config.event_log = event_log; return std::unique_ptr(new AudioNetworkAdaptorImpl( - config, ControllerManagerImpl::Create( - config_string, NumChannels(), supported_frame_lengths_ms(), - AudioEncoderOpusConfig::kMinBitrateBps, - num_channels_to_encode_, next_frame_length_ms_, - GetTargetBitrate(), config_.fec_enabled, GetDtx()))); + config, + ControllerManagerImpl::Create( + config_string, NumChannels(), supported_frame_lengths_ms(), + kOpusMinBitrateBps, num_channels_to_encode_, next_frame_length_ms_, + GetTargetBitrate(), config_.fec_enabled, GetDtx()))); } -void AudioEncoderOpusImpl::MaybeUpdateUplinkBandwidth() { +void AudioEncoderOpus::MaybeUpdateUplinkBandwidth() { if (audio_network_adaptor_) { int64_t now_ms = rtc::TimeMillis(); if (!bitrate_smoother_last_update_time_ || diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h index 93895c21db..a1a4d7069b 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h @@ -18,7 +18,6 @@ #include "webrtc/api/audio_codecs/audio_encoder.h" #include "webrtc/api/audio_codecs/audio_format.h" -#include "webrtc/api/audio_codecs/opus/audio_encoder_opus_config.h" #include "webrtc/base/constructormagic.h" #include "webrtc/base/optional.h" #include "webrtc/base/protobuf_utils.h" @@ -32,31 +31,70 @@ class RtcEventLog; struct CodecInst; -class AudioEncoderOpusImpl final : public AudioEncoder { +class AudioEncoderOpus final : public AudioEncoder { public: - static AudioEncoderOpusConfig CreateConfig(const CodecInst& codec_inst); - static rtc::Optional SdpToConfig( - const SdpAudioFormat& format); + enum ApplicationMode { + kVoip = 0, + kAudio = 1, + }; - // Returns empty if the current bitrate falls within the hysteresis window, - // defined by complexity_threshold_bps +/- complexity_threshold_window_bps. - // Otherwise, returns the current complexity depending on whether the current - // bitrate is above or below complexity_threshold_bps. - static rtc::Optional GetNewComplexity( - const AudioEncoderOpusConfig& config); + struct Config { + Config(); + Config(const Config&); + ~Config(); + Config& operator=(const Config&); + + bool IsOk() const; + int GetBitrateBps() const; + // Returns empty if the current bitrate falls within the hysteresis window, + // defined by complexity_threshold_bps +/- complexity_threshold_window_bps. + // Otherwise, returns the current complexity depending on whether the + // current bitrate is above or below complexity_threshold_bps. + rtc::Optional GetNewComplexity() const; + + static constexpr int kDefaultFrameSizeMs = 20; + int frame_size_ms = kDefaultFrameSizeMs; + size_t num_channels = 1; + int payload_type = 120; + ApplicationMode application = kVoip; + rtc::Optional bitrate_bps; // Unset means to use default value. + bool fec_enabled = false; + bool cbr_enabled = false; + int max_playback_rate_hz = 48000; + int complexity = kDefaultComplexity; + // This value may change in the struct's constructor. + int low_rate_complexity = kDefaultComplexity; + // low_rate_complexity is used when the bitrate is below this threshold. + int complexity_threshold_bps = 12500; + int complexity_threshold_window_bps = 1500; + bool dtx_enabled = false; + std::vector supported_frame_lengths_ms; + int uplink_bandwidth_update_interval_ms = 200; + + private: +#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) || defined(WEBRTC_ARCH_ARM) + // If we are on Android, iOS and/or ARM, use a lower complexity setting as + // default, to save encoder complexity. + static const int kDefaultComplexity = 5; +#else + static const int kDefaultComplexity = 9; +#endif + }; + + static Config CreateConfig(int payload_type, const SdpAudioFormat& format); + static Config CreateConfig(const CodecInst& codec_inst); using AudioNetworkAdaptorCreator = std::function(const std::string&, RtcEventLog*)>; - AudioEncoderOpusImpl( - const AudioEncoderOpusConfig& config, - int payload_type, + AudioEncoderOpus( + const Config& config, AudioNetworkAdaptorCreator&& audio_network_adaptor_creator = nullptr, std::unique_ptr bitrate_smoother = nullptr); - explicit AudioEncoderOpusImpl(const CodecInst& codec_inst); - AudioEncoderOpusImpl(int payload_type, const SdpAudioFormat& format); - ~AudioEncoderOpusImpl() override; + explicit AudioEncoderOpus(const CodecInst& codec_inst); + AudioEncoderOpus(int payload_type, const SdpAudioFormat& format); + ~AudioEncoderOpus() override; // Static interface for use by BuiltinAudioEncoderFactory. static constexpr const char* GetPayloadName() { return "opus"; } @@ -100,9 +138,7 @@ class AudioEncoderOpusImpl final : public AudioEncoder { // Getters for testing. float packet_loss_rate() const { return packet_loss_rate_; } - AudioEncoderOpusConfig::ApplicationMode application() const { - return config_.application; - } + ApplicationMode application() const { return config_.application; } bool fec_enabled() const { return config_.fec_enabled; } size_t num_channels_to_encode() const { return num_channels_to_encode_; } int next_frame_length_ms() const { return next_frame_length_ms_; } @@ -118,7 +154,7 @@ class AudioEncoderOpusImpl final : public AudioEncoder { size_t Num10msFramesPerPacket() const; size_t SamplesPer10msFrame() const; size_t SufficientOutputBufferSize() const; - bool RecreateEncoderInstance(const AudioEncoderOpusConfig& config); + bool RecreateEncoderInstance(const Config& config); void SetFrameLength(int frame_length_ms); void SetNumChannelsToEncode(size_t num_channels_to_encode); void SetProjectedPacketLossRate(float fraction); @@ -134,8 +170,7 @@ class AudioEncoderOpusImpl final : public AudioEncoder { void MaybeUpdateUplinkBandwidth(); - AudioEncoderOpusConfig config_; - const int payload_type_; + Config config_; const bool send_side_bwe_with_overhead_; float packet_loss_rate_; std::vector input_buffer_; @@ -151,7 +186,7 @@ class AudioEncoderOpusImpl final : public AudioEncoder { const std::unique_ptr bitrate_smoother_; rtc::Optional bitrate_smoother_last_update_time_; - RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderOpusImpl); + RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderOpus); }; } // namespace webrtc diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc index 8137998b9c..76574d6432 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc @@ -33,30 +33,30 @@ namespace { const CodecInst kDefaultOpusSettings = {105, "opus", 48000, 960, 1, 32000}; constexpr int64_t kInitialTimeUs = 12345678; -AudioEncoderOpusConfig CreateConfig(const CodecInst& codec_inst) { - AudioEncoderOpusConfig config; +AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { + AudioEncoderOpus::Config config; config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); config.num_channels = codec_inst.channels; - config.bitrate_bps = codec_inst.rate; - config.application = config.num_channels == 1 - ? AudioEncoderOpusConfig::ApplicationMode::kVoip - : AudioEncoderOpusConfig::ApplicationMode::kAudio; + config.bitrate_bps = rtc::Optional(codec_inst.rate); + config.payload_type = codec_inst.pltype; + config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip + : AudioEncoderOpus::kAudio; config.supported_frame_lengths_ms.push_back(config.frame_size_ms); return config; } -AudioEncoderOpusConfig CreateConfigWithParameters( +AudioEncoderOpus::Config CreateConfigWithParameters( const SdpAudioFormat::Parameters& params) { - const SdpAudioFormat format("opus", 48000, 2, params); - return *AudioEncoderOpusImpl::SdpToConfig(format); + SdpAudioFormat format("opus", 48000, 2, params); + return AudioEncoderOpus::CreateConfig(0, format); } struct AudioEncoderOpusStates { std::shared_ptr mock_audio_network_adaptor; MockSmoothingFilter* mock_bitrate_smoother; - std::unique_ptr encoder; + std::unique_ptr encoder; std::unique_ptr fake_clock; - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; }; AudioEncoderOpusStates CreateCodec(size_t num_channels) { @@ -67,7 +67,7 @@ AudioEncoderOpusStates CreateCodec(size_t num_channels) { states.fake_clock->SetTimeMicros(kInitialTimeUs); std::weak_ptr mock_ptr( states.mock_audio_network_adaptor); - AudioEncoderOpusImpl::AudioNetworkAdaptorCreator creator = + AudioEncoderOpus::AudioNetworkAdaptorCreator creator = [mock_ptr](const std::string&, RtcEventLog* event_log) { std::unique_ptr adaptor( new NiceMock()); @@ -87,9 +87,8 @@ AudioEncoderOpusStates CreateCodec(size_t num_channels) { new MockSmoothingFilter()); states.mock_bitrate_smoother = bitrate_smoother.get(); - states.encoder.reset(new AudioEncoderOpusImpl( - states.config, codec_inst.pltype, std::move(creator), - std::move(bitrate_smoother))); + states.encoder.reset(new AudioEncoderOpus(states.config, std::move(creator), + std::move(bitrate_smoother))); return states; } @@ -111,7 +110,7 @@ AudioEncoderRuntimeConfig CreateEncoderRuntimeConfig() { return config; } -void CheckEncoderRuntimeConfig(const AudioEncoderOpusImpl* encoder, +void CheckEncoderRuntimeConfig(const AudioEncoderOpus* encoder, const AudioEncoderRuntimeConfig& config) { EXPECT_EQ(*config.bitrate_bps, encoder->GetTargetBitrate()); EXPECT_EQ(*config.frame_length_ms, encoder->next_frame_length_ms()); @@ -122,7 +121,7 @@ void CheckEncoderRuntimeConfig(const AudioEncoderOpusImpl* encoder, // Create 10ms audio data blocks for a total packet size of "packet_size_ms". std::unique_ptr Create10msAudioBlocks( - const std::unique_ptr& encoder, + const std::unique_ptr& encoder, int packet_size_ms) { const std::string file_name = test::ResourcePath("audio_coding/testfile32kHz", "pcm"); @@ -143,22 +142,19 @@ std::unique_ptr Create10msAudioBlocks( TEST(AudioEncoderOpusTest, DefaultApplicationModeMono) { auto states = CreateCodec(1); - EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip, - states.encoder->application()); + EXPECT_EQ(AudioEncoderOpus::kVoip, states.encoder->application()); } TEST(AudioEncoderOpusTest, DefaultApplicationModeStereo) { auto states = CreateCodec(2); - EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kAudio, - states.encoder->application()); + EXPECT_EQ(AudioEncoderOpus::kAudio, states.encoder->application()); } TEST(AudioEncoderOpusTest, ChangeApplicationMode) { auto states = CreateCodec(2); EXPECT_TRUE( states.encoder->SetApplication(AudioEncoder::Application::kSpeech)); - EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip, - states.encoder->application()); + EXPECT_EQ(AudioEncoderOpus::kVoip, states.encoder->application()); } TEST(AudioEncoderOpusTest, ResetWontChangeApplicationMode) { @@ -167,20 +163,17 @@ TEST(AudioEncoderOpusTest, ResetWontChangeApplicationMode) { // Trigger a reset. states.encoder->Reset(); // Verify that the mode is still kAudio. - EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kAudio, - states.encoder->application()); + EXPECT_EQ(AudioEncoderOpus::kAudio, states.encoder->application()); // Now change to kVoip. EXPECT_TRUE( states.encoder->SetApplication(AudioEncoder::Application::kSpeech)); - EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip, - states.encoder->application()); + EXPECT_EQ(AudioEncoderOpus::kVoip, states.encoder->application()); // Trigger a reset again. states.encoder->Reset(); // Verify that the mode is still kVoip. - EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip, - states.encoder->application()); + EXPECT_EQ(AudioEncoderOpus::kVoip, states.encoder->application()); } TEST(AudioEncoderOpusTest, ToggleDtx) { @@ -245,7 +238,7 @@ void TestSetPacketLossRate(AudioEncoderOpusStates* states, float expected_return) { // |kSampleIntervalMs| is chosen to ease the calculation since // 0.9999 ^ 184198 = 1e-8. Which minimizes the effect of - // PacketLossFractionSmoother used in AudioEncoderOpusImpl. + // PacketLossFractionSmoother used in AudioEncoderOpus. constexpr int64_t kSampleIntervalMs = 184198; for (float loss : losses) { states->encoder->OnReceivedUplinkPacketLossFraction(loss); @@ -459,29 +452,25 @@ TEST(AudioEncoderOpusTest, BitrateBounded) { // Verifies that the complexity adaptation in the config works as intended. TEST(AudioEncoderOpusTest, ConfigComplexityAdaptation) { - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; config.low_rate_complexity = 8; config.complexity = 6; // Bitrate within hysteresis window. Expect empty output. - config.bitrate_bps = 12500; - EXPECT_EQ(rtc::Optional(), - AudioEncoderOpusImpl::GetNewComplexity(config)); + config.bitrate_bps = rtc::Optional(12500); + EXPECT_EQ(rtc::Optional(), config.GetNewComplexity()); // Bitrate below hysteresis window. Expect higher complexity. - config.bitrate_bps = 10999; - EXPECT_EQ(rtc::Optional(8), - AudioEncoderOpusImpl::GetNewComplexity(config)); + config.bitrate_bps = rtc::Optional(10999); + EXPECT_EQ(rtc::Optional(8), config.GetNewComplexity()); // Bitrate within hysteresis window. Expect empty output. - config.bitrate_bps = 12500; - EXPECT_EQ(rtc::Optional(), - AudioEncoderOpusImpl::GetNewComplexity(config)); + config.bitrate_bps = rtc::Optional(12500); + EXPECT_EQ(rtc::Optional(), config.GetNewComplexity()); // Bitrate above hysteresis window. Expect lower complexity. - config.bitrate_bps = 14001; - EXPECT_EQ(rtc::Optional(6), - AudioEncoderOpusImpl::GetNewComplexity(config)); + config.bitrate_bps = rtc::Optional(14001); + EXPECT_EQ(rtc::Optional(6), config.GetNewComplexity()); } TEST(AudioEncoderOpusTest, EmptyConfigDoesNotAffectEncoderSettings) { @@ -563,82 +552,84 @@ TEST(AudioEncoderOpusTest, EncodeAtMinBitrate) { } TEST(AudioEncoderOpusTest, TestConfigDefaults) { - const auto config_opt = AudioEncoderOpusImpl::SdpToConfig({"opus", 48000, 2}); - ASSERT_TRUE(config_opt); - EXPECT_EQ(48000, config_opt->max_playback_rate_hz); - EXPECT_EQ(1u, config_opt->num_channels); - EXPECT_FALSE(config_opt->fec_enabled); - EXPECT_FALSE(config_opt->dtx_enabled); - EXPECT_EQ(20, config_opt->frame_size_ms); + const AudioEncoderOpus::Config config = + AudioEncoderOpus::CreateConfig(0, {"opus", 48000, 2}); + + EXPECT_EQ(48000, config.max_playback_rate_hz); + EXPECT_EQ(1u, config.num_channels); + EXPECT_FALSE(config.fec_enabled); + EXPECT_FALSE(config.dtx_enabled); + EXPECT_EQ(20, config.frame_size_ms); } TEST(AudioEncoderOpusTest, TestConfigFromParams) { - const auto config1 = CreateConfigWithParameters({{"stereo", "0"}}); - EXPECT_EQ(1U, config1.num_channels); + AudioEncoderOpus::Config config; - const auto config2 = CreateConfigWithParameters({{"stereo", "1"}}); - EXPECT_EQ(2U, config2.num_channels); + config = CreateConfigWithParameters({{"stereo", "0"}}); + EXPECT_EQ(1U, config.num_channels); - const auto config3 = CreateConfigWithParameters({{"useinbandfec", "0"}}); - EXPECT_FALSE(config3.fec_enabled); + config = CreateConfigWithParameters({{"stereo", "1"}}); + EXPECT_EQ(2U, config.num_channels); - const auto config4 = CreateConfigWithParameters({{"useinbandfec", "1"}}); - EXPECT_TRUE(config4.fec_enabled); + config = CreateConfigWithParameters({{"useinbandfec", "0"}}); + EXPECT_FALSE(config.fec_enabled); - const auto config5 = CreateConfigWithParameters({{"usedtx", "0"}}); - EXPECT_FALSE(config5.dtx_enabled); + config = CreateConfigWithParameters({{"useinbandfec", "1"}}); + EXPECT_TRUE(config.fec_enabled); - const auto config6 = CreateConfigWithParameters({{"usedtx", "1"}}); - EXPECT_TRUE(config6.dtx_enabled); + config = CreateConfigWithParameters({{"usedtx", "0"}}); + EXPECT_FALSE(config.dtx_enabled); - const auto config7 = CreateConfigWithParameters({{"cbr", "0"}}); - EXPECT_FALSE(config7.cbr_enabled); + config = CreateConfigWithParameters({{"usedtx", "1"}}); + EXPECT_TRUE(config.dtx_enabled); - const auto config8 = CreateConfigWithParameters({{"cbr", "1"}}); - EXPECT_TRUE(config8.cbr_enabled); + config = CreateConfigWithParameters({{"cbr", "0"}}); + EXPECT_FALSE(config.cbr_enabled); - const auto config9 = - CreateConfigWithParameters({{"maxplaybackrate", "12345"}}); - EXPECT_EQ(12345, config9.max_playback_rate_hz); + config = CreateConfigWithParameters({{"cbr", "1"}}); + EXPECT_TRUE(config.cbr_enabled); - const auto config10 = - CreateConfigWithParameters({{"maxaveragebitrate", "96000"}}); - EXPECT_EQ(96000, config10.bitrate_bps); + config = CreateConfigWithParameters({{"maxplaybackrate", "12345"}}); + EXPECT_EQ(12345, config.max_playback_rate_hz); - const auto config11 = CreateConfigWithParameters({{"maxptime", "40"}}); - for (int frame_length : config11.supported_frame_lengths_ms) { + config = CreateConfigWithParameters({{"maxaveragebitrate", "96000"}}); + EXPECT_EQ(96000, config.bitrate_bps); + + config = CreateConfigWithParameters({{"maxptime", "40"}}); + for (int frame_length : config.supported_frame_lengths_ms) { EXPECT_LE(frame_length, 40); } - const auto config12 = CreateConfigWithParameters({{"minptime", "40"}}); - for (int frame_length : config12.supported_frame_lengths_ms) { + config = CreateConfigWithParameters({{"minptime", "40"}}); + for (int frame_length : config.supported_frame_lengths_ms) { EXPECT_GE(frame_length, 40); } - const auto config13 = CreateConfigWithParameters({{"ptime", "40"}}); - EXPECT_EQ(40, config13.frame_size_ms); + config = CreateConfigWithParameters({{"ptime", "40"}}); + EXPECT_EQ(40, config.frame_size_ms); constexpr int kMinSupportedFrameLength = 10; constexpr int kMaxSupportedFrameLength = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60; - const auto config14 = CreateConfigWithParameters({{"ptime", "1"}}); - EXPECT_EQ(kMinSupportedFrameLength, config14.frame_size_ms); + config = CreateConfigWithParameters({{"ptime", "1"}}); + EXPECT_EQ(kMinSupportedFrameLength, config.frame_size_ms); - const auto config15 = CreateConfigWithParameters({{"ptime", "2000"}}); - EXPECT_EQ(kMaxSupportedFrameLength, config15.frame_size_ms); + config = CreateConfigWithParameters({{"ptime", "2000"}}); + EXPECT_EQ(kMaxSupportedFrameLength, config.frame_size_ms); } TEST(AudioEncoderOpusTest, TestConfigFromInvalidParams) { const webrtc::SdpAudioFormat format("opus", 48000, 2); - const auto default_config = *AudioEncoderOpusImpl::SdpToConfig(format); + const AudioEncoderOpus::Config default_config = + AudioEncoderOpus::CreateConfig(0, format); #if WEBRTC_OPUS_SUPPORT_120MS_PTIME const std::vector default_supported_frame_lengths_ms({20, 60, 120}); #else const std::vector default_supported_frame_lengths_ms({20, 60}); #endif - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; config = CreateConfigWithParameters({{"stereo", "invalid"}}); EXPECT_EQ(default_config.num_channels, config.num_channels); @@ -690,18 +681,18 @@ TEST(AudioEncoderOpusTest, TestConfigFromInvalidParams) { // range of 6000 and 510000 TEST(AudioEncoderOpusTest, SetSendCodecOpusMaxAverageBitrate) { // Ignore if less than 6000. - const auto config1 = AudioEncoderOpusImpl::SdpToConfig( - {"opus", 48000, 2, {{"maxaveragebitrate", "5999"}}}); - EXPECT_EQ(6000, config1->bitrate_bps); + const AudioEncoderOpus::Config config1 = AudioEncoderOpus::CreateConfig( + 0, {"opus", 48000, 2, {{"maxaveragebitrate", "5999"}}}); + EXPECT_EQ(6000, config1.bitrate_bps); // Ignore if larger than 510000. - const auto config2 = AudioEncoderOpusImpl::SdpToConfig( - {"opus", 48000, 2, {{"maxaveragebitrate", "510001"}}}); - EXPECT_EQ(510000, config2->bitrate_bps); + const AudioEncoderOpus::Config config2 = AudioEncoderOpus::CreateConfig( + 0, {"opus", 48000, 2, {{"maxaveragebitrate", "510001"}}}); + EXPECT_EQ(510000, config2.bitrate_bps); - const auto config3 = AudioEncoderOpusImpl::SdpToConfig( - {"opus", 48000, 2, {{"maxaveragebitrate", "200000"}}}); - EXPECT_EQ(200000, config3->bitrate_bps); + const AudioEncoderOpus::Config config3 = AudioEncoderOpus::CreateConfig( + 0, {"opus", 48000, 2, {{"maxaveragebitrate", "200000"}}}); + EXPECT_EQ(200000, config3.bitrate_bps); } // Test maxplaybackrate <= 8000 triggers Opus narrow band mode. diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_complexity_unittest.cc b/webrtc/modules/audio_coding/codecs/opus/opus_complexity_unittest.cc index aad413acfc..b19991251b 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_complexity_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/opus/opus_complexity_unittest.cc @@ -19,10 +19,9 @@ namespace webrtc { namespace { -int64_t RunComplexityTest(const AudioEncoderOpusConfig& config) { +int64_t RunComplexityTest(const AudioEncoderOpus::Config& config) { // Create encoder. - constexpr int payload_type = 17; - AudioEncoderOpusImpl encoder(config, payload_type); + AudioEncoderOpus encoder(config); // Open speech file. const std::string kInputFileName = webrtc::test::ResourcePath("audio_coding/speech_mono_32_48kHz", "pcm"); @@ -61,14 +60,14 @@ int64_t RunComplexityTest(const AudioEncoderOpusConfig& config) { // the lower rate. TEST(AudioEncoderOpusComplexityAdaptationTest, AdaptationOn) { // Create config. - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; // The limit -- including the hysteresis window -- at which the complexity // shuold be increased. - config.bitrate_bps = 11000 - 1; + config.bitrate_bps = rtc::Optional(11000 - 1); config.low_rate_complexity = 9; int64_t runtime_10999bps = RunComplexityTest(config); - config.bitrate_bps = 15500; + config.bitrate_bps = rtc::Optional(15500); int64_t runtime_15500bps = RunComplexityTest(config); test::PrintResult("opus_encoding_complexity_ratio", "", "adaptation_on", @@ -81,14 +80,14 @@ TEST(AudioEncoderOpusComplexityAdaptationTest, AdaptationOn) { // that the resulting ratio is less than 100% at all times. TEST(AudioEncoderOpusComplexityAdaptationTest, AdaptationOff) { // Create config. - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; // The limit -- including the hysteresis window -- at which the complexity // shuold be increased (but not in this test since complexity adaptation is // disabled). - config.bitrate_bps = 11000 - 1; + config.bitrate_bps = rtc::Optional(11000 - 1); int64_t runtime_10999bps = RunComplexityTest(config); - config.bitrate_bps = 15500; + config.bitrate_bps = rtc::Optional(15500); int64_t runtime_15500bps = RunComplexityTest(config); test::PrintResult("opus_encoding_complexity_ratio", "", "adaptation_off", diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc index 6db4317a6e..8dcb416217 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc @@ -17,7 +17,6 @@ #include #include -#include "webrtc/api/audio_codecs/opus/audio_encoder_opus.h" #include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h" #include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h" #include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h" @@ -29,6 +28,7 @@ #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h" #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h" #include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" +#include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h" #include "webrtc/modules/audio_coding/neteq/tools/resample_input_audio_file.h" @@ -434,10 +434,11 @@ class AudioDecoderOpusTest : public AudioDecoderTest { frame_size_ = 480; data_length_ = 10 * frame_size_; decoder_ = new AudioDecoderOpus(1); - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; config.frame_size_ms = static_cast(frame_size_) / 48; - config.application = AudioEncoderOpusConfig::ApplicationMode::kVoip; - audio_encoder_ = AudioEncoderOpus::MakeAudioEncoder(config, payload_type_); + config.payload_type = payload_type_; + config.application = AudioEncoderOpus::kVoip; + audio_encoder_.reset(new AudioEncoderOpus(config)); } }; @@ -447,11 +448,12 @@ class AudioDecoderOpusStereoTest : public AudioDecoderOpusTest { channels_ = 2; delete decoder_; decoder_ = new AudioDecoderOpus(2); - AudioEncoderOpusConfig config; + AudioEncoderOpus::Config config; config.frame_size_ms = static_cast(frame_size_) / 48; config.num_channels = 2; - config.application = AudioEncoderOpusConfig::ApplicationMode::kAudio; - audio_encoder_ = AudioEncoderOpus::MakeAudioEncoder(config, payload_type_); + config.payload_type = payload_type_; + config.application = AudioEncoderOpus::kAudio; + audio_encoder_.reset(new AudioEncoderOpus(config)); } };