Add encode/decode time tracing to audio_coding.

Also removes virtual from VideoDecoder::Decode and updated mocks and
tests accordingly to use VideoDecoder::DecodeInternal instead.

BUG=webrtc:5167
R=henrik.lundin@webrtc.org

Review URL: https://codereview.webrtc.org/1512483003 .

Cr-Commit-Position: refs/heads/master@{#10935}
This commit is contained in:
Peter Boström 2015-12-08 13:41:35 +01:00
parent 9f45a45a62
commit d7b7ae8bda
8 changed files with 99 additions and 79 deletions

View File

@ -976,7 +976,29 @@ TEST_F(AcmReceiverBitExactnessOldApi, IF_ALL_CODECS(MAYBE_48kHzOutput)) {
#endif
TEST_F(AcmReceiverBitExactnessOldApi,
IF_ALL_CODECS(MAYBE_48kHzOutputExternalDecoder)) {
// Class intended to forward a call from a mock DecodeInternal to Decode on
// the real decoder's Decode. DecodeInternal for the real decoder isn't
// public.
class DecodeForwarder {
public:
DecodeForwarder(AudioDecoder* decoder) : decoder_(decoder) {}
int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
AudioDecoder::SpeechType* speech_type) {
return decoder_->Decode(encoded, encoded_len, sample_rate_hz,
decoder_->PacketDuration(encoded, encoded_len) *
decoder_->Channels() * sizeof(int16_t),
decoded, speech_type);
}
private:
AudioDecoder* const decoder_;
};
AudioDecoderPcmU decoder(1);
DecodeForwarder decode_forwarder(&decoder);
MockAudioDecoder mock_decoder;
// Set expectations on the mock decoder and also delegate the calls to the
// real decoder.
@ -986,9 +1008,9 @@ TEST_F(AcmReceiverBitExactnessOldApi,
EXPECT_CALL(mock_decoder, Channels())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Channels));
EXPECT_CALL(mock_decoder, Decode(_, _, _, _, _, _))
EXPECT_CALL(mock_decoder, DecodeInternal(_, _, _, _, _))
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Decode));
.WillRepeatedly(Invoke(&decode_forwarder, &DecodeForwarder::Decode));
EXPECT_CALL(mock_decoder, HasDecodePlc())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::HasDecodePlc));

View File

