Revert r8248 "Introduce ACMGenericCodecWrapper"

This reverts r8248 due to some build bot failures.

TBR=kwiberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/40649004

Cr-Commit-Position: refs/heads/master@{#8249}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8249 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org 2015-02-05 09:36:58 +00:00
parent af8c13f2a1
commit 3a87630629
3 changed files with 30 additions and 919 deletions

View File

@ -12,59 +12,15 @@
#include <assert.h>
#include <string.h>
#include <algorithm>
#include <utility>
#include "webrtc/base/checks.h"
#include "webrtc/common_audio/vad/include/webrtc_vad.h"
#include "webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h"
#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h"
#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h"
#include "webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h"
#include "webrtc/modules/audio_coding/codecs/ilbc/interface/audio_encoder_ilbc.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h"
#include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"
#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h"
#include "webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
#include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc {
namespace {
static const int kInvalidPayloadType = 255;
void SetCngPtInMap(
std::map<int, std::pair<int, WebRtcACMEncodingType>>* cng_pt_map,
int sample_rate_hz,
int payload_type) {
if (payload_type == kInvalidPayloadType)
return;
CHECK_GE(payload_type, 0);
CHECK_LT(payload_type, 128);
WebRtcACMEncodingType encoding_type;
switch (sample_rate_hz) {
case 8000:
encoding_type = kPassiveDTXNB;
break;
case 16000:
encoding_type = kPassiveDTXWB;
break;
case 32000:
encoding_type = kPassiveDTXSWB;
break;
case 48000:
encoding_type = kPassiveDTXFB;
break;
default:
FATAL() << "Unsupported frequency.";
}
(*cng_pt_map)[payload_type] = std::make_pair(sample_rate_hz, encoding_type);
}
} // namespace
namespace acm2 {
// Enum for CNG
@ -260,8 +216,7 @@ bool ACMGenericCodec::ExternalRedNeeded() {
int16_t ACMGenericCodec::Encode(uint8_t* bitstream,
int16_t* bitstream_len_byte,
uint32_t* timestamp,
WebRtcACMEncodingType* encoding_type,
AudioEncoder::EncodedInfo* /*encoded_info*/) {
WebRtcACMEncodingType* encoding_type) {
if (!HasFrameToEncode()) {
// There is not enough audio
*timestamp = 0;
@ -696,9 +651,6 @@ int16_t ACMGenericCodec::SetVAD(bool* enable_dtx,
return SetVADSafe(enable_dtx, enable_vad, mode);
}
void ACMGenericCodec::SetCngPt(int sample_rate_hz, int payload_type) {
}
int16_t ACMGenericCodec::SetVADSafe(bool* enable_dtx,
bool* enable_vad,
ACMVADMode* mode) {
@ -1070,663 +1022,6 @@ int ACMGenericCodec::SetOpusMaxPlaybackRate(int /* frequency_hz */) {
return -1;
}
AudioDecoderProxy::AudioDecoderProxy()
: decoder_lock_(CriticalSectionWrapper::CreateCriticalSection()),
decoder_(nullptr) {
}
void AudioDecoderProxy::SetDecoder(AudioDecoder* decoder) {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
decoder_ = decoder;
channels_ = decoder->channels();
CHECK_EQ(decoder_->Init(), 0);
}
bool AudioDecoderProxy::IsSet() const {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return (decoder_ != nullptr);
}
int AudioDecoderProxy::Decode(const uint8_t* encoded,
size_t encoded_len,
int16_t* decoded,
SpeechType* speech_type) {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->Decode(encoded, encoded_len, decoded, speech_type);
}
int AudioDecoderProxy::DecodeRedundant(const uint8_t* encoded,
size_t encoded_len,
int16_t* decoded,
SpeechType* speech_type) {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->DecodeRedundant(encoded, encoded_len, decoded, speech_type);
}
bool AudioDecoderProxy::HasDecodePlc() const {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->HasDecodePlc();
}
int AudioDecoderProxy::DecodePlc(int num_frames, int16_t* decoded) {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->DecodePlc(num_frames, decoded);
}
int AudioDecoderProxy::Init() {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->Init();
}
int AudioDecoderProxy::IncomingPacket(const uint8_t* payload,
size_t payload_len,
uint16_t rtp_sequence_number,
uint32_t rtp_timestamp,
uint32_t arrival_timestamp) {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->IncomingPacket(payload, payload_len, rtp_sequence_number,
rtp_timestamp, arrival_timestamp);
}
int AudioDecoderProxy::ErrorCode() {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->ErrorCode();
}
int AudioDecoderProxy::PacketDuration(const uint8_t* encoded,
size_t encoded_len) {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->PacketDuration(encoded, encoded_len);
}
int AudioDecoderProxy::PacketDurationRedundant(const uint8_t* encoded,
size_t encoded_len) const {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->PacketDurationRedundant(encoded, encoded_len);
}
bool AudioDecoderProxy::PacketHasFec(const uint8_t* encoded,
size_t encoded_len) const {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->PacketHasFec(encoded, encoded_len);
}
CNG_dec_inst* AudioDecoderProxy::CngDecoderInstance() {
CriticalSectionScoped decoder_lock(decoder_lock_.get());
return decoder_->CngDecoderInstance();
}
////////////////////////////////////////
// ACMGenericCodecWrapper implementation
ACMGenericCodecWrapper::ACMGenericCodecWrapper(const CodecInst& codec_inst,
int cng_pt_nb,
int cng_pt_wb,
int cng_pt_swb,
int cng_pt_fb,
bool enable_red,
int red_payload_type)
: ACMGenericCodec(enable_red),
encoder_(NULL),
bitrate_bps_(0),
fec_enabled_(false),
loss_rate_(0),
max_playback_rate_hz_(48000),
max_payload_size_bytes_(-1),
max_rate_bps_(-1),
is_opus_(false),
is_isac_(false),
first_frame_(true),
red_payload_type_(red_payload_type),
opus_application_set_(false) {
acm_codec_params_.codec_inst = codec_inst;
acm_codec_params_.enable_dtx = false;
acm_codec_params_.enable_vad = false;
acm_codec_params_.vad_mode = VADNormal;
SetCngPtInMap(&cng_pt_, 8000, cng_pt_nb);
SetCngPtInMap(&cng_pt_, 16000, cng_pt_wb);
SetCngPtInMap(&cng_pt_, 32000, cng_pt_swb);
SetCngPtInMap(&cng_pt_, 48000, cng_pt_fb);
ResetAudioEncoder();
CHECK(encoder_);
}
ACMGenericCodec* ACMGenericCodecWrapper::CreateInstance() {
FATAL();
return 0;
}
int16_t ACMGenericCodecWrapper::Encode(
uint8_t* bitstream,
int16_t* bitstream_len_byte,
uint32_t* timestamp,
WebRtcACMEncodingType* encoding_type,
AudioEncoder::EncodedInfo* encoded_info) {
WriteLockScoped wl(codec_wrapper_lock_);
CHECK(!input_.empty());
CHECK(encoder_->Encode(rtp_timestamp_, &input_[0],
input_.size() / encoder_->num_channels(),
2 * MAX_PAYLOAD_SIZE_BYTE, bitstream, encoded_info));
input_.clear();
*bitstream_len_byte = static_cast<int16_t>(encoded_info->encoded_bytes);
if (encoded_info->encoded_bytes == 0) {
*encoding_type = kNoEncoding;
return 0;
}
*timestamp = encoded_info->encoded_timestamp;
int payload_type = encoded_info->payload_type;
if (!encoded_info->redundant.empty())
payload_type = encoded_info->redundant[0].payload_type;
auto cng_iter = cng_pt_.find(payload_type);
if (cng_iter == cng_pt_.end()) {
*encoding_type = kActiveNormalEncoded;
} else {
*encoding_type = cng_iter->second.second;
}
return *bitstream_len_byte;
}
bool ACMGenericCodecWrapper::EncoderInitialized() {
FATAL();
return 0;
}
int16_t ACMGenericCodecWrapper::EncoderParams(
WebRtcACMCodecParams* enc_params) {
ReadLockScoped rl(codec_wrapper_lock_);
*enc_params = acm_codec_params_;
return 0;
}
int16_t ACMGenericCodecWrapper::InitEncoder(WebRtcACMCodecParams* codec_params,
bool force_initialization) {
WriteLockScoped wl(codec_wrapper_lock_);
bitrate_bps_ = 0;
loss_rate_ = 0;
acm_codec_params_ = *codec_params;
if (force_initialization)
opus_application_set_ = false;
opus_application_ = GetOpusApplication(codec_params->codec_inst.channels);
opus_application_set_ = true;
ResetAudioEncoder();
return 0;
}
void ACMGenericCodecWrapper::ResetAudioEncoder() {
const CodecInst& codec_inst = acm_codec_params_.codec_inst;
bool using_codec_internal_red = false;
if (!STR_CASE_CMP(codec_inst.plname, "PCMU")) {
AudioEncoderPcmU::Config config;
config.num_channels = codec_inst.channels;
config.frame_size_ms = codec_inst.pacsize / 8;
config.payload_type = codec_inst.pltype;
audio_encoder_.reset(new AudioEncoderPcmU(config));
} else if (!STR_CASE_CMP(codec_inst.plname, "PCMA")) {
AudioEncoderPcmA::Config config;
config.num_channels = codec_inst.channels;
config.frame_size_ms = codec_inst.pacsize / 8;
config.payload_type = codec_inst.pltype;
audio_encoder_.reset(new AudioEncoderPcmA(config));
#ifdef WEBRTC_CODEC_PCM16
} else if (!STR_CASE_CMP(codec_inst.plname, "L16")) {
AudioEncoderPcm16B::Config config;
config.num_channels = codec_inst.channels;
config.sample_rate_hz = codec_inst.plfreq;
config.frame_size_ms = codec_inst.pacsize / (config.sample_rate_hz / 1000);
config.payload_type = codec_inst.pltype;
audio_encoder_.reset(new AudioEncoderPcm16B(config));
#endif
#ifdef WEBRTC_CODEC_ILBC
} else if (!STR_CASE_CMP(codec_inst.plname, "ILBC")) {
AudioEncoderIlbc::Config config;
config.frame_size_ms = codec_inst.pacsize / 8;
config.payload_type = codec_inst.pltype;
audio_encoder_.reset(new AudioEncoderIlbc(config));
#endif
#ifdef WEBRTC_CODEC_OPUS
} else if (!STR_CASE_CMP(codec_inst.plname, "opus")) {
is_opus_ = true;
has_internal_fec_ = true;
AudioEncoderOpus::Config config;
config.frame_size_ms = codec_inst.pacsize / 48;
config.num_channels = codec_inst.channels;
config.fec_enabled = fec_enabled_;
config.bitrate_bps = codec_inst.rate;
config.max_playback_rate_hz = max_playback_rate_hz_;
config.payload_type = codec_inst.pltype;
switch (GetOpusApplication(config.num_channels)) {
case kVoip:
config.application = AudioEncoderOpus::ApplicationMode::kVoip;
break;
case kAudio:
config.application = AudioEncoderOpus::ApplicationMode::kAudio;
break;
}
audio_encoder_.reset(new AudioEncoderOpus(config));
#endif
#ifdef WEBRTC_CODEC_G722
} else if (!STR_CASE_CMP(codec_inst.plname, "G722")) {
AudioEncoderG722::Config config;
config.num_channels = codec_inst.channels;
config.frame_size_ms = codec_inst.pacsize / 16;
config.payload_type = codec_inst.pltype;
audio_encoder_.reset(new AudioEncoderG722(config));
#endif
#ifdef WEBRTC_CODEC_ISACFX
} else if (!STR_CASE_CMP(codec_inst.plname, "ISAC")) {
DCHECK_EQ(codec_inst.plfreq, 16000);
is_isac_ = true;
AudioEncoderDecoderIsacFix* enc_dec;
if (codec_inst.rate == -1) {
// Adaptive mode.
AudioEncoderDecoderIsacFix::ConfigAdaptive config;
config.payload_type = codec_inst.pltype;
enc_dec = new AudioEncoderDecoderIsacFix(config);
} else {
// Channel independent mode.
AudioEncoderDecoderIsacFix::Config config;
config.bit_rate = codec_inst.rate;
config.frame_size_ms = codec_inst.pacsize / 16;
config.payload_type = codec_inst.pltype;
enc_dec = new AudioEncoderDecoderIsacFix(config);
}
audio_encoder_.reset(enc_dec);
decoder_proxy_.SetDecoder(enc_dec);
#endif
#ifdef WEBRTC_CODEC_ISAC
} else if (!STR_CASE_CMP(codec_inst.plname, "ISAC")) {
is_isac_ = true;
if (copy_red_enabled_) {
using_codec_internal_red = true;
AudioEncoderDecoderIsacRed* enc_dec;
if (codec_inst.rate == -1) {
// Adaptive mode.
AudioEncoderDecoderIsacRed::ConfigAdaptive config;
config.sample_rate_hz = codec_inst.plfreq;
config.initial_frame_size_ms = rtc::CheckedDivExact(
1000 * codec_inst.pacsize, config.sample_rate_hz);
config.max_payload_size_bytes = max_payload_size_bytes_;
config.max_bit_rate = max_rate_bps_;
config.payload_type = codec_inst.pltype;
config.red_payload_type = red_payload_type_;
enc_dec = new AudioEncoderDecoderIsacRed(config);
} else {
// Channel independent mode.
AudioEncoderDecoderIsacRed::Config config;
config.sample_rate_hz = codec_inst.plfreq;
config.bit_rate = codec_inst.rate;
config.frame_size_ms = rtc::CheckedDivExact(1000 * codec_inst.pacsize,
config.sample_rate_hz);
config.max_payload_size_bytes = max_payload_size_bytes_;
config.max_bit_rate = max_rate_bps_;
config.payload_type = codec_inst.pltype;
config.red_payload_type = red_payload_type_;
enc_dec = new AudioEncoderDecoderIsacRed(config);
}
audio_encoder_.reset(enc_dec);
decoder_proxy_.SetDecoder(enc_dec);
} else {
AudioEncoderDecoderIsac* enc_dec;
if (codec_inst.rate == -1) {
// Adaptive mode.
AudioEncoderDecoderIsac::ConfigAdaptive config;
config.sample_rate_hz = codec_inst.plfreq;
config.initial_frame_size_ms = rtc::CheckedDivExact(
1000 * codec_inst.pacsize, config.sample_rate_hz);
config.max_payload_size_bytes = max_payload_size_bytes_;
config.max_bit_rate = max_rate_bps_;
config.payload_type = codec_inst.pltype;
enc_dec = new AudioEncoderDecoderIsac(config);
} else {
// Channel independent mode.
AudioEncoderDecoderIsac::Config config;
config.sample_rate_hz = codec_inst.plfreq;
config.bit_rate = codec_inst.rate;
config.frame_size_ms = rtc::CheckedDivExact(1000 * codec_inst.pacsize,
config.sample_rate_hz);
config.max_payload_size_bytes = max_payload_size_bytes_;
config.max_bit_rate = max_rate_bps_;
config.payload_type = codec_inst.pltype;
enc_dec = new AudioEncoderDecoderIsac(config);
}
audio_encoder_.reset(enc_dec);
decoder_proxy_.SetDecoder(enc_dec);
}
#endif
} else {
FATAL();
}
if (bitrate_bps_ != 0)
audio_encoder_->SetTargetBitrate(bitrate_bps_);
audio_encoder_->SetProjectedPacketLossRate(loss_rate_ / 100.0);
encoder_ = audio_encoder_.get();
// Attach RED if needed.
if (copy_red_enabled_ && !using_codec_internal_red) {
CHECK_NE(red_payload_type_, kInvalidPayloadType);
AudioEncoderCopyRed::Config config;
config.payload_type = red_payload_type_;
config.speech_encoder = encoder_;
red_encoder_.reset(new AudioEncoderCopyRed(config));
encoder_ = red_encoder_.get();
} else {
red_encoder_.reset();
}
// Attach CNG if needed.
// Reverse-lookup from sample rate to complete key-value pair.
const int sample_rate_hz = audio_encoder_->sample_rate_hz();
// Create a local const reference to cng_pt_. The reason is that GCC doesn't
// accept using "const decltype(...)" for the argument in the lambda below.
const auto& cng_pt = cng_pt_;
auto pt_iter = find_if(cng_pt.begin(), cng_pt.end(),
[sample_rate_hz](decltype(*cng_pt.begin()) p) {
return p.second.first == sample_rate_hz;
});
if (acm_codec_params_.enable_dtx && pt_iter != cng_pt_.end()) {
AudioEncoderCng::Config config;
config.num_channels = acm_codec_params_.codec_inst.channels;
config.payload_type = pt_iter->first;
config.speech_encoder = encoder_;
switch (acm_codec_params_.vad_mode) {
case VADNormal:
config.vad_mode = Vad::kVadNormal;
break;
case VADLowBitrate:
config.vad_mode = Vad::kVadLowBitrate;
break;
case VADAggr:
config.vad_mode = Vad::kVadAggressive;
break;
case VADVeryAggr:
config.vad_mode = Vad::kVadVeryAggressive;
break;
default:
FATAL();
}
cng_encoder_.reset(new AudioEncoderCng(config));
encoder_ = cng_encoder_.get();
} else {
cng_encoder_.reset();
}
}
OpusApplicationMode ACMGenericCodecWrapper::GetOpusApplication(
int num_channels) const {
if (opus_application_set_)
return opus_application_;
return num_channels == 1 ? kVoip : kAudio;
}
int32_t ACMGenericCodecWrapper::Add10MsData(const uint32_t timestamp,
const int16_t* data,
const uint16_t length_per_channel,
const uint8_t audio_channel) {
WriteLockScoped wl(codec_wrapper_lock_);
CHECK(input_.empty());
CHECK_EQ(length_per_channel, encoder_->sample_rate_hz() / 100);
for (int i = 0; i < length_per_channel * encoder_->num_channels(); ++i) {
input_.push_back(data[i]);
}
rtp_timestamp_ = first_frame_
? timestamp
: last_rtp_timestamp_ +
rtc::CheckedDivExact(
timestamp - last_timestamp_,
static_cast<uint32_t>(rtc::CheckedDivExact(
audio_encoder_->sample_rate_hz(),
audio_encoder_->rtp_timestamp_rate_hz())));
last_timestamp_ = timestamp;
last_rtp_timestamp_ = rtp_timestamp_;
first_frame_ = false;
CHECK_EQ(audio_channel, encoder_->num_channels());
return 0;
}
uint32_t ACMGenericCodecWrapper::NoMissedSamples() const {
FATAL();
return 0;
}
void ACMGenericCodecWrapper::ResetNoMissedSamples() {
FATAL();
}
int16_t ACMGenericCodecWrapper::SetBitRate(const int32_t bitrate_bps) {
WriteLockScoped wl(codec_wrapper_lock_);
encoder_->SetTargetBitrate(bitrate_bps);
bitrate_bps_ = bitrate_bps;
return 0;
}
uint32_t ACMGenericCodecWrapper::EarliestTimestamp() const {
FATAL();
return 0;
}
int16_t ACMGenericCodecWrapper::SetVAD(bool* enable_dtx,
bool* enable_vad,
ACMVADMode* mode) {
WriteLockScoped wl(codec_wrapper_lock_);
if (is_opus_) {
*enable_dtx = false;
*enable_vad = false;
return 0;
}
// Note: |enable_vad| is not used; VAD is enabled based on the DTX setting and
// the |enable_vad| is set equal to |enable_dtx|.
// The case when VAD is enabled but DTX is disabled may result in a
// kPassiveNormalEncoded frame type, but this is not a case that VoE
// distinguishes from the cases where DTX is in fact used. In the case where
// DTX is enabled but VAD is disabled, the comment in the ACM interface states
// that VAD will be enabled anyway.
DCHECK_EQ(*enable_dtx, *enable_vad);
*enable_vad = *enable_dtx;
acm_codec_params_.enable_dtx = *enable_dtx;
acm_codec_params_.enable_vad = *enable_vad;
acm_codec_params_.vad_mode = *mode;
if (acm_codec_params_.enable_dtx && !cng_encoder_) {
ResetAudioEncoder();
} else if (!acm_codec_params_.enable_dtx && cng_encoder_) {
cng_encoder_.reset();
encoder_ = audio_encoder_.get();
}
return 0;
}
void ACMGenericCodecWrapper::SetCngPt(int sample_rate_hz, int payload_type) {
WriteLockScoped wl(codec_wrapper_lock_);
SetCngPtInMap(&cng_pt_, sample_rate_hz, payload_type);
ResetAudioEncoder();
}
int32_t ACMGenericCodecWrapper::ReplaceInternalDTX(
const bool replace_internal_dtx) {
FATAL();
return 0;
}
int32_t ACMGenericCodecWrapper::GetEstimatedBandwidth() {
FATAL();
return 0;
}
int32_t ACMGenericCodecWrapper::SetEstimatedBandwidth(
int32_t estimated_bandwidth) {
FATAL();
return 0;
}
int32_t ACMGenericCodecWrapper::GetRedPayload(uint8_t* red_payload,
int16_t* payload_bytes) {
FATAL();
return 0;
}
int16_t ACMGenericCodecWrapper::ResetEncoder() {
return 0;
}
void ACMGenericCodecWrapper::DestructEncoder() {
}
int16_t ACMGenericCodecWrapper::SamplesLeftToEncode() {
FATAL();
return 0;
}
void ACMGenericCodecWrapper::SetUniqueID(const uint32_t id) {
// Do nothing.
}
int16_t ACMGenericCodecWrapper::UpdateDecoderSampFreq(int16_t codec_id) {
#ifdef WEBRTC_CODEC_ISAC
WriteLockScoped wl(codec_wrapper_lock_);
if (is_isac_) {
switch (codec_id) {
case ACMCodecDB::kISAC:
static_cast<AudioEncoderDecoderIsac*>(audio_encoder_.get())
->UpdateDecoderSampleRate(16000);
return 0;
case ACMCodecDB::kISACSWB:
case ACMCodecDB::kISACFB:
static_cast<AudioEncoderDecoderIsac*>(audio_encoder_.get())
->UpdateDecoderSampleRate(32000);
return 0;
default:
FATAL() << "Unexpected codec id.";
}
}
#endif
return 0;
}
int16_t ACMGenericCodecWrapper::UpdateEncoderSampFreq(uint16_t samp_freq_hz) {
FATAL();
return 0;
}
int16_t ACMGenericCodecWrapper::EncoderSampFreq(uint16_t* samp_freq_hz) {
FATAL();
return 0;
}
int32_t ACMGenericCodecWrapper::ConfigISACBandwidthEstimator(
const uint8_t init_frame_size_msec,
const uint16_t init_rate_bps,
const bool enforce_frame_size) {
FATAL();
return 0;
}
int32_t ACMGenericCodecWrapper::SetISACMaxPayloadSize(
const uint16_t max_payload_len_bytes) {
WriteLockScoped wl(codec_wrapper_lock_);
if (!is_isac_)
return -1; // Needed for tests to pass.
max_payload_size_bytes_ = max_payload_len_bytes;
ResetAudioEncoder();
return 0;
}
int32_t ACMGenericCodecWrapper::SetISACMaxRate(const uint32_t max_rate_bps) {
WriteLockScoped wl(codec_wrapper_lock_);
if (!is_isac_)
return -1; // Needed for tests to pass.
max_rate_bps_ = max_rate_bps;
ResetAudioEncoder();
return 0;
}
int16_t ACMGenericCodecWrapper::REDPayloadISAC(const int32_t isac_rate,
const int16_t isac_bw_estimate,
uint8_t* payload,
int16_t* payload_len_bytes) {
FATAL();
return 0;
}
int ACMGenericCodecWrapper::SetOpusMaxPlaybackRate(int frequency_hz) {
WriteLockScoped wl(codec_wrapper_lock_);
if (!is_opus_)
return -1; // Needed for tests to pass.
max_playback_rate_hz_ = frequency_hz;
ResetAudioEncoder();
return 0;
}
bool ACMGenericCodecWrapper::HasFrameToEncode() const {
FATAL();
return 0;
}
AudioDecoder* ACMGenericCodecWrapper::Decoder(int /* codec_id */) {
ReadLockScoped rl(codec_wrapper_lock_);
return decoder_proxy_.IsSet() ? &decoder_proxy_ : nullptr;
}
int ACMGenericCodecWrapper::SetFEC(bool enable_fec) {
if (!HasInternalFEC())
return enable_fec ? -1 : 0;
WriteLockScoped wl(codec_wrapper_lock_);
if (fec_enabled_ != enable_fec) {
fec_enabled_ = enable_fec;
ResetAudioEncoder();
}
return 0;
}
int ACMGenericCodecWrapper::SetOpusApplication(
OpusApplicationMode application) {
WriteLockScoped wl(codec_wrapper_lock_);
opus_application_ = application;
opus_application_set_ = true;
ResetAudioEncoder();
return 0;
}
int ACMGenericCodecWrapper::SetPacketLossRate(int loss_rate) {
WriteLockScoped wl(codec_wrapper_lock_);
encoder_->SetProjectedPacketLossRate(loss_rate / 100.0);
loss_rate_ = loss_rate;
return 0;
}
void ACMGenericCodecWrapper::EnableCopyRed(bool enable, int red_payload_type) {
ACMGenericCodec::EnableCopyRed(enable, red_payload_type);
WriteLockScoped wl(codec_wrapper_lock_);
red_payload_type_ = red_payload_type;
ResetAudioEncoder();
}
bool ACMGenericCodecWrapper::ExternalRedNeeded() {
return false;
}
void ACMGenericCodecWrapper::DestructEncoderSafe() {
FATAL();
}
int16_t ACMGenericCodecWrapper::InternalEncode(uint8_t* bitstream,
int16_t* bitstream_len_byte) {
FATAL();
return 0;
}
int16_t ACMGenericCodecWrapper::InternalInitEncoder(
WebRtcACMCodecParams* codec_params) {
FATAL();
return 0;
}
int16_t ACMGenericCodecWrapper::InternalCreateEncoder() {
FATAL();
return 0;
}
} // namespace acm2
} // namespace webrtc

View File

@ -11,17 +11,12 @@
#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_GENERIC_CODEC_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_GENERIC_CODEC_H_
#include <map>
#include "webrtc/base/thread_annotations.h"
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
#include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/system_wrappers/interface/trace.h"
#define MAX_FRAME_SIZE_10MSEC 6
@ -111,11 +106,10 @@ class ACMGenericCodec {
// -1 if error is occurred, otherwise the length of the bit-stream in
// bytes.
//
virtual int16_t Encode(uint8_t* bitstream,
int16_t* bitstream_len_byte,
uint32_t* timestamp,
WebRtcACMEncodingType* encoding_type,
AudioEncoder::EncodedInfo* encoded_info);
int16_t Encode(uint8_t* bitstream,
int16_t* bitstream_len_byte,
uint32_t* timestamp,
WebRtcACMEncodingType* encoding_type);
///////////////////////////////////////////////////////////////////////////
// bool EncoderInitialized();
@ -124,7 +118,7 @@ class ACMGenericCodec {
// True if the encoder is successfully initialized,
// false otherwise.
//
virtual bool EncoderInitialized();
bool EncoderInitialized();
///////////////////////////////////////////////////////////////////////////
// int16_t EncoderParams()
@ -140,7 +134,7 @@ class ACMGenericCodec {
// -1 if the encoder is not initialized,
// 0 otherwise.
//
virtual int16_t EncoderParams(WebRtcACMCodecParams* enc_params);
int16_t EncoderParams(WebRtcACMCodecParams* enc_params);
///////////////////////////////////////////////////////////////////////////
// int16_t InitEncoder(...)
@ -158,8 +152,8 @@ class ACMGenericCodec {
// -1 if failed to initialize.
//
//
virtual int16_t InitEncoder(WebRtcACMCodecParams* codec_params,
bool force_initialization);
int16_t InitEncoder(WebRtcACMCodecParams* codec_params,
bool force_initialization);
///////////////////////////////////////////////////////////////////////////
// int32_t Add10MsData(...)
@ -180,10 +174,10 @@ class ACMGenericCodec {
// -1 if failed
// 0 otherwise.
//
virtual int32_t Add10MsData(const uint32_t timestamp,
const int16_t* data,
const uint16_t length,
const uint8_t audio_channel);
int32_t Add10MsData(const uint32_t timestamp,
const int16_t* data,
const uint16_t length,
const uint8_t audio_channel);
///////////////////////////////////////////////////////////////////////////
// uint32_t NoMissedSamples()
@ -195,14 +189,14 @@ class ACMGenericCodec {
// Return Value:
// Number of samples which are overwritten.
//
virtual uint32_t NoMissedSamples() const;
uint32_t NoMissedSamples() const;
///////////////////////////////////////////////////////////////////////////
// void ResetNoMissedSamples()
// This function resets the number of overwritten samples to zero.
// (We might remove this function if we remove NoMissedSamples())
//
virtual void ResetNoMissedSamples();
void ResetNoMissedSamples();
///////////////////////////////////////////////////////////////////////////
// int16_t SetBitRate()
@ -216,7 +210,7 @@ class ACMGenericCodec {
// codec is not rate-adjustable.
// 0 if the rate is adjusted successfully
//
virtual int16_t SetBitRate(const int32_t bitrate_bps);
int16_t SetBitRate(const int32_t bitrate_bps);
///////////////////////////////////////////////////////////////////////////
// uint32_t EarliestTimestamp()
@ -226,7 +220,7 @@ class ACMGenericCodec {
// Return value:
// timestamp of the first 10 ms audio in the audio buffer.
//
virtual uint32_t EarliestTimestamp() const;
uint32_t EarliestTimestamp() const;
///////////////////////////////////////////////////////////////////////////
// int16_t SetVAD()
@ -255,10 +249,7 @@ class ACMGenericCodec {
// -1 if failed to set DTX & VAD as specified,
// 0 if succeeded.
//
virtual int16_t SetVAD(bool* enable_dtx, bool* enable_vad, ACMVADMode* mode);
// Registers comfort noise at |sample_rate_hz| to use |payload_type|.
virtual void SetCngPt(int sample_rate_hz, int payload_type);
int16_t SetVAD(bool* enable_dtx, bool* enable_vad, ACMVADMode* mode);
///////////////////////////////////////////////////////////////////////////
// int32_t ReplaceInternalDTX()
@ -273,7 +264,7 @@ class ACMGenericCodec {
// -1 if failed to replace internal DTX,
// 0 if succeeded.
//
virtual int32_t ReplaceInternalDTX(const bool replace_internal_dtx);
int32_t ReplaceInternalDTX(const bool replace_internal_dtx);
///////////////////////////////////////////////////////////////////////////
// int32_t IsInternalDTXReplaced()
@ -312,7 +303,7 @@ class ACMGenericCodec {
// -1 if fails to get decoder estimated bandwidth,
// >0 estimated bandwidth in bits/sec.
//
virtual int32_t GetEstimatedBandwidth();
int32_t GetEstimatedBandwidth();
///////////////////////////////////////////////////////////////////////////
// int32_t SetEstimatedBandwidth()
@ -326,7 +317,7 @@ class ACMGenericCodec {
// -1 if fails to set estimated bandwidth,
// 0 on success.
//
virtual int32_t SetEstimatedBandwidth(int32_t estimated_bandwidth);
int32_t SetEstimatedBandwidth(int32_t estimated_bandwidth);
///////////////////////////////////////////////////////////////////////////
// int32_t GetRedPayload()
@ -341,7 +332,7 @@ class ACMGenericCodec {
// -1 if fails to get codec specific RED,
// 0 if succeeded.
//
virtual int32_t GetRedPayload(uint8_t* red_payload, int16_t* payload_bytes);
int32_t GetRedPayload(uint8_t* red_payload, int16_t* payload_bytes);
///////////////////////////////////////////////////////////////////////////
// int16_t ResetEncoder()
@ -353,7 +344,7 @@ class ACMGenericCodec {
// -1 if failed,
// 0 if succeeded.
//
virtual int16_t ResetEncoder();
int16_t ResetEncoder();
///////////////////////////////////////////////////////////////////////////
// void DestructEncoder()
@ -362,7 +353,7 @@ class ACMGenericCodec {
// instance we cannot delete the encoder and instead we will initialize the
// encoder. We also delete VAD and DTX if they have been created.
//
virtual void DestructEncoder();
void DestructEncoder();
///////////////////////////////////////////////////////////////////////////
// int16_t SamplesLeftToEncode()
@ -371,7 +362,7 @@ class ACMGenericCodec {
// Return value:
// Number of samples.
//
virtual int16_t SamplesLeftToEncode();
int16_t SamplesLeftToEncode();
///////////////////////////////////////////////////////////////////////////
// SetUniqueID()
@ -380,7 +371,7 @@ class ACMGenericCodec {
// Input
// -id : A number to identify the codec.
//
virtual void SetUniqueID(const uint32_t id);
void SetUniqueID(const uint32_t id);
///////////////////////////////////////////////////////////////////////////
// UpdateDecoderSampFreq()
@ -569,7 +560,7 @@ class ACMGenericCodec {
// Returns true if there is enough audio buffered for encoding, such that
// calling Encode() will return a payload.
//
virtual bool HasFrameToEncode() const;
bool HasFrameToEncode() const;
//
// Returns pointer to the AudioDecoder class of this codec. A codec which
@ -981,181 +972,6 @@ class ACMGenericCodec {
uint32_t unique_id_;
};
// Proxy for AudioDecoder
class AudioDecoderProxy final : public AudioDecoder {
public:
AudioDecoderProxy();
void SetDecoder(AudioDecoder* decoder);
bool IsSet() const;
int Decode(const uint8_t* encoded,
size_t encoded_len,
int16_t* decoded,
SpeechType* speech_type) override;
int DecodeRedundant(const uint8_t* encoded,
size_t encoded_len,
int16_t* decoded,
SpeechType* speech_type) override;
bool HasDecodePlc() const override;
int DecodePlc(int num_frames, int16_t* decoded) override;
int Init() override;
int IncomingPacket(const uint8_t* payload,
size_t payload_len,
uint16_t rtp_sequence_number,
uint32_t rtp_timestamp,
uint32_t arrival_timestamp) override;
int ErrorCode() override;
int PacketDuration(const uint8_t* encoded, size_t encoded_len) override;
int PacketDurationRedundant(const uint8_t* encoded,
size_t encoded_len) const override;
bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override;
CNG_dec_inst* CngDecoderInstance() override;
private:
scoped_ptr<CriticalSectionWrapper> decoder_lock_;
AudioDecoder* decoder_ GUARDED_BY(decoder_lock_);
};
class ACMGenericCodecWrapper : public ACMGenericCodec {
public:
ACMGenericCodecWrapper(const CodecInst& codec_inst,
int cng_pt_nb,
int cng_pt_wb,
int cng_pt_swb,
int cng_pt_fb,
bool enable_red,
int red_payload_type);
virtual ~ACMGenericCodecWrapper() = default;
ACMGenericCodec* CreateInstance() override;
int16_t Encode(uint8_t* bitstream,
int16_t* bitstream_len_byte,
uint32_t* timestamp,
WebRtcACMEncodingType* encoding_type,
AudioEncoder::EncodedInfo* encoded_info) override;
bool EncoderInitialized() override;
int16_t EncoderParams(WebRtcACMCodecParams* enc_params) override;
int16_t InitEncoder(WebRtcACMCodecParams* codec_params,
bool force_initialization) override;
int32_t Add10MsData(const uint32_t timestamp,
const int16_t* data,
const uint16_t length,
const uint8_t audio_channel) override;
uint32_t NoMissedSamples() const override;
void ResetNoMissedSamples() override;
int16_t SetBitRate(const int32_t bitrate_bps) override;
uint32_t EarliestTimestamp() const override;
int16_t SetVAD(bool* enable_dtx, bool* enable_vad, ACMVADMode* mode) override;
void SetCngPt(int sample_rate_hz, int payload_type) override;
int32_t ReplaceInternalDTX(const bool replace_internal_dtx) override;
int32_t GetEstimatedBandwidth() override;
int32_t SetEstimatedBandwidth(int32_t estimated_bandwidth) override;
int32_t GetRedPayload(uint8_t* red_payload, int16_t* payload_bytes) override;
int16_t ResetEncoder() override;
void DestructEncoder() override;
int16_t SamplesLeftToEncode() override;
void SetUniqueID(const uint32_t id) override;
int16_t UpdateDecoderSampFreq(int16_t codec_id) override;
int16_t UpdateEncoderSampFreq(uint16_t samp_freq_hz) override
EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
int16_t EncoderSampFreq(uint16_t* samp_freq_hz) override
SHARED_LOCKS_REQUIRED(codec_wrapper_lock_);
int32_t ConfigISACBandwidthEstimator(const uint8_t init_frame_size_msec,
const uint16_t init_rate_bps,
const bool enforce_frame_size) override;
int32_t SetISACMaxPayloadSize(const uint16_t max_payload_len_bytes) override;
int32_t SetISACMaxRate(const uint32_t max_rate_bps) override;
int16_t REDPayloadISAC(const int32_t isac_rate,
const int16_t isac_bw_estimate,
uint8_t* payload,
int16_t* payload_len_bytes) override;
int SetOpusMaxPlaybackRate(int /* frequency_hz */) override;
bool HasFrameToEncode() const override;
AudioDecoder* Decoder(int /* codec_id */) override;
int SetFEC(bool enable_fec) override;
int SetOpusApplication(OpusApplicationMode mode) override;
int SetPacketLossRate(int /* loss_rate */) override;
void EnableCopyRed(bool enable, int red_payload_type) override;
bool ExternalRedNeeded() override;
protected:
void DestructEncoderSafe() override
EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
int16_t InternalEncode(uint8_t* bitstream,
int16_t* bitstream_len_byte) override
EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
int16_t InternalInitEncoder(WebRtcACMCodecParams* codec_params) override
EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
int16_t InternalCreateEncoder() override;
private:
void ResetAudioEncoder() EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
OpusApplicationMode GetOpusApplication(int num_channels) const
EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
scoped_ptr<AudioEncoder> audio_encoder_ GUARDED_BY(codec_wrapper_lock_);
scoped_ptr<AudioEncoder> cng_encoder_ GUARDED_BY(codec_wrapper_lock_);
scoped_ptr<AudioEncoder> red_encoder_ GUARDED_BY(codec_wrapper_lock_);
AudioEncoder* encoder_ GUARDED_BY(codec_wrapper_lock_);
AudioDecoderProxy decoder_proxy_ GUARDED_BY(codec_wrapper_lock_);
std::vector<int16_t> input_ GUARDED_BY(codec_wrapper_lock_);
WebRtcACMCodecParams acm_codec_params_ GUARDED_BY(codec_wrapper_lock_);
int bitrate_bps_ GUARDED_BY(codec_wrapper_lock_);
bool fec_enabled_ GUARDED_BY(codec_wrapper_lock_);
int loss_rate_ GUARDED_BY(codec_wrapper_lock_);
int max_playback_rate_hz_ GUARDED_BY(codec_wrapper_lock_);
int max_payload_size_bytes_ GUARDED_BY(codec_wrapper_lock_);
int max_rate_bps_ GUARDED_BY(codec_wrapper_lock_);
bool is_opus_ GUARDED_BY(codec_wrapper_lock_);
bool is_isac_ GUARDED_BY(codec_wrapper_lock_);
bool first_frame_ GUARDED_BY(codec_wrapper_lock_);
uint32_t rtp_timestamp_ GUARDED_BY(codec_wrapper_lock_);
uint32_t last_rtp_timestamp_ GUARDED_BY(codec_wrapper_lock_);
// Map from payload type to sample rate (Hz) and encoding type.
std::map<int, std::pair<int, WebRtcACMEncodingType>> cng_pt_
GUARDED_BY(codec_wrapper_lock_);
int red_payload_type_ GUARDED_BY(codec_wrapper_lock_);
OpusApplicationMode opus_application_ GUARDED_BY(codec_wrapper_lock_);
bool opus_application_set_ GUARDED_BY(codec_wrapper_lock_);
};
} // namespace acm2
} // namespace webrtc

View File

@ -258,9 +258,9 @@ int32_t AudioCodingModuleImpl::Process() {
if (!HaveValidEncoder("Process")) {
return -1;
}
AudioEncoder::EncodedInfo encoded_info;
status = codecs_[current_send_codec_idx_]->Encode(
stream, &length_bytes, &rtp_timestamp, &encoding_type, &encoded_info);
status = codecs_[current_send_codec_idx_]->Encode(stream, &length_bytes,
&rtp_timestamp,
&encoding_type);
if (status < 0) {
// Encode failed.
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,