From 44d7ec06830ea1103f5a4c4e841980c94942a9aa Mon Sep 17 00:00:00 2001 From: Karl Wiberg Date: Tue, 26 Nov 2019 14:00:41 +0100 Subject: [PATCH] Add Opus-only audio codec factories Many WebRTC users need only Opus, and no other audio codecs. This makes it convenient for them to do the right thing. To prove that the new factories work, use them in PeerConnectionEndToEndTest. Bug: webrtc:11130 Change-Id: I2c2450ba0fb33ef3b50da8f6cd325cad6b1e59a6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/160648 Reviewed-by: Mirko Bonadei Commit-Queue: Karl Wiberg Cr-Commit-Position: refs/heads/master@{#29921} --- api/audio_codecs/BUILD.gn | 32 ++++++++++++ .../builtin_audio_decoder_factory.h | 4 ++ .../builtin_audio_encoder_factory.h | 4 ++ .../opus_audio_decoder_factory.cc | 49 +++++++++++++++++ api/audio_codecs/opus_audio_decoder_factory.h | 26 ++++++++++ .../opus_audio_encoder_factory.cc | 52 +++++++++++++++++++ api/audio_codecs/opus_audio_encoder_factory.h | 26 ++++++++++ pc/BUILD.gn | 2 + pc/peer_connection_end_to_end_unittest.cc | 16 +++--- 9 files changed, 203 insertions(+), 8 deletions(-) create mode 100644 api/audio_codecs/opus_audio_decoder_factory.cc create mode 100644 api/audio_codecs/opus_audio_decoder_factory.h create mode 100644 api/audio_codecs/opus_audio_encoder_factory.cc create mode 100644 api/audio_codecs/opus_audio_encoder_factory.h diff --git a/api/audio_codecs/BUILD.gn b/api/audio_codecs/BUILD.gn index 18126d8ab9..987e20f178 100644 --- a/api/audio_codecs/BUILD.gn +++ b/api/audio_codecs/BUILD.gn @@ -110,3 +110,35 @@ rtc_library("builtin_audio_encoder_factory") { defines += [ "WEBRTC_USE_BUILTIN_OPUS=0" ] } } + +rtc_library("opus_audio_decoder_factory") { + visibility = [ "*" ] + allow_poison = [ "audio_codecs" ] + sources = [ + "opus_audio_decoder_factory.cc", + "opus_audio_decoder_factory.h", + ] + deps = [ + ":audio_codecs_api", + "..:scoped_refptr", + "../../rtc_base:rtc_base_approved", + "opus:audio_decoder_multiopus", + "opus:audio_decoder_opus", + ] +} + +rtc_library("opus_audio_encoder_factory") { + visibility = [ "*" ] + allow_poison = [ "audio_codecs" ] + sources = [ + "opus_audio_encoder_factory.cc", + "opus_audio_encoder_factory.h", + ] + deps = [ + ":audio_codecs_api", + "..:scoped_refptr", + "../../rtc_base:rtc_base_approved", + "opus:audio_encoder_multiopus", + "opus:audio_encoder_opus", + ] +} diff --git a/api/audio_codecs/builtin_audio_decoder_factory.h b/api/audio_codecs/builtin_audio_decoder_factory.h index 8776196d26..72e1e3d96e 100644 --- a/api/audio_codecs/builtin_audio_decoder_factory.h +++ b/api/audio_codecs/builtin_audio_decoder_factory.h @@ -17,6 +17,10 @@ namespace webrtc { // Creates a new factory that can create the built-in types of audio decoders. +// Note: This will link with all the code implementing those codecs, so if you +// only need a subset of the codecs, consider using +// CreateAudioDecoderFactory<...codecs listed here...>() or +// CreateOpusAudioDecoderFactory() instead. rtc::scoped_refptr CreateBuiltinAudioDecoderFactory(); } // namespace webrtc diff --git a/api/audio_codecs/builtin_audio_encoder_factory.h b/api/audio_codecs/builtin_audio_encoder_factory.h index 48ebc43112..f833de10f1 100644 --- a/api/audio_codecs/builtin_audio_encoder_factory.h +++ b/api/audio_codecs/builtin_audio_encoder_factory.h @@ -17,6 +17,10 @@ namespace webrtc { // Creates a new factory that can create the built-in types of audio encoders. +// Note: This will link with all the code implementing those codecs, so if you +// only need a subset of the codecs, consider using +// CreateAudioEncoderFactory<...codecs listed here...>() or +// CreateOpusAudioEncoderFactory() instead. rtc::scoped_refptr CreateBuiltinAudioEncoderFactory(); } // namespace webrtc diff --git a/api/audio_codecs/opus_audio_decoder_factory.cc b/api/audio_codecs/opus_audio_decoder_factory.cc new file mode 100644 index 0000000000..ed68f2584e --- /dev/null +++ b/api/audio_codecs/opus_audio_decoder_factory.cc @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019 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 "api/audio_codecs/opus_audio_decoder_factory.h" + +#include +#include + +#include "api/audio_codecs/audio_decoder_factory_template.h" +#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h" +#include "api/audio_codecs/opus/audio_decoder_opus.h" + +namespace webrtc { + +namespace { + +// Modify an audio decoder to not advertise support for anything. +template +struct NotAdvertised { + using Config = typename T::Config; + static absl::optional SdpToConfig( + const SdpAudioFormat& audio_format) { + return T::SdpToConfig(audio_format); + } + static void AppendSupportedDecoders(std::vector* specs) { + // Don't advertise support for anything. + } + static std::unique_ptr MakeAudioDecoder( + const Config& config, + absl::optional codec_pair_id = absl::nullopt) { + return T::MakeAudioDecoder(config, codec_pair_id); + } +}; + +} // namespace + +rtc::scoped_refptr CreateOpusAudioDecoderFactory() { + return CreateAudioDecoderFactory< + AudioDecoderOpus, NotAdvertised>(); +} + +} // namespace webrtc diff --git a/api/audio_codecs/opus_audio_decoder_factory.h b/api/audio_codecs/opus_audio_decoder_factory.h new file mode 100644 index 0000000000..b4f497f8ff --- /dev/null +++ b/api/audio_codecs/opus_audio_decoder_factory.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019 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 API_AUDIO_CODECS_OPUS_AUDIO_DECODER_FACTORY_H_ +#define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_FACTORY_H_ + +#include "api/audio_codecs/audio_decoder_factory.h" +#include "api/scoped_refptr.h" + +namespace webrtc { + +// Creates a new factory that can create only Opus audio decoders. Works like +// CreateAudioDecoderFactory(), but is easier to use and is +// not inline because it isn't a template. +rtc::scoped_refptr CreateOpusAudioDecoderFactory(); + +} // namespace webrtc + +#endif // API_AUDIO_CODECS_OPUS_AUDIO_DECODER_FACTORY_H_ diff --git a/api/audio_codecs/opus_audio_encoder_factory.cc b/api/audio_codecs/opus_audio_encoder_factory.cc new file mode 100644 index 0000000000..5f0c7147f5 --- /dev/null +++ b/api/audio_codecs/opus_audio_encoder_factory.cc @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 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 "api/audio_codecs/opus_audio_encoder_factory.h" + +#include +#include + +#include "api/audio_codecs/audio_encoder_factory_template.h" +#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h" +#include "api/audio_codecs/opus/audio_encoder_opus.h" + +namespace webrtc { +namespace { + +// Modify an audio encoder to not advertise support for anything. +template +struct NotAdvertised { + using Config = typename T::Config; + static absl::optional SdpToConfig( + const SdpAudioFormat& audio_format) { + return T::SdpToConfig(audio_format); + } + static void AppendSupportedEncoders(std::vector* specs) { + // Don't advertise support for anything. + } + static AudioCodecInfo QueryAudioEncoder(const Config& config) { + return T::QueryAudioEncoder(config); + } + static std::unique_ptr MakeAudioEncoder( + const Config& config, + int payload_type, + absl::optional codec_pair_id = absl::nullopt) { + return T::MakeAudioEncoder(config, payload_type, codec_pair_id); + } +}; + +} // namespace + +rtc::scoped_refptr CreateOpusAudioEncoderFactory() { + return CreateAudioEncoderFactory< + AudioEncoderOpus, NotAdvertised>(); +} + +} // namespace webrtc diff --git a/api/audio_codecs/opus_audio_encoder_factory.h b/api/audio_codecs/opus_audio_encoder_factory.h new file mode 100644 index 0000000000..8c1683b6f5 --- /dev/null +++ b/api/audio_codecs/opus_audio_encoder_factory.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019 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 API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_FACTORY_H_ +#define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_FACTORY_H_ + +#include "api/audio_codecs/audio_encoder_factory.h" +#include "api/scoped_refptr.h" + +namespace webrtc { + +// Creates a new factory that can create only Opus audio encoders. Works like +// CreateAudioEncoderFactory(), but is easier to use and is +// not inline because it isn't a template. +rtc::scoped_refptr CreateOpusAudioEncoderFactory(); + +} // namespace webrtc + +#endif // API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_FACTORY_H_ diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 83318b5d0b..4d0b61f9fe 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -613,6 +613,8 @@ if (rtc_include_tests) { "../api/audio_codecs:audio_codecs_api", "../api/audio_codecs:builtin_audio_decoder_factory", "../api/audio_codecs:builtin_audio_encoder_factory", + "../api/audio_codecs:opus_audio_decoder_factory", + "../api/audio_codecs:opus_audio_encoder_factory", "../api/audio_codecs/L16:audio_decoder_L16", "../api/audio_codecs/L16:audio_encoder_L16", "../api/video_codecs:builtin_video_decoder_factory", diff --git a/pc/peer_connection_end_to_end_unittest.cc b/pc/peer_connection_end_to_end_unittest.cc index 2c8d6ea6de..24ef69c111 100644 --- a/pc/peer_connection_end_to_end_unittest.cc +++ b/pc/peer_connection_end_to_end_unittest.cc @@ -16,8 +16,8 @@ #include "api/audio_codecs/audio_codec_pair_id.h" #include "api/audio_codecs/audio_decoder_factory_template.h" #include "api/audio_codecs/audio_encoder_factory_template.h" -#include "api/audio_codecs/builtin_audio_decoder_factory.h" -#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/audio_codecs/opus_audio_decoder_factory.h" +#include "api/audio_codecs/opus_audio_encoder_factory.h" #include "media/sctp/sctp_transport_internal.h" #include "rtc_base/gunit.h" #include "rtc_base/logging.h" @@ -358,8 +358,8 @@ struct AudioDecoderUnicornSparklesRainbow { TEST_P(PeerConnectionEndToEndTest, Call) { rtc::scoped_refptr real_decoder_factory = - webrtc::CreateBuiltinAudioDecoderFactory(); - CreatePcs(webrtc::CreateBuiltinAudioEncoderFactory(), + webrtc::CreateOpusAudioDecoderFactory(); + CreatePcs(webrtc::CreateOpusAudioEncoderFactory(), CreateForwardingMockDecoderFactory(real_decoder_factory.get())); GetAndAddUserMedia(); Negotiate(); @@ -368,8 +368,8 @@ TEST_P(PeerConnectionEndToEndTest, Call) { TEST_P(PeerConnectionEndToEndTest, CallWithSdesKeyNegotiation) { config_.enable_dtls_srtp = false; - CreatePcs(webrtc::CreateBuiltinAudioEncoderFactory(), - webrtc::CreateBuiltinAudioDecoderFactory()); + CreatePcs(webrtc::CreateOpusAudioEncoderFactory(), + webrtc::CreateOpusAudioDecoderFactory()); GetAndAddUserMedia(); Negotiate(); WaitForCallEstablished(); @@ -739,8 +739,8 @@ TEST_P(PeerConnectionEndToEndTest, TooManyDataChannelsOpenedBeforeConnecting) { TEST_P(PeerConnectionEndToEndTest, CanRestartIce) { rtc::scoped_refptr real_decoder_factory = - webrtc::CreateBuiltinAudioDecoderFactory(); - CreatePcs(webrtc::CreateBuiltinAudioEncoderFactory(), + webrtc::CreateOpusAudioDecoderFactory(); + CreatePcs(webrtc::CreateOpusAudioEncoderFactory(), CreateForwardingMockDecoderFactory(real_decoder_factory.get())); GetAndAddUserMedia(); Negotiate();