blob: 1b1e950a82f7743052c379ac0d0b09166464f330 [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11/*
12 * This file includes unit tests for NetEQ.
13 */
14
15#include "webrtc/modules/audio_coding/neteq4/interface/neteq.h"
16
17#include <stdlib.h>
18#include <string.h> // memset
19
turaj@webrtc.orgff43c852013-09-25 00:07:27 +000020#include <cmath>
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000021#include <string>
22#include <vector>
23
turaj@webrtc.orga6101d72013-10-01 22:01:09 +000024#include "gflags/gflags.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000025#include "gtest/gtest.h"
26#include "webrtc/modules/audio_coding/neteq4/test/NETEQTEST_RTPpacket.h"
turaj@webrtc.orgff43c852013-09-25 00:07:27 +000027#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000028#include "webrtc/test/testsupport/fileutils.h"
henrike@webrtc.orga950300b2013-07-08 18:53:54 +000029#include "webrtc/test/testsupport/gtest_disable.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000030#include "webrtc/typedefs.h"
31
turaj@webrtc.orga6101d72013-10-01 22:01:09 +000032DEFINE_bool(gen_ref, false, "Generate reference files.");
33
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000034namespace webrtc {
35
turaj@webrtc.org7b75ac62013-09-26 00:27:56 +000036static bool IsAllZero(const int16_t* buf, int buf_length) {
37 bool all_zero = true;
38 for (int n = 0; n < buf_length && all_zero; ++n)
39 all_zero = buf[n] == 0;
40 return all_zero;
41}
42
43static bool IsAllNonZero(const int16_t* buf, int buf_length) {
44 bool all_non_zero = true;
45 for (int n = 0; n < buf_length && all_non_zero; ++n)
46 all_non_zero = buf[n] != 0;
47 return all_non_zero;
48}
49
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000050class RefFiles {
51 public:
52 RefFiles(const std::string& input_file, const std::string& output_file);
53 ~RefFiles();
54 template<class T> void ProcessReference(const T& test_results);
55 template<typename T, size_t n> void ProcessReference(
56 const T (&test_results)[n],
57 size_t length);
58 template<typename T, size_t n> void WriteToFile(
59 const T (&test_results)[n],
60 size_t length);
61 template<typename T, size_t n> void ReadFromFileAndCompare(
62 const T (&test_results)[n],
63 size_t length);
64 void WriteToFile(const NetEqNetworkStatistics& stats);
65 void ReadFromFileAndCompare(const NetEqNetworkStatistics& stats);
66 void WriteToFile(const RtcpStatistics& stats);
67 void ReadFromFileAndCompare(const RtcpStatistics& stats);
68
69 FILE* input_fp_;
70 FILE* output_fp_;
71};
72
73RefFiles::RefFiles(const std::string &input_file,
74 const std::string &output_file)
75 : input_fp_(NULL),
76 output_fp_(NULL) {
77 if (!input_file.empty()) {
78 input_fp_ = fopen(input_file.c_str(), "rb");
79 EXPECT_TRUE(input_fp_ != NULL);
80 }
81 if (!output_file.empty()) {
82 output_fp_ = fopen(output_file.c_str(), "wb");
83 EXPECT_TRUE(output_fp_ != NULL);
84 }
85}
86
87RefFiles::~RefFiles() {
88 if (input_fp_) {
89 EXPECT_EQ(EOF, fgetc(input_fp_)); // Make sure that we reached the end.
90 fclose(input_fp_);
91 }
92 if (output_fp_) fclose(output_fp_);
93}
94
95template<class T>
96void RefFiles::ProcessReference(const T& test_results) {
97 WriteToFile(test_results);
98 ReadFromFileAndCompare(test_results);
99}
100
101template<typename T, size_t n>
102void RefFiles::ProcessReference(const T (&test_results)[n], size_t length) {
103 WriteToFile(test_results, length);
104 ReadFromFileAndCompare(test_results, length);
105}
106
107template<typename T, size_t n>
108void RefFiles::WriteToFile(const T (&test_results)[n], size_t length) {
109 if (output_fp_) {
110 ASSERT_EQ(length, fwrite(&test_results, sizeof(T), length, output_fp_));
111 }
112}
113
114template<typename T, size_t n>
115void RefFiles::ReadFromFileAndCompare(const T (&test_results)[n],
116 size_t length) {
117 if (input_fp_) {
118 // Read from ref file.
119 T* ref = new T[length];
120 ASSERT_EQ(length, fread(ref, sizeof(T), length, input_fp_));
121 // Compare
122 ASSERT_EQ(0, memcmp(&test_results, ref, sizeof(T) * length));
123 delete [] ref;
124 }
125}
126
127void RefFiles::WriteToFile(const NetEqNetworkStatistics& stats) {
128 if (output_fp_) {
129 ASSERT_EQ(1u, fwrite(&stats, sizeof(NetEqNetworkStatistics), 1,
130 output_fp_));
131 }
132}
133
134void RefFiles::ReadFromFileAndCompare(
135 const NetEqNetworkStatistics& stats) {
136 if (input_fp_) {
137 // Read from ref file.
138 size_t stat_size = sizeof(NetEqNetworkStatistics);
139 NetEqNetworkStatistics ref_stats;
140 ASSERT_EQ(1u, fread(&ref_stats, stat_size, 1, input_fp_));
141 // Compare
142 EXPECT_EQ(0, memcmp(&stats, &ref_stats, stat_size));
143 }
144}
145
146void RefFiles::WriteToFile(const RtcpStatistics& stats) {
147 if (output_fp_) {
148 ASSERT_EQ(1u, fwrite(&(stats.fraction_lost), sizeof(stats.fraction_lost), 1,
149 output_fp_));
150 ASSERT_EQ(1u, fwrite(&(stats.cumulative_lost),
151 sizeof(stats.cumulative_lost), 1, output_fp_));
sprang@webrtc.orgfe5d36b2013-10-28 09:21:07 +0000152 ASSERT_EQ(1u, fwrite(&(stats.extended_max_sequence_number),
153 sizeof(stats.extended_max_sequence_number), 1,
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000154 output_fp_));
155 ASSERT_EQ(1u, fwrite(&(stats.jitter), sizeof(stats.jitter), 1,
156 output_fp_));
157 }
158}
159
160void RefFiles::ReadFromFileAndCompare(
161 const RtcpStatistics& stats) {
162 if (input_fp_) {
163 // Read from ref file.
164 RtcpStatistics ref_stats;
165 ASSERT_EQ(1u, fread(&(ref_stats.fraction_lost),
166 sizeof(ref_stats.fraction_lost), 1, input_fp_));
167 ASSERT_EQ(1u, fread(&(ref_stats.cumulative_lost),
168 sizeof(ref_stats.cumulative_lost), 1, input_fp_));
sprang@webrtc.orgfe5d36b2013-10-28 09:21:07 +0000169 ASSERT_EQ(1u, fread(&(ref_stats.extended_max_sequence_number),
170 sizeof(ref_stats.extended_max_sequence_number), 1,
171 input_fp_));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000172 ASSERT_EQ(1u, fread(&(ref_stats.jitter), sizeof(ref_stats.jitter), 1,
173 input_fp_));
174 // Compare
175 EXPECT_EQ(ref_stats.fraction_lost, stats.fraction_lost);
176 EXPECT_EQ(ref_stats.cumulative_lost, stats.cumulative_lost);
sprang@webrtc.orgfe5d36b2013-10-28 09:21:07 +0000177 EXPECT_EQ(ref_stats.extended_max_sequence_number,
178 stats.extended_max_sequence_number);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000179 EXPECT_EQ(ref_stats.jitter, stats.jitter);
180 }
181}
182
183class NetEqDecodingTest : public ::testing::Test {
184 protected:
185 // NetEQ must be polled for data once every 10 ms. Thus, neither of the
186 // constants below can be changed.
187 static const int kTimeStepMs = 10;
188 static const int kBlockSize8kHz = kTimeStepMs * 8;
189 static const int kBlockSize16kHz = kTimeStepMs * 16;
190 static const int kBlockSize32kHz = kTimeStepMs * 32;
191 static const int kMaxBlockSize = kBlockSize32kHz;
192 static const int kInitSampleRateHz = 8000;
193
194 NetEqDecodingTest();
195 virtual void SetUp();
196 virtual void TearDown();
197 void SelectDecoders(NetEqDecoder* used_codec);
198 void LoadDecoders();
199 void OpenInputFile(const std::string &rtp_file);
200 void Process(NETEQTEST_RTPpacket* rtp_ptr, int* out_len);
201 void DecodeAndCompare(const std::string &rtp_file,
202 const std::string &ref_file);
203 void DecodeAndCheckStats(const std::string &rtp_file,
204 const std::string &stat_ref_file,
205 const std::string &rtcp_ref_file);
206 static void PopulateRtpInfo(int frame_index,
207 int timestamp,
208 WebRtcRTPHeader* rtp_info);
209 static void PopulateCng(int frame_index,
210 int timestamp,
211 WebRtcRTPHeader* rtp_info,
212 uint8_t* payload,
213 int* payload_len);
214
turaj@webrtc.orgff43c852013-09-25 00:07:27 +0000215 void CheckBgnOff(int sampling_rate, NetEqBackgroundNoiseMode bgn_mode);
216
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000217 NetEq* neteq_;
218 FILE* rtp_fp_;
219 unsigned int sim_clock_;
220 int16_t out_data_[kMaxBlockSize];
221 int output_sample_rate_;
222};
223
224// Allocating the static const so that it can be passed by reference.
225const int NetEqDecodingTest::kTimeStepMs;
226const int NetEqDecodingTest::kBlockSize8kHz;
227const int NetEqDecodingTest::kBlockSize16kHz;
228const int NetEqDecodingTest::kBlockSize32kHz;
229const int NetEqDecodingTest::kMaxBlockSize;
230const int NetEqDecodingTest::kInitSampleRateHz;
231
232NetEqDecodingTest::NetEqDecodingTest()
233 : neteq_(NULL),
234 rtp_fp_(NULL),
235 sim_clock_(0),
236 output_sample_rate_(kInitSampleRateHz) {
237 memset(out_data_, 0, sizeof(out_data_));
238}
239
240void NetEqDecodingTest::SetUp() {
241 neteq_ = NetEq::Create(kInitSampleRateHz);
242 ASSERT_TRUE(neteq_);
243 LoadDecoders();
244}
245
246void NetEqDecodingTest::TearDown() {
247 delete neteq_;
248 if (rtp_fp_)
249 fclose(rtp_fp_);
250}
251
252void NetEqDecodingTest::LoadDecoders() {
253 // Load PCMu.
254 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderPCMu, 0));
255 // Load PCMa.
256 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderPCMa, 8));
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000257#ifndef WEBRTC_ANDROID
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000258 // Load iLBC.
259 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderILBC, 102));
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000260#endif // WEBRTC_ANDROID
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000261 // Load iSAC.
262 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderISAC, 103));
263 // Load iSAC SWB.
264 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderISACswb, 104));
henrik.lundin@webrtc.orgac59dba2013-01-31 09:55:24 +0000265 // Load iSAC FB.
266 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderISACfb, 105));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000267 // Load PCM16B nb.
268 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderPCM16B, 93));
269 // Load PCM16B wb.
270 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderPCM16Bwb, 94));
271 // Load PCM16B swb32.
272 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderPCM16Bswb32kHz, 95));
273 // Load CNG 8 kHz.
274 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderCNGnb, 13));
275 // Load CNG 16 kHz.
276 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderCNGwb, 98));
277}
278
279void NetEqDecodingTest::OpenInputFile(const std::string &rtp_file) {
280 rtp_fp_ = fopen(rtp_file.c_str(), "rb");
281 ASSERT_TRUE(rtp_fp_ != NULL);
282 ASSERT_EQ(0, NETEQTEST_RTPpacket::skipFileHeader(rtp_fp_));
283}
284
285void NetEqDecodingTest::Process(NETEQTEST_RTPpacket* rtp, int* out_len) {
286 // Check if time to receive.
287 while ((sim_clock_ >= rtp->time()) &&
288 (rtp->dataLen() >= 0)) {
289 if (rtp->dataLen() > 0) {
290 WebRtcRTPHeader rtpInfo;
291 rtp->parseHeader(&rtpInfo);
292 ASSERT_EQ(0, neteq_->InsertPacket(
293 rtpInfo,
294 rtp->payload(),
295 rtp->payloadLen(),
296 rtp->time() * (output_sample_rate_ / 1000)));
297 }
298 // Get next packet.
299 ASSERT_NE(-1, rtp->readFromFile(rtp_fp_));
300 }
301
henrik.lundin@webrtc.orge1d468c2013-01-30 07:37:20 +0000302 // Get audio from NetEq.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000303 NetEqOutputType type;
304 int num_channels;
305 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, out_len,
306 &num_channels, &type));
307 ASSERT_TRUE((*out_len == kBlockSize8kHz) ||
308 (*out_len == kBlockSize16kHz) ||
309 (*out_len == kBlockSize32kHz));
310 output_sample_rate_ = *out_len / 10 * 1000;
311
312 // Increase time.
313 sim_clock_ += kTimeStepMs;
314}
315
316void NetEqDecodingTest::DecodeAndCompare(const std::string &rtp_file,
317 const std::string &ref_file) {
318 OpenInputFile(rtp_file);
319
320 std::string ref_out_file = "";
321 if (ref_file.empty()) {
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000322 ref_out_file = webrtc::test::OutputPath() + "neteq_universal_ref.pcm";
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000323 }
324 RefFiles ref_files(ref_file, ref_out_file);
325
326 NETEQTEST_RTPpacket rtp;
327 ASSERT_GT(rtp.readFromFile(rtp_fp_), 0);
328 int i = 0;
329 while (rtp.dataLen() >= 0) {
330 std::ostringstream ss;
331 ss << "Lap number " << i++ << " in DecodeAndCompare while loop";
332 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
333 int out_len;
334 ASSERT_NO_FATAL_FAILURE(Process(&rtp, &out_len));
335 ASSERT_NO_FATAL_FAILURE(ref_files.ProcessReference(out_data_, out_len));
336 }
337}
338
339void NetEqDecodingTest::DecodeAndCheckStats(const std::string &rtp_file,
340 const std::string &stat_ref_file,
341 const std::string &rtcp_ref_file) {
342 OpenInputFile(rtp_file);
343 std::string stat_out_file = "";
344 if (stat_ref_file.empty()) {
345 stat_out_file = webrtc::test::OutputPath() +
346 "neteq_network_stats.dat";
347 }
348 RefFiles network_stat_files(stat_ref_file, stat_out_file);
349
350 std::string rtcp_out_file = "";
351 if (rtcp_ref_file.empty()) {
352 rtcp_out_file = webrtc::test::OutputPath() +
353 "neteq_rtcp_stats.dat";
354 }
355 RefFiles rtcp_stat_files(rtcp_ref_file, rtcp_out_file);
356
357 NETEQTEST_RTPpacket rtp;
358 ASSERT_GT(rtp.readFromFile(rtp_fp_), 0);
359 while (rtp.dataLen() >= 0) {
360 int out_len;
361 Process(&rtp, &out_len);
362
363 // Query the network statistics API once per second
364 if (sim_clock_ % 1000 == 0) {
365 // Process NetworkStatistics.
366 NetEqNetworkStatistics network_stats;
367 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats));
368 network_stat_files.ProcessReference(network_stats);
369
370 // Process RTCPstat.
371 RtcpStatistics rtcp_stats;
372 neteq_->GetRtcpStatistics(&rtcp_stats);
373 rtcp_stat_files.ProcessReference(rtcp_stats);
374 }
375 }
376}
377
378void NetEqDecodingTest::PopulateRtpInfo(int frame_index,
379 int timestamp,
380 WebRtcRTPHeader* rtp_info) {
381 rtp_info->header.sequenceNumber = frame_index;
382 rtp_info->header.timestamp = timestamp;
383 rtp_info->header.ssrc = 0x1234; // Just an arbitrary SSRC.
384 rtp_info->header.payloadType = 94; // PCM16b WB codec.
385 rtp_info->header.markerBit = 0;
386}
387
388void NetEqDecodingTest::PopulateCng(int frame_index,
389 int timestamp,
390 WebRtcRTPHeader* rtp_info,
391 uint8_t* payload,
392 int* payload_len) {
393 rtp_info->header.sequenceNumber = frame_index;
394 rtp_info->header.timestamp = timestamp;
395 rtp_info->header.ssrc = 0x1234; // Just an arbitrary SSRC.
396 rtp_info->header.payloadType = 98; // WB CNG.
397 rtp_info->header.markerBit = 0;
398 payload[0] = 64; // Noise level -64 dBov, quite arbitrarily chosen.
399 *payload_len = 1; // Only noise level, no spectral parameters.
400}
401
turaj@webrtc.orgff43c852013-09-25 00:07:27 +0000402void NetEqDecodingTest::CheckBgnOff(int sampling_rate_hz,
403 NetEqBackgroundNoiseMode bgn_mode) {
404 int expected_samples_per_channel = 0;
405 uint8_t payload_type = 0xFF; // Invalid.
406 if (sampling_rate_hz == 8000) {
407 expected_samples_per_channel = kBlockSize8kHz;
408 payload_type = 93; // PCM 16, 8 kHz.
409 } else if (sampling_rate_hz == 16000) {
410 expected_samples_per_channel = kBlockSize16kHz;
411 payload_type = 94; // PCM 16, 16 kHZ.
412 } else if (sampling_rate_hz == 32000) {
413 expected_samples_per_channel = kBlockSize32kHz;
414 payload_type = 95; // PCM 16, 32 kHz.
415 } else {
416 ASSERT_TRUE(false); // Unsupported test case.
417 }
418
419 NetEqOutputType type;
420 int16_t output[kBlockSize32kHz]; // Maximum size is chosen.
421 int16_t input[kBlockSize32kHz]; // Maximum size is chosen.
422
423 // Payload of 10 ms of PCM16 32 kHz.
424 uint8_t payload[kBlockSize32kHz * sizeof(int16_t)];
425
426 // Random payload.
427 for (int n = 0; n < expected_samples_per_channel; ++n) {
428 input[n] = (rand() & ((1 << 10) - 1)) - ((1 << 5) - 1);
429 }
430 int enc_len_bytes = WebRtcPcm16b_EncodeW16(
431 input, expected_samples_per_channel, reinterpret_cast<int16_t*>(payload));
432 ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2);
433
434 WebRtcRTPHeader rtp_info;
435 PopulateRtpInfo(0, 0, &rtp_info);
436 rtp_info.header.payloadType = payload_type;
437
438 int number_channels = 0;
439 int samples_per_channel = 0;
440
441 uint32_t receive_timestamp = 0;
442 for (int n = 0; n < 10; ++n) { // Insert few packets and get audio.
443 number_channels = 0;
444 samples_per_channel = 0;
445 ASSERT_EQ(0, neteq_->InsertPacket(
446 rtp_info, payload, enc_len_bytes, receive_timestamp));
447 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize32kHz, output, &samples_per_channel,
448 &number_channels, &type));
449 ASSERT_EQ(1, number_channels);
450 ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
451 ASSERT_EQ(kOutputNormal, type);
452
453 // Next packet.
454 rtp_info.header.timestamp += expected_samples_per_channel;
455 rtp_info.header.sequenceNumber++;
456 receive_timestamp += expected_samples_per_channel;
457 }
458
459 number_channels = 0;
460 samples_per_channel = 0;
461
462 // Get audio without inserting packets, expecting PLC and PLC-to-CNG. Pull one
463 // frame without checking speech-type. This is the first frame pulled without
464 // inserting any packet, and might not be labeled as PCL.
465 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize32kHz, output, &samples_per_channel,
466 &number_channels, &type));
467 ASSERT_EQ(1, number_channels);
468 ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
469
470 // To be able to test the fading of background noise we need at lease to pull
471 // 610 frames.
472 const int kFadingThreshold = 610;
473
474 // Test several CNG-to-PLC packet for the expected behavior. The number 20 is
475 // arbitrary, but sufficiently large to test enough number of frames.
476 const int kNumPlcToCngTestFrames = 20;
477 bool plc_to_cng = false;
478 for (int n = 0; n < kFadingThreshold + kNumPlcToCngTestFrames; ++n) {
479 number_channels = 0;
480 samples_per_channel = 0;
481 memset(output, 1, sizeof(output)); // Set to non-zero.
482 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize32kHz, output, &samples_per_channel,
483 &number_channels, &type));
484 ASSERT_EQ(1, number_channels);
485 ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
486 if (type == kOutputPLCtoCNG) {
487 plc_to_cng = true;
488 double sum_squared = 0;
489 for (int k = 0; k < number_channels * samples_per_channel; ++k)
490 sum_squared += output[k] * output[k];
491 if (bgn_mode == kBgnOn) {
492 EXPECT_NE(0, sum_squared);
493 } else if (bgn_mode == kBgnOff || n > kFadingThreshold) {
494 EXPECT_EQ(0, sum_squared);
495 }
496 } else {
497 EXPECT_EQ(kOutputPLC, type);
498 }
499 }
500 EXPECT_TRUE(plc_to_cng); // Just to be sure that PLC-to-CNG has occurred.
501}
502
kjellander@webrtc.org6eba2772013-06-04 05:46:37 +0000503#if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS)
504// Disabled for Windows 64-bit until webrtc:1458 is fixed.
505#define MAYBE_TestBitExactness DISABLED_TestBitExactness
506#else
507#define MAYBE_TestBitExactness TestBitExactness
508#endif
509
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000510TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(MAYBE_TestBitExactness)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000511 const std::string kInputRtpFile = webrtc::test::ProjectRootPath() +
henrik.lundin@webrtc.org73deaad2013-01-31 13:32:51 +0000512 "resources/audio_coding/neteq_universal_new.rtp";
henrik.lundin@webrtc.org6e3968f2013-01-31 15:07:30 +0000513#if defined(_MSC_VER) && (_MSC_VER >= 1700)
514 // For Visual Studio 2012 and later, we will have to use the generic reference
515 // file, rather than the windows-specific one.
516 const std::string kInputRefFile = webrtc::test::ProjectRootPath() +
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000517 "resources/audio_coding/neteq4_universal_ref.pcm";
henrik.lundin@webrtc.org6e3968f2013-01-31 15:07:30 +0000518#else
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000519 const std::string kInputRefFile =
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000520 webrtc::test::ResourcePath("audio_coding/neteq4_universal_ref", "pcm");
henrik.lundin@webrtc.org6e3968f2013-01-31 15:07:30 +0000521#endif
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000522
523 if (FLAGS_gen_ref) {
524 DecodeAndCompare(kInputRtpFile, "");
525 } else {
526 DecodeAndCompare(kInputRtpFile, kInputRefFile);
527 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000528}
529
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000530TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(TestNetworkStatistics)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000531 const std::string kInputRtpFile = webrtc::test::ProjectRootPath() +
henrik.lundin@webrtc.org73deaad2013-01-31 13:32:51 +0000532 "resources/audio_coding/neteq_universal_new.rtp";
henrik.lundin@webrtc.org6e3968f2013-01-31 15:07:30 +0000533#if defined(_MSC_VER) && (_MSC_VER >= 1700)
534 // For Visual Studio 2012 and later, we will have to use the generic reference
535 // file, rather than the windows-specific one.
536 const std::string kNetworkStatRefFile = webrtc::test::ProjectRootPath() +
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000537 "resources/audio_coding/neteq4_network_stats.dat";
henrik.lundin@webrtc.org6e3968f2013-01-31 15:07:30 +0000538#else
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000539 const std::string kNetworkStatRefFile =
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000540 webrtc::test::ResourcePath("audio_coding/neteq4_network_stats", "dat");
henrik.lundin@webrtc.org6e3968f2013-01-31 15:07:30 +0000541#endif
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000542 const std::string kRtcpStatRefFile =
turaj@webrtc.orga6101d72013-10-01 22:01:09 +0000543 webrtc::test::ResourcePath("audio_coding/neteq4_rtcp_stats", "dat");
544 if (FLAGS_gen_ref) {
545 DecodeAndCheckStats(kInputRtpFile, "", "");
546 } else {
547 DecodeAndCheckStats(kInputRtpFile, kNetworkStatRefFile, kRtcpStatRefFile);
548 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000549}
550
551// TODO(hlundin): Re-enable test once the statistics interface is up and again.
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000552TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(TestFrameWaitingTimeStatistics)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000553 // Use fax mode to avoid time-scaling. This is to simplify the testing of
554 // packet waiting times in the packet buffer.
555 neteq_->SetPlayoutMode(kPlayoutFax);
556 ASSERT_EQ(kPlayoutFax, neteq_->PlayoutMode());
557 // Insert 30 dummy packets at once. Each packet contains 10 ms 16 kHz audio.
558 size_t num_frames = 30;
559 const int kSamples = 10 * 16;
560 const int kPayloadBytes = kSamples * 2;
561 for (size_t i = 0; i < num_frames; ++i) {
562 uint16_t payload[kSamples] = {0};
563 WebRtcRTPHeader rtp_info;
564 rtp_info.header.sequenceNumber = i;
565 rtp_info.header.timestamp = i * kSamples;
566 rtp_info.header.ssrc = 0x1234; // Just an arbitrary SSRC.
567 rtp_info.header.payloadType = 94; // PCM16b WB codec.
568 rtp_info.header.markerBit = 0;
569 ASSERT_EQ(0, neteq_->InsertPacket(
570 rtp_info,
571 reinterpret_cast<uint8_t*>(payload),
572 kPayloadBytes, 0));
573 }
574 // Pull out all data.
575 for (size_t i = 0; i < num_frames; ++i) {
576 int out_len;
577 int num_channels;
578 NetEqOutputType type;
579 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
580 &num_channels, &type));
581 ASSERT_EQ(kBlockSize16kHz, out_len);
582 }
583
584 std::vector<int> waiting_times;
585 neteq_->WaitingTimes(&waiting_times);
586 int len = waiting_times.size();
587 EXPECT_EQ(num_frames, waiting_times.size());
588 // Since all frames are dumped into NetEQ at once, but pulled out with 10 ms
589 // spacing (per definition), we expect the delay to increase with 10 ms for
590 // each packet.
591 for (size_t i = 0; i < waiting_times.size(); ++i) {
592 EXPECT_EQ(static_cast<int>(i + 1) * 10, waiting_times[i]);
593 }
594
595 // Check statistics again and make sure it's been reset.
596 neteq_->WaitingTimes(&waiting_times);
597 len = waiting_times.size();
598 EXPECT_EQ(0, len);
599
600 // Process > 100 frames, and make sure that that we get statistics
601 // only for 100 frames. Note the new SSRC, causing NetEQ to reset.
602 num_frames = 110;
603 for (size_t i = 0; i < num_frames; ++i) {
604 uint16_t payload[kSamples] = {0};
605 WebRtcRTPHeader rtp_info;
606 rtp_info.header.sequenceNumber = i;
607 rtp_info.header.timestamp = i * kSamples;
608 rtp_info.header.ssrc = 0x1235; // Just an arbitrary SSRC.
609 rtp_info.header.payloadType = 94; // PCM16b WB codec.
610 rtp_info.header.markerBit = 0;
611 ASSERT_EQ(0, neteq_->InsertPacket(
612 rtp_info,
613 reinterpret_cast<uint8_t*>(payload),
614 kPayloadBytes, 0));
615 int out_len;
616 int num_channels;
617 NetEqOutputType type;
618 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
619 &num_channels, &type));
620 ASSERT_EQ(kBlockSize16kHz, out_len);
621 }
622
623 neteq_->WaitingTimes(&waiting_times);
624 EXPECT_EQ(100u, waiting_times.size());
625}
626
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000627TEST_F(NetEqDecodingTest,
628 DISABLED_ON_ANDROID(TestAverageInterArrivalTimeNegative)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000629 const int kNumFrames = 3000; // Needed for convergence.
630 int frame_index = 0;
631 const int kSamples = 10 * 16;
632 const int kPayloadBytes = kSamples * 2;
633 while (frame_index < kNumFrames) {
634 // Insert one packet each time, except every 10th time where we insert two
635 // packets at once. This will create a negative clock-drift of approx. 10%.
636 int num_packets = (frame_index % 10 == 0 ? 2 : 1);
637 for (int n = 0; n < num_packets; ++n) {
638 uint8_t payload[kPayloadBytes] = {0};
639 WebRtcRTPHeader rtp_info;
640 PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info);
641 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
642 ++frame_index;
643 }
644
645 // Pull out data once.
646 int out_len;
647 int num_channels;
648 NetEqOutputType type;
649 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
650 &num_channels, &type));
651 ASSERT_EQ(kBlockSize16kHz, out_len);
652 }
653
654 NetEqNetworkStatistics network_stats;
655 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats));
656 EXPECT_EQ(-103196, network_stats.clockdrift_ppm);
657}
658
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000659TEST_F(NetEqDecodingTest,
660 DISABLED_ON_ANDROID(TestAverageInterArrivalTimePositive)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000661 const int kNumFrames = 5000; // Needed for convergence.
662 int frame_index = 0;
663 const int kSamples = 10 * 16;
664 const int kPayloadBytes = kSamples * 2;
665 for (int i = 0; i < kNumFrames; ++i) {
666 // Insert one packet each time, except every 10th time where we don't insert
667 // any packet. This will create a positive clock-drift of approx. 11%.
668 int num_packets = (i % 10 == 9 ? 0 : 1);
669 for (int n = 0; n < num_packets; ++n) {
670 uint8_t payload[kPayloadBytes] = {0};
671 WebRtcRTPHeader rtp_info;
672 PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info);
673 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
674 ++frame_index;
675 }
676
677 // Pull out data once.
678 int out_len;
679 int num_channels;
680 NetEqOutputType type;
681 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
682 &num_channels, &type));
683 ASSERT_EQ(kBlockSize16kHz, out_len);
684 }
685
686 NetEqNetworkStatistics network_stats;
687 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats));
688 EXPECT_EQ(110946, network_stats.clockdrift_ppm);
689}
690
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000691TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(LongCngWithClockDrift)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000692 uint16_t seq_no = 0;
693 uint32_t timestamp = 0;
694 const int kFrameSizeMs = 30;
695 const int kSamples = kFrameSizeMs * 16;
696 const int kPayloadBytes = kSamples * 2;
697 // Apply a clock drift of -25 ms / s (sender faster than receiver).
698 const double kDriftFactor = 1000.0 / (1000.0 + 25.0);
699 double next_input_time_ms = 0.0;
700 double t_ms;
701 NetEqOutputType type;
702
703 // Insert speech for 5 seconds.
704 const int kSpeechDurationMs = 5000;
705 for (t_ms = 0; t_ms < kSpeechDurationMs; t_ms += 10) {
706 // Each turn in this for loop is 10 ms.
707 while (next_input_time_ms <= t_ms) {
708 // Insert one 30 ms speech frame.
709 uint8_t payload[kPayloadBytes] = {0};
710 WebRtcRTPHeader rtp_info;
711 PopulateRtpInfo(seq_no, timestamp, &rtp_info);
712 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
713 ++seq_no;
714 timestamp += kSamples;
715 next_input_time_ms += static_cast<double>(kFrameSizeMs) * kDriftFactor;
716 }
717 // Pull out data once.
718 int out_len;
719 int num_channels;
720 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
721 &num_channels, &type));
722 ASSERT_EQ(kBlockSize16kHz, out_len);
723 }
724
725 EXPECT_EQ(kOutputNormal, type);
726 int32_t delay_before = timestamp - neteq_->PlayoutTimestamp();
727
728 // Insert CNG for 1 minute (= 60000 ms).
729 const int kCngPeriodMs = 100;
730 const int kCngPeriodSamples = kCngPeriodMs * 16; // Period in 16 kHz samples.
731 const int kCngDurationMs = 60000;
732 for (; t_ms < kSpeechDurationMs + kCngDurationMs; t_ms += 10) {
733 // Each turn in this for loop is 10 ms.
734 while (next_input_time_ms <= t_ms) {
735 // Insert one CNG frame each 100 ms.
736 uint8_t payload[kPayloadBytes];
737 int payload_len;
738 WebRtcRTPHeader rtp_info;
739 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len);
740 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, payload_len, 0));
741 ++seq_no;
742 timestamp += kCngPeriodSamples;
743 next_input_time_ms += static_cast<double>(kCngPeriodMs) * kDriftFactor;
744 }
745 // Pull out data once.
746 int out_len;
747 int num_channels;
748 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
749 &num_channels, &type));
750 ASSERT_EQ(kBlockSize16kHz, out_len);
751 }
752
753 EXPECT_EQ(kOutputCNG, type);
754
755 // Insert speech again until output type is speech.
756 while (type != kOutputNormal) {
757 // Each turn in this for loop is 10 ms.
758 while (next_input_time_ms <= t_ms) {
759 // Insert one 30 ms speech frame.
760 uint8_t payload[kPayloadBytes] = {0};
761 WebRtcRTPHeader rtp_info;
762 PopulateRtpInfo(seq_no, timestamp, &rtp_info);
763 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
764 ++seq_no;
765 timestamp += kSamples;
766 next_input_time_ms += static_cast<double>(kFrameSizeMs) * kDriftFactor;
767 }
768 // Pull out data once.
769 int out_len;
770 int num_channels;
771 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
772 &num_channels, &type));
773 ASSERT_EQ(kBlockSize16kHz, out_len);
774 // Increase clock.
775 t_ms += 10;
776 }
777
778 int32_t delay_after = timestamp - neteq_->PlayoutTimestamp();
779 // Compare delay before and after, and make sure it differs less than 20 ms.
780 EXPECT_LE(delay_after, delay_before + 20 * 16);
781 EXPECT_GE(delay_after, delay_before - 20 * 16);
782}
783
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000784TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(UnknownPayloadType)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000785 const int kPayloadBytes = 100;
786 uint8_t payload[kPayloadBytes] = {0};
787 WebRtcRTPHeader rtp_info;
788 PopulateRtpInfo(0, 0, &rtp_info);
789 rtp_info.header.payloadType = 1; // Not registered as a decoder.
790 EXPECT_EQ(NetEq::kFail,
791 neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
792 EXPECT_EQ(NetEq::kUnknownRtpPayloadType, neteq_->LastError());
793}
794
minyue@webrtc.org7bb54362013-08-06 05:40:57 +0000795TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(OversizePacket)) {
796 // Payload size is greater than packet buffer size
797 const int kPayloadBytes = NetEq::kMaxBytesInBuffer + 1;
798 uint8_t payload[kPayloadBytes] = {0};
799 WebRtcRTPHeader rtp_info;
800 PopulateRtpInfo(0, 0, &rtp_info);
801 rtp_info.header.payloadType = 103; // iSAC, no packet splitting.
802 EXPECT_EQ(NetEq::kFail,
803 neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
804 EXPECT_EQ(NetEq::kOversizePacket, neteq_->LastError());
805}
806
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000807TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(DecoderError)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000808 const int kPayloadBytes = 100;
809 uint8_t payload[kPayloadBytes] = {0};
810 WebRtcRTPHeader rtp_info;
811 PopulateRtpInfo(0, 0, &rtp_info);
812 rtp_info.header.payloadType = 103; // iSAC, but the payload is invalid.
813 EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0));
814 NetEqOutputType type;
815 // Set all of |out_data_| to 1, and verify that it was set to 0 by the call
816 // to GetAudio.
817 for (int i = 0; i < kMaxBlockSize; ++i) {
818 out_data_[i] = 1;
819 }
820 int num_channels;
821 int samples_per_channel;
822 EXPECT_EQ(NetEq::kFail,
823 neteq_->GetAudio(kMaxBlockSize, out_data_,
824 &samples_per_channel, &num_channels, &type));
825 // Verify that there is a decoder error to check.
826 EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
827 // Code 6730 is an iSAC error code.
828 EXPECT_EQ(6730, neteq_->LastDecoderError());
829 // Verify that the first 160 samples are set to 0, and that the remaining
830 // samples are left unmodified.
831 static const int kExpectedOutputLength = 160; // 10 ms at 16 kHz sample rate.
832 for (int i = 0; i < kExpectedOutputLength; ++i) {
833 std::ostringstream ss;
834 ss << "i = " << i;
835 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
836 EXPECT_EQ(0, out_data_[i]);
837 }
838 for (int i = kExpectedOutputLength; i < kMaxBlockSize; ++i) {
839 std::ostringstream ss;
840 ss << "i = " << i;
841 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
842 EXPECT_EQ(1, out_data_[i]);
843 }
844}
845
henrike@webrtc.orga950300b2013-07-08 18:53:54 +0000846TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(GetAudioBeforeInsertPacket)) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000847 NetEqOutputType type;
848 // Set all of |out_data_| to 1, and verify that it was set to 0 by the call
849 // to GetAudio.
850 for (int i = 0; i < kMaxBlockSize; ++i) {
851 out_data_[i] = 1;
852 }
853 int num_channels;
854 int samples_per_channel;
855 EXPECT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_,
856 &samples_per_channel,
857 &num_channels, &type));
858 // Verify that the first block of samples is set to 0.
859 static const int kExpectedOutputLength =
860 kInitSampleRateHz / 100; // 10 ms at initial sample rate.
861 for (int i = 0; i < kExpectedOutputLength; ++i) {
862 std::ostringstream ss;
863 ss << "i = " << i;
864 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
865 EXPECT_EQ(0, out_data_[i]);
866 }
867}
turaj@webrtc.orgff43c852013-09-25 00:07:27 +0000868
turaj@webrtc.org3fdeddb2013-09-25 22:19:22 +0000869TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(BackgroundNoise)) {
turaj@webrtc.orgff43c852013-09-25 00:07:27 +0000870 neteq_->SetBackgroundNoiseMode(kBgnOn);
871 CheckBgnOff(8000, kBgnOn);
872 CheckBgnOff(16000, kBgnOn);
873 CheckBgnOff(32000, kBgnOn);
874 EXPECT_EQ(kBgnOn, neteq_->BackgroundNoiseMode());
875
876 neteq_->SetBackgroundNoiseMode(kBgnOff);
877 CheckBgnOff(8000, kBgnOff);
878 CheckBgnOff(16000, kBgnOff);
879 CheckBgnOff(32000, kBgnOff);
880 EXPECT_EQ(kBgnOff, neteq_->BackgroundNoiseMode());
881
882 neteq_->SetBackgroundNoiseMode(kBgnFade);
883 CheckBgnOff(8000, kBgnFade);
884 CheckBgnOff(16000, kBgnFade);
885 CheckBgnOff(32000, kBgnFade);
886 EXPECT_EQ(kBgnFade, neteq_->BackgroundNoiseMode());
887}
turaj@webrtc.org7b75ac62013-09-26 00:27:56 +0000888
889TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(SyncPacketInsert)) {
890 WebRtcRTPHeader rtp_info;
891 uint32_t receive_timestamp = 0;
892 // For the readability use the following payloads instead of the defaults of
893 // this test.
894 uint8_t kPcm16WbPayloadType = 1;
895 uint8_t kCngNbPayloadType = 2;
896 uint8_t kCngWbPayloadType = 3;
897 uint8_t kCngSwb32PayloadType = 4;
898 uint8_t kCngSwb48PayloadType = 5;
899 uint8_t kAvtPayloadType = 6;
900 uint8_t kRedPayloadType = 7;
901 uint8_t kIsacPayloadType = 9; // Payload type 8 is already registered.
902
903 // Register decoders.
904 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderPCM16Bwb,
905 kPcm16WbPayloadType));
906 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderCNGnb, kCngNbPayloadType));
907 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderCNGwb, kCngWbPayloadType));
908 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderCNGswb32kHz,
909 kCngSwb32PayloadType));
910 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderCNGswb48kHz,
911 kCngSwb48PayloadType));
912 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderAVT, kAvtPayloadType));
913 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderRED, kRedPayloadType));
914 ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderISAC, kIsacPayloadType));
915
916 PopulateRtpInfo(0, 0, &rtp_info);
917 rtp_info.header.payloadType = kPcm16WbPayloadType;
918
919 // The first packet injected cannot be sync-packet.
920 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
921
922 // Payload length of 10 ms PCM16 16 kHz.
923 const int kPayloadBytes = kBlockSize16kHz * sizeof(int16_t);
924 uint8_t payload[kPayloadBytes] = {0};
925 ASSERT_EQ(0, neteq_->InsertPacket(
926 rtp_info, payload, kPayloadBytes, receive_timestamp));
927
928 // Next packet. Last packet contained 10 ms audio.
929 rtp_info.header.sequenceNumber++;
930 rtp_info.header.timestamp += kBlockSize16kHz;
931 receive_timestamp += kBlockSize16kHz;
932
933 // Unacceptable payload types CNG, AVT (DTMF), RED.
934 rtp_info.header.payloadType = kCngNbPayloadType;
935 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
936
937 rtp_info.header.payloadType = kCngWbPayloadType;
938 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
939
940 rtp_info.header.payloadType = kCngSwb32PayloadType;
941 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
942
943 rtp_info.header.payloadType = kCngSwb48PayloadType;
944 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
945
946 rtp_info.header.payloadType = kAvtPayloadType;
947 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
948
949 rtp_info.header.payloadType = kRedPayloadType;
950 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
951
952 // Change of codec cannot be initiated with a sync packet.
953 rtp_info.header.payloadType = kIsacPayloadType;
954 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
955
956 // Change of SSRC is not allowed with a sync packet.
957 rtp_info.header.payloadType = kPcm16WbPayloadType;
958 ++rtp_info.header.ssrc;
959 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
960
961 --rtp_info.header.ssrc;
962 EXPECT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
963}
964
965// First insert several noise like packets, then sync-packets. Decoding all
966// packets should not produce error, statistics should not show any packet loss
967// and sync-packets should decode to zero.
968TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(SyncPacketDecode)) {
969 WebRtcRTPHeader rtp_info;
970 PopulateRtpInfo(0, 0, &rtp_info);
971 const int kPayloadBytes = kBlockSize16kHz * sizeof(int16_t);
972 uint8_t payload[kPayloadBytes];
973 int16_t decoded[kBlockSize16kHz];
974 for (int n = 0; n < kPayloadBytes; ++n) {
975 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence.
976 }
977 // Insert some packets which decode to noise. We are not interested in
978 // actual decoded values.
979 NetEqOutputType output_type;
980 int num_channels;
981 int samples_per_channel;
982 uint32_t receive_timestamp = 0;
983 int delay_samples = 0;
984 for (int n = 0; n < 100; ++n) {
985 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes,
986 receive_timestamp));
987 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
988 &samples_per_channel, &num_channels,
989 &output_type));
990 ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
991 ASSERT_EQ(1, num_channels);
992
993 // Even if there is RTP packet in NetEq's buffer, the first frame pulled
994 // from NetEq starts with few zero samples. Here we measure this delay.
995 if (n == 0) {
996 while(decoded[delay_samples] == 0) delay_samples++;
997 }
998 rtp_info.header.sequenceNumber++;
999 rtp_info.header.timestamp += kBlockSize16kHz;
1000 receive_timestamp += kBlockSize16kHz;
1001 }
1002 const int kNumSyncPackets = 10;
1003 // Insert sync-packets, the decoded sequence should be all-zero.
1004 for (int n = 0; n < kNumSyncPackets; ++n) {
1005 ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
1006 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
1007 &samples_per_channel, &num_channels,
1008 &output_type));
1009 ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
1010 ASSERT_EQ(1, num_channels);
1011 EXPECT_TRUE(IsAllZero(&decoded[delay_samples],
1012 samples_per_channel * num_channels - delay_samples));
1013 delay_samples = 0; // Delay only matters in the first frame.
1014 rtp_info.header.sequenceNumber++;
1015 rtp_info.header.timestamp += kBlockSize16kHz;
1016 receive_timestamp += kBlockSize16kHz;
1017 }
1018 // We insert a regular packet, if sync packet are not correctly buffered then
1019 // network statistics would show some packet loss.
1020 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes,
1021 receive_timestamp));
1022 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
1023 &samples_per_channel, &num_channels,
1024 &output_type));
1025 // Make sure the last inserted packet is decoded and there are non-zero
1026 // samples.
1027 EXPECT_FALSE(IsAllZero(decoded, samples_per_channel * num_channels));
1028 NetEqNetworkStatistics network_stats;
1029 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats));
1030 // Expecting a "clean" network.
1031 EXPECT_EQ(0, network_stats.packet_loss_rate);
1032 EXPECT_EQ(0, network_stats.expand_rate);
1033 EXPECT_EQ(0, network_stats.accelerate_rate);
1034 EXPECT_EQ(0, network_stats.preemptive_rate);
1035}
1036
1037// Test if the size of the packet buffer reported correctly when containing
1038// sync packets. Also, test if network packets override sync packets. That is to
1039// prefer decoding a network packet to a sync packet, if both have same sequence
1040// number and timestamp.
1041TEST_F(NetEqDecodingTest,
1042 DISABLED_ON_ANDROID(SyncPacketBufferSizeAndOverridenByNetworkPackets)) {
1043 WebRtcRTPHeader rtp_info;
1044 PopulateRtpInfo(0, 0, &rtp_info);
1045 const int kPayloadBytes = kBlockSize16kHz * sizeof(int16_t);
1046 uint8_t payload[kPayloadBytes];
1047 int16_t decoded[kBlockSize16kHz];
1048 for (int n = 0; n < kPayloadBytes; ++n) {
1049 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence.
1050 }
1051 // Insert some packets which decode to noise. We are not interested in
1052 // actual decoded values.
1053 NetEqOutputType output_type;
1054 int num_channels;
1055 int samples_per_channel;
1056 uint32_t receive_timestamp = 0;
1057 for (int n = 0; n < 1; ++n) {
1058 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes,
1059 receive_timestamp));
1060 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
1061 &samples_per_channel, &num_channels,
1062 &output_type));
1063 ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
1064 ASSERT_EQ(1, num_channels);
1065 rtp_info.header.sequenceNumber++;
1066 rtp_info.header.timestamp += kBlockSize16kHz;
1067 receive_timestamp += kBlockSize16kHz;
1068 }
1069 const int kNumSyncPackets = 10;
1070
1071 WebRtcRTPHeader first_sync_packet_rtp_info;
1072 memcpy(&first_sync_packet_rtp_info, &rtp_info, sizeof(rtp_info));
1073
1074 // Insert sync-packets, but no decoding.
1075 for (int n = 0; n < kNumSyncPackets; ++n) {
1076 ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
1077 rtp_info.header.sequenceNumber++;
1078 rtp_info.header.timestamp += kBlockSize16kHz;
1079 receive_timestamp += kBlockSize16kHz;
1080 }
1081 NetEqNetworkStatistics network_stats;
1082 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats));
1083 EXPECT_EQ(kNumSyncPackets * 10, network_stats.current_buffer_size_ms);
1084
1085 // Rewind |rtp_info| to that of the first sync packet.
1086 memcpy(&rtp_info, &first_sync_packet_rtp_info, sizeof(rtp_info));
1087
1088 // Insert.
1089 for (int n = 0; n < kNumSyncPackets; ++n) {
1090 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes,
1091 receive_timestamp));
1092 rtp_info.header.sequenceNumber++;
1093 rtp_info.header.timestamp += kBlockSize16kHz;
1094 receive_timestamp += kBlockSize16kHz;
1095 }
1096
1097 // Decode.
1098 for (int n = 0; n < kNumSyncPackets; ++n) {
1099 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
1100 &samples_per_channel, &num_channels,
1101 &output_type));
1102 ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
1103 ASSERT_EQ(1, num_channels);
1104 EXPECT_TRUE(IsAllNonZero(decoded, samples_per_channel * num_channels));
1105 }
1106}
1107
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001108} // namespace