New NetEq test to verify correct timestamp propagation

BUG=3154
R=turaj@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/11319004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5860 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org
2014-04-07 21:21:45 +00:00
parent 74a7c482b9
commit b287d968d9
3 changed files with 103 additions and 0 deletions

View File

@@ -402,6 +402,11 @@ NetEqBackgroundNoiseMode NetEqImpl::BackgroundNoiseMode() const {
return background_noise_->mode();
}
const SyncBuffer* NetEqImpl::sync_buffer_for_test() const {
CriticalSectionScoped lock(crit_sect_.get());
return sync_buffer_.get();
}
// Methods below this line are private.
int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header,

View File

@@ -200,6 +200,9 @@ class NetEqImpl : public webrtc::NetEq {
// Gets background noise mode.
virtual NetEqBackgroundNoiseMode BackgroundNoiseMode() const;
// This accessor method is only intended for testing purposes.
virtual const SyncBuffer* sync_buffer_for_test() const;
private:
static const int kOutputSizeMs = 10;
static const int kMaxFrameSize = 2880; // 60 ms @ 48 kHz.

View File

@@ -25,6 +25,7 @@
#include "webrtc/modules/audio_coding/neteq4/mock/mock_packet_buffer.h"
#include "webrtc/modules/audio_coding/neteq4/mock/mock_payload_splitter.h"
#include "webrtc/modules/audio_coding/neteq4/preemptive_expand.h"
#include "webrtc/modules/audio_coding/neteq4/sync_buffer.h"
#include "webrtc/modules/audio_coding/neteq4/timestamp_scaler.h"
using ::testing::Return;
@@ -396,4 +397,98 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
EXPECT_EQ(rtp_header.header.sequenceNumber, test_header->sequenceNumber);
}
// This test verifies that timestamps propagate from the incoming packets
// through to the sync buffer and to the playout timestamp.
TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
UseNoMocks();
CreateInstance();
const uint8_t kPayloadType = 17; // Just an arbitrary number.
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
const int kSampleRateHz = 8000;
const int kPayloadLengthSamples = 10 * kSampleRateHz / 1000; // 10 ms.
const size_t kPayloadLengthBytes = kPayloadLengthSamples;
uint8_t payload[kPayloadLengthBytes] = {0};
WebRtcRTPHeader rtp_header;
rtp_header.header.payloadType = kPayloadType;
rtp_header.header.sequenceNumber = 0x1234;
rtp_header.header.timestamp = 0x12345678;
rtp_header.header.ssrc = 0x87654321;
// This is a dummy decoder that produces as many output samples as the input
// has bytes. The output is an increasing series, starting at 1 for the first
// sample, and then increasing by 1 for each sample.
class CountingSamplesDecoder : public AudioDecoder {
public:
explicit CountingSamplesDecoder(enum NetEqDecoder type)
: AudioDecoder(type), next_value_(1) {}
// Produce as many samples as input bytes (|encoded_len|).
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int16_t* decoded,
SpeechType* speech_type) {
for (size_t i = 0; i < encoded_len; ++i) {
decoded[i] = next_value_++;
}
*speech_type = kSpeech;
return encoded_len;
}
virtual int Init() {
next_value_ = 1;
return 0;
}
uint16_t next_value() const { return next_value_; }
private:
int16_t next_value_;
} decoder_(kDecoderPCM16B);
EXPECT_EQ(NetEq::kOK,
neteq_->RegisterExternalDecoder(
&decoder_, kDecoderPCM16B, 8000, kPayloadType));
// Insert one packet.
EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(
rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
// Pull audio once.
const int kMaxOutputSize = 10 * kSampleRateHz / 1000;
int16_t output[kMaxOutputSize];
int samples_per_channel;
int num_channels;
NetEqOutputType type;
EXPECT_EQ(
NetEq::kOK,
neteq_->GetAudio(
kMaxOutputSize, output, &samples_per_channel, &num_channels, &type));
ASSERT_EQ(kMaxOutputSize, samples_per_channel);
EXPECT_EQ(1, num_channels);
EXPECT_EQ(kOutputNormal, type);
// Start with a simple check that the fake decoder is behaving as expected.
EXPECT_EQ(kPayloadLengthSamples, decoder_.next_value() - 1);
// The value of the last of the output samples is the same as the number of
// samples played from the decoded packet. Thus, this number + the RTP
// timestamp should match the playout timestamp.
EXPECT_EQ(rtp_header.header.timestamp + output[samples_per_channel - 1],
neteq_->PlayoutTimestamp());
// Check the timestamp for the last value in the sync buffer. This should
// be one full frame length ahead of the RTP timestamp.
const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
ASSERT_TRUE(sync_buffer != NULL);
EXPECT_EQ(rtp_header.header.timestamp + kPayloadLengthSamples,
sync_buffer->end_timestamp());
// Check that the number of samples still to play from the sync buffer add
// up with what was already played out.
EXPECT_EQ(kPayloadLengthSamples - output[samples_per_channel - 1],
static_cast<int>(sync_buffer->FutureLength()));
}
} // namespace webrtc