AudioCodingModule: Remove support for creating encoders

After this CL, all audio encoders have to be injected by the caller.
This means that there is no special "built-in" set of codecs, and
users won't have to pay the binary size and security costs of codecs
they aren't using.

Bug: webrtc:8396
Change-Id: Idb0959ce395940c8bb3bbb49256cdcd84fc87bb6
Reviewed-on: https://webrtc-review.googlesource.com/c/103821
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25600}
This commit is contained in:
Karl Wiberg
2018-11-12 14:21:58 +01:00
committed by Commit Bot
parent 80c6762a37
commit 49c33ce528
9 changed files with 75 additions and 1402 deletions

View File

@ -18,7 +18,6 @@
#include "api/array_view.h"
#include "modules/audio_coding/acm2/acm_receiver.h"
#include "modules/audio_coding/acm2/acm_resampler.h"
#include "modules/audio_coding/acm2/codec_manager.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "modules/include/module_common_types.h"
#include "modules/include/module_common_types_public.h"
@ -34,12 +33,6 @@ namespace webrtc {
namespace {
struct EncoderFactory {
AudioEncoder* external_speech_encoder = nullptr;
acm2::CodecManager codec_manager;
acm2::RentACodec rent_a_codec;
};
class AudioCodingModuleImpl final : public AudioCodingModule {
public:
explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config);
@ -49,12 +42,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
// Sender
//
// Can be called multiple times for Codec, CNG, RED.
int RegisterSendCodec(const CodecInst& send_codec) override;
void RegisterExternalSendCodec(
AudioEncoder* external_speech_encoder) override;
void ModifyEncoder(rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)>
modifier) override;
@ -73,26 +60,10 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
// Add 10 ms of raw (PCM) audio data to the encoder.
int Add10MsData(const AudioFrame& audio_frame) override;
/////////////////////////////////////////
// (RED) Redundant Coding
//
// Configure RED status i.e. on/off.
int SetREDStatus(bool enable_red) override;
// Get RED status.
bool REDStatus() const override;
/////////////////////////////////////////
// (FEC) Forward Error Correction (codec internal)
//
// Configure FEC status i.e. on/off.
int SetCodecFEC(bool enabled_codec_fec) override;
// Get FEC status.
bool CodecFEC() const override;
// Set target packet loss rate
int SetPacketLossRate(int loss_rate) override;
@ -102,14 +73,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
// (CNG) Comfort Noise Generation
//
int SetVAD(bool enable_dtx = true,
bool enable_vad = false,
ACMVADMode mode = VADNormal) override;
int VAD(bool* dtx_enabled,
bool* vad_enabled,
ACMVADMode* mode) const override;
int RegisterVADCallback(ACMVADCallback* vad_callback) override;
/////////////////////////////////////////
@ -130,11 +93,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
bool RegisterReceiveCodec(int rtp_payload_type,
const SdpAudioFormat& audio_format) override;
int RegisterReceiveCodec(const CodecInst& receive_codec) override;
int RegisterReceiveCodec(
const CodecInst& receive_codec,
rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory) override;
int RegisterExternalReceiveCodec(int rtp_payload_type,
AudioDecoder* external_decoder,
int sample_rate_hz,
@ -222,11 +180,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
const std::string histogram_name_;
};
int RegisterReceiveCodecUnlocked(
const CodecInst& codec,
rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory)
RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
int Add10MsDataInternal(const AudioFrame& audio_frame, InputData* input_data)
RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
int Encode(const InputData& input_data)
@ -264,12 +217,7 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
acm2::AcmReceiver receiver_; // AcmReceiver has it's own internal lock.
ChangeLogger bitrate_logger_ RTC_GUARDED_BY(acm_crit_sect_);
std::unique_ptr<EncoderFactory> encoder_factory_
RTC_GUARDED_BY(acm_crit_sect_);
// Current encoder stack, either obtained from
// encoder_factory_->rent_a_codec.RentEncoderStack or provided by a call to
// RegisterEncoder.
// Current encoder stack, provided by a call to RegisterEncoder.
std::unique_ptr<AudioEncoder> encoder_stack_ RTC_GUARDED_BY(acm_crit_sect_);
std::unique_ptr<AudioDecoder> isac_decoder_16k_
@ -405,28 +353,6 @@ class RawAudioEncoderWrapper final : public AudioEncoder {
AudioEncoder* enc_;
};
// Return false on error.
bool CreateSpeechEncoderIfNecessary(EncoderFactory* ef) {
auto* sp = ef->codec_manager.GetStackParams();
if (sp->speech_encoder) {
// Do nothing; we already have a speech encoder.
} else if (ef->codec_manager.GetCodecInst()) {
RTC_DCHECK(!ef->external_speech_encoder);
// We have no speech encoder, but we have a specification for making one.
std::unique_ptr<AudioEncoder> enc =
ef->rent_a_codec.RentEncoder(*ef->codec_manager.GetCodecInst());
if (!enc)
return false; // Encoder spec was bad.
sp->speech_encoder = std::move(enc);
} else if (ef->external_speech_encoder) {
RTC_DCHECK(!ef->codec_manager.GetCodecInst());
// We have an external speech encoder.
sp->speech_encoder = std::unique_ptr<AudioEncoder>(
new RawAudioEncoderWrapper(ef->external_speech_encoder));
}
return true;
}
void AudioCodingModuleImpl::ChangeLogger::MaybeLog(int value) {
if (value != last_value_ || first_time_) {
first_time_ = false;
@ -441,7 +367,6 @@ AudioCodingModuleImpl::AudioCodingModuleImpl(
expected_in_ts_(0xD87F3F9F),
receiver_(config),
bitrate_logger_("WebRTC.Audio.TargetBitrateInKbps"),
encoder_factory_(new EncoderFactory),
encoder_stack_(nullptr),
previous_pltype_(255),
receiver_initialized_(false),
@ -549,69 +474,29 @@ int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) {
// Sender
//
// Can be called multiple times for Codec, CNG, RED.
int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) {
rtc::CritScope lock(&acm_crit_sect_);
if (!encoder_factory_->codec_manager.RegisterEncoder(send_codec)) {
return -1;
}
if (encoder_factory_->codec_manager.GetCodecInst()) {
encoder_factory_->external_speech_encoder = nullptr;
}
if (!CreateSpeechEncoderIfNecessary(encoder_factory_.get())) {
return -1;
}
auto* sp = encoder_factory_->codec_manager.GetStackParams();
if (sp->speech_encoder)
encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
return 0;
}
void AudioCodingModuleImpl::RegisterExternalSendCodec(
AudioEncoder* external_speech_encoder) {
rtc::CritScope lock(&acm_crit_sect_);
encoder_factory_->codec_manager.UnsetCodecInst();
encoder_factory_->external_speech_encoder = external_speech_encoder;
RTC_CHECK(CreateSpeechEncoderIfNecessary(encoder_factory_.get()));
auto* sp = encoder_factory_->codec_manager.GetStackParams();
RTC_CHECK(sp->speech_encoder);
encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
}
void AudioCodingModuleImpl::ModifyEncoder(
rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier) {
rtc::CritScope lock(&acm_crit_sect_);
// Wipe the encoder factory, so that everything that relies on it will fail.
// We don't want the complexity of supporting swapping back and forth.
if (encoder_factory_) {
encoder_factory_.reset();
RTC_CHECK(!encoder_stack_); // Ensure we hadn't started using the factory.
}
modifier(&encoder_stack_);
}
// Get current send codec.
absl::optional<CodecInst> AudioCodingModuleImpl::SendCodec() const {
rtc::CritScope lock(&acm_crit_sect_);
if (encoder_factory_) {
auto* ci = encoder_factory_->codec_manager.GetCodecInst();
if (ci) {
return *ci;
}
CreateSpeechEncoderIfNecessary(encoder_factory_.get());
const std::unique_ptr<AudioEncoder>& enc =
encoder_factory_->codec_manager.GetStackParams()->speech_encoder;
if (enc) {
return acm2::CodecManager::ForgeCodecInst(enc.get());
}
return absl::nullopt;
if (encoder_stack_) {
CodecInst ci;
ci.channels = encoder_stack_->NumChannels();
ci.plfreq = encoder_stack_->SampleRateHz();
ci.pacsize = rtc::CheckedDivExact(
static_cast<int>(encoder_stack_->Max10MsFramesInAPacket() * ci.plfreq),
100);
ci.pltype = -1; // Not valid.
ci.rate = -1; // Not valid.
static const char kName[] = "external";
memcpy(ci.plname, kName, sizeof(kName));
return ci;
} else {
return encoder_stack_
? absl::optional<CodecInst>(
acm2::CodecManager::ForgeCodecInst(encoder_stack_.get()))
: absl::nullopt;
return absl::nullopt;
}
}
@ -808,59 +693,10 @@ int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame,
return 0;
}
/////////////////////////////////////////
// (RED) Redundant Coding
//
bool AudioCodingModuleImpl::REDStatus() const {
rtc::CritScope lock(&acm_crit_sect_);
return encoder_factory_->codec_manager.GetStackParams()->use_red;
}
// Configure RED status i.e on/off.
int AudioCodingModuleImpl::SetREDStatus(bool enable_red) {
#ifdef WEBRTC_CODEC_RED
rtc::CritScope lock(&acm_crit_sect_);
CreateSpeechEncoderIfNecessary(encoder_factory_.get());
if (!encoder_factory_->codec_manager.SetCopyRed(enable_red)) {
return -1;
}
auto* sp = encoder_factory_->codec_manager.GetStackParams();
if (sp->speech_encoder)
encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
return 0;
#else
RTC_LOG(LS_WARNING) << " WEBRTC_CODEC_RED is undefined";
return -1;
#endif
}
/////////////////////////////////////////
// (FEC) Forward Error Correction (codec internal)
//
bool AudioCodingModuleImpl::CodecFEC() const {
rtc::CritScope lock(&acm_crit_sect_);
return encoder_factory_->codec_manager.GetStackParams()->use_codec_fec;
}
int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) {
rtc::CritScope lock(&acm_crit_sect_);
CreateSpeechEncoderIfNecessary(encoder_factory_.get());
if (!encoder_factory_->codec_manager.SetCodecFEC(enable_codec_fec)) {
return -1;
}
auto* sp = encoder_factory_->codec_manager.GetStackParams();
if (sp->speech_encoder)
encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
if (enable_codec_fec) {
return sp->use_codec_fec ? 0 : -1;
} else {
RTC_DCHECK(!sp->use_codec_fec);
return 0;
}
}
int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) {
rtc::CritScope lock(&acm_crit_sect_);
if (HaveValidEncoder("SetPacketLossRate")) {
@ -869,36 +705,6 @@ int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) {
return 0;
}
/////////////////////////////////////////
// (VAD) Voice Activity Detection
//
int AudioCodingModuleImpl::SetVAD(bool enable_dtx,
bool enable_vad,
ACMVADMode mode) {
// Note: |enable_vad| is not used; VAD is enabled based on the DTX setting.
RTC_DCHECK_EQ(enable_dtx, enable_vad);
rtc::CritScope lock(&acm_crit_sect_);
CreateSpeechEncoderIfNecessary(encoder_factory_.get());
if (!encoder_factory_->codec_manager.SetVAD(enable_dtx, mode)) {
return -1;
}
auto* sp = encoder_factory_->codec_manager.GetStackParams();
if (sp->speech_encoder)
encoder_stack_ = encoder_factory_->rent_a_codec.RentEncoderStack(sp);
return 0;
}
// Get VAD/DTX settings.
int AudioCodingModuleImpl::VAD(bool* dtx_enabled,
bool* vad_enabled,
ACMVADMode* mode) const {
rtc::CritScope lock(&acm_crit_sect_);
const auto* sp = encoder_factory_->codec_manager.GetStackParams();
*dtx_enabled = *vad_enabled = sp->use_cng;
*mode = sp->vad_mode;
return 0;
}
/////////////////////////////////////////
// Receiver
//
@ -957,59 +763,6 @@ bool AudioCodingModuleImpl::RegisterReceiveCodec(
return receiver_.AddCodec(rtp_payload_type, audio_format);
}
int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) {
rtc::CritScope lock(&acm_crit_sect_);
auto* ef = encoder_factory_.get();
return RegisterReceiveCodecUnlocked(
codec, [&] { return ef->rent_a_codec.RentIsacDecoder(codec.plfreq); });
}
int AudioCodingModuleImpl::RegisterReceiveCodec(
const CodecInst& codec,
rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory) {
rtc::CritScope lock(&acm_crit_sect_);
return RegisterReceiveCodecUnlocked(codec, isac_factory);
}
int AudioCodingModuleImpl::RegisterReceiveCodecUnlocked(
const CodecInst& codec,
rtc::FunctionView<std::unique_ptr<AudioDecoder>()> isac_factory) {
RTC_DCHECK(receiver_initialized_);
if (codec.channels > 2) {
RTC_LOG_F(LS_ERROR) << "Unsupported number of channels: " << codec.channels;
return -1;
}
auto codec_id = acm2::RentACodec::CodecIdByParams(codec.plname, codec.plfreq,
codec.channels);
if (!codec_id) {
RTC_LOG_F(LS_ERROR)
<< "Wrong codec params to be registered as receive codec";
return -1;
}
auto codec_index = acm2::RentACodec::CodecIndexFromId(*codec_id);
RTC_CHECK(codec_index) << "Invalid codec ID: " << static_cast<int>(*codec_id);
// Check if the payload-type is valid.
if (!acm2::RentACodec::IsPayloadTypeValid(codec.pltype)) {
RTC_LOG_F(LS_ERROR) << "Invalid payload type " << codec.pltype << " for "
<< codec.plname;
return -1;
}
AudioDecoder* isac_decoder = nullptr;
if (absl::EqualsIgnoreCase(codec.plname, "isac")) {
std::unique_ptr<AudioDecoder>& saved_isac_decoder =
codec.plfreq == 16000 ? isac_decoder_16k_ : isac_decoder_32k_;
if (!saved_isac_decoder) {
saved_isac_decoder = isac_factory();
}
isac_decoder = saved_isac_decoder.get();
}
return receiver_.AddCodec(*codec_index, codec.pltype, codec.channels,
codec.plfreq, isac_decoder, codec.plname);
}
int AudioCodingModuleImpl::RegisterExternalReceiveCodec(
int rtp_payload_type,
AudioDecoder* external_decoder,