iSAC: Make separate AudioEncoder and AudioDecoder objects
The only shared state is now the bandwidth estimation info.
This reduces the amount and complexity of the locking
substantially.
Review URL: https://codereview.webrtc.org/1208993010
Cr-Commit-Position: refs/heads/master@{#9762}
diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn
index 8a27900..d98d9c3 100644
--- a/webrtc/modules/audio_coding/BUILD.gn
+++ b/webrtc/modules/audio_coding/BUILD.gn
@@ -380,6 +380,15 @@
]
}
+source_set("isac_common") {
+ sources = [
+ "codecs/isac/audio_encoder_isac_t.h",
+ "codecs/isac/audio_encoder_isac_t_impl.h",
+ "codecs/isac/locked_bandwidth_info.cc",
+ "codecs/isac/locked_bandwidth_info.h",
+ ]
+}
+
config("isac_config") {
include_dirs = [
"../../..",
@@ -389,8 +398,6 @@
source_set("isac") {
sources = [
- "codecs/isac/audio_encoder_isac_t.h",
- "codecs/isac/audio_encoder_isac_t_impl.h",
"codecs/isac/main/interface/audio_encoder_isac.h",
"codecs/isac/main/interface/isac.h",
"codecs/isac/main/source/arith_routines.c",
@@ -458,6 +465,7 @@
deps = [
":audio_decoder_interface",
":audio_encoder_interface",
+ ":isac_common",
"../../common_audio",
]
}
@@ -471,8 +479,6 @@
source_set("isac_fix") {
sources = [
- "codecs/isac/audio_encoder_isac_t.h",
- "codecs/isac/audio_encoder_isac_t_impl.h",
"codecs/isac/fix/interface/audio_encoder_isacfix.h",
"codecs/isac/fix/interface/isacfix.h",
"codecs/isac/fix/source/arith_routines.c",
@@ -533,6 +539,7 @@
deps = [
":audio_encoder_interface",
+ ":isac_common",
"../../common_audio",
"../../system_wrappers",
]
diff --git a/webrtc/modules/audio_coding/audio_coding.gypi b/webrtc/modules/audio_coding/audio_coding.gypi
index 90a6f39..bc3c48d 100644
--- a/webrtc/modules/audio_coding/audio_coding.gypi
+++ b/webrtc/modules/audio_coding/audio_coding.gypi
@@ -15,6 +15,7 @@
'codecs/g722/g722.gypi',
'codecs/ilbc/ilbc.gypi',
'codecs/isac/isac.gypi',
+ 'codecs/isac/isac_common.gypi',
'codecs/isac/isacfix.gypi',
'codecs/pcm16b/pcm16b.gypi',
'codecs/red/red.gypi',
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
index 49df3c6..7093304 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
@@ -13,17 +13,14 @@
#include <vector>
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/thread_annotations.h"
#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
+#include "webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h"
namespace webrtc {
-class CriticalSectionWrapper;
-
template <typename T>
-class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder {
+class AudioEncoderIsacT final : public AudioEncoder {
public:
// Allowed combinations of sample rate, frame size, and bit rate are
// - 16000 Hz, 30 ms, 10000-32000 bps
@@ -34,6 +31,8 @@
Config();
bool IsOk() const;
+ LockedIsacBandwidthInfo* bwinfo;
+
int payload_type;
int sample_rate_hz;
int frame_size_ms;
@@ -50,18 +49,50 @@
bool enforce_frame_size;
};
- explicit AudioEncoderDecoderIsacT(const Config& config);
- ~AudioEncoderDecoderIsacT() override;
+ explicit AudioEncoderIsacT(const Config& config);
+ ~AudioEncoderIsacT() override;
- // AudioEncoder public methods.
int SampleRateHz() const override;
int NumChannels() const override;
size_t MaxEncodedBytes() const override;
int Num10MsFramesInNextPacket() const override;
int Max10MsFramesInAPacket() const override;
int GetTargetBitrate() const override;
+ EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
+ const int16_t* audio,
+ size_t max_encoded_bytes,
+ uint8_t* encoded) override;
- // AudioDecoder methods.
+ private:
+ // This value is taken from STREAM_SIZE_MAX_60 for iSAC float (60 ms) and
+ // STREAM_MAXW16_60MS for iSAC fix (60 ms).
+ static const size_t kSufficientEncodeBufferSizeBytes = 400;
+
+ const int payload_type_;
+ typename T::instance_type* isac_state_;
+ LockedIsacBandwidthInfo* bwinfo_;
+
+ // Have we accepted input but not yet emitted it in a packet?
+ bool packet_in_progress_;
+
+ // Timestamp of the first input of the currently in-progress packet.
+ uint32_t packet_timestamp_;
+
+ // Timestamp of the previously encoded packet.
+ uint32_t last_encoded_timestamp_;
+
+ const int target_bitrate_bps_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioEncoderIsacT);
+};
+
+template <typename T>
+class AudioDecoderIsacT final : public AudioDecoder {
+ public:
+ AudioDecoderIsacT();
+ explicit AudioDecoderIsacT(LockedIsacBandwidthInfo* bwinfo);
+ ~AudioDecoderIsacT() override;
+
bool HasDecodePlc() const override;
int DecodePlc(int num_frames, int16_t* decoded) override;
int Init() override;
@@ -71,15 +102,7 @@
uint32_t rtp_timestamp,
uint32_t arrival_timestamp) override;
int ErrorCode() override;
- size_t Channels() const override { return 1; }
-
- // AudioEncoder protected method.
- EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
- const int16_t* audio,
- size_t max_encoded_bytes,
- uint8_t* encoded) override;
-
- // AudioDecoder protected method.
+ size_t Channels() const override;
int DecodeInternal(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
@@ -87,44 +110,11 @@
SpeechType* speech_type) override;
private:
- // This value is taken from STREAM_SIZE_MAX_60 for iSAC float (60 ms) and
- // STREAM_MAXW16_60MS for iSAC fix (60 ms).
- static const size_t kSufficientEncodeBufferSizeBytes = 400;
+ typename T::instance_type* isac_state_;
+ LockedIsacBandwidthInfo* bwinfo_;
+ int decoder_sample_rate_hz_;
- const int payload_type_;
-
- // iSAC encoder/decoder state, guarded by a mutex to ensure that encode calls
- // from one thread won't clash with decode calls from another thread.
- // Note: PT_GUARDED_BY is disabled since it is not yet supported by clang.
- const rtc::scoped_ptr<CriticalSectionWrapper> state_lock_;
- typename T::instance_type* isac_state_
- GUARDED_BY(state_lock_) /* PT_GUARDED_BY(lock_)*/;
-
- int decoder_sample_rate_hz_ GUARDED_BY(state_lock_);
-
- // Must be acquired before state_lock_.
- const rtc::scoped_ptr<CriticalSectionWrapper> lock_;
-
- // Have we accepted input but not yet emitted it in a packet?
- bool packet_in_progress_ GUARDED_BY(lock_);
-
- // Timestamp of the first input of the currently in-progress packet.
- uint32_t packet_timestamp_ GUARDED_BY(lock_);
-
- // Timestamp of the previously encoded packet.
- uint32_t last_encoded_timestamp_ GUARDED_BY(lock_);
-
- const int target_bitrate_bps_;
-
- DISALLOW_COPY_AND_ASSIGN(AudioEncoderDecoderIsacT);
-};
-
-struct CodecInst;
-
-class AudioEncoderDecoderMutableIsac : public AudioEncoderMutable,
- public AudioDecoder {
- public:
- virtual void UpdateSettings(const CodecInst& codec_inst) = 0;
+ DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsacT);
};
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
index d2b20e3..ce70db4 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
@@ -17,7 +17,6 @@
#include "webrtc/base/checks.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h"
-#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc {
@@ -25,8 +24,9 @@
const int kDefaultBitRate = 32000;
template <typename T>
-AudioEncoderDecoderIsacT<T>::Config::Config()
- : payload_type(kIsacPayloadType),
+AudioEncoderIsacT<T>::Config::Config()
+ : bwinfo(nullptr),
+ payload_type(kIsacPayloadType),
sample_rate_hz(16000),
frame_size_ms(30),
bit_rate(kDefaultBitRate),
@@ -37,11 +37,13 @@
}
template <typename T>
-bool AudioEncoderDecoderIsacT<T>::Config::IsOk() const {
+bool AudioEncoderIsacT<T>::Config::IsOk() const {
if (max_bit_rate < 32000 && max_bit_rate != -1)
return false;
if (max_payload_size_bytes < 120 && max_payload_size_bytes != -1)
return false;
+ if (adaptive_mode && !bwinfo)
+ return false;
switch (sample_rate_hz) {
case 16000:
if (max_bit_rate > 53400)
@@ -65,11 +67,9 @@
}
template <typename T>
-AudioEncoderDecoderIsacT<T>::AudioEncoderDecoderIsacT(const Config& config)
+AudioEncoderIsacT<T>::AudioEncoderIsacT(const Config& config)
: payload_type_(config.payload_type),
- state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
- decoder_sample_rate_hz_(0),
- lock_(CriticalSectionWrapper::CreateCriticalSection()),
+ bwinfo_(config.bwinfo),
packet_in_progress_(false),
target_bitrate_bps_(config.adaptive_mode ? -1 : (config.bit_rate == 0
? kDefaultBitRate
@@ -85,80 +85,82 @@
} else {
CHECK_EQ(0, T::Control(isac_state_, bit_rate, config.frame_size_ms));
}
- // When config.sample_rate_hz is set to 48000 Hz (iSAC-fb), the decoder is
- // still set to 32000 Hz, since there is no full-band mode in the decoder.
- CHECK_EQ(0, T::SetDecSampRate(isac_state_,
- std::min(config.sample_rate_hz, 32000)));
if (config.max_payload_size_bytes != -1)
CHECK_EQ(0,
T::SetMaxPayloadSize(isac_state_, config.max_payload_size_bytes));
if (config.max_bit_rate != -1)
CHECK_EQ(0, T::SetMaxRate(isac_state_, config.max_bit_rate));
- CHECK_EQ(0, T::DecoderInit(isac_state_));
+
+ // When config.sample_rate_hz is set to 48000 Hz (iSAC-fb), the decoder is
+ // still set to 32000 Hz, since there is no full-band mode in the decoder.
+ const int decoder_sample_rate_hz = std::min(config.sample_rate_hz, 32000);
+
+ // Set the decoder sample rate even though we just use the encoder. This
+ // doesn't appear to be necessary to produce a valid encoding, but without it
+ // we get an encoding that isn't bit-for-bit identical with what a combined
+ // encoder+decoder object produces.
+ CHECK_EQ(0, T::SetDecSampRate(isac_state_, decoder_sample_rate_hz));
}
template <typename T>
-AudioEncoderDecoderIsacT<T>::~AudioEncoderDecoderIsacT() {
+AudioEncoderIsacT<T>::~AudioEncoderIsacT() {
CHECK_EQ(0, T::Free(isac_state_));
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::SampleRateHz() const {
- CriticalSectionScoped cs(state_lock_.get());
+int AudioEncoderIsacT<T>::SampleRateHz() const {
return T::EncSampRate(isac_state_);
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::NumChannels() const {
+int AudioEncoderIsacT<T>::NumChannels() const {
return 1;
}
template <typename T>
-size_t AudioEncoderDecoderIsacT<T>::MaxEncodedBytes() const {
+size_t AudioEncoderIsacT<T>::MaxEncodedBytes() const {
return kSufficientEncodeBufferSizeBytes;
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::Num10MsFramesInNextPacket() const {
- CriticalSectionScoped cs(state_lock_.get());
+int AudioEncoderIsacT<T>::Num10MsFramesInNextPacket() const {
const int samples_in_next_packet = T::GetNewFrameLen(isac_state_);
return rtc::CheckedDivExact(samples_in_next_packet,
rtc::CheckedDivExact(SampleRateHz(), 100));
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::Max10MsFramesInAPacket() const {
+int AudioEncoderIsacT<T>::Max10MsFramesInAPacket() const {
return 6; // iSAC puts at most 60 ms in a packet.
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::GetTargetBitrate() const {
+int AudioEncoderIsacT<T>::GetTargetBitrate() const {
return target_bitrate_bps_;
}
template <typename T>
-AudioEncoder::EncodedInfo AudioEncoderDecoderIsacT<T>::EncodeInternal(
+AudioEncoder::EncodedInfo AudioEncoderIsacT<T>::EncodeInternal(
uint32_t rtp_timestamp,
const int16_t* audio,
size_t max_encoded_bytes,
uint8_t* encoded) {
- CriticalSectionScoped cs_lock(lock_.get());
if (!packet_in_progress_) {
// Starting a new packet; remember the timestamp for later.
packet_in_progress_ = true;
packet_timestamp_ = rtp_timestamp;
}
- int r;
- {
- CriticalSectionScoped cs(state_lock_.get());
- r = T::Encode(isac_state_, audio, encoded);
- CHECK_GE(r, 0) << "Encode failed (error code "
- << T::GetErrorCode(isac_state_) << ")";
+ if (bwinfo_) {
+ IsacBandwidthInfo bwinfo = bwinfo_->Get();
+ T::SetBandwidthInfo(isac_state_, &bwinfo);
}
+ int r = T::Encode(isac_state_, audio, encoded);
+ CHECK_GE(r, 0) << "Encode failed (error code " << T::GetErrorCode(isac_state_)
+ << ")";
// T::Encode doesn't allow us to tell it the size of the output
// buffer. All we can do is check for an overrun after the fact.
- CHECK(static_cast<size_t>(r) <= max_encoded_bytes);
+ CHECK_LE(static_cast<size_t>(r), max_encoded_bytes);
if (r == 0)
return EncodedInfo();
@@ -174,12 +176,33 @@
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::DecodeInternal(const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- int16_t* decoded,
- SpeechType* speech_type) {
- CriticalSectionScoped cs(state_lock_.get());
+AudioDecoderIsacT<T>::AudioDecoderIsacT()
+ : AudioDecoderIsacT(nullptr) {
+}
+
+template <typename T>
+AudioDecoderIsacT<T>::AudioDecoderIsacT(LockedIsacBandwidthInfo* bwinfo)
+ : bwinfo_(bwinfo), decoder_sample_rate_hz_(-1) {
+ CHECK_EQ(0, T::Create(&isac_state_));
+ CHECK_EQ(0, T::DecoderInit(isac_state_));
+ if (bwinfo_) {
+ IsacBandwidthInfo bwinfo;
+ T::GetBandwidthInfo(isac_state_, &bwinfo);
+ bwinfo_->Set(bwinfo);
+ }
+}
+
+template <typename T>
+AudioDecoderIsacT<T>::~AudioDecoderIsacT() {
+ CHECK_EQ(0, T::Free(isac_state_));
+}
+
+template <typename T>
+int AudioDecoderIsacT<T>::DecodeInternal(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ int16_t* decoded,
+ SpeechType* speech_type) {
// We want to crate the illusion that iSAC supports 48000 Hz decoding, while
// in fact it outputs 32000 Hz. This is the iSAC fullband mode.
if (sample_rate_hz == 48000)
@@ -199,40 +222,47 @@
}
template <typename T>
-bool AudioEncoderDecoderIsacT<T>::HasDecodePlc() const {
+bool AudioDecoderIsacT<T>::HasDecodePlc() const {
return false;
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::DecodePlc(int num_frames, int16_t* decoded) {
- CriticalSectionScoped cs(state_lock_.get());
+int AudioDecoderIsacT<T>::DecodePlc(int num_frames, int16_t* decoded) {
return T::DecodePlc(isac_state_, decoded, num_frames);
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::Init() {
- CriticalSectionScoped cs(state_lock_.get());
+int AudioDecoderIsacT<T>::Init() {
return T::DecoderInit(isac_state_);
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::IncomingPacket(const uint8_t* payload,
- size_t payload_len,
- uint16_t rtp_sequence_number,
- uint32_t rtp_timestamp,
- uint32_t arrival_timestamp) {
- CriticalSectionScoped cs(state_lock_.get());
- return T::UpdateBwEstimate(
+int AudioDecoderIsacT<T>::IncomingPacket(const uint8_t* payload,
+ size_t payload_len,
+ uint16_t rtp_sequence_number,
+ uint32_t rtp_timestamp,
+ uint32_t arrival_timestamp) {
+ int ret = T::UpdateBwEstimate(
isac_state_, payload, static_cast<int32_t>(payload_len),
rtp_sequence_number, rtp_timestamp, arrival_timestamp);
+ if (bwinfo_) {
+ IsacBandwidthInfo bwinfo;
+ T::GetBandwidthInfo(isac_state_, &bwinfo);
+ bwinfo_->Set(bwinfo);
+ }
+ return ret;
}
template <typename T>
-int AudioEncoderDecoderIsacT<T>::ErrorCode() {
- CriticalSectionScoped cs(state_lock_.get());
+int AudioDecoderIsacT<T>::ErrorCode() {
return T::GetErrorCode(isac_state_);
}
+template <typename T>
+size_t AudioDecoderIsacT<T>::Channels() const {
+ return 1;
+}
+
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_
diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h b/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
index 02b5d3c..9d51161 100644
--- a/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
+++ b/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
@@ -120,46 +120,18 @@
}
};
-typedef AudioEncoderDecoderIsacT<IsacFix> AudioEncoderDecoderIsacFix;
+using AudioEncoderIsacFix = AudioEncoderIsacT<IsacFix>;
+using AudioDecoderIsacFix = AudioDecoderIsacT<IsacFix>;
struct CodecInst;
-class AudioEncoderDecoderMutableIsacFix
- : public AudioEncoderMutableImpl<AudioEncoderDecoderIsacFix,
- AudioEncoderDecoderMutableIsac> {
+class AudioEncoderMutableIsacFix
+ : public AudioEncoderMutableImpl<AudioEncoderIsacFix> {
public:
- explicit AudioEncoderDecoderMutableIsacFix(const CodecInst& codec_inst);
- void UpdateSettings(const CodecInst& codec_inst) override;
+ explicit AudioEncoderMutableIsacFix(const CodecInst& codec_inst,
+ LockedIsacBandwidthInfo* bwinfo);
void SetMaxPayloadSize(int max_payload_size_bytes) override;
void SetMaxRate(int max_rate_bps) override;
-
- // From AudioDecoder.
- int Decode(const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- int16_t* decoded,
- SpeechType* speech_type) override;
- int DecodeRedundant(const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- 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) const 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;
- size_t Channels() const override;
};
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc b/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc
index c7999b5..2f8d4b6 100644
--- a/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc
+++ b/webrtc/modules/audio_coding/codecs/isac/fix/source/audio_encoder_isacfix.cc
@@ -17,13 +17,15 @@
const uint16_t IsacFix::kFixSampleRate;
-// Explicit instantiation of AudioEncoderDecoderIsacT<IsacFix>, a.k.a.
-// AudioEncoderDecoderIsacFix.
-template class AudioEncoderDecoderIsacT<IsacFix>;
+// Explicit instantiation:
+template class AudioEncoderIsacT<IsacFix>;
+template class AudioDecoderIsacT<IsacFix>;
namespace {
-AudioEncoderDecoderIsacFix::Config CreateConfig(const CodecInst& codec_inst) {
- AudioEncoderDecoderIsacFix::Config config;
+AudioEncoderIsacFix::Config CreateConfig(const CodecInst& codec_inst,
+ LockedIsacBandwidthInfo* bwinfo) {
+ AudioEncoderIsacFix::Config config;
+ config.bwinfo = bwinfo;
config.payload_type = codec_inst.pltype;
config.sample_rate_hz = codec_inst.plfreq;
config.frame_size_ms =
@@ -35,110 +37,22 @@
}
} // namespace
-AudioEncoderDecoderMutableIsacFix::AudioEncoderDecoderMutableIsacFix(
- const CodecInst& codec_inst)
- : AudioEncoderMutableImpl<AudioEncoderDecoderIsacFix,
- AudioEncoderDecoderMutableIsac>(
- CreateConfig(codec_inst)) {
-}
+AudioEncoderMutableIsacFix::AudioEncoderMutableIsacFix(
+ const CodecInst& codec_inst,
+ LockedIsacBandwidthInfo* bwinfo)
+ : AudioEncoderMutableImpl<AudioEncoderIsacFix>(
+ CreateConfig(codec_inst, bwinfo)) {}
-void AudioEncoderDecoderMutableIsacFix::UpdateSettings(
- const CodecInst& codec_inst) {
- bool success = Reconstruct(CreateConfig(codec_inst));
- DCHECK(success);
-}
-
-void AudioEncoderDecoderMutableIsacFix::SetMaxPayloadSize(
- int max_payload_size_bytes) {
+void AudioEncoderMutableIsacFix::SetMaxPayloadSize(int max_payload_size_bytes) {
auto conf = config();
conf.max_payload_size_bytes = max_payload_size_bytes;
Reconstruct(conf);
}
-void AudioEncoderDecoderMutableIsacFix::SetMaxRate(int max_rate_bps) {
+void AudioEncoderMutableIsacFix::SetMaxRate(int max_rate_bps) {
auto conf = config();
conf.max_bit_rate = max_rate_bps;
Reconstruct(conf);
}
-int AudioEncoderDecoderMutableIsacFix::Decode(const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- int16_t* decoded,
- SpeechType* speech_type) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->Decode(encoded, encoded_len, sample_rate_hz,
- max_decoded_bytes, decoded, speech_type);
-}
-
-int AudioEncoderDecoderMutableIsacFix::DecodeRedundant(
- const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- int16_t* decoded,
- SpeechType* speech_type) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->DecodeRedundant(encoded, encoded_len, sample_rate_hz,
- max_decoded_bytes, decoded, speech_type);
-}
-
-bool AudioEncoderDecoderMutableIsacFix::HasDecodePlc() const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->HasDecodePlc();
-}
-
-int AudioEncoderDecoderMutableIsacFix::DecodePlc(int num_frames,
- int16_t* decoded) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->DecodePlc(num_frames, decoded);
-}
-
-int AudioEncoderDecoderMutableIsacFix::Init() {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->Init();
-}
-
-int AudioEncoderDecoderMutableIsacFix::IncomingPacket(
- const uint8_t* payload,
- size_t payload_len,
- uint16_t rtp_sequence_number,
- uint32_t rtp_timestamp,
- uint32_t arrival_timestamp) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->IncomingPacket(payload, payload_len, rtp_sequence_number,
- rtp_timestamp, arrival_timestamp);
-}
-
-int AudioEncoderDecoderMutableIsacFix::ErrorCode() {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->ErrorCode();
-}
-
-int AudioEncoderDecoderMutableIsacFix::PacketDuration(
- const uint8_t* encoded,
- size_t encoded_len) const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->PacketDuration(encoded, encoded_len);
-}
-
-int AudioEncoderDecoderMutableIsacFix::PacketDurationRedundant(
- const uint8_t* encoded,
- size_t encoded_len) const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->PacketDurationRedundant(encoded, encoded_len);
-}
-
-bool AudioEncoderDecoderMutableIsacFix::PacketHasFec(const uint8_t* encoded,
- size_t encoded_len) const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->PacketHasFec(encoded, encoded_len);
-}
-
-size_t AudioEncoderDecoderMutableIsacFix::Channels() const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->Channels();
-}
-
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c
index ba055eb..9b61d60 100644
--- a/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c
+++ b/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c
@@ -241,6 +241,31 @@
}
#endif
+static void InitFunctionPointers(void) {
+ WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
+ WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
+ WebRtcIsacfix_CalculateResidualEnergy =
+ WebRtcIsacfix_CalculateResidualEnergyC;
+ WebRtcIsacfix_AllpassFilter2FixDec16 = WebRtcIsacfix_AllpassFilter2FixDec16C;
+ WebRtcIsacfix_HighpassFilterFixDec32 = WebRtcIsacfix_HighpassFilterFixDec32C;
+ WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecC;
+ WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeC;
+ WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C;
+ WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C;
+
+#ifdef WEBRTC_DETECT_NEON
+ if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
+ WebRtcIsacfix_InitNeon();
+ }
+#elif defined(WEBRTC_HAS_NEON)
+ WebRtcIsacfix_InitNeon();
+#endif
+
+#if defined(MIPS32_LE)
+ WebRtcIsacfix_InitMIPS();
+#endif
+}
+
/****************************************************************************
* WebRtcIsacfix_EncoderInit(...)
*
@@ -317,29 +342,7 @@
WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACenc_obj.interpolatorstr_obj);
#endif
- // Initiaze function pointers.
- WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
- WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
- WebRtcIsacfix_CalculateResidualEnergy =
- WebRtcIsacfix_CalculateResidualEnergyC;
- WebRtcIsacfix_AllpassFilter2FixDec16 = WebRtcIsacfix_AllpassFilter2FixDec16C;
- WebRtcIsacfix_HighpassFilterFixDec32 = WebRtcIsacfix_HighpassFilterFixDec32C;
- WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecC;
- WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeC;
- WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C;
- WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C;
-
-#ifdef WEBRTC_DETECT_NEON
- if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
- WebRtcIsacfix_InitNeon();
- }
-#elif defined(WEBRTC_HAS_NEON)
- WebRtcIsacfix_InitNeon();
-#endif
-
-#if defined(MIPS32_LE)
- WebRtcIsacfix_InitMIPS();
-#endif
+ InitFunctionPointers();
return statusInit;
}
@@ -575,6 +578,8 @@
{
ISACFIX_SubStruct *ISAC_inst;
+ InitFunctionPointers();
+
/* typecast pointer to real structure */
ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
diff --git a/webrtc/modules/audio_coding/codecs/isac/isac.gypi b/webrtc/modules/audio_coding/codecs/isac/isac.gypi
index 50cc867..8ecc2dc 100644
--- a/webrtc/modules/audio_coding/codecs/isac/isac.gypi
+++ b/webrtc/modules/audio_coding/codecs/isac/isac.gypi
@@ -15,6 +15,7 @@
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
'audio_decoder_interface',
'audio_encoder_interface',
+ 'isac_common',
],
'include_dirs': [
'main/interface',
@@ -27,8 +28,6 @@
],
},
'sources': [
- 'audio_encoder_isac_t.h',
- 'audio_encoder_isac_t_impl.h',
'main/interface/audio_encoder_isac.h',
'main/interface/isac.h',
'main/source/arith_routines.c',
diff --git a/webrtc/modules/audio_coding/codecs/isac/isac_common.gypi b/webrtc/modules/audio_coding/codecs/isac/isac_common.gypi
new file mode 100644
index 0000000..135ecd2
--- /dev/null
+++ b/webrtc/modules/audio_coding/codecs/isac/isac_common.gypi
@@ -0,0 +1,22 @@
+# Copyright (c) 2015 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.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'isac_common',
+ 'type': 'static_library',
+ 'sources': [
+ 'audio_encoder_isac_t.h',
+ 'audio_encoder_isac_t_impl.h',
+ 'locked_bandwidth_info.cc',
+ 'locked_bandwidth_info.h',
+ ],
+ },
+ ],
+}
diff --git a/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi b/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi
index e20177c..81b4375 100644
--- a/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi
+++ b/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi
@@ -14,6 +14,7 @@
'dependencies': [
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
'<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers',
+ 'isac_common',
],
'include_dirs': [
'fix/interface',
@@ -26,8 +27,6 @@
],
},
'sources': [
- 'audio_encoder_isac_t.h',
- 'audio_encoder_isac_t_impl.h',
'fix/interface/audio_encoder_isacfix.h',
'fix/interface/isacfix.h',
'fix/source/arith_routines.c',
diff --git a/webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.cc b/webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.cc
new file mode 100644
index 0000000..78b415c
--- /dev/null
+++ b/webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.cc
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 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/modules/audio_coding/codecs/isac/locked_bandwidth_info.h"
+
+namespace webrtc {
+
+LockedIsacBandwidthInfo::LockedIsacBandwidthInfo()
+ : lock_(CriticalSectionWrapper::CreateCriticalSection()) {
+ bwinfo_.in_use = 0;
+}
+
+LockedIsacBandwidthInfo::~LockedIsacBandwidthInfo() = default;
+
+} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h b/webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h
new file mode 100644
index 0000000..bf39003
--- /dev/null
+++ b/webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 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_MODULES_AUDIO_CODING_CODECS_ISAC_LOCKED_BANDWIDTH_INFO_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_LOCKED_BANDWIDTH_INFO_H_
+
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/thread_annotations.h"
+#include "webrtc/modules/audio_coding/codecs/isac/bandwidth_info.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+
+namespace webrtc {
+
+// An IsacBandwidthInfo that's safe to access from multiple threads because
+// it's protected by a mutex.
+class LockedIsacBandwidthInfo final {
+ public:
+ LockedIsacBandwidthInfo();
+ ~LockedIsacBandwidthInfo();
+
+ IsacBandwidthInfo Get() const {
+ CriticalSectionScoped cs(lock_.get());
+ return bwinfo_;
+ }
+
+ void Set(const IsacBandwidthInfo& bwinfo) {
+ CriticalSectionScoped cs(lock_.get());
+ bwinfo_ = bwinfo;
+ }
+
+ private:
+ const rtc::scoped_ptr<CriticalSectionWrapper> lock_;
+ IsacBandwidthInfo bwinfo_ GUARDED_BY(lock_);
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_LOCKED_BANDWIDTH_INFO_H_
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h b/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
index 2799892..c0f3b11 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
+++ b/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
@@ -118,46 +118,18 @@
}
};
-typedef AudioEncoderDecoderIsacT<IsacFloat> AudioEncoderDecoderIsac;
+using AudioEncoderIsac = AudioEncoderIsacT<IsacFloat>;
+using AudioDecoderIsac = AudioDecoderIsacT<IsacFloat>;
struct CodecInst;
-class AudioEncoderDecoderMutableIsacFloat
- : public AudioEncoderMutableImpl<AudioEncoderDecoderIsac,
- AudioEncoderDecoderMutableIsac> {
+class AudioEncoderMutableIsacFloat
+ : public AudioEncoderMutableImpl<AudioEncoderIsac> {
public:
- explicit AudioEncoderDecoderMutableIsacFloat(const CodecInst& codec_inst);
- void UpdateSettings(const CodecInst& codec_inst) override;
+ AudioEncoderMutableIsacFloat(const CodecInst& codec_inst,
+ LockedIsacBandwidthInfo* bwinfo);
void SetMaxPayloadSize(int max_payload_size_bytes) override;
void SetMaxRate(int max_rate_bps) override;
-
- // From AudioDecoder.
- int Decode(const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- int16_t* decoded,
- SpeechType* speech_type) override;
- int DecodeRedundant(const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- 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) const 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;
- size_t Channels() const override;
};
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
index 201a2d4..195265d 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
+++ b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
@@ -15,13 +15,15 @@
namespace webrtc {
-// Explicit instantiation of AudioEncoderDecoderIsacT<IsacFloat>, a.k.a.
-// AudioEncoderDecoderIsac.
-template class AudioEncoderDecoderIsacT<IsacFloat>;
+// Explicit instantiation:
+template class AudioEncoderIsacT<IsacFloat>;
+template class AudioDecoderIsacT<IsacFloat>;
namespace {
-AudioEncoderDecoderIsac::Config CreateConfig(const CodecInst& codec_inst) {
- AudioEncoderDecoderIsac::Config config;
+AudioEncoderIsac::Config CreateConfig(const CodecInst& codec_inst,
+ LockedIsacBandwidthInfo* bwinfo) {
+ AudioEncoderIsac::Config config;
+ config.bwinfo = bwinfo;
config.payload_type = codec_inst.pltype;
config.sample_rate_hz = codec_inst.plfreq;
config.frame_size_ms =
@@ -33,111 +35,24 @@
}
} // namespace
-AudioEncoderDecoderMutableIsacFloat::AudioEncoderDecoderMutableIsacFloat(
- const CodecInst& codec_inst)
- : AudioEncoderMutableImpl<AudioEncoderDecoderIsac,
- AudioEncoderDecoderMutableIsac>(
- CreateConfig(codec_inst)) {
+AudioEncoderMutableIsacFloat::AudioEncoderMutableIsacFloat(
+ const CodecInst& codec_inst,
+ LockedIsacBandwidthInfo* bwinfo)
+ : AudioEncoderMutableImpl<AudioEncoderIsac>(
+ CreateConfig(codec_inst, bwinfo)) {
}
-void AudioEncoderDecoderMutableIsacFloat::UpdateSettings(
- const CodecInst& codec_inst) {
- bool success = Reconstruct(CreateConfig(codec_inst));
- DCHECK(success);
-}
-
-void AudioEncoderDecoderMutableIsacFloat::SetMaxPayloadSize(
+void AudioEncoderMutableIsacFloat::SetMaxPayloadSize(
int max_payload_size_bytes) {
auto conf = config();
conf.max_payload_size_bytes = max_payload_size_bytes;
Reconstruct(conf);
}
-void AudioEncoderDecoderMutableIsacFloat::SetMaxRate(int max_rate_bps) {
+void AudioEncoderMutableIsacFloat::SetMaxRate(int max_rate_bps) {
auto conf = config();
conf.max_bit_rate = max_rate_bps;
Reconstruct(conf);
}
-int AudioEncoderDecoderMutableIsacFloat::Decode(const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- int16_t* decoded,
- SpeechType* speech_type) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->Decode(encoded, encoded_len, sample_rate_hz,
- max_decoded_bytes, decoded, speech_type);
-}
-
-int AudioEncoderDecoderMutableIsacFloat::DecodeRedundant(
- const uint8_t* encoded,
- size_t encoded_len,
- int sample_rate_hz,
- size_t max_decoded_bytes,
- int16_t* decoded,
- SpeechType* speech_type) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->DecodeRedundant(encoded, encoded_len, sample_rate_hz,
- max_decoded_bytes, decoded, speech_type);
-}
-
-bool AudioEncoderDecoderMutableIsacFloat::HasDecodePlc() const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->HasDecodePlc();
-}
-
-int AudioEncoderDecoderMutableIsacFloat::DecodePlc(int num_frames,
- int16_t* decoded) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->DecodePlc(num_frames, decoded);
-}
-
-int AudioEncoderDecoderMutableIsacFloat::Init() {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->Init();
-}
-
-int AudioEncoderDecoderMutableIsacFloat::IncomingPacket(
- const uint8_t* payload,
- size_t payload_len,
- uint16_t rtp_sequence_number,
- uint32_t rtp_timestamp,
- uint32_t arrival_timestamp) {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->IncomingPacket(payload, payload_len, rtp_sequence_number,
- rtp_timestamp, arrival_timestamp);
-}
-
-int AudioEncoderDecoderMutableIsacFloat::ErrorCode() {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->ErrorCode();
-}
-
-int AudioEncoderDecoderMutableIsacFloat::PacketDuration(
- const uint8_t* encoded,
- size_t encoded_len) const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->PacketDuration(encoded, encoded_len);
-}
-
-int AudioEncoderDecoderMutableIsacFloat::PacketDurationRedundant(
- const uint8_t* encoded,
- size_t encoded_len) const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->PacketDurationRedundant(encoded, encoded_len);
-}
-
-bool AudioEncoderDecoderMutableIsacFloat::PacketHasFec(
- const uint8_t* encoded,
- size_t encoded_len) const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->PacketHasFec(encoded, encoded_len);
-}
-
-size_t AudioEncoderDecoderMutableIsacFloat::Channels() const {
- CriticalSectionScoped cs(encoder_lock_.get());
- return encoder()->Channels();
-}
-
} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_unittest.cc b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_unittest.cc
index ee5c031..ff941ea 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_unittest.cc
+++ b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_unittest.cc
@@ -17,13 +17,13 @@
namespace {
-void TestBadConfig(const AudioEncoderDecoderIsac::Config& config) {
+void TestBadConfig(const AudioEncoderIsac::Config& config) {
EXPECT_FALSE(config.IsOk());
}
-void TestGoodConfig(const AudioEncoderDecoderIsac::Config& config) {
+void TestGoodConfig(const AudioEncoderIsac::Config& config) {
EXPECT_TRUE(config.IsOk());
- AudioEncoderDecoderIsac ed(config);
+ AudioEncoderIsac aei(config);
}
// Wrap subroutine calls that test things in this, so that the error messages
@@ -34,7 +34,7 @@
} // namespace
TEST(AudioEncoderIsacTest, TestConfigBitrate) {
- AudioEncoderDecoderIsac::Config config;
+ AudioEncoderIsac::Config config;
// The default value is some real, positive value.
EXPECT_GT(config.bit_rate, 1);
diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc
index 568ae1e..71c436b 100644
--- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc
+++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc
@@ -721,9 +721,9 @@
receive_packet_count_(0),
next_insert_packet_time_ms_(0),
fake_clock_(new SimulatedClock(0)) {
- AudioEncoderDecoderIsac::Config config;
+ AudioEncoderIsac::Config config;
config.payload_type = kPayloadType;
- isac_encoder_.reset(new AudioEncoderDecoderIsac(config));
+ isac_encoder_.reset(new AudioEncoderIsac(config));
clock_ = fake_clock_.get();
}
@@ -845,7 +845,7 @@
bool codec_registered_ GUARDED_BY(crit_sect_);
int receive_packet_count_ GUARDED_BY(crit_sect_);
int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_);
- rtc::scoped_ptr<AudioEncoderDecoderIsac> isac_encoder_;
+ rtc::scoped_ptr<AudioEncoderIsac> isac_encoder_;
rtc::scoped_ptr<SimulatedClock> fake_clock_;
test::AudioLoop audio_loop_;
};
diff --git a/webrtc/modules/audio_coding/main/acm2/codec_owner.cc b/webrtc/modules/audio_coding/main/acm2/codec_owner.cc
index 4d214be..ed23e10 100644
--- a/webrtc/modules/audio_coding/main/acm2/codec_owner.cc
+++ b/webrtc/modules/audio_coding/main/acm2/codec_owner.cc
@@ -75,55 +75,61 @@
}
} // namespace
-CodecOwner::CodecOwner()
- : isac_is_encoder_(false), external_speech_encoder_(nullptr) {
+CodecOwner::CodecOwner() : external_speech_encoder_(nullptr) {
}
CodecOwner::~CodecOwner() = default;
namespace {
-AudioEncoderDecoderMutableIsac* CreateIsacCodec(const CodecInst& speech_inst) {
+
+rtc::scoped_ptr<AudioDecoder> CreateIsacDecoder(
+ LockedIsacBandwidthInfo* bwinfo) {
#if defined(WEBRTC_CODEC_ISACFX)
- return new AudioEncoderDecoderMutableIsacFix(speech_inst);
+ return rtc_make_scoped_ptr(new AudioDecoderIsacFix(bwinfo));
#elif defined(WEBRTC_CODEC_ISAC)
- return new AudioEncoderDecoderMutableIsacFloat(speech_inst);
+ return rtc_make_scoped_ptr(new AudioDecoderIsac(bwinfo));
#else
FATAL() << "iSAC is not supported.";
- return nullptr;
+ return rtc::scoped_ptr<AudioDecoder>();
#endif
}
-void CreateSpeechEncoder(
+rtc::scoped_ptr<AudioEncoderMutable> CreateIsacEncoder(
const CodecInst& speech_inst,
- rtc::scoped_ptr<AudioEncoderMutable>* speech_encoder,
- rtc::scoped_ptr<AudioEncoderDecoderMutableIsac>* isac_codec,
- bool* isac_is_encoder) {
+ LockedIsacBandwidthInfo* bwinfo) {
+#if defined(WEBRTC_CODEC_ISACFX)
+ return rtc_make_scoped_ptr(
+ new AudioEncoderMutableIsacFix(speech_inst, bwinfo));
+#elif defined(WEBRTC_CODEC_ISAC)
+ return rtc_make_scoped_ptr(
+ new AudioEncoderMutableIsacFloat(speech_inst, bwinfo));
+#else
+ FATAL() << "iSAC is not supported.";
+ return rtc::scoped_ptr<AudioEncoderMutable>();
+#endif
+}
+
+rtc::scoped_ptr<AudioEncoderMutable> CreateSpeechEncoder(
+ const CodecInst& speech_inst,
+ LockedIsacBandwidthInfo* bwinfo) {
if (IsIsac(speech_inst)) {
- if (*isac_codec) {
- (*isac_codec)->UpdateSettings(speech_inst);
- } else {
- isac_codec->reset(CreateIsacCodec(speech_inst));
- }
- *isac_is_encoder = true;
- speech_encoder->reset();
- return;
- }
- if (IsOpus(speech_inst)) {
- speech_encoder->reset(new AudioEncoderMutableOpus(speech_inst));
+ return CreateIsacEncoder(speech_inst, bwinfo);
+ } else if (IsOpus(speech_inst)) {
+ return rtc_make_scoped_ptr(new AudioEncoderMutableOpus(speech_inst));
} else if (IsPcmU(speech_inst)) {
- speech_encoder->reset(new AudioEncoderMutablePcmU(speech_inst));
+ return rtc_make_scoped_ptr(new AudioEncoderMutablePcmU(speech_inst));
} else if (IsPcmA(speech_inst)) {
- speech_encoder->reset(new AudioEncoderMutablePcmA(speech_inst));
+ return rtc_make_scoped_ptr(new AudioEncoderMutablePcmA(speech_inst));
} else if (IsPcm16B(speech_inst)) {
- speech_encoder->reset(new AudioEncoderMutablePcm16B(speech_inst));
+ return rtc_make_scoped_ptr(new AudioEncoderMutablePcm16B(speech_inst));
} else if (IsIlbc(speech_inst)) {
- speech_encoder->reset(new AudioEncoderMutableIlbc(speech_inst));
+ return rtc_make_scoped_ptr(new AudioEncoderMutableIlbc(speech_inst));
} else if (IsG722(speech_inst)) {
- speech_encoder->reset(new AudioEncoderMutableG722(speech_inst));
+ return rtc_make_scoped_ptr(new AudioEncoderMutableG722(speech_inst));
} else {
FATAL();
+ return rtc::scoped_ptr<AudioEncoderMutable>();
}
- *isac_is_encoder = false;
}
AudioEncoder* CreateRedEncoder(int red_payload_type,
@@ -176,8 +182,7 @@
int cng_payload_type,
ACMVADMode vad_mode,
int red_payload_type) {
- CreateSpeechEncoder(speech_inst, &speech_encoder_, &isac_codec_,
- &isac_is_encoder_);
+ speech_encoder_ = CreateSpeechEncoder(speech_inst, &isac_bandwidth_info_);
external_speech_encoder_ = nullptr;
ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type);
}
@@ -188,7 +193,6 @@
int red_payload_type) {
external_speech_encoder_ = external_speech_encoder;
speech_encoder_.reset();
- isac_is_encoder_ = false;
ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type);
}
@@ -204,24 +208,13 @@
AudioEncoder* encoder =
CreateRedEncoder(red_payload_type, speech_encoder, &red_encoder_);
CreateCngEncoder(cng_payload_type, vad_mode, encoder, &cng_encoder_);
- int num_true =
- !!speech_encoder_ + !!external_speech_encoder_ + isac_is_encoder_;
- DCHECK_EQ(num_true, 1);
- DCHECK(!isac_is_encoder_ || isac_codec_);
+ DCHECK_EQ(!!speech_encoder_ + !!external_speech_encoder_, 1);
}
AudioDecoder* CodecOwner::GetIsacDecoder() {
- if (!isac_codec_) {
- DCHECK(!isac_is_encoder_);
- // None of the parameter values in |speech_inst| matter when the codec is
- // used only as a decoder.
- CodecInst speech_inst;
- speech_inst.plfreq = 16000;
- speech_inst.rate = -1;
- speech_inst.pacsize = 480;
- isac_codec_.reset(CreateIsacCodec(speech_inst));
- }
- return isac_codec_.get();
+ if (!isac_decoder_)
+ isac_decoder_ = CreateIsacDecoder(&isac_bandwidth_info_);
+ return isac_decoder_.get();
}
AudioEncoder* CodecOwner::Encoder() {
@@ -243,15 +236,9 @@
}
const AudioEncoderMutable* CodecOwner::SpeechEncoder() const {
- int num_true =
- !!speech_encoder_ + !!external_speech_encoder_ + isac_is_encoder_;
- DCHECK_GE(num_true, 0);
- DCHECK_LE(num_true, 1);
- if (external_speech_encoder_)
- return external_speech_encoder_;
- if (speech_encoder_)
- return speech_encoder_.get();
- return isac_is_encoder_ ? isac_codec_.get() : nullptr;
+ DCHECK(!speech_encoder_ || !external_speech_encoder_);
+ return external_speech_encoder_ ? external_speech_encoder_
+ : speech_encoder_.get();
}
} // namespace acm2
diff --git a/webrtc/modules/audio_coding/main/acm2/codec_owner.h b/webrtc/modules/audio_coding/main/acm2/codec_owner.h
index 2468c3c..2c5e942 100644
--- a/webrtc/modules/audio_coding/main/acm2/codec_owner.h
+++ b/webrtc/modules/audio_coding/main/acm2/codec_owner.h
@@ -53,21 +53,17 @@
const AudioEncoderMutable* SpeechEncoder() const;
private:
- // There are three main cases for the state of the encoder members below:
- // 1. An external encoder is used. |external_speech_encoder_| points to it.
- // |speech_encoder_| is null, and |isac_is_encoder_| is false.
- // 2. The internal iSAC codec is used as encoder. |isac_codec_| points to it
- // and |isac_is_encoder_| is true. |external_speech_encoder_| and
- // |speech_encoder_| are null.
- // 3. Another internal encoder is used. |speech_encoder_| points to it.
- // |external_speech_encoder_| is null, and |isac_is_encoder_| is false.
- // In addition to case 2, |isac_codec_| is valid when GetIsacDecoder has been
- // called.
+ // At most one of these is non-null:
rtc::scoped_ptr<AudioEncoderMutable> speech_encoder_;
- rtc::scoped_ptr<AudioEncoderDecoderMutableIsac> isac_codec_;
- bool isac_is_encoder_;
AudioEncoderMutable* external_speech_encoder_;
+ // If we've created an iSAC decoder because someone called GetIsacDecoder,
+ // store it here.
+ rtc::scoped_ptr<AudioDecoder> isac_decoder_;
+
+ // iSAC bandwidth estimation info, for use with iSAC encoders and decoders.
+ LockedIsacBandwidthInfo isac_bandwidth_info_;
+
// |cng_encoder_| and |red_encoder_| are valid iff CNG or RED, respectively,
// are active.
rtc::scoped_ptr<AudioEncoder> cng_encoder_;
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
index 6a9b953..53dc033 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
@@ -559,22 +559,13 @@
return new AudioDecoderIlbc;
#endif
#if defined(WEBRTC_CODEC_ISACFX)
- case kDecoderISAC: {
- AudioEncoderDecoderIsacFix::Config config;
- return new AudioEncoderDecoderIsacFix(config);
- }
+ case kDecoderISAC:
+ return new AudioDecoderIsacFix();
#elif defined(WEBRTC_CODEC_ISAC)
- case kDecoderISAC: {
- AudioEncoderDecoderIsac::Config config;
- config.sample_rate_hz = 16000;
- return new AudioEncoderDecoderIsac(config);
- }
+ case kDecoderISAC:
case kDecoderISACswb:
- case kDecoderISACfb: {
- AudioEncoderDecoderIsac::Config config;
- config.sample_rate_hz = 32000;
- return new AudioEncoderDecoderIsac(config);
- }
+ case kDecoderISACfb:
+ return new AudioDecoderIsac();
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16B:
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
index d54fbe9..3983c07 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
@@ -358,17 +358,14 @@
codec_input_rate_hz_ = 16000;
frame_size_ = 480;
data_length_ = 10 * frame_size_;
- AudioEncoderDecoderIsac::Config config;
+ AudioEncoderIsac::Config config;
config.payload_type = payload_type_;
config.sample_rate_hz = codec_input_rate_hz_;
config.adaptive_mode = false;
config.frame_size_ms =
1000 * static_cast<int>(frame_size_) / codec_input_rate_hz_;
-
- // We need to create separate AudioEncoderDecoderIsac objects for encoding
- // and decoding, because the test class destructor destroys them both.
- audio_encoder_.reset(new AudioEncoderDecoderIsac(config));
- decoder_ = new AudioEncoderDecoderIsac(config);
+ audio_encoder_.reset(new AudioEncoderIsac(config));
+ decoder_ = new AudioDecoderIsac();
}
};
@@ -378,17 +375,14 @@
codec_input_rate_hz_ = 32000;
frame_size_ = 960;
data_length_ = 10 * frame_size_;
- AudioEncoderDecoderIsac::Config config;
+ AudioEncoderIsac::Config config;
config.payload_type = payload_type_;
config.sample_rate_hz = codec_input_rate_hz_;
config.adaptive_mode = false;
config.frame_size_ms =
1000 * static_cast<int>(frame_size_) / codec_input_rate_hz_;
-
- // We need to create separate AudioEncoderDecoderIsac objects for encoding
- // and decoding, because the test class destructor destroys them both.
- audio_encoder_.reset(new AudioEncoderDecoderIsac(config));
- decoder_ = new AudioEncoderDecoderIsac(config);
+ audio_encoder_.reset(new AudioEncoderIsac(config));
+ decoder_ = new AudioDecoderIsac();
}
};
@@ -398,18 +392,14 @@
codec_input_rate_hz_ = 16000;
frame_size_ = 480;
data_length_ = 10 * frame_size_;
- AudioEncoderDecoderIsacFix::Config config;
+ AudioEncoderIsacFix::Config config;
config.payload_type = payload_type_;
config.sample_rate_hz = codec_input_rate_hz_;
config.adaptive_mode = false;
config.frame_size_ms =
1000 * static_cast<int>(frame_size_) / codec_input_rate_hz_;
-
- // We need to create separate AudioEncoderDecoderIsacFix objects for
- // encoding and decoding, because the test class destructor destroys them
- // both.
- audio_encoder_.reset(new AudioEncoderDecoderIsacFix(config));
- decoder_ = new AudioEncoderDecoderIsacFix(config);
+ audio_encoder_.reset(new AudioEncoderIsacFix(config));
+ decoder_ = new AudioDecoderIsacFix();
}
};