diff options
author | kwiberg <kwiberg@webrtc.org> | 2015-08-24 02:03:23 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-24 09:03:28 +0000 |
commit | 608c3cfe77c165965ea04fcd0a2a71aad05a1d16 (patch) | |
tree | c2d1c2895e126e244f5e415a1094154f80206127 /webrtc/modules/audio_coding/codecs | |
parent | 2159b89fa2cb55beeef38f72bd45e217f3d33d4e (diff) | |
download | webrtc-608c3cfe77c165965ea04fcd0a2a71aad05a1d16.tar.gz |
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}
Diffstat (limited to 'webrtc/modules/audio_coding/codecs')
13 files changed, 284 insertions, 399 deletions
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 49df3c68be..7093304264 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 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder { Config(); bool IsOk() const; + LockedIsacBandwidthInfo* bwinfo; + int payload_type; int sample_rate_hz; int frame_size_ms; @@ -50,81 +49,72 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder { 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; - - // AudioDecoder methods. - 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; - 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. - int DecodeInternal(const uint8_t* encoded, - size_t encoded_len, - int sample_rate_hz, - int16_t* decoded, - 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; 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_; + typename T::instance_type* isac_state_; + LockedIsacBandwidthInfo* bwinfo_; // Have we accepted input but not yet emitted it in a packet? - bool packet_in_progress_ GUARDED_BY(lock_); + bool packet_in_progress_; // Timestamp of the first input of the currently in-progress packet. - uint32_t packet_timestamp_ GUARDED_BY(lock_); + uint32_t packet_timestamp_; // Timestamp of the previously encoded packet. - uint32_t last_encoded_timestamp_ GUARDED_BY(lock_); + uint32_t last_encoded_timestamp_; const int target_bitrate_bps_; - DISALLOW_COPY_AND_ASSIGN(AudioEncoderDecoderIsacT); + DISALLOW_COPY_AND_ASSIGN(AudioEncoderIsacT); }; -struct CodecInst; - -class AudioEncoderDecoderMutableIsac : public AudioEncoderMutable, - public AudioDecoder { +template <typename T> +class AudioDecoderIsacT final : public AudioDecoder { public: - virtual void UpdateSettings(const CodecInst& codec_inst) = 0; + AudioDecoderIsacT(); + explicit AudioDecoderIsacT(LockedIsacBandwidthInfo* bwinfo); + ~AudioDecoderIsacT() 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; + size_t Channels() const override; + int DecodeInternal(const uint8_t* encoded, + size_t encoded_len, + int sample_rate_hz, + int16_t* decoded, + SpeechType* speech_type) override; + + private: + typename T::instance_type* isac_state_; + LockedIsacBandwidthInfo* bwinfo_; + int decoder_sample_rate_hz_; + + 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 d2b20e3b94..ce70db455b 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 kIsacPayloadType = 103; 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 @@ AudioEncoderDecoderIsacT<T>::Config::Config() } 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 @@ bool AudioEncoderDecoderIsacT<T>::Config::IsOk() const { } 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 @@ AudioEncoderDecoderIsacT<T>::AudioEncoderDecoderIsacT(const Config& config) } 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 @@ AudioEncoder::EncodedInfo AudioEncoderDecoderIsacT<T>::EncodeInternal( } 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 @@ int AudioEncoderDecoderIsacT<T>::DecodeInternal(const uint8_t* encoded, } 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 02b5d3cab8..9d51161c31 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 @@ struct IsacFix { } }; -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 c7999b56be..2f8d4b6e5d 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 @@ namespace webrtc { 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 @@ AudioEncoderDecoderIsacFix::Config CreateConfig(const CodecInst& codec_inst) { } } // namespace -AudioEncoderDecoderMutableIsacFix::AudioEncoderDecoderMutableIsacFix( - const CodecInst& codec_inst) - : AudioEncoderMutableImpl<AudioEncoderDecoderIsacFix, - AudioEncoderDecoderMutableIsac>( - CreateConfig(codec_inst)) { -} - -void AudioEncoderDecoderMutableIsacFix::UpdateSettings( - const CodecInst& codec_inst) { - bool success = Reconstruct(CreateConfig(codec_inst)); - DCHECK(success); -} +AudioEncoderMutableIsacFix::AudioEncoderMutableIsacFix( + const CodecInst& codec_inst, + LockedIsacBandwidthInfo* bwinfo) + : AudioEncoderMutableImpl<AudioEncoderIsacFix>( + CreateConfig(codec_inst, bwinfo)) {} -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 ba055ebdf5..9b61d60215 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 @@ static void WebRtcIsacfix_InitMIPS(void) { } #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 @@ int16_t WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst, 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 @@ int16_t WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst) { 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 50cc867b23..8ecc2dc414 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 0000000000..135ecd27cc --- /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 e20177c365..81b4375c21 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 0000000000..78b415c4c9 --- /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 0000000000..bf39003c12 --- /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 27998923f0..c0f3b11a09 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 @@ struct IsacFloat { } }; -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 201a2d4bb4..195265dba6 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 @@ AudioEncoderDecoderIsac::Config CreateConfig(const CodecInst& codec_inst) { } } // 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 ee5c03121b..ff941ea79c 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 webrtc { 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 @@ void TestGoodConfig(const AudioEncoderDecoderIsac::Config& config) { } // namespace TEST(AudioEncoderIsacTest, TestConfigBitrate) { - AudioEncoderDecoderIsac::Config config; + AudioEncoderIsac::Config config; // The default value is some real, positive value. EXPECT_GT(config.bit_rate, 1); |