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:
@@ -402,6 +402,11 @@ NetEqBackgroundNoiseMode NetEqImpl::BackgroundNoiseMode() const {
|
|||||||
return background_noise_->mode();
|
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.
|
// Methods below this line are private.
|
||||||
|
|
||||||
int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header,
|
int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header,
|
||||||
|
|||||||
@@ -200,6 +200,9 @@ class NetEqImpl : public webrtc::NetEq {
|
|||||||
// Gets background noise mode.
|
// Gets background noise mode.
|
||||||
virtual NetEqBackgroundNoiseMode BackgroundNoiseMode() const;
|
virtual NetEqBackgroundNoiseMode BackgroundNoiseMode() const;
|
||||||
|
|
||||||
|
// This accessor method is only intended for testing purposes.
|
||||||
|
virtual const SyncBuffer* sync_buffer_for_test() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int kOutputSizeMs = 10;
|
static const int kOutputSizeMs = 10;
|
||||||
static const int kMaxFrameSize = 2880; // 60 ms @ 48 kHz.
|
static const int kMaxFrameSize = 2880; // 60 ms @ 48 kHz.
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "webrtc/modules/audio_coding/neteq4/mock/mock_packet_buffer.h"
|
#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/mock/mock_payload_splitter.h"
|
||||||
#include "webrtc/modules/audio_coding/neteq4/preemptive_expand.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"
|
#include "webrtc/modules/audio_coding/neteq4/timestamp_scaler.h"
|
||||||
|
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
@@ -396,4 +397,98 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
|
|||||||
EXPECT_EQ(rtp_header.header.sequenceNumber, test_header->sequenceNumber);
|
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
|
} // namespace webrtc
|
||||||
|
|||||||
Reference in New Issue
Block a user