diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-07-14 17:41:05 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2016-08-04 12:37:36 +0000 |
commit | 399c965b6064c440ddcf4015f5f8e9d131c7a0a6 (patch) | |
tree | 6b06b60ff365abef0e13b3503d593a0df48d20e8 /chromium/third_party/webrtc/modules/audio_coding/codecs | |
parent | 7366110654eec46f21b6824f302356426f48cd74 (diff) | |
download | qtwebengine-chromium-399c965b6064c440ddcf4015f5f8e9d131c7a0a6.tar.gz |
BASELINE: Update Chromium to 52.0.2743.76 and Ninja to 1.7.1
Change-Id: I382f51b959689505a60f8b707255ecb344f7d8b4
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/webrtc/modules/audio_coding/codecs')
59 files changed, 1317 insertions, 1440 deletions
diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.cc index d2984b97b09..442ddc1e4b8 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.cc @@ -82,11 +82,6 @@ bool AudioDecoder::PacketHasFec(const uint8_t* encoded, return false; } -CNG_dec_inst* AudioDecoder::CngDecoderInstance() { - FATAL() << "Not a CNG decoder"; - return NULL; -} - AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) { switch (type) { case 0: // TODO(hlundin): Both iSAC and Opus return 0 for speech. diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.h index 81ac8731830..580ddbf74ff 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder.h @@ -14,7 +14,6 @@ #include <stdlib.h> // NULL #include "webrtc/base/constructormagic.h" -#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -94,10 +93,6 @@ class AudioDecoder { // Returns true if the packet has FEC and false otherwise. virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const; - // If this is a CNG decoder, return the underlying CNG_dec_inst*. If this - // isn't a CNG decoder, don't call this method. - virtual CNG_dec_inst* CngDecoderInstance(); - virtual size_t Channels() const = 0; protected: diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder_factory.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder_factory.h new file mode 100644 index 00000000000..12b97780918 --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder_factory.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 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_AUDIO_DECODER_FACTORY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_DECODER_FACTORY_H_ + +#include <memory> +#include <vector> + +#include "webrtc/modules/audio_coding/codecs/audio_decoder.h" +#include "webrtc/modules/audio_coding/codecs/audio_format.h" + +namespace webrtc { + +// A factory that creates AudioDecoders. +// NOTE: This class is still under development and may change without notice. +class AudioDecoderFactory { + public: + virtual ~AudioDecoderFactory() = default; + + virtual std::vector<SdpAudioFormat> GetSupportedFormats() = 0; + + virtual std::unique_ptr<AudioDecoder> MakeAudioDecoder( + const SdpAudioFormat& format) = 0; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_DECODER_FACTORY_H_ diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder_factory_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder_factory_unittest.cc new file mode 100644 index 00000000000..12a0a4047e8 --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_decoder_factory_unittest.cc @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2016 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 <memory> + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h" + +namespace webrtc { + +TEST(AudioDecoderFactoryTest, CreateUnknownDecoder) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("rey", 8000, 1))); +} + +TEST(AudioDecoderFactoryTest, CreatePcmu) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + // PCMu supports 8 kHz, and any number of channels. + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 0))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 1))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 2))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 3))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 16000, 1))); +} + +TEST(AudioDecoderFactoryTest, CreatePcma) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + // PCMa supports 8 kHz, and any number of channels. + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 0))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 1))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 2))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 3))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("pcma", 16000, 1))); +} + +TEST(AudioDecoderFactoryTest, CreateIlbc) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + // iLBC supports 8 kHz, 1 channel. + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 0))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 1))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 2))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 16000, 1))); + + // iLBC actually uses a 16 kHz sample rate instead of the nominal 8 kHz. + // TODO(kwiberg): Uncomment this once AudioDecoder has a SampleRateHz method. + // std::unique_ptr<AudioDecoder> dec = + // adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 1)); + // EXPECT_EQ(16000, dec->SampleRateHz()); +} + +TEST(AudioDecoderFactoryTest, CreateIsac) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + // iSAC supports 16 kHz, 1 channel. The float implementation additionally + // supports 32 kHz, 1 channel. + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("isac", 16000, 0))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("isac", 16000, 1))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("isac", 16000, 2))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("isac", 8000, 1))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("isac", 48000, 1))); +#ifdef WEBRTC_ARCH_ARM + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("isac", 32000, 1))); +#else + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("isac", 32000, 1))); +#endif +} + +TEST(AudioDecoderFactoryTest, CreateL16) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + // L16 supports any clock rate, any number of channels. + const int clockrates[] = {8000, 16000, 32000, 48000}; + const int num_channels[] = {1, 2, 3, 4711}; + for (int clockrate : clockrates) { + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("l16", clockrate, 0))); + for (int channels : num_channels) { + EXPECT_TRUE( + adf->MakeAudioDecoder(SdpAudioFormat("l16", clockrate, channels))); + } + } +} + +TEST(AudioDecoderFactoryTest, CreateG722) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + // g722 supports 8 kHz, 1-2 channels. + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 0))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 1))); + EXPECT_TRUE(adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 2))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 3))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("g722", 16000, 1))); + EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("g722", 32000, 1))); +} + +TEST(AudioDecoderFactoryTest, CreateOpus) { + std::unique_ptr<AudioDecoderFactory> adf = CreateBuiltinAudioDecoderFactory(); + ASSERT_TRUE(adf); + // Opus supports 48 kHz, 2 channels, and wants a "stereo" parameter whose + // value is either "0" or "1". + for (int hz : {8000, 16000, 32000, 48000}) { + for (int channels : {0, 1, 2, 3}) { + for (std::string stereo : {"XX", "0", "1", "2"}) { + std::map<std::string, std::string> params; + if (stereo != "XX") { + params["stereo"] = stereo; + } + bool good = + (hz == 48000 && channels == 2 && (stereo == "0" || stereo == "1")); + EXPECT_EQ(good, static_cast<bool>(adf->MakeAudioDecoder(SdpAudioFormat( + "opus", hz, channels, std::move(params))))); + } + } + } +} + +} // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.cc index 6f793e25314..6b7f5f893fd 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.cc @@ -16,8 +16,13 @@ namespace webrtc { AudioEncoder::EncodedInfo::EncodedInfo() = default; - +AudioEncoder::EncodedInfo::EncodedInfo(const EncodedInfo&) = default; +AudioEncoder::EncodedInfo::EncodedInfo(EncodedInfo&&) = default; AudioEncoder::EncodedInfo::~EncodedInfo() = default; +AudioEncoder::EncodedInfo& AudioEncoder::EncodedInfo::operator=( + const EncodedInfo&) = default; +AudioEncoder::EncodedInfo& AudioEncoder::EncodedInfo::operator=(EncodedInfo&&) = + default; int AudioEncoder::RtpTimestampRateHz() const { return SampleRateHz(); @@ -37,55 +42,6 @@ AudioEncoder::EncodedInfo AudioEncoder::Encode( return info; } -AudioEncoder::EncodedInfo AudioEncoder::Encode( - uint32_t rtp_timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_encoded_bytes, - uint8_t* encoded) { - return DEPRECATED_Encode(rtp_timestamp, audio, max_encoded_bytes, encoded); -} - -AudioEncoder::EncodedInfo AudioEncoder::DEPRECATED_Encode( - uint32_t rtp_timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_encoded_bytes, - uint8_t* encoded) { - TRACE_EVENT0("webrtc", "AudioEncoder::Encode"); - RTC_CHECK_EQ(audio.size(), - static_cast<size_t>(NumChannels() * SampleRateHz() / 100)); - EncodedInfo info = - EncodeInternal(rtp_timestamp, audio, max_encoded_bytes, encoded); - RTC_CHECK_LE(info.encoded_bytes, max_encoded_bytes); - return info; -} - -AudioEncoder::EncodedInfo AudioEncoder::EncodeImpl( - uint32_t rtp_timestamp, - rtc::ArrayView<const int16_t> audio, - rtc::Buffer* encoded) -{ - EncodedInfo info; - encoded->AppendData(MaxEncodedBytes(), [&] (rtc::ArrayView<uint8_t> encoded) { - info = EncodeInternal(rtp_timestamp, audio, - encoded.size(), encoded.data()); - return info.encoded_bytes; - }); - return info; -} - -AudioEncoder::EncodedInfo AudioEncoder::EncodeInternal( - uint32_t rtp_timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_encoded_bytes, - uint8_t* encoded) -{ - rtc::Buffer temp_buffer; - EncodedInfo info = EncodeImpl(rtp_timestamp, audio, &temp_buffer); - RTC_DCHECK_LE(temp_buffer.size(), max_encoded_bytes); - std::memcpy(encoded, temp_buffer.data(), info.encoded_bytes); - return info; -} - bool AudioEncoder::SetFec(bool enable) { return !enable; } @@ -104,4 +60,7 @@ void AudioEncoder::SetProjectedPacketLossRate(double fraction) {} void AudioEncoder::SetTargetBitrate(int target_bps) {} +rtc::ArrayView<std::unique_ptr<AudioEncoder>> +AudioEncoder::ReclaimContainedEncoders() { return nullptr; } + } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.h index 3fdee259ce7..ecc28d96a16 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder.h @@ -25,12 +25,32 @@ namespace webrtc { // type must have an implementation of this class. class AudioEncoder { public: + // Used for UMA logging of codec usage. The same codecs, with the + // same values, must be listed in + // src/tools/metrics/histograms/histograms.xml in chromium to log + // correct values. + enum class CodecType { + kOther = 0, // Codec not specified, and/or not listed in this enum + kOpus = 1, + kIsac = 2, + kPcmA = 3, + kPcmU = 4, + kG722 = 5, + kIlbc = 6, + + // Number of histogram bins in the UMA logging of codec types. The + // total number of different codecs that are logged cannot exceed this + // number. + kMaxLoggedAudioCodecTypes + }; + struct EncodedInfoLeaf { size_t encoded_bytes = 0; uint32_t encoded_timestamp = 0; int payload_type = 0; bool send_even_if_empty = false; bool speech = true; + CodecType encoder_type = CodecType::kOther; }; // This is the main struct for auxiliary encoding information. Each encoded @@ -45,21 +65,17 @@ class AudioEncoder { // vector. struct EncodedInfo : public EncodedInfoLeaf { EncodedInfo(); + EncodedInfo(const EncodedInfo&); + EncodedInfo(EncodedInfo&&); ~EncodedInfo(); + EncodedInfo& operator=(const EncodedInfo&); + EncodedInfo& operator=(EncodedInfo&&); std::vector<EncodedInfoLeaf> redundant; }; virtual ~AudioEncoder() = default; - // Returns the maximum number of bytes that can be produced by the encoder - // at each Encode() call. The caller can use the return value to determine - // the size of the buffer that needs to be allocated. This value is allowed - // to depend on encoder parameters like bitrate, frame size etc., so if - // any of these change, the caller of Encode() is responsible for checking - // that the buffer is large enough by calling MaxEncodedBytes() again. - virtual size_t MaxEncodedBytes() const = 0; - // Returns the input sample rate in Hz and the number of input channels. // These are constants set at instantiation time. virtual int SampleRateHz() const = 0; @@ -95,33 +111,6 @@ class AudioEncoder { rtc::ArrayView<const int16_t> audio, rtc::Buffer* encoded); - // Deprecated interface to Encode (remove eventually, bug 5591). May incur a - // copy. The encoder produces zero or more bytes of output in |encoded| and - // returns additional encoding information. The caller is responsible for - // making sure that |max_encoded_bytes| is not smaller than the number of - // bytes actually produced by the encoder. - RTC_DEPRECATED EncodedInfo Encode(uint32_t rtp_timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_encoded_bytes, - uint8_t* encoded); - - EncodedInfo DEPRECATED_Encode(uint32_t rtp_timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_encoded_bytes, - uint8_t* encoded); - - // Deprecated interface EncodeInternal (see bug 5591). May incur a copy. - // Subclasses implement this to perform the actual encoding. Called by - // Encode(). By default, this is implemented as a call to the newer - // EncodeImpl() that accepts an rtc::Buffer instead of a raw pointer. - // That version is protected, so see below. At least one of EncodeInternal - // or EncodeImpl _must_ be implemented by a subclass. - virtual EncodedInfo EncodeInternal( - uint32_t rtp_timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_encoded_bytes, - uint8_t* encoded); - // Resets the encoder to its starting state, discarding any input that has // been fed to the encoder but not yet emitted in a packet. virtual void Reset() = 0; @@ -160,15 +149,21 @@ class AudioEncoder { // implementation does the latter). virtual void SetTargetBitrate(int target_bps); + // Causes this encoder to let go of any other encoders it contains, and + // returns a pointer to an array where they are stored (which is required to + // live as long as this encoder). Unless the returned array is empty, you may + // not call any methods on this encoder afterwards, except for the + // destructor. The default implementation just returns an empty array. + // NOTE: This method is subject to change. Do not call or override it. + virtual rtc::ArrayView<std::unique_ptr<AudioEncoder>> + ReclaimContainedEncoders(); + protected: // Subclasses implement this to perform the actual encoding. Called by - // Encode(). For compatibility reasons, this is implemented by default as a - // call to the older interface EncodeInternal(). At least one of - // EncodeInternal or EncodeImpl _must_ be implemented by a - // subclass. Preferably this one. + // Encode(). virtual EncodedInfo EncodeImpl(uint32_t rtp_timestamp, rtc::ArrayView<const int16_t> audio, - rtc::Buffer* encoded); + rtc::Buffer* encoded) = 0; }; } // namespace webrtc #endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_ENCODER_H_ diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder_unittest.cc deleted file mode 100644 index 71ffcde323b..00000000000 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_encoder_unittest.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016 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 "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" - -using ::testing::_; -using ::testing::Invoke; -using ::testing::Return; - -namespace webrtc { - -TEST(AudioEncoderTest, EncodeInternalRedirectsOk) { - const size_t kPayloadSize = 16; - const uint8_t payload[kPayloadSize] = - {0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, - 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0}; - - MockAudioEncoderDeprecated old_impl; - MockAudioEncoder new_impl; - MockAudioEncoderBase* impls[] = { &old_impl, &new_impl }; - for (auto* impl : impls) { - EXPECT_CALL(*impl, Die()); - EXPECT_CALL(*impl, MaxEncodedBytes()) - .WillRepeatedly(Return(kPayloadSize * 2)); - EXPECT_CALL(*impl, NumChannels()).WillRepeatedly(Return(1)); - EXPECT_CALL(*impl, SampleRateHz()).WillRepeatedly(Return(8000)); - } - - EXPECT_CALL(old_impl, EncodeInternal(_, _, _, _)).WillOnce( - Invoke(MockAudioEncoderDeprecated::CopyEncoding(payload))); - - EXPECT_CALL(new_impl, EncodeImpl(_, _, _)).WillOnce( - Invoke(MockAudioEncoder::CopyEncoding(payload))); - - int16_t audio[80]; - uint8_t output_array[kPayloadSize * 2]; - rtc::Buffer output_buffer; - - AudioEncoder* old_encoder = &old_impl; - AudioEncoder* new_encoder = &new_impl; - auto old_info = old_encoder->Encode(0, audio, &output_buffer); - auto new_info = new_encoder->DEPRECATED_Encode(0, audio, - kPayloadSize * 2, - output_array); - - EXPECT_EQ(old_info.encoded_bytes, kPayloadSize); - EXPECT_EQ(new_info.encoded_bytes, kPayloadSize); - EXPECT_EQ(output_buffer.size(), kPayloadSize); - - for (size_t i = 0; i != kPayloadSize; ++i) { - EXPECT_EQ(output_buffer.data()[i], payload[i]); - EXPECT_EQ(output_array[i], payload[i]); - } -} - -} // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_format.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_format.cc new file mode 100644 index 00000000000..bb69cbdb2f7 --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_format.cc @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 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/audio_format.h" + +namespace webrtc { + +SdpAudioFormat::SdpAudioFormat() = default; +SdpAudioFormat::SdpAudioFormat(const SdpAudioFormat&) = default; +SdpAudioFormat::SdpAudioFormat(SdpAudioFormat&&) = default; + +SdpAudioFormat::SdpAudioFormat(const char* name, + int clockrate_hz, + int num_channels) + : name(name), clockrate_hz(clockrate_hz), num_channels(num_channels) {} + +SdpAudioFormat::SdpAudioFormat(const char* name, + int clockrate_hz, + int num_channels, + Parameters&& param) + : name(name), + clockrate_hz(clockrate_hz), + num_channels(num_channels), + parameters(std::move(param)) {} + +SdpAudioFormat::~SdpAudioFormat() = default; +SdpAudioFormat& SdpAudioFormat::operator=(const SdpAudioFormat&) = default; +SdpAudioFormat& SdpAudioFormat::operator=(SdpAudioFormat&&) = default; + +void swap(SdpAudioFormat& a, SdpAudioFormat& b) { + using std::swap; + swap(a.name, b.name); + swap(a.clockrate_hz, b.clockrate_hz); + swap(a.num_channels, b.num_channels); + swap(a.parameters, b.parameters); +} + +std::ostream& operator<<(std::ostream& os, const SdpAudioFormat& saf) { + os << "{name: " << saf.name; + os << ", clockrate_hz: " << saf.clockrate_hz; + os << ", num_channels: " << saf.num_channels; + os << ", parameters: {"; + const char* sep = ""; + for (const auto& kv : saf.parameters) { + os << sep << kv.first << ": " << kv.second; + sep = ", "; + } + os << "}}"; + return os; +} + +} // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_format.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_format.h new file mode 100644 index 00000000000..61c0dd9f6fa --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/audio_format.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016 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_AUDIO_FORMAT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_FORMAT_H_ + +#include <map> +#include <ostream> +#include <string> +#include <utility> + +namespace webrtc { + +// SDP specification for a single audio codec. +// NOTE: This class is still under development and may change without notice. +struct SdpAudioFormat { + using Parameters = std::map<std::string, std::string>; + + // TODO(kwiberg): Get rid of the default constructor when rtc::Optional no + // longer requires it. + SdpAudioFormat(); + SdpAudioFormat(const SdpAudioFormat&); + SdpAudioFormat(SdpAudioFormat&&); + SdpAudioFormat(const char* name, int clockrate_hz, int num_channels); + SdpAudioFormat(const char* name, + int clockrate_hz, + int num_channels, + Parameters&& param); + ~SdpAudioFormat(); + + SdpAudioFormat& operator=(const SdpAudioFormat&); + SdpAudioFormat& operator=(SdpAudioFormat&&); + + std::string name; + int clockrate_hz; + int num_channels; + Parameters parameters; + // Parameters feedback_parameters; ?? +}; + +void swap(SdpAudioFormat& a, SdpAudioFormat& b); +std::ostream& operator<<(std::ostream& os, const SdpAudioFormat& saf); + +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_FORMAT_H_ diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.cc new file mode 100644 index 00000000000..4c7445672ac --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.cc @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2016 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/builtin_audio_decoder_factory.h" + +#include <vector> + +#include "webrtc/base/checks.h" +#include "webrtc/base/optional.h" +#include "webrtc/common_types.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h" +#ifdef WEBRTC_CODEC_G722 +#include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h" +#endif +#ifdef WEBRTC_CODEC_ILBC +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h" +#endif +#ifdef WEBRTC_CODEC_ISACFX +#include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h" +#endif +#ifdef WEBRTC_CODEC_ISAC +#include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h" +#endif +#ifdef WEBRTC_CODEC_OPUS +#include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" +#endif +#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" + +namespace webrtc { + +namespace { + +struct NamedDecoderConstructor { + const char* name; + std::unique_ptr<AudioDecoder> (*constructor)(const SdpAudioFormat&); +}; + +std::unique_ptr<AudioDecoder> Unique(AudioDecoder* d) { + return std::unique_ptr<AudioDecoder>(d); +} + +// TODO(kwiberg): These factory functions should probably be moved to each +// decoder. +NamedDecoderConstructor decoder_constructors[] = { + {"pcmu", + [](const SdpAudioFormat& format) { + return format.clockrate_hz == 8000 && format.num_channels >= 1 + ? Unique(new AudioDecoderPcmU(format.num_channels)) + : nullptr; + }}, + {"pcma", + [](const SdpAudioFormat& format) { + return format.clockrate_hz == 8000 && format.num_channels >= 1 + ? Unique(new AudioDecoderPcmA(format.num_channels)) + : nullptr; + }}, +#ifdef WEBRTC_CODEC_ILBC + {"ilbc", + [](const SdpAudioFormat& format) { + return format.clockrate_hz == 8000 && format.num_channels == 1 + ? Unique(new AudioDecoderIlbc) + : nullptr; + }}, +#endif +#if defined(WEBRTC_CODEC_ISACFX) + {"isac", + [](const SdpAudioFormat& format) { + return format.clockrate_hz == 16000 && format.num_channels == 1 + ? Unique(new AudioDecoderIsacFix) + : nullptr; + }}, +#elif defined(WEBRTC_CODEC_ISAC) + {"isac", + [](const SdpAudioFormat& format) { + return (format.clockrate_hz == 16000 || format.clockrate_hz == 32000) && + format.num_channels == 1 + ? Unique(new AudioDecoderIsac) + : nullptr; + }}, +#endif + {"l16", + [](const SdpAudioFormat& format) { + return format.num_channels >= 1 + ? Unique(new AudioDecoderPcm16B(format.num_channels)) + : nullptr; + }}, +#ifdef WEBRTC_CODEC_G722 + {"g722", + [](const SdpAudioFormat& format) { + if (format.clockrate_hz == 8000) { + if (format.num_channels == 1) + return Unique(new AudioDecoderG722); + if (format.num_channels == 2) + return Unique(new AudioDecoderG722Stereo); + } + return Unique(nullptr); + }}, +#endif +#ifdef WEBRTC_CODEC_OPUS + {"opus", + [](const SdpAudioFormat& format) { + rtc::Optional<int> num_channels = [&] { + auto stereo = format.parameters.find("stereo"); + if (stereo != format.parameters.end()) { + if (stereo->second == "0") { + return rtc::Optional<int>(1); + } else if (stereo->second == "1") { + return rtc::Optional<int>(2); + } + } + return rtc::Optional<int>(); + }(); + return format.clockrate_hz == 48000 && format.num_channels == 2 && + num_channels + ? Unique(new AudioDecoderOpus(*num_channels)) + : nullptr; + }}, +#endif +}; + +class BuiltinAudioDecoderFactory : public AudioDecoderFactory { + public: + std::vector<SdpAudioFormat> GetSupportedFormats() override { + FATAL() << "Not implemented yet!"; + } + + std::unique_ptr<AudioDecoder> MakeAudioDecoder( + const SdpAudioFormat& format) override { + for (const auto& dc : decoder_constructors) { + if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) { + return std::unique_ptr<AudioDecoder>(dc.constructor(format)); + } + } + return nullptr; + } +}; + +} // namespace + +std::unique_ptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() { + return std::unique_ptr<AudioDecoderFactory>(new BuiltinAudioDecoderFactory); +} + +} // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h new file mode 100644 index 00000000000..7234c160b5c --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 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_BUILTIN_AUDIO_DECODER_FACTORY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_ + +#include <memory> + +#include "webrtc/modules/audio_coding/codecs/audio_decoder_factory.h" + +namespace webrtc { + +// Creates a new factory that can create the built-in types of audio decoders. +// NOTE: This function is still under development and may change without notice. +std::unique_ptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory(); + +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_ diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc index 3b48131a754..d2edcb5c265 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc @@ -21,33 +21,10 @@ namespace { const int kMaxFrameSizeMs = 60; -std::unique_ptr<CNG_enc_inst, CngInstDeleter> CreateCngInst( - int sample_rate_hz, - int sid_frame_interval_ms, - int num_cng_coefficients) { - CNG_enc_inst* ci; - RTC_CHECK_EQ(0, WebRtcCng_CreateEnc(&ci)); - std::unique_ptr<CNG_enc_inst, CngInstDeleter> cng_inst(ci); - RTC_CHECK_EQ(0, - WebRtcCng_InitEnc(cng_inst.get(), sample_rate_hz, - sid_frame_interval_ms, num_cng_coefficients)); - return cng_inst; -} - } // namespace AudioEncoderCng::Config::Config() = default; - -// TODO(kwiberg): =default this when Visual Studio learns to handle it. -AudioEncoderCng::Config::Config(Config&& c) - : num_channels(c.num_channels), - payload_type(c.payload_type), - speech_encoder(std::move(c.speech_encoder)), - vad_mode(c.vad_mode), - sid_frame_interval_ms(c.sid_frame_interval_ms), - num_cng_coefficients(c.num_cng_coefficients), - vad(c.vad) {} - +AudioEncoderCng::Config::Config(Config&&) = default; AudioEncoderCng::Config::~Config() = default; bool AudioEncoderCng::Config::IsOk() const { @@ -75,20 +52,14 @@ AudioEncoderCng::AudioEncoderCng(Config&& config) sid_frame_interval_ms_(config.sid_frame_interval_ms), last_frame_active_(true), vad_(config.vad ? std::unique_ptr<Vad>(config.vad) - : CreateVad(config.vad_mode)) { - cng_inst_ = CreateCngInst(SampleRateHz(), sid_frame_interval_ms_, - num_cng_coefficients_); + : CreateVad(config.vad_mode)), + cng_encoder_(new ComfortNoiseEncoder(SampleRateHz(), + sid_frame_interval_ms_, + num_cng_coefficients_)) { } AudioEncoderCng::~AudioEncoderCng() = default; -size_t AudioEncoderCng::MaxEncodedBytes() const { - const size_t max_encoded_bytes_active = speech_encoder_->MaxEncodedBytes(); - const size_t max_encoded_bytes_passive = - rtc::CheckedDivExact(kMaxFrameSizeMs, 10) * SamplesPer10msFrame(); - return std::max(max_encoded_bytes_active, max_encoded_bytes_passive); -} - int AudioEncoderCng::SampleRateHz() const { return speech_encoder_->SampleRateHz(); } @@ -187,8 +158,9 @@ void AudioEncoderCng::Reset() { rtp_timestamps_.clear(); last_frame_active_ = true; vad_->Reset(); - cng_inst_ = CreateCngInst(SampleRateHz(), sid_frame_interval_ms_, - num_cng_coefficients_); + cng_encoder_.reset( + new ComfortNoiseEncoder(SampleRateHz(), sid_frame_interval_ms_, + num_cng_coefficients_)); } bool AudioEncoderCng::SetFec(bool enable) { @@ -215,38 +187,38 @@ void AudioEncoderCng::SetTargetBitrate(int bits_per_second) { speech_encoder_->SetTargetBitrate(bits_per_second); } +rtc::ArrayView<std::unique_ptr<AudioEncoder>> +AudioEncoderCng::ReclaimContainedEncoders() { + return rtc::ArrayView<std::unique_ptr<AudioEncoder>>(&speech_encoder_, 1); +} + AudioEncoder::EncodedInfo AudioEncoderCng::EncodePassive( size_t frames_to_encode, rtc::Buffer* encoded) { bool force_sid = last_frame_active_; bool output_produced = false; const size_t samples_per_10ms_frame = SamplesPer10msFrame(); - const size_t bytes_to_encode = frames_to_encode * samples_per_10ms_frame; AudioEncoder::EncodedInfo info; - encoded->AppendData(bytes_to_encode, [&] (rtc::ArrayView<uint8_t> encoded) { - for (size_t i = 0; i < frames_to_encode; ++i) { - // It's important not to pass &info.encoded_bytes directly to - // WebRtcCng_Encode(), since later loop iterations may return zero in - // that value, in which case we don't want to overwrite any value from - // an earlier iteration. - size_t encoded_bytes_tmp = 0; - RTC_CHECK_GE( - WebRtcCng_Encode(cng_inst_.get(), - &speech_buffer_[i * samples_per_10ms_frame], - samples_per_10ms_frame, encoded.data(), - &encoded_bytes_tmp, force_sid), - 0); - if (encoded_bytes_tmp > 0) { - RTC_CHECK(!output_produced); - info.encoded_bytes = encoded_bytes_tmp; - output_produced = true; - force_sid = false; - } - } - - return info.encoded_bytes; - }); + for (size_t i = 0; i < frames_to_encode; ++i) { + // It's important not to pass &info.encoded_bytes directly to + // WebRtcCng_Encode(), since later loop iterations may return zero in + // that value, in which case we don't want to overwrite any value from + // an earlier iteration. + size_t encoded_bytes_tmp = + cng_encoder_->Encode( + rtc::ArrayView<const int16_t>( + &speech_buffer_[i * samples_per_10ms_frame], + samples_per_10ms_frame), + force_sid, encoded); + + if (encoded_bytes_tmp > 0) { + RTC_CHECK(!output_produced); + info.encoded_bytes = encoded_bytes_tmp; + output_produced = true; + force_sid = false; + } + } info.encoded_timestamp = rtp_timestamps_.front(); info.payload_type = cng_payload_type_; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h index 1384cd511ee..a895e69de44 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h @@ -21,11 +21,6 @@ namespace webrtc { -// Deleter for use with unique_ptr. -struct CngInstDeleter { - void operator()(CNG_enc_inst* ptr) const { WebRtcCng_FreeEnc(ptr); } -}; - class Vad; class AudioEncoderCng final : public AudioEncoder { @@ -52,7 +47,6 @@ class AudioEncoderCng final : public AudioEncoder { explicit AudioEncoderCng(Config&& config); ~AudioEncoderCng() override; - size_t MaxEncodedBytes() const override; int SampleRateHz() const override; size_t NumChannels() const override; int RtpTimestampRateHz() const override; @@ -69,6 +63,8 @@ class AudioEncoderCng final : public AudioEncoder { void SetMaxPlaybackRate(int frequency_hz) override; void SetProjectedPacketLossRate(double fraction) override; void SetTargetBitrate(int target_bps) override; + rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders() + override; private: EncodedInfo EncodePassive(size_t frames_to_encode, @@ -85,7 +81,7 @@ class AudioEncoderCng final : public AudioEncoder { std::vector<uint32_t> rtp_timestamps_; bool last_frame_active_; std::unique_ptr<Vad> vad_; - std::unique_ptr<CNG_enc_inst, CngInstDeleter> cng_inst_; + std::unique_ptr<ComfortNoiseEncoder> cng_encoder_; RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderCng); }; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc index 8f30d783ae4..eb6c6d3607e 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc @@ -12,6 +12,7 @@ #include <vector> #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/constructormagic.h" #include "webrtc/common_audio/vad/mock/mock_vad.h" #include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h" #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" @@ -25,7 +26,6 @@ using ::testing::Invoke; namespace webrtc { namespace { -static const size_t kMockMaxEncodedBytes = 1000; static const size_t kMaxNumSamples = 48 * 10 * 2; // 10 ms @ 48 kHz stereo. static const size_t kMockReturnEncodedBytes = 17; static const int kCngPayloadType = 18; @@ -74,8 +74,6 @@ class AudioEncoderCngTest : public ::testing::Test { // as long as it is smaller than 10. EXPECT_CALL(*mock_encoder_, Max10MsFramesInAPacket()) .WillOnce(Return(1u)); - EXPECT_CALL(*mock_encoder_, MaxEncodedBytes()) - .WillRepeatedly(Return(kMockMaxEncodedBytes)); } cng_.reset(new AudioEncoderCng(std::move(config))); } @@ -90,8 +88,8 @@ class AudioEncoderCngTest : public ::testing::Test { } // Expect |num_calls| calls to the encoder, all successful. The last call - // claims to have encoded |kMockMaxEncodedBytes| bytes, and all the preceding - // ones 0 bytes. + // claims to have encoded |kMockReturnEncodedBytes| bytes, and all the + // preceding ones 0 bytes. void ExpectEncodeCalls(size_t num_calls) { InSequence s; AudioEncoder::EncodedInfo info; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng.gypi b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng.gypi index c020f4740d4..bbff9f8edfe 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng.gypi +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng.gypi @@ -18,9 +18,7 @@ 'sources': [ 'audio_encoder_cng.cc', 'audio_encoder_cng.h', - 'cng_helpfuns.c', - 'cng_helpfuns.h', - 'webrtc_cng.c', + 'webrtc_cng.cc', 'webrtc_cng.h', ], }, diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.c deleted file mode 100644 index bc08d431a69..00000000000 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011 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 "cng_helpfuns.h" - -#include "signal_processing_library.h" -#include "webrtc/typedefs.h" -#include "webrtc_cng.h" - -/* Values in |k| are Q15, and |a| Q12. */ -void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a) { - int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1]; - int16_t *aptr, *aptr2, *anyptr; - const int16_t *kptr; - int m, i; - - kptr = k; - *a = 4096; /* i.e., (Word16_MAX >> 3) + 1 */ - *any = *a; - a[1] = (*k + 4) >> 3; - for (m = 1; m < useOrder; m++) { - kptr++; - aptr = a; - aptr++; - aptr2 = &a[m]; - anyptr = any; - anyptr++; - - any[m + 1] = (*kptr + 4) >> 3; - for (i = 0; i < m; i++) { - *anyptr++ = (*aptr++) + - (int16_t)((((int32_t)(*aptr2--) * (int32_t) * kptr) + 16384) >> 15); - } - - aptr = a; - anyptr = any; - for (i = 0; i < (m + 2); i++) { - *aptr++ = *anyptr++; - } - } -} diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.h deleted file mode 100644 index a553a7615e6..00000000000 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2011 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_CNG_CNG_HELPFUNS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_CNG_HELPFUNS_H_ - -#include "webrtc/typedefs.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a); - -#ifdef __cplusplus -} -#endif - -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_CNG_HELPFUNS_H_ diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_unittest.cc index 1061dca69ac..95132a96178 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_unittest.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/cng_unittest.cc @@ -7,11 +7,12 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ +#include <memory> #include <string> #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/test/testsupport/fileutils.h" -#include "webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" namespace webrtc { @@ -21,7 +22,7 @@ enum { kSidLongIntervalUpdate = 10000 }; -enum { +enum : size_t { kCNGNumParamsLow = 0, kCNGNumParamsNormal = 8, kCNGNumParamsHigh = WEBRTC_CNG_MAX_LPC_ORDER, @@ -35,19 +36,13 @@ enum { class CngTest : public ::testing::Test { protected: - CngTest(); virtual void SetUp(); - CNG_enc_inst* cng_enc_inst_; - CNG_dec_inst* cng_dec_inst_; + void TestCngEncode(int sample_rate_hz, int quality); + int16_t speech_data_[640]; // Max size of CNG internal buffers. }; -CngTest::CngTest() - : cng_enc_inst_(NULL), - cng_dec_inst_(NULL) { -} - void CngTest::SetUp() { FILE* input_file; const std::string file_name = @@ -60,289 +55,187 @@ void CngTest::SetUp() { input_file = NULL; } -// Test failing Create. -TEST_F(CngTest, CngCreateFail) { - // Test to see that an invalid pointer is caught. - EXPECT_EQ(-1, WebRtcCng_CreateEnc(NULL)); - EXPECT_EQ(-1, WebRtcCng_CreateDec(NULL)); -} - -// Test normal Create. -TEST_F(CngTest, CngCreate) { - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); - EXPECT_TRUE(cng_enc_inst_ != NULL); - EXPECT_TRUE(cng_dec_inst_ != NULL); - // Free encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); +void CngTest::TestCngEncode(int sample_rate_hz, int quality) { + const size_t num_samples_10ms = rtc::CheckedDivExact(sample_rate_hz, 100); + rtc::Buffer sid_data; + + ComfortNoiseEncoder cng_encoder(sample_rate_hz, kSidNormalIntervalUpdate, + quality); + EXPECT_EQ(0U, cng_encoder.Encode(rtc::ArrayView<const int16_t>( + speech_data_, num_samples_10ms), + kNoSid, &sid_data)); + EXPECT_EQ(static_cast<size_t>(quality + 1), + cng_encoder.Encode( + rtc::ArrayView<const int16_t>(speech_data_, num_samples_10ms), + kForceSid, &sid_data)); } +#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) // Create CNG encoder, init with faulty values, free CNG encoder. TEST_F(CngTest, CngInitFail) { - // Create encoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - // Call with too few parameters. - EXPECT_EQ(-1, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, - kCNGNumParamsLow)); - EXPECT_EQ(6130, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); - + EXPECT_DEATH({ ComfortNoiseEncoder(8000, kSidNormalIntervalUpdate, + kCNGNumParamsLow); }, ""); // Call with too many parameters. - EXPECT_EQ(-1, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, - kCNGNumParamsTooHigh)); - EXPECT_EQ(6130, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); - - // Free encoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); -} - -TEST_F(CngTest, CngEncode) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - size_t number_bytes; - - // Create encoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - - // 8 kHz, Normal number of parameters - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 80, sid_data, - &number_bytes, kNoSid)); - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 80, sid_data, &number_bytes, kForceSid)); - - // 16 kHz, Normal number of parameters - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, - &number_bytes, kNoSid)); - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); - - // 32 kHz, Max number of parameters - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 32000, kSidNormalIntervalUpdate, - kCNGNumParamsHigh)); - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 320, sid_data, - &number_bytes, kNoSid)); - EXPECT_EQ(kCNGNumParamsHigh + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 320, sid_data, &number_bytes, kForceSid)); - - // 48 kHz, Normal number of parameters - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 48000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 480, sid_data, - &number_bytes, kNoSid)); - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 480, sid_data, &number_bytes, kForceSid)); - - // 64 kHz, Normal number of parameters - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 64000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 640, sid_data, - &number_bytes, kNoSid)); - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 640, sid_data, &number_bytes, kForceSid)); - - // Free encoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); + EXPECT_DEATH({ ComfortNoiseEncoder(8000, kSidNormalIntervalUpdate, + kCNGNumParamsTooHigh); }, ""); } // Encode Cng with too long input vector. TEST_F(CngTest, CngEncodeTooLong) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - size_t number_bytes; - - // Create and init encoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); + rtc::Buffer sid_data; + // Create encoder. + ComfortNoiseEncoder cng_encoder(8000, kSidNormalIntervalUpdate, + kCNGNumParamsNormal); // Run encoder with too much data. - EXPECT_EQ(-1, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 641, sid_data, - &number_bytes, kNoSid)); - EXPECT_EQ(6140, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); + EXPECT_DEATH( + cng_encoder.Encode(rtc::ArrayView<const int16_t>(speech_data_, 641), + kNoSid, &sid_data), + ""); +} +#endif // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) - // Free encoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); +TEST_F(CngTest, CngEncode8000) { + TestCngEncode(8000, kCNGNumParamsNormal); } -// Call encode without calling init. -TEST_F(CngTest, CngEncodeNoInit) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - size_t number_bytes; +TEST_F(CngTest, CngEncode16000) { + TestCngEncode(16000, kCNGNumParamsNormal); +} - // Create encoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); +TEST_F(CngTest, CngEncode32000) { + TestCngEncode(32000, kCNGNumParamsHigh); +} - // Run encoder without calling init. - EXPECT_EQ(-1, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 640, sid_data, - &number_bytes, kNoSid)); - EXPECT_EQ(6120, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); +TEST_F(CngTest, CngEncode48000) { + TestCngEncode(48000, kCNGNumParamsNormal); +} - // Free encoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); +TEST_F(CngTest, CngEncode64000) { + TestCngEncode(64000, kCNGNumParamsNormal); } // Update SID parameters, for both 9 and 16 parameters. TEST_F(CngTest, CngUpdateSid) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - size_t number_bytes; + rtc::Buffer sid_data; - // Create and initialize encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - WebRtcCng_InitDec(cng_dec_inst_); + // Create and initialize encoder and decoder. + ComfortNoiseEncoder cng_encoder(16000, kSidNormalIntervalUpdate, + kCNGNumParamsNormal); + ComfortNoiseDecoder cng_decoder; // Run normal Encode and UpdateSid. - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); - EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, - kCNGNumParamsNormal + 1)); + EXPECT_EQ(kCNGNumParamsNormal + 1, + cng_encoder.Encode(rtc::ArrayView<const int16_t>(speech_data_, 160), + kForceSid, &sid_data)); + cng_decoder.UpdateSid(sid_data); // Reinit with new length. - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, - kCNGNumParamsHigh)); - WebRtcCng_InitDec(cng_dec_inst_); + cng_encoder.Reset(16000, kSidNormalIntervalUpdate, kCNGNumParamsHigh); + cng_decoder.Reset(); // Expect 0 because of unstable parameters after switching length. - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, - &number_bytes, kForceSid)); - EXPECT_EQ(kCNGNumParamsHigh + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_ + 160, 160, sid_data, &number_bytes, - kForceSid)); - EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, - kCNGNumParamsNormal + 1)); - - // Free encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); + EXPECT_EQ(0U, + cng_encoder.Encode(rtc::ArrayView<const int16_t>(speech_data_, 160), + kForceSid, &sid_data)); + EXPECT_EQ( + kCNGNumParamsHigh + 1, + cng_encoder.Encode(rtc::ArrayView<const int16_t>(speech_data_ + 160, 160), + kForceSid, &sid_data)); + cng_decoder.UpdateSid( + rtc::ArrayView<const uint8_t>(sid_data.data(), kCNGNumParamsNormal + 1)); } // Update SID parameters, with wrong parameters or without calling decode. TEST_F(CngTest, CngUpdateSidErroneous) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - size_t number_bytes; - - // Create encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); + rtc::Buffer sid_data; // Encode. - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); - - // Update Sid before initializing decoder. - EXPECT_EQ(-1, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, - kCNGNumParamsNormal + 1)); - EXPECT_EQ(6220, WebRtcCng_GetErrorCodeDec(cng_dec_inst_)); - - // Initialize decoder. - WebRtcCng_InitDec(cng_dec_inst_); + ComfortNoiseEncoder cng_encoder(16000, kSidNormalIntervalUpdate, + kCNGNumParamsNormal); + ComfortNoiseDecoder cng_decoder; + EXPECT_EQ(kCNGNumParamsNormal + 1, + cng_encoder.Encode(rtc::ArrayView<const int16_t>(speech_data_, 160), + kForceSid, &sid_data)); // First run with valid parameters, then with too many CNG parameters. // The function will operate correctly by only reading the maximum number of // parameters, skipping the extra. - EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, - kCNGNumParamsNormal + 1)); - EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, - kCNGNumParamsTooHigh + 1)); - - // Free encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); + EXPECT_EQ(kCNGNumParamsNormal + 1, sid_data.size()); + cng_decoder.UpdateSid(sid_data); + + // Make sure the input buffer is large enough. Since Encode() appends data, we + // need to set the size manually only afterwards, or the buffer will be bigger + // than anticipated. + sid_data.SetSize(kCNGNumParamsTooHigh + 1); + cng_decoder.UpdateSid(sid_data); } // Test to generate cng data, by forcing SID. Both normal and faulty condition. TEST_F(CngTest, CngGenerate) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + rtc::Buffer sid_data; int16_t out_data[640]; - size_t number_bytes; - // Create and initialize encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - WebRtcCng_InitDec(cng_dec_inst_); + // Create and initialize encoder and decoder. + ComfortNoiseEncoder cng_encoder(16000, kSidNormalIntervalUpdate, + kCNGNumParamsNormal); + ComfortNoiseDecoder cng_decoder; // Normal Encode. - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); + EXPECT_EQ(kCNGNumParamsNormal + 1, + cng_encoder.Encode(rtc::ArrayView<const int16_t>(speech_data_, 160), + kForceSid, &sid_data)); // Normal UpdateSid. - EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, - kCNGNumParamsNormal + 1)); + cng_decoder.UpdateSid(sid_data); // Two normal Generate, one with new_period. - EXPECT_EQ(0, WebRtcCng_Generate(cng_dec_inst_, out_data, 640, 1)); - EXPECT_EQ(0, WebRtcCng_Generate(cng_dec_inst_, out_data, 640, 0)); + EXPECT_TRUE(cng_decoder.Generate(rtc::ArrayView<int16_t>(out_data, 640), 1)); + EXPECT_TRUE(cng_decoder.Generate(rtc::ArrayView<int16_t>(out_data, 640), 0)); // Call Genereate with too much data. - EXPECT_EQ(-1, WebRtcCng_Generate(cng_dec_inst_, out_data, 641, 0)); - EXPECT_EQ(6140, WebRtcCng_GetErrorCodeDec(cng_dec_inst_)); - - // Free encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); + EXPECT_FALSE(cng_decoder.Generate(rtc::ArrayView<int16_t>(out_data, 641), 0)); } // Test automatic SID. TEST_F(CngTest, CngAutoSid) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - size_t number_bytes; + rtc::Buffer sid_data; - // Create and initialize encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, - kCNGNumParamsNormal)); - WebRtcCng_InitDec(cng_dec_inst_); + // Create and initialize encoder and decoder. + ComfortNoiseEncoder cng_encoder(16000, kSidNormalIntervalUpdate, + kCNGNumParamsNormal); + ComfortNoiseDecoder cng_decoder; // Normal Encode, 100 msec, where no SID data should be generated. for (int i = 0; i < 10; i++) { - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, - &number_bytes, kNoSid)); + EXPECT_EQ(0U, cng_encoder.Encode( + rtc::ArrayView<const int16_t>(speech_data_, 160), kNoSid, &sid_data)); } // We have reached 100 msec, and SID data should be generated. - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kNoSid)); - - // Free encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); + EXPECT_EQ(kCNGNumParamsNormal + 1, cng_encoder.Encode( + rtc::ArrayView<const int16_t>(speech_data_, 160), kNoSid, &sid_data)); } // Test automatic SID, with very short interval. TEST_F(CngTest, CngAutoSidShort) { - uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - size_t number_bytes; + rtc::Buffer sid_data; - // Create and initialize encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); - EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidShortIntervalUpdate, - kCNGNumParamsNormal)); - WebRtcCng_InitDec(cng_dec_inst_); + // Create and initialize encoder and decoder. + ComfortNoiseEncoder cng_encoder(16000, kSidShortIntervalUpdate, + kCNGNumParamsNormal); + ComfortNoiseDecoder cng_decoder; // First call will never generate SID, unless forced to. - EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, - &number_bytes, kNoSid)); + EXPECT_EQ(0U, cng_encoder.Encode( + rtc::ArrayView<const int16_t>(speech_data_, 160), kNoSid, &sid_data)); // Normal Encode, 100 msec, SID data should be generated all the time. for (int i = 0; i < 10; i++) { - EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( - cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kNoSid)); + EXPECT_EQ(kCNGNumParamsNormal + 1, cng_encoder.Encode( + rtc::ArrayView<const int16_t>(speech_data_, 160), kNoSid, &sid_data)); } - - // Free encoder and decoder memory. - EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); - EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); } } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.c deleted file mode 100644 index 8dddc5c717d..00000000000 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (c) 2012 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_cng.h" - -#include <string.h> -#include <stdlib.h> - -#include "cng_helpfuns.h" -#include "signal_processing_library.h" - -typedef struct WebRtcCngDecoder_ { - uint32_t dec_seed; - int32_t dec_target_energy; - int32_t dec_used_energy; - int16_t dec_target_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t dec_used_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t dec_filtstate[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t dec_filtstateLow[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t dec_Efiltstate[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t dec_EfiltstateLow[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t dec_order; - int16_t dec_target_scale_factor; /* Q29 */ - int16_t dec_used_scale_factor; /* Q29 */ - int16_t target_scale_factor; /* Q13 */ - int16_t errorcode; - int16_t initflag; -} WebRtcCngDecoder; - -typedef struct WebRtcCngEncoder_ { - size_t enc_nrOfCoefs; - int enc_sampfreq; - int16_t enc_interval; - int16_t enc_msSinceSID; - int32_t enc_Energy; - int16_t enc_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int32_t enc_corrVector[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - uint32_t enc_seed; - int16_t errorcode; - int16_t initflag; -} WebRtcCngEncoder; - -const int32_t WebRtcCng_kDbov[94] = { - 1081109975, 858756178, 682134279, 541838517, 430397633, 341876992, - 271562548, 215709799, 171344384, 136103682, 108110997, 85875618, - 68213428, 54183852, 43039763, 34187699, 27156255, 21570980, - 17134438, 13610368, 10811100, 8587562, 6821343, 5418385, - 4303976, 3418770, 2715625, 2157098, 1713444, 1361037, - 1081110, 858756, 682134, 541839, 430398, 341877, - 271563, 215710, 171344, 136104, 108111, 85876, - 68213, 54184, 43040, 34188, 27156, 21571, - 17134, 13610, 10811, 8588, 6821, 5418, - 4304, 3419, 2716, 2157, 1713, 1361, - 1081, 859, 682, 542, 430, 342, - 272, 216, 171, 136, 108, 86, - 68, 54, 43, 34, 27, 22, - 17, 14, 11, 9, 7, 5, - 4, 3, 3, 2, 2, 1, - 1, 1, 1, 1 -}; - -const int16_t WebRtcCng_kCorrWindow[WEBRTC_CNG_MAX_LPC_ORDER] = { - 32702, 32636, 32570, 32505, 32439, 32374, - 32309, 32244, 32179, 32114, 32049, 31985 -}; - -/**************************************************************************** - * WebRtcCng_CreateEnc/Dec(...) - * - * These functions create an instance to the specified structure - * - * Input: - * - XXX_inst : Pointer to created instance that should be created - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_CreateEnc(CNG_enc_inst** cng_inst) { - if (cng_inst != NULL) { - *cng_inst = (CNG_enc_inst*) malloc(sizeof(WebRtcCngEncoder)); - if (*cng_inst != NULL) { - (*(WebRtcCngEncoder**) cng_inst)->errorcode = 0; - (*(WebRtcCngEncoder**) cng_inst)->initflag = 0; - - /* Needed to get the right function pointers in SPLIB. */ - WebRtcSpl_Init(); - - return 0; - } else { - /* The memory could not be allocated. */ - return -1; - } - } else { - /* The input pointer is invalid (NULL). */ - return -1; - } -} - -int16_t WebRtcCng_CreateDec(CNG_dec_inst** cng_inst) { - if (cng_inst != NULL ) { - *cng_inst = (CNG_dec_inst*) malloc(sizeof(WebRtcCngDecoder)); - if (*cng_inst != NULL ) { - (*(WebRtcCngDecoder**) cng_inst)->errorcode = 0; - (*(WebRtcCngDecoder**) cng_inst)->initflag = 0; - - /* Needed to get the right function pointers in SPLIB. */ - WebRtcSpl_Init(); - - return 0; - } else { - /* The memory could not be allocated */ - return -1; - } - } else { - /* The input pointer is invalid (NULL). */ - return -1; - } -} - -/**************************************************************************** - * WebRtcCng_InitEnc/Dec(...) - * - * This function initializes a instance - * - * Input: - * - cng_inst : Instance that should be initialized - * - * - fs : 8000 for narrowband and 16000 for wideband - * - interval : generate SID data every interval ms - * - quality : TBD - * - * Output: - * - cng_inst : Initialized instance - * - * Return value : 0 - Ok - * -1 - Error - */ -int WebRtcCng_InitEnc(CNG_enc_inst* cng_inst, int fs, int16_t interval, - int16_t quality) { - int i; - WebRtcCngEncoder* inst = (WebRtcCngEncoder*) cng_inst; - memset(inst, 0, sizeof(WebRtcCngEncoder)); - - /* Check LPC order */ - if (quality > WEBRTC_CNG_MAX_LPC_ORDER || quality <= 0) { - inst->errorcode = CNG_DISALLOWED_LPC_ORDER; - return -1; - } - - inst->enc_sampfreq = fs; - inst->enc_interval = interval; - inst->enc_nrOfCoefs = quality; - inst->enc_msSinceSID = 0; - inst->enc_seed = 7777; /* For debugging only. */ - inst->enc_Energy = 0; - for (i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER + 1); i++) { - inst->enc_reflCoefs[i] = 0; - inst->enc_corrVector[i] = 0; - } - inst->initflag = 1; - - return 0; -} - -void WebRtcCng_InitDec(CNG_dec_inst* cng_inst) { - int i; - - WebRtcCngDecoder* inst = (WebRtcCngDecoder*) cng_inst; - - memset(inst, 0, sizeof(WebRtcCngDecoder)); - inst->dec_seed = 7777; /* For debugging only. */ - inst->dec_order = 5; - inst->dec_target_scale_factor = 0; - inst->dec_used_scale_factor = 0; - for (i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER + 1); i++) { - inst->dec_filtstate[i] = 0; - inst->dec_target_reflCoefs[i] = 0; - inst->dec_used_reflCoefs[i] = 0; - } - inst->dec_target_reflCoefs[0] = 0; - inst->dec_used_reflCoefs[0] = 0; - inst->dec_used_energy = 0; - inst->initflag = 1; -} - -/**************************************************************************** - * WebRtcCng_FreeEnc/Dec(...) - * - * These functions frees the dynamic memory of a specified instance - * - * Input: - * - cng_inst : Pointer to created instance that should be freed - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_FreeEnc(CNG_enc_inst* cng_inst) { - free(cng_inst); - return 0; -} - -int16_t WebRtcCng_FreeDec(CNG_dec_inst* cng_inst) { - free(cng_inst); - return 0; -} - -/**************************************************************************** - * WebRtcCng_Encode(...) - * - * These functions analyzes background noise - * - * Input: - * - cng_inst : Pointer to created instance - * - speech : Signal (noise) to be analyzed - * - nrOfSamples : Size of speech vector - * - bytesOut : Nr of bytes to transmit, might be 0 - * - * Return value : 0 - Ok - * -1 - Error - */ -int WebRtcCng_Encode(CNG_enc_inst* cng_inst, int16_t* speech, - size_t nrOfSamples, uint8_t* SIDdata, - size_t* bytesOut, int16_t forceSID) { - WebRtcCngEncoder* inst = (WebRtcCngEncoder*) cng_inst; - - int16_t arCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int32_t corrVector[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t hanningW[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; - int16_t ReflBeta = 19661; /* 0.6 in q15. */ - int16_t ReflBetaComp = 13107; /* 0.4 in q15. */ - int32_t outEnergy; - int outShifts; - size_t i; - int stab; - int acorrScale; - size_t index; - size_t ind, factor; - int32_t* bptr; - int32_t blo, bhi; - int16_t negate; - const int16_t* aptr; - int16_t speechBuf[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; - - /* Check if encoder initiated. */ - if (inst->initflag != 1) { - inst->errorcode = CNG_ENCODER_NOT_INITIATED; - return -1; - } - - /* Check framesize. */ - if (nrOfSamples > WEBRTC_CNG_MAX_OUTSIZE_ORDER) { - inst->errorcode = CNG_DISALLOWED_FRAME_SIZE; - return -1; - } - - for (i = 0; i < nrOfSamples; i++) { - speechBuf[i] = speech[i]; - } - - factor = nrOfSamples; - - /* Calculate energy and a coefficients. */ - outEnergy = WebRtcSpl_Energy(speechBuf, nrOfSamples, &outShifts); - while (outShifts > 0) { - /* We can only do 5 shifts without destroying accuracy in - * division factor. */ - if (outShifts > 5) { - outEnergy <<= (outShifts - 5); - outShifts = 5; - } else { - factor /= 2; - outShifts--; - } - } - outEnergy = WebRtcSpl_DivW32W16(outEnergy, (int16_t)factor); - - if (outEnergy > 1) { - /* Create Hanning Window. */ - WebRtcSpl_GetHanningWindow(hanningW, nrOfSamples / 2); - for (i = 0; i < (nrOfSamples / 2); i++) - hanningW[nrOfSamples - i - 1] = hanningW[i]; - - WebRtcSpl_ElementwiseVectorMult(speechBuf, hanningW, speechBuf, nrOfSamples, - 14); - - WebRtcSpl_AutoCorrelation(speechBuf, nrOfSamples, inst->enc_nrOfCoefs, - corrVector, &acorrScale); - - if (*corrVector == 0) - *corrVector = WEBRTC_SPL_WORD16_MAX; - - /* Adds the bandwidth expansion. */ - aptr = WebRtcCng_kCorrWindow; - bptr = corrVector; - - /* (zzz) lpc16_1 = 17+1+820+2+2 = 842 (ordo2=700). */ - for (ind = 0; ind < inst->enc_nrOfCoefs; ind++) { - /* The below code multiplies the 16 b corrWindow values (Q15) with - * the 32 b corrvector (Q0) and shifts the result down 15 steps. */ - negate = *bptr < 0; - if (negate) - *bptr = -*bptr; - - blo = (int32_t) * aptr * (*bptr & 0xffff); - bhi = ((blo >> 16) & 0xffff) - + ((int32_t)(*aptr++) * ((*bptr >> 16) & 0xffff)); - blo = (blo & 0xffff) | ((bhi & 0xffff) << 16); - - *bptr = (((bhi >> 16) & 0x7fff) << 17) | ((uint32_t) blo >> 15); - if (negate) - *bptr = -*bptr; - bptr++; - } - /* End of bandwidth expansion. */ - - stab = WebRtcSpl_LevinsonDurbin(corrVector, arCoefs, refCs, - inst->enc_nrOfCoefs); - - if (!stab) { - /* Disregard from this frame */ - *bytesOut = 0; - return 0; - } - - } else { - for (i = 0; i < inst->enc_nrOfCoefs; i++) - refCs[i] = 0; - } - - if (forceSID) { - /* Read instantaneous values instead of averaged. */ - for (i = 0; i < inst->enc_nrOfCoefs; i++) - inst->enc_reflCoefs[i] = refCs[i]; - inst->enc_Energy = outEnergy; - } else { - /* Average history with new values. */ - for (i = 0; i < (inst->enc_nrOfCoefs); i++) { - inst->enc_reflCoefs[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( - inst->enc_reflCoefs[i], ReflBeta, 15); - inst->enc_reflCoefs[i] += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( - refCs[i], ReflBetaComp, 15); - } - inst->enc_Energy = (outEnergy >> 2) + (inst->enc_Energy >> 1) - + (inst->enc_Energy >> 2); - } - - if (inst->enc_Energy < 1) { - inst->enc_Energy = 1; - } - - if ((inst->enc_msSinceSID > (inst->enc_interval - 1)) || forceSID) { - - /* Search for best dbov value. */ - index = 0; - for (i = 1; i < 93; i++) { - /* Always round downwards. */ - if ((inst->enc_Energy - WebRtcCng_kDbov[i]) > 0) { - index = i; - break; - } - } - if ((i == 93) && (index == 0)) - index = 94; - SIDdata[0] = (uint8_t)index; - - /* Quantize coefficients with tweak for WebRtc implementation of RFC3389. */ - if (inst->enc_nrOfCoefs == WEBRTC_CNG_MAX_LPC_ORDER) { - for (i = 0; i < inst->enc_nrOfCoefs; i++) { - /* Q15 to Q7 with rounding. */ - SIDdata[i + 1] = ((inst->enc_reflCoefs[i] + 128) >> 8); - } - } else { - for (i = 0; i < inst->enc_nrOfCoefs; i++) { - /* Q15 to Q7 with rounding. */ - SIDdata[i + 1] = (127 + ((inst->enc_reflCoefs[i] + 128) >> 8)); - } - } - - inst->enc_msSinceSID = 0; - *bytesOut = inst->enc_nrOfCoefs + 1; - - inst->enc_msSinceSID += - (int16_t)((1000 * nrOfSamples) / inst->enc_sampfreq); - return (int)(inst->enc_nrOfCoefs + 1); - } else { - inst->enc_msSinceSID += - (int16_t)((1000 * nrOfSamples) / inst->enc_sampfreq); - *bytesOut = 0; - return 0; - } -} - -/**************************************************************************** - * WebRtcCng_UpdateSid(...) - * - * These functions updates the CN state, when a new SID packet arrives - * - * Input: - * - cng_inst : Pointer to created instance that should be freed - * - SID : SID packet, all headers removed - * - length : Length in bytes of SID packet - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_UpdateSid(CNG_dec_inst* cng_inst, uint8_t* SID, - size_t length) { - - WebRtcCngDecoder* inst = (WebRtcCngDecoder*) cng_inst; - int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER]; - int32_t targetEnergy; - int i; - - if (inst->initflag != 1) { - inst->errorcode = CNG_DECODER_NOT_INITIATED; - return -1; - } - - /* Throw away reflection coefficients of higher order than we can handle. */ - if (length > (WEBRTC_CNG_MAX_LPC_ORDER + 1)) - length = WEBRTC_CNG_MAX_LPC_ORDER + 1; - - inst->dec_order = (int16_t)length - 1; - - if (SID[0] > 93) - SID[0] = 93; - targetEnergy = WebRtcCng_kDbov[SID[0]]; - /* Take down target energy to 75%. */ - targetEnergy = targetEnergy >> 1; - targetEnergy += targetEnergy >> 2; - - inst->dec_target_energy = targetEnergy; - - /* Reconstruct coeffs with tweak for WebRtc implementation of RFC3389. */ - if (inst->dec_order == WEBRTC_CNG_MAX_LPC_ORDER) { - for (i = 0; i < (inst->dec_order); i++) { - refCs[i] = SID[i + 1] << 8; /* Q7 to Q15*/ - inst->dec_target_reflCoefs[i] = refCs[i]; - } - } else { - for (i = 0; i < (inst->dec_order); i++) { - refCs[i] = (SID[i + 1] - 127) << 8; /* Q7 to Q15. */ - inst->dec_target_reflCoefs[i] = refCs[i]; - } - } - - for (i = (inst->dec_order); i < WEBRTC_CNG_MAX_LPC_ORDER; i++) { - refCs[i] = 0; - inst->dec_target_reflCoefs[i] = refCs[i]; - } - - return 0; -} - -/**************************************************************************** - * WebRtcCng_Generate(...) - * - * These functions generates CN data when needed - * - * Input: - * - cng_inst : Pointer to created instance that should be freed - * - outData : pointer to area to write CN data - * - nrOfSamples : How much data to generate - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_Generate(CNG_dec_inst* cng_inst, int16_t* outData, - size_t nrOfSamples, int16_t new_period) { - WebRtcCngDecoder* inst = (WebRtcCngDecoder*) cng_inst; - - size_t i; - int16_t excitation[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; - int16_t low[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; - int16_t lpPoly[WEBRTC_CNG_MAX_LPC_ORDER + 1]; - int16_t ReflBetaStd = 26214; /* 0.8 in q15. */ - int16_t ReflBetaCompStd = 6553; /* 0.2 in q15. */ - int16_t ReflBetaNewP = 19661; /* 0.6 in q15. */ - int16_t ReflBetaCompNewP = 13107; /* 0.4 in q15. */ - int16_t Beta, BetaC, tmp1, tmp2, tmp3; - int32_t targetEnergy; - int16_t En; - int16_t temp16; - - if (nrOfSamples > WEBRTC_CNG_MAX_OUTSIZE_ORDER) { - inst->errorcode = CNG_DISALLOWED_FRAME_SIZE; - return -1; - } - - if (new_period) { - inst->dec_used_scale_factor = inst->dec_target_scale_factor; - Beta = ReflBetaNewP; - BetaC = ReflBetaCompNewP; - } else { - Beta = ReflBetaStd; - BetaC = ReflBetaCompStd; - } - - /* Here we use a 0.5 weighting, should possibly be modified to 0.6. */ - tmp1 = inst->dec_used_scale_factor << 2; /* Q13->Q15 */ - tmp2 = inst->dec_target_scale_factor << 2; /* Q13->Q15 */ - tmp3 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(tmp1, Beta, 15); - tmp3 += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(tmp2, BetaC, 15); - inst->dec_used_scale_factor = tmp3 >> 2; /* Q15->Q13 */ - - inst->dec_used_energy = inst->dec_used_energy >> 1; - inst->dec_used_energy += inst->dec_target_energy >> 1; - - /* Do the same for the reflection coeffs. */ - for (i = 0; i < WEBRTC_CNG_MAX_LPC_ORDER; i++) { - inst->dec_used_reflCoefs[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( - inst->dec_used_reflCoefs[i], Beta, 15); - inst->dec_used_reflCoefs[i] += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( - inst->dec_target_reflCoefs[i], BetaC, 15); - } - - /* Compute the polynomial coefficients. */ - WebRtcCng_K2a16(inst->dec_used_reflCoefs, WEBRTC_CNG_MAX_LPC_ORDER, lpPoly); - - - targetEnergy = inst->dec_used_energy; - - /* Calculate scaling factor based on filter energy. */ - En = 8192; /* 1.0 in Q13. */ - for (i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER); i++) { - - /* Floating point value for reference. - E *= 1.0 - (inst->dec_used_reflCoefs[i] / 32768.0) * - (inst->dec_used_reflCoefs[i] / 32768.0); - */ - - /* Same in fixed point. */ - /* K(i).^2 in Q15. */ - temp16 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( - inst->dec_used_reflCoefs[i], inst->dec_used_reflCoefs[i], 15); - /* 1 - K(i).^2 in Q15. */ - temp16 = 0x7fff - temp16; - En = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(En, temp16, 15); - } - - /* float scaling= sqrt(E * inst->dec_target_energy / (1 << 24)); */ - - /* Calculate sqrt(En * target_energy / excitation energy) */ - targetEnergy = WebRtcSpl_Sqrt(inst->dec_used_energy); - - En = (int16_t) WebRtcSpl_Sqrt(En) << 6; - En = (En * 3) >> 1; /* 1.5 estimates sqrt(2). */ - inst->dec_used_scale_factor = (int16_t)((En * targetEnergy) >> 12); - - /* Generate excitation. */ - /* Excitation energy per sample is 2.^24 - Q13 N(0,1). */ - for (i = 0; i < nrOfSamples; i++) { - excitation[i] = WebRtcSpl_RandN(&inst->dec_seed) >> 1; - } - - /* Scale to correct energy. */ - WebRtcSpl_ScaleVector(excitation, excitation, inst->dec_used_scale_factor, - nrOfSamples, 13); - - /* |lpPoly| - Coefficients in Q12. - * |excitation| - Speech samples. - * |nst->dec_filtstate| - State preservation. - * |outData| - Filtered speech samples. */ - WebRtcSpl_FilterAR(lpPoly, WEBRTC_CNG_MAX_LPC_ORDER + 1, excitation, - nrOfSamples, inst->dec_filtstate, WEBRTC_CNG_MAX_LPC_ORDER, - inst->dec_filtstateLow, WEBRTC_CNG_MAX_LPC_ORDER, outData, - low, nrOfSamples); - - return 0; -} - -/**************************************************************************** - * WebRtcCng_GetErrorCodeEnc/Dec(...) - * - * This functions can be used to check the error code of a CNG instance. When - * a function returns -1 a error code will be set for that instance. The - * function below extract the code of the last error that occured in the - * specified instance. - * - * Input: - * - CNG_inst : CNG enc/dec instance - * - * Return value : Error code - */ -int16_t WebRtcCng_GetErrorCodeEnc(CNG_enc_inst* cng_inst) { - /* Typecast pointer to real structure. */ - WebRtcCngEncoder* inst = (WebRtcCngEncoder*) cng_inst; - return inst->errorcode; -} - -int16_t WebRtcCng_GetErrorCodeDec(CNG_dec_inst* cng_inst) { - /* Typecast pointer to real structure. */ - WebRtcCngDecoder* inst = (WebRtcCngDecoder*) cng_inst; - return inst->errorcode; -} diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.cc new file mode 100644 index 00000000000..b4da260dba2 --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.cc @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2012 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/cng/webrtc_cng.h" + +#include <algorithm> + +#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" + +namespace webrtc { + +namespace { + +const size_t kCngMaxOutsizeOrder = 640; + +// TODO(ossu): Rename the left-over WebRtcCng according to style guide. +void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a); + +const int32_t WebRtcCng_kDbov[94] = { + 1081109975, 858756178, 682134279, 541838517, 430397633, 341876992, + 271562548, 215709799, 171344384, 136103682, 108110997, 85875618, + 68213428, 54183852, 43039763, 34187699, 27156255, 21570980, + 17134438, 13610368, 10811100, 8587562, 6821343, 5418385, + 4303976, 3418770, 2715625, 2157098, 1713444, 1361037, + 1081110, 858756, 682134, 541839, 430398, 341877, + 271563, 215710, 171344, 136104, 108111, 85876, + 68213, 54184, 43040, 34188, 27156, 21571, + 17134, 13610, 10811, 8588, 6821, 5418, + 4304, 3419, 2716, 2157, 1713, 1361, + 1081, 859, 682, 542, 430, 342, + 272, 216, 171, 136, 108, 86, + 68, 54, 43, 34, 27, 22, + 17, 14, 11, 9, 7, 5, + 4, 3, 3, 2, 2, 1, + 1, 1, 1, 1 +}; + +const int16_t WebRtcCng_kCorrWindow[WEBRTC_CNG_MAX_LPC_ORDER] = { + 32702, 32636, 32570, 32505, 32439, 32374, + 32309, 32244, 32179, 32114, 32049, 31985 +}; + +} // namespace + +ComfortNoiseDecoder::ComfortNoiseDecoder() { + /* Needed to get the right function pointers in SPLIB. */ + WebRtcSpl_Init(); + Reset(); +} + +void ComfortNoiseDecoder::Reset() { + dec_seed_ = 7777; /* For debugging only. */ + dec_target_energy_ = 0; + dec_used_energy_ = 0; + for (auto& c : dec_target_reflCoefs_) + c = 0; + for (auto& c : dec_used_reflCoefs_) + c = 0; + for (auto& c : dec_filtstate_) + c = 0; + for (auto& c : dec_filtstateLow_) + c = 0; + dec_order_ = 5; + dec_target_scale_factor_ = 0; + dec_used_scale_factor_ = 0; +} + +void ComfortNoiseDecoder::UpdateSid(rtc::ArrayView<const uint8_t> sid) { + int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER]; + int32_t targetEnergy; + size_t length = sid.size(); + /* Throw away reflection coefficients of higher order than we can handle. */ + if (length > (WEBRTC_CNG_MAX_LPC_ORDER + 1)) + length = WEBRTC_CNG_MAX_LPC_ORDER + 1; + + dec_order_ = static_cast<uint16_t>(length - 1); + + uint8_t sid0 = std::min<uint8_t>(sid[0], 93); + targetEnergy = WebRtcCng_kDbov[sid0]; + /* Take down target energy to 75%. */ + targetEnergy = targetEnergy >> 1; + targetEnergy += targetEnergy >> 2; + + dec_target_energy_ = targetEnergy; + + /* Reconstruct coeffs with tweak for WebRtc implementation of RFC3389. */ + if (dec_order_ == WEBRTC_CNG_MAX_LPC_ORDER) { + for (size_t i = 0; i < (dec_order_); i++) { + refCs[i] = sid[i + 1] << 8; /* Q7 to Q15*/ + dec_target_reflCoefs_[i] = refCs[i]; + } + } else { + for (size_t i = 0; i < (dec_order_); i++) { + refCs[i] = (sid[i + 1] - 127) << 8; /* Q7 to Q15. */ + dec_target_reflCoefs_[i] = refCs[i]; + } + } + + for (size_t i = (dec_order_); i < WEBRTC_CNG_MAX_LPC_ORDER; i++) { + refCs[i] = 0; + dec_target_reflCoefs_[i] = refCs[i]; + } +} + +bool ComfortNoiseDecoder::Generate(rtc::ArrayView<int16_t> out_data, + bool new_period) { + int16_t excitation[kCngMaxOutsizeOrder]; + int16_t low[kCngMaxOutsizeOrder]; + int16_t lpPoly[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int16_t ReflBetaStd = 26214; /* 0.8 in q15. */ + int16_t ReflBetaCompStd = 6553; /* 0.2 in q15. */ + int16_t ReflBetaNewP = 19661; /* 0.6 in q15. */ + int16_t ReflBetaCompNewP = 13107; /* 0.4 in q15. */ + int16_t Beta, BetaC, tmp1, tmp2, tmp3; + int32_t targetEnergy; + int16_t En; + int16_t temp16; + const size_t num_samples = out_data.size(); + + if (num_samples > kCngMaxOutsizeOrder) { + return false; + } + + if (new_period) { + dec_used_scale_factor_ = dec_target_scale_factor_; + Beta = ReflBetaNewP; + BetaC = ReflBetaCompNewP; + } else { + Beta = ReflBetaStd; + BetaC = ReflBetaCompStd; + } + + /* Here we use a 0.5 weighting, should possibly be modified to 0.6. */ + tmp1 = dec_used_scale_factor_ << 2; /* Q13->Q15 */ + tmp2 = dec_target_scale_factor_ << 2; /* Q13->Q15 */ + tmp3 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(tmp1, Beta, 15); + tmp3 += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(tmp2, BetaC, 15); + dec_used_scale_factor_ = tmp3 >> 2; /* Q15->Q13 */ + + dec_used_energy_ = dec_used_energy_ >> 1; + dec_used_energy_ += dec_target_energy_ >> 1; + + /* Do the same for the reflection coeffs. */ + for (size_t i = 0; i < WEBRTC_CNG_MAX_LPC_ORDER; i++) { + dec_used_reflCoefs_[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( + dec_used_reflCoefs_[i], Beta, 15); + dec_used_reflCoefs_[i] += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( + dec_target_reflCoefs_[i], BetaC, 15); + } + + /* Compute the polynomial coefficients. */ + WebRtcCng_K2a16(dec_used_reflCoefs_, WEBRTC_CNG_MAX_LPC_ORDER, lpPoly); + + + targetEnergy = dec_used_energy_; + + /* Calculate scaling factor based on filter energy. */ + En = 8192; /* 1.0 in Q13. */ + for (size_t i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER); i++) { + /* Floating point value for reference. + E *= 1.0 - (dec_used_reflCoefs_[i] / 32768.0) * + (dec_used_reflCoefs_[i] / 32768.0); + */ + + /* Same in fixed point. */ + /* K(i).^2 in Q15. */ + temp16 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( + dec_used_reflCoefs_[i], dec_used_reflCoefs_[i], 15); + /* 1 - K(i).^2 in Q15. */ + temp16 = 0x7fff - temp16; + En = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(En, temp16, 15); + } + + /* float scaling= sqrt(E * dec_target_energy_ / (1 << 24)); */ + + /* Calculate sqrt(En * target_energy / excitation energy) */ + targetEnergy = WebRtcSpl_Sqrt(dec_used_energy_); + + En = (int16_t) WebRtcSpl_Sqrt(En) << 6; + En = (En * 3) >> 1; /* 1.5 estimates sqrt(2). */ + dec_used_scale_factor_ = (int16_t)((En * targetEnergy) >> 12); + + /* Generate excitation. */ + /* Excitation energy per sample is 2.^24 - Q13 N(0,1). */ + for (size_t i = 0; i < num_samples; i++) { + excitation[i] = WebRtcSpl_RandN(&dec_seed_) >> 1; + } + + /* Scale to correct energy. */ + WebRtcSpl_ScaleVector(excitation, excitation, dec_used_scale_factor_, + num_samples, 13); + + /* |lpPoly| - Coefficients in Q12. + * |excitation| - Speech samples. + * |nst->dec_filtstate| - State preservation. + * |out_data| - Filtered speech samples. */ + WebRtcSpl_FilterAR(lpPoly, WEBRTC_CNG_MAX_LPC_ORDER + 1, excitation, + num_samples, dec_filtstate_, WEBRTC_CNG_MAX_LPC_ORDER, + dec_filtstateLow_, WEBRTC_CNG_MAX_LPC_ORDER, + out_data.data(), low, num_samples); + + return true; +} + +ComfortNoiseEncoder::ComfortNoiseEncoder(int fs, int interval, int quality) + : enc_nrOfCoefs_(quality), + enc_sampfreq_(fs), + enc_interval_(interval), + enc_msSinceSid_(0), + enc_Energy_(0), + enc_reflCoefs_{0}, + enc_corrVector_{0}, + enc_seed_(7777) /* For debugging only. */ { + RTC_CHECK(quality <= WEBRTC_CNG_MAX_LPC_ORDER && quality > 0); + /* Needed to get the right function pointers in SPLIB. */ + WebRtcSpl_Init(); +} + +void ComfortNoiseEncoder::Reset(int fs, int interval, int quality) { + RTC_CHECK(quality <= WEBRTC_CNG_MAX_LPC_ORDER && quality > 0); + enc_nrOfCoefs_ = quality; + enc_sampfreq_ = fs; + enc_interval_ = interval; + enc_msSinceSid_ = 0; + enc_Energy_ = 0; + for (auto& c : enc_reflCoefs_) + c = 0; + for (auto& c : enc_corrVector_) + c = 0; + enc_seed_ = 7777; /* For debugging only. */ +} + +size_t ComfortNoiseEncoder::Encode(rtc::ArrayView<const int16_t> speech, + bool force_sid, + rtc::Buffer* output) { + int16_t arCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int32_t corrVector[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int16_t hanningW[kCngMaxOutsizeOrder]; + int16_t ReflBeta = 19661; /* 0.6 in q15. */ + int16_t ReflBetaComp = 13107; /* 0.4 in q15. */ + int32_t outEnergy; + int outShifts; + size_t i; + int stab; + int acorrScale; + size_t index; + size_t ind, factor; + int32_t* bptr; + int32_t blo, bhi; + int16_t negate; + const int16_t* aptr; + int16_t speechBuf[kCngMaxOutsizeOrder]; + + const size_t num_samples = speech.size(); + RTC_CHECK_LE(num_samples, static_cast<size_t>(kCngMaxOutsizeOrder)); + + for (i = 0; i < num_samples; i++) { + speechBuf[i] = speech[i]; + } + + factor = num_samples; + + /* Calculate energy and a coefficients. */ + outEnergy = WebRtcSpl_Energy(speechBuf, num_samples, &outShifts); + while (outShifts > 0) { + /* We can only do 5 shifts without destroying accuracy in + * division factor. */ + if (outShifts > 5) { + outEnergy <<= (outShifts - 5); + outShifts = 5; + } else { + factor /= 2; + outShifts--; + } + } + outEnergy = WebRtcSpl_DivW32W16(outEnergy, (int16_t)factor); + + if (outEnergy > 1) { + /* Create Hanning Window. */ + WebRtcSpl_GetHanningWindow(hanningW, num_samples / 2); + for (i = 0; i < (num_samples / 2); i++) + hanningW[num_samples - i - 1] = hanningW[i]; + + WebRtcSpl_ElementwiseVectorMult(speechBuf, hanningW, speechBuf, num_samples, + 14); + + WebRtcSpl_AutoCorrelation(speechBuf, num_samples, enc_nrOfCoefs_, + corrVector, &acorrScale); + + if (*corrVector == 0) + *corrVector = WEBRTC_SPL_WORD16_MAX; + + /* Adds the bandwidth expansion. */ + aptr = WebRtcCng_kCorrWindow; + bptr = corrVector; + + /* (zzz) lpc16_1 = 17+1+820+2+2 = 842 (ordo2=700). */ + for (ind = 0; ind < enc_nrOfCoefs_; ind++) { + /* The below code multiplies the 16 b corrWindow values (Q15) with + * the 32 b corrvector (Q0) and shifts the result down 15 steps. */ + negate = *bptr < 0; + if (negate) + *bptr = -*bptr; + + blo = (int32_t) * aptr * (*bptr & 0xffff); + bhi = ((blo >> 16) & 0xffff) + + ((int32_t)(*aptr++) * ((*bptr >> 16) & 0xffff)); + blo = (blo & 0xffff) | ((bhi & 0xffff) << 16); + + *bptr = (((bhi >> 16) & 0x7fff) << 17) | ((uint32_t) blo >> 15); + if (negate) + *bptr = -*bptr; + bptr++; + } + /* End of bandwidth expansion. */ + + stab = WebRtcSpl_LevinsonDurbin(corrVector, arCoefs, refCs, + enc_nrOfCoefs_); + + if (!stab) { + /* Disregard from this frame */ + return 0; + } + + } else { + for (i = 0; i < enc_nrOfCoefs_; i++) + refCs[i] = 0; + } + + if (force_sid) { + /* Read instantaneous values instead of averaged. */ + for (i = 0; i < enc_nrOfCoefs_; i++) + enc_reflCoefs_[i] = refCs[i]; + enc_Energy_ = outEnergy; + } else { + /* Average history with new values. */ + for (i = 0; i < enc_nrOfCoefs_; i++) { + enc_reflCoefs_[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( + enc_reflCoefs_[i], ReflBeta, 15); + enc_reflCoefs_[i] += + (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(refCs[i], ReflBetaComp, 15); + } + enc_Energy_ = + (outEnergy >> 2) + (enc_Energy_ >> 1) + (enc_Energy_ >> 2); + } + + if (enc_Energy_ < 1) { + enc_Energy_ = 1; + } + + if ((enc_msSinceSid_ > (enc_interval_ - 1)) || force_sid) { + /* Search for best dbov value. */ + index = 0; + for (i = 1; i < 93; i++) { + /* Always round downwards. */ + if ((enc_Energy_ - WebRtcCng_kDbov[i]) > 0) { + index = i; + break; + } + } + if ((i == 93) && (index == 0)) + index = 94; + + const size_t output_coefs = enc_nrOfCoefs_ + 1; + output->AppendData(output_coefs, [&] (rtc::ArrayView<uint8_t> output) { + output[0] = (uint8_t)index; + + /* Quantize coefficients with tweak for WebRtc implementation of + * RFC3389. */ + if (enc_nrOfCoefs_ == WEBRTC_CNG_MAX_LPC_ORDER) { + for (i = 0; i < enc_nrOfCoefs_; i++) { + /* Q15 to Q7 with rounding. */ + output[i + 1] = ((enc_reflCoefs_[i] + 128) >> 8); + } + } else { + for (i = 0; i < enc_nrOfCoefs_; i++) { + /* Q15 to Q7 with rounding. */ + output[i + 1] = (127 + ((enc_reflCoefs_[i] + 128) >> 8)); + } + } + + return output_coefs; + }); + + enc_msSinceSid_ = + static_cast<int16_t>((1000 * num_samples) / enc_sampfreq_); + return output_coefs; + } else { + enc_msSinceSid_ += + static_cast<int16_t>((1000 * num_samples) / enc_sampfreq_); + return 0; + } +} + +namespace { +/* Values in |k| are Q15, and |a| Q12. */ +void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a) { + int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1]; + int16_t* aptr; + int16_t* aptr2; + int16_t* anyptr; + const int16_t* kptr; + int m, i; + + kptr = k; + *a = 4096; /* i.e., (Word16_MAX >> 3) + 1 */ + *any = *a; + a[1] = (*k + 4) >> 3; + for (m = 1; m < useOrder; m++) { + kptr++; + aptr = a; + aptr++; + aptr2 = &a[m]; + anyptr = any; + anyptr++; + + any[m + 1] = (*kptr + 4) >> 3; + for (i = 0; i < m; i++) { + *anyptr++ = + (*aptr++) + + (int16_t)((((int32_t)(*aptr2--) * (int32_t)*kptr) + 16384) >> 15); + } + + aptr = a; + anyptr = any; + for (i = 0; i < (m + 2); i++) { + *aptr++ = *anyptr++; + } + } +} + +} // namespace + +} // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h index 64bea1e26f6..fb0a53df270 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h @@ -12,152 +12,88 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ -#include <stddef.h> -#include "webrtc/typedefs.h" +#include <cstddef> -#ifdef __cplusplus -extern "C" { -#endif +#include "webrtc/base/array_view.h" +#include "webrtc/base/buffer.h" +#include "webrtc/typedefs.h" #define WEBRTC_CNG_MAX_LPC_ORDER 12 -#define WEBRTC_CNG_MAX_OUTSIZE_ORDER 640 - -/* Define Error codes. */ - -/* 6100 Encoder */ -#define CNG_ENCODER_NOT_INITIATED 6120 -#define CNG_DISALLOWED_LPC_ORDER 6130 -#define CNG_DISALLOWED_FRAME_SIZE 6140 -#define CNG_DISALLOWED_SAMPLING_FREQUENCY 6150 -/* 6200 Decoder */ -#define CNG_DECODER_NOT_INITIATED 6220 - -typedef struct WebRtcCngEncInst CNG_enc_inst; -typedef struct WebRtcCngDecInst CNG_dec_inst; - -/**************************************************************************** - * WebRtcCng_CreateEnc/Dec(...) - * - * These functions create an instance to the specified structure - * - * Input: - * - XXX_inst : Pointer to created instance that should be created - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_CreateEnc(CNG_enc_inst** cng_inst); -int16_t WebRtcCng_CreateDec(CNG_dec_inst** cng_inst); - -/**************************************************************************** - * WebRtcCng_InitEnc/Dec(...) - * - * This function initializes a instance - * - * Input: - * - cng_inst : Instance that should be initialized - * - * - fs : 8000 for narrowband and 16000 for wideband - * - interval : generate SID data every interval ms - * - quality : Number of refl. coefs, maximum allowed is 12 - * - * Output: - * - cng_inst : Initialized instance - * - * Return value : 0 - Ok - * -1 - Error - */ - -int WebRtcCng_InitEnc(CNG_enc_inst* cng_inst, int fs, int16_t interval, - int16_t quality); -void WebRtcCng_InitDec(CNG_dec_inst* cng_inst); - -/**************************************************************************** - * WebRtcCng_FreeEnc/Dec(...) - * - * These functions frees the dynamic memory of a specified instance - * - * Input: - * - cng_inst : Pointer to created instance that should be freed - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_FreeEnc(CNG_enc_inst* cng_inst); -int16_t WebRtcCng_FreeDec(CNG_dec_inst* cng_inst); - -/**************************************************************************** - * WebRtcCng_Encode(...) - * - * These functions analyzes background noise - * - * Input: - * - cng_inst : Pointer to created instance - * - speech : Signal to be analyzed - * - nrOfSamples : Size of speech vector - * - forceSID : not zero to force SID frame and reset - * - * Output: - * - bytesOut : Nr of bytes to transmit, might be 0 - * - * Return value : 0 - Ok - * -1 - Error - */ -int WebRtcCng_Encode(CNG_enc_inst* cng_inst, int16_t* speech, - size_t nrOfSamples, uint8_t* SIDdata, - size_t* bytesOut, int16_t forceSID); - -/**************************************************************************** - * WebRtcCng_UpdateSid(...) - * - * These functions updates the CN state, when a new SID packet arrives - * - * Input: - * - cng_inst : Pointer to created instance that should be freed - * - SID : SID packet, all headers removed - * - length : Length in bytes of SID packet - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_UpdateSid(CNG_dec_inst* cng_inst, uint8_t* SID, - size_t length); - -/**************************************************************************** - * WebRtcCng_Generate(...) - * - * These functions generates CN data when needed - * - * Input: - * - cng_inst : Pointer to created instance that should be freed - * - outData : pointer to area to write CN data - * - nrOfSamples : How much data to generate - * - new_period : >0 if a new period of CNG, will reset history - * - * Return value : 0 - Ok - * -1 - Error - */ -int16_t WebRtcCng_Generate(CNG_dec_inst* cng_inst, int16_t* outData, - size_t nrOfSamples, int16_t new_period); - -/***************************************************************************** - * WebRtcCng_GetErrorCodeEnc/Dec(...) - * - * This functions can be used to check the error code of a CNG instance. When - * a function returns -1 a error code will be set for that instance. The - * function below extract the code of the last error that occurred in the - * specified instance. - * - * Input: - * - CNG_inst : CNG enc/dec instance - * - * Return value : Error code - */ -int16_t WebRtcCng_GetErrorCodeEnc(CNG_enc_inst* cng_inst); -int16_t WebRtcCng_GetErrorCodeDec(CNG_dec_inst* cng_inst); -#ifdef __cplusplus -} -#endif +namespace webrtc { + +class ComfortNoiseDecoder { + public: + ComfortNoiseDecoder(); + ~ComfortNoiseDecoder() = default; + + ComfortNoiseDecoder(const ComfortNoiseDecoder&) = delete; + ComfortNoiseDecoder& operator=(const ComfortNoiseDecoder&) = delete; + + void Reset(); + + // Updates the CN state when a new SID packet arrives. + // |sid| is a view of the SID packet without the headers. + void UpdateSid(rtc::ArrayView<const uint8_t> sid); + + // Generates comfort noise. + // |out_data| will be filled with samples - its size determines the number of + // samples generated. When |new_period| is true, CNG history will be reset + // before any audio is generated. Returns |false| if outData is too large - + // currently 640 bytes (equalling 10ms at 64kHz). + // TODO(ossu): Specify better limits for the size of out_data. Either let it + // be unbounded or limit to 10ms in the current sample rate. + bool Generate(rtc::ArrayView<int16_t> out_data, bool new_period); + + private: + uint32_t dec_seed_; + int32_t dec_target_energy_; + int32_t dec_used_energy_; + int16_t dec_target_reflCoefs_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int16_t dec_used_reflCoefs_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int16_t dec_filtstate_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int16_t dec_filtstateLow_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + uint16_t dec_order_; + int16_t dec_target_scale_factor_; /* Q29 */ + int16_t dec_used_scale_factor_; /* Q29 */ +}; + +class ComfortNoiseEncoder { + public: + // Creates a comfort noise encoder. + // |fs| selects sample rate: 8000 for narrowband or 16000 for wideband. + // |interval| sets the interval at which to generate SID data (in ms). + // |quality| selects the number of refl. coeffs. Maximum allowed is 12. + ComfortNoiseEncoder(int fs, int interval, int quality); + ~ComfortNoiseEncoder() = default; + + ComfortNoiseEncoder(const ComfortNoiseEncoder&) = delete; + ComfortNoiseEncoder& operator=(const ComfortNoiseEncoder&) = delete; + + // Resets the comfort noise encoder to its initial state. + // Parameters are set as during construction. + void Reset(int fs, int interval, int quality); + + // Analyzes background noise from |speech| and appends coefficients to + // |output|. Returns the number of coefficients generated. If |force_sid| is + // true, a SID frame is forced and the internal sid interval counter is reset. + // Will fail if the input size is too large (> 640 samples, see + // ComfortNoiseDecoder::Generate). + size_t Encode(rtc::ArrayView<const int16_t> speech, + bool force_sid, + rtc::Buffer* output); + + private: + size_t enc_nrOfCoefs_; + int enc_sampfreq_; + int16_t enc_interval_; + int16_t enc_msSinceSid_; + int32_t enc_Energy_; + int16_t enc_reflCoefs_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + int32_t enc_corrVector_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + uint32_t enc_seed_; +}; + +} // namespace webrtc #endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h index 9dc3a6fd7ad..7a627e757c9 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h @@ -12,6 +12,7 @@ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_ #include "webrtc/base/checks.h" +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" namespace webrtc { diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc index a24b1526fd2..baa5d382d32 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc @@ -52,10 +52,6 @@ AudioEncoderPcm::AudioEncoderPcm(const Config& config, int sample_rate_hz) AudioEncoderPcm::~AudioEncoderPcm() = default; -size_t AudioEncoderPcm::MaxEncodedBytes() const { - return full_frame_samples_ * BytesPerSample(); -} - int AudioEncoderPcm::SampleRateHz() const { return sample_rate_hz_; } @@ -93,13 +89,14 @@ AudioEncoder::EncodedInfo AudioEncoderPcm::EncodeImpl( info.encoded_timestamp = first_timestamp_in_buffer_; info.payload_type = payload_type_; info.encoded_bytes = - encoded->AppendData(MaxEncodedBytes(), + encoded->AppendData(full_frame_samples_ * BytesPerSample(), [&] (rtc::ArrayView<uint8_t> encoded) { return EncodeCall(&speech_buffer_[0], full_frame_samples_, encoded.data()); }); speech_buffer_.clear(); + info.encoder_type = GetCodecType(); return info; } @@ -120,6 +117,10 @@ size_t AudioEncoderPcmA::BytesPerSample() const { return 1; } +AudioEncoder::CodecType AudioEncoderPcmA::GetCodecType() const { + return AudioEncoder::CodecType::kPcmA; +} + AudioEncoderPcmU::AudioEncoderPcmU(const CodecInst& codec_inst) : AudioEncoderPcmU(CreateConfig<AudioEncoderPcmU>(codec_inst)) {} @@ -133,4 +134,8 @@ size_t AudioEncoderPcmU::BytesPerSample() const { return 1; } +AudioEncoder::CodecType AudioEncoderPcmU::GetCodecType() const { + return AudioEncoder::CodecType::kPcmU; +} + } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h index 6b3cebfb336..721344528f8 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h @@ -35,7 +35,6 @@ class AudioEncoderPcm : public AudioEncoder { ~AudioEncoderPcm() override; - size_t MaxEncodedBytes() const override; int SampleRateHz() const override; size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; @@ -56,6 +55,10 @@ class AudioEncoderPcm : public AudioEncoder { virtual size_t BytesPerSample() const = 0; + // Used to set EncodedInfoLeaf::encoder_type in + // AudioEncoderPcm::EncodeImpl + virtual AudioEncoder::CodecType GetCodecType() const = 0; + private: const int sample_rate_hz_; const size_t num_channels_; @@ -85,6 +88,8 @@ class AudioEncoderPcmA final : public AudioEncoderPcm { size_t BytesPerSample() const override; + AudioEncoder::CodecType GetCodecType() const override; + private: static const int kSampleRateHz = 8000; RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderPcmA); @@ -107,6 +112,8 @@ class AudioEncoderPcmU final : public AudioEncoderPcm { size_t BytesPerSample() const override; + AudioEncoder::CodecType GetCodecType() const override; + private: static const int kSampleRateHz = 8000; RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderPcmU); diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h index 7cc2ea98773..1837ffabe29 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_DECODER_G722_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_DECODER_G722_H_ +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" typedef struct WebRtcG722DecInst G722DecInst; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc index 9256518445d..1f3936c8eee 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc @@ -60,10 +60,6 @@ AudioEncoderG722::AudioEncoderG722(const CodecInst& codec_inst) AudioEncoderG722::~AudioEncoderG722() = default; -size_t AudioEncoderG722::MaxEncodedBytes() const { - return SamplesPerChannel() / 2 * num_channels_; -} - int AudioEncoderG722::SampleRateHz() const { return kSampleRateHz; } @@ -149,6 +145,7 @@ AudioEncoder::EncodedInfo AudioEncoderG722::EncodeImpl( }); info.encoded_timestamp = first_timestamp_in_buffer_; info.payload_type = payload_type_; + info.encoder_type = CodecType::kG722; return info; } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h index dec87b2b7a4..ad49a865e25 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h @@ -14,6 +14,7 @@ #include <memory> #include "webrtc/base/buffer.h" +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" #include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" @@ -35,7 +36,6 @@ class AudioEncoderG722 final : public AudioEncoder { explicit AudioEncoderG722(const CodecInst& codec_inst); ~AudioEncoderG722() override; - size_t MaxEncodedBytes() const override; int SampleRateHz() const override; size_t NumChannels() const override; int RtpTimestampRateHz() const override; @@ -44,7 +44,7 @@ class AudioEncoderG722 final : public AudioEncoder { int GetTargetBitrate() const override; void Reset() override; -protected: + protected: EncodedInfo EncodeImpl(uint32_t rtp_timestamp, rtc::ArrayView<const int16_t> audio, rtc::Buffer* encoded) override; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h index e890635da09..036c11fac47 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_DECODER_ILBC_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_DECODER_ILBC_H_ +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" typedef struct iLBC_decinst_t_ IlbcDecoderInstance; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc index c7d7411c45d..ca11587dfab 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc @@ -56,10 +56,6 @@ AudioEncoderIlbc::~AudioEncoderIlbc() { RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderFree(encoder_)); } -size_t AudioEncoderIlbc::MaxEncodedBytes() const { - return RequiredOutputSizeBytes(); -} - int AudioEncoderIlbc::SampleRateHz() const { return kSampleRateHz; } @@ -131,6 +127,7 @@ AudioEncoder::EncodedInfo AudioEncoderIlbc::EncodeImpl( info.encoded_bytes = encoded_bytes; info.encoded_timestamp = first_timestamp_in_buffer_; info.payload_type = config_.payload_type; + info.encoder_type = CodecType::kIlbc; return info; } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h index 27329bbc4ee..63639860f45 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h @@ -34,7 +34,6 @@ class AudioEncoderIlbc final : public AudioEncoder { explicit AudioEncoderIlbc(const CodecInst& codec_inst); ~AudioEncoderIlbc() override; - size_t MaxEncodedBytes() const override; int SampleRateHz() const override; size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/get_lsp_poly.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/get_lsp_poly.c index 62a686495b1..a8375afb609 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/get_lsp_poly.c +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/get_lsp_poly.c @@ -65,15 +65,15 @@ void WebRtcIlbcfix_GetLspPoly( { /* Compute f[j] = f[j] + tmp*f[j-1] + f[j-2]; */ high = (int16_t)(fPtr[-1] >> 16); - low = (int16_t)((fPtr[-1] - ((int32_t)high << 16)) >> 1); + low = (int16_t)((fPtr[-1] & 0xffff) >> 1); - tmpW32 = ((high * *lspPtr) << 2) + (((low * *lspPtr) >> 15) << 2); + tmpW32 = 4 * high * *lspPtr + 4 * ((low * *lspPtr) >> 15); (*fPtr) += fPtr[-2]; (*fPtr) -= tmpW32; fPtr--; } - *fPtr -= *lspPtr << 10; + *fPtr -= *lspPtr * (1 << 10); fPtr+=i; lspPtr+=2; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_output.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_output.c index bd101bf30ca..8b18c047b93 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_output.c +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_output.c @@ -48,7 +48,7 @@ void WebRtcIlbcfix_HpOutput( tmpW32 = (tmpW32>>15); tmpW32 += y[0] * ba[3]; /* (-a[1])*y[i-1] (high part) */ tmpW32 += y[2] * ba[4]; /* (-a[2])*y[i-2] (high part) */ - tmpW32 = (tmpW32<<1); + tmpW32 *= 2; tmpW32 += signal[i] * ba[0]; /* b[0]*x[0] */ tmpW32 += x[0] * ba[1]; /* b[1]*x[i-1] */ @@ -77,11 +77,11 @@ void WebRtcIlbcfix_HpOutput( } else if (tmpW32<-268435456) { tmpW32 = WEBRTC_SPL_WORD32_MIN; } else { - tmpW32 <<= 3; + tmpW32 *= 8; } y[0] = (int16_t)(tmpW32 >> 16); - y[1] = (int16_t)((tmpW32 - (y[0] << 16)) >> 1); + y[1] = (int16_t)((tmpW32 & 0xffff) >> 1); } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/interfaces.gypi b/chromium/third_party/webrtc/modules/audio_coding/codecs/interfaces.gypi index d4f6a4a41e6..1aba106f909 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/interfaces.gypi +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/interfaces.gypi @@ -15,6 +15,10 @@ 'audio_decoder.cc', 'audio_decoder.h', ], + 'dependencies': [ + '<(webrtc_root)/base/base.gyp:rtc_base_approved', + '<(webrtc_root)/common.gyp:webrtc_common', + ], }, { @@ -24,6 +28,10 @@ 'audio_encoder.cc', 'audio_encoder.h', ], + 'dependencies': [ + '<(webrtc_root)/base/base.gyp:rtc_base_approved', + '<(webrtc_root)/common.gyp:webrtc_common', + ], }, ], } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_decoder_isac_t.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_decoder_isac_t.h index d9d20ec0396..b1907bbb394 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_decoder_isac_t.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_decoder_isac_t.h @@ -13,6 +13,7 @@ #include <vector> +#include "webrtc/base/constructormagic.h" #include "webrtc/base/scoped_ref_ptr.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" #include "webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h" diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h index 0da8ed71d66..f1f2714ff9c 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h @@ -13,6 +13,7 @@ #include <vector> +#include "webrtc/base/constructormagic.h" #include "webrtc/base/scoped_ref_ptr.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" #include "webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h" @@ -56,7 +57,6 @@ class AudioEncoderIsacT final : public AudioEncoder { const rtc::scoped_refptr<LockedIsacBandwidthInfo>& bwinfo); ~AudioEncoderIsacT() override; - size_t MaxEncodedBytes() const override; int SampleRateHz() const override; size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h index 1debbeb9038..b6a1747c391 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h @@ -80,11 +80,6 @@ AudioEncoderIsacT<T>::~AudioEncoderIsacT() { } template <typename T> -size_t AudioEncoderIsacT<T>::MaxEncodedBytes() const { - return kSufficientEncodeBufferSizeBytes; -} - -template <typename T> int AudioEncoderIsacT<T>::SampleRateHz() const { return T::EncSampRate(isac_state_); } @@ -150,6 +145,7 @@ AudioEncoder::EncodedInfo AudioEncoderIsacT<T>::EncodeImpl( info.encoded_bytes = encoded_bytes; info.encoded_timestamp = packet_timestamp_; info.payload_type = config_.payload_type; + info.encoder_type = CodecType::kIsac; return info; } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h index fdbb2fcb0d7..001a04f39bf 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h @@ -90,7 +90,7 @@ void WebRtcIsacfix_Spec2TimeC(int16_t* inreQ7, int32_t* outre1Q16, int32_t* outre2Q16); -#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) void WebRtcIsacfix_Time2SpecNeon(int16_t* inre1Q9, int16_t* inre2Q9, int16_t* outre, @@ -174,7 +174,7 @@ void WebRtcIsacfix_FilterMaLoopC(int16_t input0, int32_t* ptr1, int32_t* ptr2); -#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) int WebRtcIsacfix_AutocorrNeon(int32_t* __restrict r, const int16_t* __restrict x, int16_t N, diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h index 2c8c923cd33..1b87d0ea557 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h @@ -147,7 +147,7 @@ void WebRtcIsacfix_MatrixProduct2C(const int16_t matrix0[], const int matrix0_index_factor, const int matrix0_index_step); -#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) void WebRtcIsacfix_MatrixProduct1Neon(const int16_t matrix0[], const int32_t matrix1[], int32_t matrix_product[], diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h index 0e67e300ac1..d488339b31f 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h @@ -60,7 +60,7 @@ void WebRtcIsacfix_AllpassFilter2FixDec16C( int32_t *filter_state_ch1, int32_t *filter_state_ch2); -#if (defined WEBRTC_DETECT_NEON) || (defined WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) void WebRtcIsacfix_AllpassFilter2FixDec16Neon( int16_t *data_ch1, int16_t *data_ch2, diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc index 0ec115414b8..4b03181e456 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc @@ -64,11 +64,7 @@ class FilterBanksTest : public testing::Test { TEST_F(FilterBanksTest, AllpassFilter2FixDec16Test) { CalculateResidualEnergyTester(WebRtcIsacfix_AllpassFilter2FixDec16C); -#ifdef WEBRTC_DETECT_NEON - if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) { - CalculateResidualEnergyTester(WebRtcIsacfix_AllpassFilter2FixDec16Neon); - } -#elif defined(WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) CalculateResidualEnergyTester(WebRtcIsacfix_AllpassFilter2FixDec16Neon); #endif } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc index 5cce1e9f0b2..3ed57788a1f 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc @@ -59,11 +59,7 @@ class FiltersTest : public testing::Test { TEST_F(FiltersTest, AutocorrFixTest) { FiltersTester(WebRtcIsacfix_AutocorrC); -#ifdef WEBRTC_DETECT_NEON - if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) { - FiltersTester(WebRtcIsacfix_AutocorrNeon); - } -#elif defined(WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) FiltersTester(WebRtcIsacfix_AutocorrNeon); #endif } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c index aba3aa0c0bf..e7905ae81fa 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c @@ -201,7 +201,7 @@ int16_t WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst) * This function initializes function pointers for ARM Neon platform. */ -#if defined(WEBRTC_DETECT_NEON) || defined(WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) static void WebRtcIsacfix_InitNeon(void) { WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrNeon; WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopNeon; @@ -253,11 +253,7 @@ static void InitFunctionPointers(void) { WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C; WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C; -#ifdef WEBRTC_DETECT_NEON - if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) { - WebRtcIsacfix_InitNeon(); - } -#elif defined(WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) WebRtcIsacfix_InitNeon(); #endif diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c index 18377dd370f..0d881e80442 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c @@ -57,8 +57,6 @@ void WebRtcIsacfix_PCorr2Q32(const int16_t* in, int32_t* logcorQ8) { ysum32 += in[PITCH_CORR_LEN2 + k - 1] * in[PITCH_CORR_LEN2 + k - 1] >> scaling; - // TODO(zhongwei.yao): Move this function into a separate NEON code file so - // that WEBRTC_DETECT_NEON could take advantage of it. #ifdef WEBRTC_HAS_NEON { int32_t vbuff[4]; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc index 58d890011fe..c5cc87ffce2 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc @@ -179,22 +179,14 @@ class TransformTest : public testing::Test { TEST_F(TransformTest, Time2SpecTest) { Time2SpecTester(WebRtcIsacfix_Time2SpecC); -#ifdef WEBRTC_DETECT_NEON - if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) { - Time2SpecTester(WebRtcIsacfix_Time2SpecNeon); - } -#elif defined(WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) Time2SpecTester(WebRtcIsacfix_Time2SpecNeon); #endif } TEST_F(TransformTest, Spec2TimeTest) { Spec2TimeTester(WebRtcIsacfix_Spec2TimeC); -#ifdef WEBRTC_DETECT_NEON - if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) { - Spec2TimeTester(WebRtcIsacfix_Spec2TimeNeon); - } -#elif defined(WEBRTC_HAS_NEON) +#if defined(WEBRTC_HAS_NEON) Spec2TimeTester(WebRtcIsacfix_Spec2TimeNeon); #endif } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc index 32f36c52617..276eb60e280 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc @@ -25,10 +25,10 @@ class IsacSpeedTest : public AudioCodecSpeedTest { IsacSpeedTest(); void SetUp() override; void TearDown() override; - virtual float EncodeABlock(int16_t* in_data, uint8_t* bit_stream, - size_t max_bytes, size_t* encoded_bytes); - virtual float DecodeABlock(const uint8_t* bit_stream, size_t encoded_bytes, - int16_t* out_data); + float EncodeABlock(int16_t* in_data, uint8_t* bit_stream, + size_t max_bytes, size_t* encoded_bytes) override; + float DecodeABlock(const uint8_t* bit_stream, size_t encoded_bytes, + int16_t* out_data) override; ISACFIX_MainStruct *ISACFIX_main_inst_; }; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_hist.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_hist.c index 63e4928bd88..47bbe31b8ae 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_hist.c +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_hist.c @@ -214,10 +214,10 @@ int WebRtcIsac_DecHistOneStepMulti(int *data, /* output: data vector */ if (streamdata->stream_index == 0) /* first time decoder is called for this stream */ { /* read first word from bytestream */ - streamval = *stream_ptr << 24; - streamval |= *++stream_ptr << 16; - streamval |= *++stream_ptr << 8; - streamval |= *++stream_ptr; + streamval = (uint32_t)(*stream_ptr) << 24; + streamval |= (uint32_t)(*++stream_ptr) << 16; + streamval |= (uint32_t)(*++stream_ptr) << 8; + streamval |= (uint32_t)(*++stream_ptr); } else { streamval = streamdata->streamval; } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.c b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.c index c1204ad03ad..f920dc2ef8b 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.c +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.c @@ -162,9 +162,9 @@ static void FindInvArSpec(const int16_t* ARCoefQ12, } for (k = 0; k < FRAMESAMPLES / 8; k++) { - CurveQ16[FRAMESAMPLES_QUARTER - 1 - k] = CurveQ16[k] - - (diffQ16[k] << shftVal); - CurveQ16[k] += diffQ16[k] << shftVal; + int32_t diff_q16_shifted = (int32_t)((uint32_t)(diffQ16[k]) << shftVal); + CurveQ16[FRAMESAMPLES_QUARTER - 1 - k] = CurveQ16[k] - diff_q16_shifted; + CurveQ16[k] += diff_q16_shifted; } } diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h new file mode 100644 index 00000000000..6e5737c89b8 --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 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_MOCK_MOCK_AUDIO_DECODER_FACTORY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_MOCK_MOCK_AUDIO_DECODER_FACTORY_H_ + +#include <vector> + +#include "testing/gmock/include/gmock/gmock.h" +#include "webrtc/modules/audio_coding/codecs/audio_decoder_factory.h" + +namespace webrtc { + +class MockAudioDecoderFactory : public AudioDecoderFactory { + public: + MOCK_METHOD0(GetSupportedFormats, std::vector<SdpAudioFormat>()); + std::unique_ptr<AudioDecoder> MakeAudioDecoder( + const SdpAudioFormat& format) { + std::unique_ptr<AudioDecoder> return_value; + MakeAudioDecoderMock(format, &return_value); + return return_value; + } + MOCK_METHOD2(MakeAudioDecoderMock, + void(const SdpAudioFormat& format, + std::unique_ptr<AudioDecoder>* return_value)); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_MOCK_MOCK_AUDIO_DECODER_FACTORY_H_ diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.cc index 52849691ac6..a674eba6607 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.cc @@ -49,26 +49,4 @@ AudioEncoder::EncodedInfo MockAudioEncoder::CopyEncoding::operator()( return info_; } -MockAudioEncoderDeprecated::CopyEncoding::CopyEncoding( - AudioEncoder::EncodedInfo info, - rtc::ArrayView<const uint8_t> payload) - : info_(info), payload_(payload) { } - -MockAudioEncoderDeprecated::CopyEncoding::CopyEncoding( - rtc::ArrayView<const uint8_t> payload) - : payload_(payload) { - info_.encoded_bytes = payload_.size(); -} - -AudioEncoder::EncodedInfo MockAudioEncoderDeprecated::CopyEncoding::operator()( - uint32_t timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_bytes_encoded, - uint8_t* encoded) { - RTC_CHECK(encoded); - RTC_CHECK_LE(info_.encoded_bytes, payload_.size()); - std::memcpy(encoded, payload_.data(), info_.encoded_bytes); - return info_; -} - } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h index 58a1e756f97..2ffb30b708a 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h @@ -11,6 +11,8 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_MOCK_MOCK_AUDIO_ENCODER_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_MOCK_MOCK_AUDIO_ENCODER_H_ +#include <string> + #include "webrtc/base/array_view.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" @@ -18,12 +20,15 @@ namespace webrtc { -class MockAudioEncoderBase : public AudioEncoder { +class MockAudioEncoder : public AudioEncoder { public: - ~MockAudioEncoderBase() override { Die(); } + // TODO(nisse): Valid overrides commented out, because the gmock + // methods don't use any override declarations, and we want to avoid + // warnings from -Winconsistent-missing-override. See + // http://crbug.com/428099. + ~MockAudioEncoder() /* override */ { Die(); } MOCK_METHOD0(Die, void()); MOCK_METHOD1(Mark, void(std::string desc)); - MOCK_CONST_METHOD0(MaxEncodedBytes, size_t()); MOCK_CONST_METHOD0(SampleRateHz, int()); MOCK_CONST_METHOD0(NumChannels, size_t()); MOCK_CONST_METHOD0(RtpTimestampRateHz, int()); @@ -39,10 +44,7 @@ class MockAudioEncoderBase : public AudioEncoder { MOCK_METHOD1(SetTargetBitrate, void(int target_bps)); MOCK_METHOD1(SetMaxBitrate, void(int max_bps)); MOCK_METHOD1(SetMaxPayloadSize, void(int max_payload_size_bytes)); -}; -class MockAudioEncoder final : public MockAudioEncoderBase { - public: // Note, we explicitly chose not to create a mock for the Encode method. MOCK_METHOD3(EncodeImpl, EncodedInfo(uint32_t timestamp, @@ -53,11 +55,11 @@ class MockAudioEncoder final : public MockAudioEncoderBase { public: // Creates a functor that will return |info| and adjust the rtc::Buffer // given as input to it, so it is info.encoded_bytes larger. - FakeEncoding(const AudioEncoder::EncodedInfo& info); + explicit FakeEncoding(const AudioEncoder::EncodedInfo& info); // Shorthand version of the constructor above, for when only setting // encoded_bytes in the EncodedInfo object matters. - FakeEncoding(size_t encoded_bytes); + explicit FakeEncoding(size_t encoded_bytes); AudioEncoder::EncodedInfo operator()(uint32_t timestamp, rtc::ArrayView<const int16_t> audio, @@ -80,41 +82,12 @@ class MockAudioEncoder final : public MockAudioEncoderBase { // Shorthand version of the constructor above, for when you wish to append // the whole payload and do not care about any EncodedInfo attribute other // than encoded_bytes. - CopyEncoding(rtc::ArrayView<const uint8_t> payload); + explicit CopyEncoding(rtc::ArrayView<const uint8_t> payload); AudioEncoder::EncodedInfo operator()(uint32_t timestamp, rtc::ArrayView<const int16_t> audio, rtc::Buffer* encoded); - private: - AudioEncoder::EncodedInfo info_; - rtc::ArrayView<const uint8_t> payload_; - }; - -}; - -class MockAudioEncoderDeprecated final : public MockAudioEncoderBase { - public: - // Note, we explicitly chose not to create a mock for the Encode method. - MOCK_METHOD4(EncodeInternal, - EncodedInfo(uint32_t timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_encoded_bytes, - uint8_t* encoded)); - // A functor like MockAudioEncoder::CopyEncoding above, but which has the - // deprecated Encode signature. Currently only used in one test and should be - // removed once that backwards compatibility is. - class CopyEncoding { - public: - CopyEncoding(AudioEncoder::EncodedInfo info, - rtc::ArrayView<const uint8_t> payload); - - CopyEncoding(rtc::ArrayView<const uint8_t> payload); - - AudioEncoder::EncodedInfo operator()(uint32_t timestamp, - rtc::ArrayView<const int16_t> audio, - size_t max_bytes_encoded, - uint8_t* encoded); private: AudioEncoder::EncodedInfo info_; rtc::ArrayView<const uint8_t> payload_; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h index af32a84512e..be48ca988ef 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_DECODER_OPUS_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_DECODER_OPUS_H_ +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc index a599e291d47..a2497c7862a 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc @@ -10,6 +10,8 @@ #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" +#include <algorithm> + #include "webrtc/base/checks.h" #include "webrtc/base/safe_conversions.h" #include "webrtc/common_types.h" @@ -100,16 +102,6 @@ AudioEncoderOpus::~AudioEncoderOpus() { RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); } -size_t AudioEncoderOpus::MaxEncodedBytes() const { - // Calculate the number of bytes we expect the encoder to produce, - // then multiply by two to give a wide margin for error. - const size_t bytes_per_millisecond = - static_cast<size_t>(config_.bitrate_bps / (1000 * 8) + 1); - const size_t approx_encoded_bytes = - Num10msFramesPerPacket() * 10 * bytes_per_millisecond; - return 2 * approx_encoded_bytes; -} - int AudioEncoderOpus::SampleRateHz() const { return kSampleRateHz; } @@ -198,7 +190,7 @@ AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( RTC_CHECK_EQ(input_buffer_.size(), Num10msFramesPerPacket() * SamplesPer10msFrame()); - const size_t max_encoded_bytes = MaxEncodedBytes(); + const size_t max_encoded_bytes = SufficientOutputBufferSize(); EncodedInfo info; info.encoded_bytes = encoded->AppendData( @@ -220,6 +212,7 @@ AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( info.payload_type = config_.payload_type; info.send_even_if_empty = true; // Allows Opus to send empty packets. info.speech = (info.encoded_bytes > 0); + info.encoder_type = CodecType::kOpus; return info; } @@ -231,6 +224,16 @@ size_t AudioEncoderOpus::SamplesPer10msFrame() const { return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels; } +size_t AudioEncoderOpus::SufficientOutputBufferSize() const { + // Calculate the number of bytes we expect the encoder to produce, + // then multiply by two to give a wide margin for error. + const size_t bytes_per_millisecond = + static_cast<size_t>(config_.bitrate_bps / (1000 * 8) + 1); + const size_t approx_encoded_bytes = + Num10msFramesPerPacket() * 10 * bytes_per_millisecond; + return 2 * approx_encoded_bytes; +} + // If the given config is OK, recreate the Opus encoder instance with those // settings, save the config, and return true. Otherwise, do nothing and return // false. diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h index 3f11af1f9e0..8900659f48e 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h @@ -54,7 +54,6 @@ class AudioEncoderOpus final : public AudioEncoder { explicit AudioEncoderOpus(const CodecInst& codec_inst); ~AudioEncoderOpus() override; - size_t MaxEncodedBytes() const override; int SampleRateHz() const override; size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; @@ -79,7 +78,7 @@ class AudioEncoderOpus final : public AudioEncoder { ApplicationMode application() const { return config_.application; } bool dtx_enabled() const { return config_.dtx_enabled; } -protected: + protected: EncodedInfo EncodeImpl(uint32_t rtp_timestamp, rtc::ArrayView<const int16_t> audio, rtc::Buffer* encoded) override; @@ -87,6 +86,7 @@ protected: private: size_t Num10msFramesPerPacket() const; size_t SamplesPer10msFrame() const; + size_t SufficientOutputBufferSize() const; bool RecreateEncoderInstance(const Config& config); Config config_; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc index 4d1aa42c89f..7165d29c8b4 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc @@ -23,10 +23,10 @@ class OpusSpeedTest : public AudioCodecSpeedTest { OpusSpeedTest(); void SetUp() override; void TearDown() override; - virtual float EncodeABlock(int16_t* in_data, uint8_t* bit_stream, - size_t max_bytes, size_t* encoded_bytes); - virtual float DecodeABlock(const uint8_t* bit_stream, size_t encoded_bytes, - int16_t* out_data); + float EncodeABlock(int16_t* in_data, uint8_t* bit_stream, + size_t max_bytes, size_t* encoded_bytes) override; + float DecodeABlock(const uint8_t* bit_stream, size_t encoded_bytes, + int16_t* out_data) override; WebRtcOpusEncInst* opus_encoder_; WebRtcOpusDecInst* opus_decoder_; }; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc index f4d40223024..cafd3e851bd 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc @@ -26,6 +26,10 @@ size_t AudioEncoderPcm16B::BytesPerSample() const { return 2; } +AudioEncoder::CodecType AudioEncoderPcm16B::GetCodecType() const { + return CodecType::kOther; +} + namespace { AudioEncoderPcm16B::Config CreateConfig(const CodecInst& codec_inst) { AudioEncoderPcm16B::Config config; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h index 34a780b49de..bdc27a67e30 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_ENCODER_PCM16B_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_ENCODER_PCM16B_H_ +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h" namespace webrtc { @@ -38,6 +39,8 @@ class AudioEncoderPcm16B final : public AudioEncoderPcm { size_t BytesPerSample() const override; + AudioEncoder::CodecType GetCodecType() const override; + private: RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderPcm16B); }; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc index 4275f54103a..37fa55a4da1 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc @@ -19,12 +19,7 @@ namespace webrtc { AudioEncoderCopyRed::Config::Config() = default; - -// TODO(kwiberg): =default this when Visual Studio learns to handle it. -AudioEncoderCopyRed::Config::Config(Config&& c) - : payload_type(c.payload_type), - speech_encoder(std::move(c.speech_encoder)) {} - +AudioEncoderCopyRed::Config::Config(Config&&) = default; AudioEncoderCopyRed::Config::~Config() = default; AudioEncoderCopyRed::AudioEncoderCopyRed(Config&& config) @@ -35,10 +30,6 @@ AudioEncoderCopyRed::AudioEncoderCopyRed(Config&& config) AudioEncoderCopyRed::~AudioEncoderCopyRed() = default; -size_t AudioEncoderCopyRed::MaxEncodedBytes() const { - return 2 * speech_encoder_->MaxEncodedBytes(); -} - int AudioEncoderCopyRed::SampleRateHz() const { return speech_encoder_->SampleRateHz(); } @@ -132,4 +123,9 @@ void AudioEncoderCopyRed::SetTargetBitrate(int bits_per_second) { speech_encoder_->SetTargetBitrate(bits_per_second); } +rtc::ArrayView<std::unique_ptr<AudioEncoder>> +AudioEncoderCopyRed::ReclaimContainedEncoders() { + return rtc::ArrayView<std::unique_ptr<AudioEncoder>>(&speech_encoder_, 1); +} + } // namespace webrtc diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h b/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h index a67ae486bb2..a08118364cc 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h @@ -15,6 +15,7 @@ #include <vector> #include "webrtc/base/buffer.h" +#include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" namespace webrtc { @@ -37,7 +38,6 @@ class AudioEncoderCopyRed final : public AudioEncoder { ~AudioEncoderCopyRed() override; - size_t MaxEncodedBytes() const override; int SampleRateHz() const override; size_t NumChannels() const override; int RtpTimestampRateHz() const override; @@ -51,8 +51,10 @@ class AudioEncoderCopyRed final : public AudioEncoder { void SetMaxPlaybackRate(int frequency_hz) override; void SetProjectedPacketLossRate(double fraction) override; void SetTargetBitrate(int target_bps) override; + rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders() + override; -protected: + protected: EncodedInfo EncodeImpl(uint32_t rtp_timestamp, rtc::ArrayView<const int16_t> audio, rtc::Buffer* encoded) override; diff --git a/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc index c73cb9f2096..22b2ceb5f79 100644 --- a/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc +++ b/chromium/third_party/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc @@ -26,7 +26,6 @@ using ::testing::MockFunction; namespace webrtc { namespace { -static const size_t kMockMaxEncodedBytes = 1000; static const size_t kMaxNumSamples = 48 * 10 * 2; // 10 ms @ 48 kHz stereo. } @@ -46,8 +45,6 @@ class AudioEncoderCopyRedTest : public ::testing::Test { EXPECT_CALL(*mock_encoder_, NumChannels()).WillRepeatedly(Return(1U)); EXPECT_CALL(*mock_encoder_, SampleRateHz()) .WillRepeatedly(Return(sample_rate_hz_)); - EXPECT_CALL(*mock_encoder_, MaxEncodedBytes()) - .WillRepeatedly(Return(kMockMaxEncodedBytes)); } void TearDown() override { |