Revert of Remove the deprecated EncodeInternal interface from AudioEncoder (patchset #4 id:60001 of https://codereview.webrtc.org/1864993002/ )
Reason for revert: Broke import. Implementations of the old interface still exists somewhere. Original issue's description: > Remove the deprecated EncodeInternal interface from AudioEncoder > > Also hid MaxEncodedBytes by making it private. It will get removed as soon as subclasses have had time to remove their overrides. > > BUG=webrtc:5591 > > Committed: https://crrev.com/5222d315dbea8f3563c100cc9f2451907f70b05f > Cr-Commit-Position: refs/heads/master@{#12329} TBR=kwiberg@webrtc.org,solenberg@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:5591 Review URL: https://codereview.webrtc.org/1883543002 Cr-Commit-Position: refs/heads/master@{#12330}
This commit is contained in:
@ -104,6 +104,7 @@ void ConvertEncodedInfoToFragmentationHeader(
|
||||
class RawAudioEncoderWrapper final : public AudioEncoder {
|
||||
public:
|
||||
RawAudioEncoderWrapper(AudioEncoder* enc) : enc_(enc) {}
|
||||
size_t MaxEncodedBytes() const override { return enc_->MaxEncodedBytes(); }
|
||||
int SampleRateHz() const override { return enc_->SampleRateHz(); }
|
||||
size_t NumChannels() const override { return enc_->NumChannels(); }
|
||||
int RtpTimestampRateHz() const override { return enc_->RtpTimestampRateHz(); }
|
||||
@ -119,6 +120,13 @@ class RawAudioEncoderWrapper final : public AudioEncoder {
|
||||
rtc::Buffer* encoded) override {
|
||||
return enc_->Encode(rtp_timestamp, audio, encoded);
|
||||
}
|
||||
EncodedInfo EncodeInternal(uint32_t rtp_timestamp,
|
||||
rtc::ArrayView<const int16_t> audio,
|
||||
size_t max_encoded_bytes,
|
||||
uint8_t* encoded) override {
|
||||
return enc_->EncodeInternal(rtp_timestamp, audio, max_encoded_bytes,
|
||||
encoded);
|
||||
}
|
||||
void Reset() override { return enc_->Reset(); }
|
||||
bool SetFec(bool enable) override { return enc_->SetFec(enable); }
|
||||
bool SetDtx(bool enable) override { return enc_->SetDtx(enable); }
|
||||
|
||||
@ -37,6 +37,55 @@ 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;
|
||||
}
|
||||
@ -55,9 +104,4 @@ void AudioEncoder::SetProjectedPacketLossRate(double fraction) {}
|
||||
|
||||
void AudioEncoder::SetTargetBitrate(int target_bps) {}
|
||||
|
||||
size_t AudioEncoder::MaxEncodedBytes() const {
|
||||
RTC_CHECK(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -52,6 +52,14 @@ class AudioEncoder {
|
||||
|
||||
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;
|
||||
@ -87,6 +95,33 @@ 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;
|
||||
@ -127,19 +162,13 @@ class AudioEncoder {
|
||||
|
||||
protected:
|
||||
// Subclasses implement this to perform the actual encoding. Called by
|
||||
// Encode().
|
||||
// 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.
|
||||
virtual EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
|
||||
rtc::ArrayView<const int16_t> audio,
|
||||
rtc::Buffer* encoded) = 0;
|
||||
|
||||
private:
|
||||
// This function is deprecated. It was used to return the maximum number of
|
||||
// bytes that can be produced by the encoder at each Encode() call. Since the
|
||||
// Encode interface was changed to use rtc::Buffer, this is no longer
|
||||
// applicable. It is only kept in to avoid breaking subclasses that still have
|
||||
// it implemented (with the override attribute). It will be removed as soon
|
||||
// as these subclasses have been given a chance to change.
|
||||
virtual size_t MaxEncodedBytes() const;
|
||||
rtc::Buffer* encoded);
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_ENCODER_H_
|
||||
|
||||
64
webrtc/modules/audio_coding/codecs/audio_encoder_unittest.cc
Normal file
64
webrtc/modules/audio_coding/codecs/audio_encoder_unittest.cc
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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
|
||||
@ -82,6 +82,13 @@ AudioEncoderCng::AudioEncoderCng(Config&& config)
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@ -52,6 +52,7 @@ 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;
|
||||
|
||||
@ -25,6 +25,7 @@ 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;
|
||||
@ -73,6 +74,8 @@ 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)));
|
||||
}
|
||||
@ -87,8 +90,8 @@ class AudioEncoderCngTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
// Expect |num_calls| calls to the encoder, all successful. The last call
|
||||
// claims to have encoded |kMockReturnEncodedBytes| bytes, and all the
|
||||
// preceding ones 0 bytes.
|
||||
// claims to have encoded |kMockMaxEncodedBytes| bytes, and all the preceding
|
||||
// ones 0 bytes.
|
||||
void ExpectEncodeCalls(size_t num_calls) {
|
||||
InSequence s;
|
||||
AudioEncoder::EncodedInfo info;
|
||||
|
||||
@ -52,6 +52,10 @@ 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_;
|
||||
}
|
||||
@ -89,7 +93,7 @@ AudioEncoder::EncodedInfo AudioEncoderPcm::EncodeImpl(
|
||||
info.encoded_timestamp = first_timestamp_in_buffer_;
|
||||
info.payload_type = payload_type_;
|
||||
info.encoded_bytes =
|
||||
encoded->AppendData(full_frame_samples_ * BytesPerSample(),
|
||||
encoded->AppendData(MaxEncodedBytes(),
|
||||
[&] (rtc::ArrayView<uint8_t> encoded) {
|
||||
return EncodeCall(&speech_buffer_[0],
|
||||
full_frame_samples_,
|
||||
|
||||
@ -35,6 +35,7 @@ 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;
|
||||
|
||||
@ -60,6 +60,10 @@ 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;
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ 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;
|
||||
@ -43,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;
|
||||
|
||||
@ -56,6 +56,10 @@ AudioEncoderIlbc::~AudioEncoderIlbc() {
|
||||
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderFree(encoder_));
|
||||
}
|
||||
|
||||
size_t AudioEncoderIlbc::MaxEncodedBytes() const {
|
||||
return RequiredOutputSizeBytes();
|
||||
}
|
||||
|
||||
int AudioEncoderIlbc::SampleRateHz() const {
|
||||
return kSampleRateHz;
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ 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;
|
||||
|
||||
@ -56,6 +56,7 @@ 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;
|
||||
|
||||
@ -79,6 +79,11 @@ AudioEncoderIsacT<T>::~AudioEncoderIsacT() {
|
||||
RTC_CHECK_EQ(0, T::Free(isac_state_));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t AudioEncoderIsacT<T>::MaxEncodedBytes() const {
|
||||
return kSufficientEncodeBufferSizeBytes;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int AudioEncoderIsacT<T>::SampleRateHz() const {
|
||||
return T::EncSampRate(isac_state_);
|
||||
|
||||
@ -49,4 +49,26 @@ 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
|
||||
|
||||
@ -18,11 +18,12 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class MockAudioEncoder : public AudioEncoder {
|
||||
class MockAudioEncoderBase : public AudioEncoder {
|
||||
public:
|
||||
~MockAudioEncoder() override { Die(); }
|
||||
~MockAudioEncoderBase() 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());
|
||||
@ -38,7 +39,10 @@ class MockAudioEncoder : 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,
|
||||
@ -85,6 +89,36 @@ class MockAudioEncoder : public AudioEncoder {
|
||||
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_;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -100,6 +100,16 @@ 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;
|
||||
}
|
||||
@ -188,7 +198,7 @@ AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl(
|
||||
RTC_CHECK_EQ(input_buffer_.size(),
|
||||
Num10msFramesPerPacket() * SamplesPer10msFrame());
|
||||
|
||||
const size_t max_encoded_bytes = ApproximateEncodedBytes();
|
||||
const size_t max_encoded_bytes = MaxEncodedBytes();
|
||||
EncodedInfo info;
|
||||
info.encoded_bytes =
|
||||
encoded->AppendData(
|
||||
@ -221,16 +231,6 @@ size_t AudioEncoderOpus::SamplesPer10msFrame() const {
|
||||
return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels;
|
||||
}
|
||||
|
||||
size_t AudioEncoderOpus::ApproximateEncodedBytes() 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.
|
||||
|
||||
@ -54,6 +54,7 @@ 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;
|
||||
@ -78,7 +79,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;
|
||||
@ -86,7 +87,6 @@ class AudioEncoderOpus final : public AudioEncoder {
|
||||
private:
|
||||
size_t Num10msFramesPerPacket() const;
|
||||
size_t SamplesPer10msFrame() const;
|
||||
size_t ApproximateEncodedBytes() const;
|
||||
bool RecreateEncoderInstance(const Config& config);
|
||||
|
||||
Config config_;
|
||||
|
||||
@ -35,6 +35,10 @@ 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();
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ 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,7 +52,7 @@ class AudioEncoderCopyRed final : public AudioEncoder {
|
||||
void SetProjectedPacketLossRate(double fraction) override;
|
||||
void SetTargetBitrate(int target_bps) override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
|
||||
rtc::ArrayView<const int16_t> audio,
|
||||
rtc::Buffer* encoded) override;
|
||||
|
||||
@ -26,6 +26,7 @@ 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.
|
||||
}
|
||||
|
||||
@ -45,6 +46,8 @@ 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 {
|
||||
|
||||
@ -167,6 +167,7 @@
|
||||
'<(webrtc_root)/tools/tools.gyp:agc_test_utils',
|
||||
],
|
||||
'sources': [
|
||||
'audio_coding/codecs/audio_encoder_unittest.cc',
|
||||
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
|
||||
'audio_coding/acm2/acm_receiver_unittest_oldapi.cc',
|
||||
'audio_coding/acm2/audio_coding_module_unittest_oldapi.cc',
|
||||
|
||||
Reference in New Issue
Block a user