Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

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