@ -13,12 +13,14 @@
#include <assert.h>
#include "webrtc/base/checks.h"
#include "webrtc/base/trace_event.h"
namespace webrtc {
int AudioDecoder::Decode(const uint8_t* encoded, size_t encoded_len,
int sample_rate_hz, size_t max_decoded_bytes,
int16_t* decoded, SpeechType* speech_type) {
TRACE_EVENT0("webrtc", "AudioDecoder::Decode");
int duration = PacketDuration(encoded, encoded_len);
if (duration >= 0 &&
duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
@ -31,6 +33,7 @@ int AudioDecoder::Decode(const uint8_t* encoded, size_t encoded_len,
int AudioDecoder::DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
int sample_rate_hz, size_t max_decoded_bytes,
int16_t* decoded, SpeechType* speech_type) {
TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant");
int duration = PacketDurationRedundant(encoded, encoded_len);
if (duration >= 0 &&
duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
@ -40,12 +43,6 @@ int AudioDecoder::DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
speech_type);
}
int AudioDecoder::DecodeInternal(const uint8_t* encoded, size_t encoded_len,
int sample_rate_hz, int16_t* decoded,
SpeechType* speech_type) {
return kNotImplemented;
}
int AudioDecoder::DecodeRedundantInternal(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz, int16_t* decoded,

View File

@ -41,21 +41,21 @@ class AudioDecoder {
// is set to kComfortNoise, otherwise it is kSpeech. The desired output
// sample rate is provided in |sample_rate_hz|, which must be valid for the
// codec at hand.
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
size_t max_decoded_bytes,
int16_t* decoded,
SpeechType* speech_type);
int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
size_t max_decoded_bytes,
int16_t* decoded,
SpeechType* speech_type);
// Same as Decode(), but interfaces to the decoders redundant decode function.
// The default implementation simply calls the regular Decode() method.
virtual int DecodeRedundant(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
size_t max_decoded_bytes,
int16_t* decoded,
SpeechType* speech_type);
int DecodeRedundant(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
size_t max_decoded_bytes,
int16_t* decoded,
SpeechType* speech_type);
// Indicates if the decoder implements the DecodePlc method.
virtual bool HasDecodePlc() const;
@ -107,7 +107,7 @@ class AudioDecoder {
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
SpeechType* speech_type) = 0;
virtual int DecodeRedundantInternal(const uint8_t* encoded,
size_t encoded_len,

View File

@ -9,7 +9,9 @@
*/
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/trace_event.h"
namespace webrtc {
@ -26,6 +28,7 @@ AudioEncoder::EncodedInfo AudioEncoder::Encode(
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 =

View File

@ -22,9 +22,8 @@ class MockAudioDecoder : public AudioDecoder {
MockAudioDecoder() {}
virtual ~MockAudioDecoder() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_METHOD6(
Decode,
int(const uint8_t*, size_t, int, size_t, int16_t*, SpeechType*));
MOCK_METHOD5(DecodeInternal,
int(const uint8_t*, size_t, int, int16_t*, SpeechType*));
MOCK_CONST_METHOD0(HasDecodePlc, bool());
MOCK_METHOD2(DecodePlc, size_t(size_t, int16_t*));
MOCK_METHOD0(Reset, void());

View File

@ -30,7 +30,6 @@ class ExternalPcm16B : public AudioDecoder {
ExternalPcm16B() {}
void Reset() override {}
protected:
int DecodeInternal(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
@ -52,8 +51,8 @@ class MockExternalPcm16B : public ExternalPcm16B {
public:
MockExternalPcm16B() {
// By default, all calls are delegated to the real object.
ON_CALL(*this, Decode(_, _, _, _, _, _))
.WillByDefault(Invoke(&real_, &ExternalPcm16B::Decode));
ON_CALL(*this, DecodeInternal(_, _, _, _, _))
.WillByDefault(Invoke(&real_, &ExternalPcm16B::DecodeInternal));
ON_CALL(*this, HasDecodePlc())
.WillByDefault(Invoke(&real_, &ExternalPcm16B::HasDecodePlc));
ON_CALL(*this, DecodePlc(_, _))
@ -68,11 +67,10 @@ class MockExternalPcm16B : public ExternalPcm16B {
virtual ~MockExternalPcm16B() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_METHOD6(Decode,
MOCK_METHOD5(DecodeInternal,
int(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
size_t max_decoded_bytes,
int16_t* decoded,
SpeechType* speech_type));
MOCK_CONST_METHOD0(HasDecodePlc,

View File

@ -98,8 +98,9 @@ class NetEqExternalDecoderUnitTest : public test::NetEqExternalDecoderTest {
next_arrival_time = GetArrivalTime(next_send_time);
} while (Lost()); // If lost, immediately read the next packet.
EXPECT_CALL(*external_decoder_,
Decode(_, payload_size_bytes_, 1000 * samples_per_ms_, _, _, _))
EXPECT_CALL(
*external_decoder_,
DecodeInternal(_, payload_size_bytes_, 1000 * samples_per_ms_, _, _))
.Times(NumExpectedDecodeCalls(num_loops));
uint32_t time_now = 0;

View File

@ -431,12 +431,11 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
CountingSamplesDecoder() : next_value_(1) {}
// Produce as many samples as input bytes (|encoded_len|).
int Decode(const uint8_t* encoded,
size_t encoded_len,
int /* sample_rate_hz */,
size_t /* max_decoded_bytes */,
int16_t* decoded,
SpeechType* speech_type) override {
int DecodeInternal(const uint8_t* encoded,
size_t encoded_len,
int /* sample_rate_hz */,
int16_t* decoded,
SpeechType* speech_type) override {
for (size_t i = 0; i < encoded_len; ++i) {
decoded[i] = next_value_++;
}
@ -527,11 +526,11 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
int16_t dummy_output[kPayloadLengthSamples] = {0};
// The below expectation will make the mock decoder write
// |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
EXPECT_CALL(mock_decoder,
Decode(Pointee(0), kPayloadLengthBytes, kSampleRateHz, _, _, _))
.WillOnce(DoAll(SetArrayArgument<4>(dummy_output,
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
kSampleRateHz, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<5>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
@ -570,11 +569,11 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
// Expect only the second packet to be decoded (the one with "2" as the first
// payload byte).
EXPECT_CALL(mock_decoder,
Decode(Pointee(2), kPayloadLengthBytes, kSampleRateHz, _, _, _))
.WillOnce(DoAll(SetArrayArgument<4>(dummy_output,
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
kSampleRateHz, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<5>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
// Pull audio once.
@ -688,31 +687,32 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
// Pointee(x) verifies that first byte of the payload equals x, this makes it
// possible to verify that the correct payload is fed to Decode().
EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _, _))
.WillOnce(DoAll(SetArrayArgument<4>(dummy_output,
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<5>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _, _))
.WillOnce(DoAll(SetArrayArgument<4>(dummy_output,
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<5>(AudioDecoder::kComfortNoise),
SetArgPointee<4>(AudioDecoder::kComfortNoise),
Return(kPayloadLengthSamples)));
EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, kSampleRateKhz * 1000, _, _, _))
.WillOnce(DoAll(SetArrayArgument<4>(dummy_output,
EXPECT_CALL(mock_decoder,
DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<5>(AudioDecoder::kComfortNoise),
SetArgPointee<4>(AudioDecoder::kComfortNoise),
Return(kPayloadLengthSamples)));
EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _, _))
.WillOnce(DoAll(SetArrayArgument<4>(dummy_output,
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<5>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
@ -960,11 +960,11 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
// |kPayloadLengthSamples| - 5 zeros to the output array, and mark it as
// speech. That is, the decoded length is 5 samples shorter than the expected.
EXPECT_CALL(mock_decoder,
Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
.WillOnce(
DoAll(SetArrayArgument<4>(dummy_output,
DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples - 5),
SetArgPointee<5>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples - 5)));
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
@ -1034,30 +1034,30 @@ TEST_F(NetEqImplTest, DecodingError) {
InSequence sequence; // Dummy variable.
// Mock decoder works normally the first time.
EXPECT_CALL(mock_decoder,
Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
.Times(3)
.WillRepeatedly(
DoAll(SetArrayArgument<4>(dummy_output,
DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kFrameLengthSamples),
SetArgPointee<5>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kFrameLengthSamples)))
.RetiresOnSaturation();
// Then mock decoder fails. A common reason for failure can be buffer being
// too short
EXPECT_CALL(mock_decoder,
Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
.WillOnce(Return(-1))
.RetiresOnSaturation();
// Mock decoder finally returns to normal.
EXPECT_CALL(mock_decoder,
Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
.Times(2)
.WillRepeatedly(
DoAll(SetArrayArgument<4>(dummy_output,
dummy_output + kFrameLengthSamples),
SetArgPointee<5>(AudioDecoder::kSpeech),
DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kFrameLengthSamples),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kFrameLengthSamples)));
}
@ -1157,28 +1157,28 @@ TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
InSequence sequence; // Dummy variable.
// Mock decoder works normally the first 2 times.
EXPECT_CALL(mock_decoder,
Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
.Times(2)
.WillRepeatedly(
DoAll(SetArrayArgument<4>(dummy_output,
DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kFrameLengthSamples),
SetArgPointee<5>(AudioDecoder::kComfortNoise),
SetArgPointee<4>(AudioDecoder::kComfortNoise),
Return(kFrameLengthSamples)))
.RetiresOnSaturation();
// Then mock decoder fails. A common reason for failure can be buffer being
// too short
EXPECT_CALL(mock_decoder, Decode(nullptr, 0, kSampleRateHz, _, _, _))
EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
.WillOnce(Return(-1))
.RetiresOnSaturation();
// Mock decoder finally returns to normal.
EXPECT_CALL(mock_decoder, Decode(nullptr, 0, kSampleRateHz, _, _, _))
EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
.Times(2)
.WillRepeatedly(
DoAll(SetArrayArgument<4>(dummy_output,
dummy_output + kFrameLengthSamples),
SetArgPointee<5>(AudioDecoder::kComfortNoise),
DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kFrameLengthSamples),
SetArgPointee<4>(AudioDecoder::kComfortNoise),
Return(kFrameLengthSamples)));
}