12c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org/* 22c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 32c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org * 42c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org * Use of this source code is governed by a BSD-style license 52c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org * that can be found in the LICENSE file in the root of the source 62c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org * tree. An additional intellectual property rights grant can be found 72c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org * in the file PATENTS. All contributing project authors may 82c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org * be found in the AUTHORS file in the root of the source tree. 92c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org */ 102c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 112c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org#include "testing/gmock/include/gmock/gmock.h" 1200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h" 132c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org#include "webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h" 142c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h" 152c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 162c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgnamespace webrtc { 172c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgnamespace test { 182c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 192c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgusing ::testing::_; 202c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgusing ::testing::SetArgPointee; 212c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgusing ::testing::Return; 222c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 238967183bf79322c5cb3cbd99e9b7aa298228d0a2kwibergclass MockAudioDecoder final : public AudioDecoder { 242c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org public: 252c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org static const int kPacketDuration = 960; // 48 kHz * 20 ms 262c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 278967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg explicit MockAudioDecoder(size_t num_channels) 288967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg : num_channels_(num_channels), fec_enabled_(false) { 292c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 308967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg ~MockAudioDecoder() override { Die(); } 312c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org MOCK_METHOD0(Die, void()); 322c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 334376648df021fd82f25a38694e33678f802d06eaKarl Wiberg MOCK_METHOD0(Reset, void()); 342c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 352c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org int PacketDuration(const uint8_t* encoded, 362c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org size_t encoded_len) const override { 372c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org return kPacketDuration; 382c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 392c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 402c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org int PacketDurationRedundant(const uint8_t* encoded, 412c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org size_t encoded_len) const override { 422c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org return kPacketDuration; 432c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 442c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 452c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override { 462c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org return fec_enabled_; 472c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 482c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 498967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg size_t Channels() const override { return num_channels_; } 508967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg 512c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org void set_fec_enabled(bool enable_fec) { fec_enabled_ = enable_fec; } 522c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 532c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org bool fec_enabled() const { return fec_enabled_; } 542c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 557f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org protected: 567f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org // Override the following methods such that no actual payload is needed. 577f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org int DecodeInternal(const uint8_t* encoded, 587f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org size_t encoded_len, 597f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org int /*sample_rate_hz*/, 607f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org int16_t* decoded, 617f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org SpeechType* speech_type) override { 627f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org *speech_type = kSpeech; 636dba1ebd14d8cd96e6e56adad868b33fdedecc53henrik.lundin@webrtc.org memset(decoded, 0, sizeof(int16_t) * kPacketDuration * Channels()); 646dba1ebd14d8cd96e6e56adad868b33fdedecc53henrik.lundin@webrtc.org return kPacketDuration * Channels(); 657f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org } 667f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org 677f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org int DecodeRedundantInternal(const uint8_t* encoded, 687f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org size_t encoded_len, 697f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org int sample_rate_hz, 707f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org int16_t* decoded, 717f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org SpeechType* speech_type) override { 727f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded, 737f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org speech_type); 747f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org } 757f7d7e3427cc70e1b8b050283ef031e28c83699aminyue@webrtc.org 762c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org private: 778967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg const size_t num_channels_; 782c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org bool fec_enabled_; 792c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org}; 802c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 812c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgclass NetEqNetworkStatsTest : public NetEqExternalDecoderTest { 822c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org public: 832c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org static const int kPayloadSizeByte = 30; 848967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg static const int kFrameSizeMs = 20; 852c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org static const int kMaxOutputSize = 960; // 10 ms * 48 kHz * 2 channels. 862c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 872c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgenum logic { 882c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org IGNORE, 892c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EQUAL, 902c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org SMALLER_THAN, 912c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org LARGER_THAN, 922c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org}; 932c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 942c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.orgstruct NetEqNetworkStatsCheck { 952c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic current_buffer_size_ms; 962c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic preferred_buffer_size_ms; 972c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic jitter_peaks_found; 982c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic packet_loss_rate; 992c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic packet_discard_rate; 1002c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic expand_rate; 1017d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org logic speech_expand_rate; 1022c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic preemptive_rate; 1032c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic accelerate_rate; 1042c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic secondary_decoded_rate; 1052c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic clockdrift_ppm; 1062c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org logic added_zero_samples; 1072c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org NetEqNetworkStatistics stats_ref; 1082c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org}; 1092c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1102c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org NetEqNetworkStatsTest(NetEqDecoder codec, 1118967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg MockAudioDecoder* decoder) 1122c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org : NetEqExternalDecoderTest(codec, decoder), 1132c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org external_decoder_(decoder), 1142c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org samples_per_ms_(CodecSampleRateHz(codec) / 1000), 1152c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org frame_size_samples_(kFrameSizeMs * samples_per_ms_), 1162c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org rtp_generator_(new test::RtpGenerator(samples_per_ms_)), 1172c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org last_lost_time_(0), 1182c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org packet_loss_interval_(0xffffffff) { 1192c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org Init(); 1202c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1212c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1222c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org bool Lost(uint32_t send_time) { 1232c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org if (send_time - last_lost_time_ >= packet_loss_interval_) { 1242c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org last_lost_time_ = send_time; 1252c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org return true; 1262c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1272c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org return false; 1282c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1292c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1302c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org void SetPacketLossRate(double loss_rate) { 1312c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org packet_loss_interval_ = (loss_rate >= 1e-3 ? 1322c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org static_cast<double>(kFrameSizeMs) / loss_rate : 0xffffffff); 1332c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1342c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1352c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // |stats_ref| 1362c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // expects.x = -1, do not care 1372c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // expects.x = 0, 'x' in current stats should equal 'x' in |stats_ref| 1382c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // expects.x = 1, 'x' in current stats should < 'x' in |stats_ref| 1392c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // expects.x = 2, 'x' in current stats should > 'x' in |stats_ref| 1402c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org void CheckNetworkStatistics(NetEqNetworkStatsCheck expects) { 1412c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org NetEqNetworkStatistics stats; 1422c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org neteq()->NetworkStatistics(&stats); 1432c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1442c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org#define CHECK_NETEQ_NETWORK_STATS(x)\ 1452c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org switch (expects.x) {\ 1462c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org case EQUAL:\ 1472c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EXPECT_EQ(stats.x, expects.stats_ref.x);\ 1482c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org break;\ 1492c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org case SMALLER_THAN:\ 1502c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EXPECT_LT(stats.x, expects.stats_ref.x);\ 1512c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org break;\ 1522c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org case LARGER_THAN:\ 1532c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EXPECT_GT(stats.x, expects.stats_ref.x);\ 1542c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org break;\ 1552c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org default:\ 1562c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org break;\ 1572c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1582c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1592c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(current_buffer_size_ms); 1602c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(preferred_buffer_size_ms); 1612c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(jitter_peaks_found); 1622c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(packet_loss_rate); 1632c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(packet_discard_rate); 1642c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(expand_rate); 1657d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(speech_expand_rate); 1662c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(preemptive_rate); 1672c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(accelerate_rate); 1682c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(secondary_decoded_rate); 1692c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(clockdrift_ppm); 1702c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CHECK_NETEQ_NETWORK_STATS(added_zero_samples); 1712c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1722c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org#undef CHECK_NETEQ_NETWORK_STATS 1739c3efd00523a81d0f2b582799fbe67afe44139b2henrik.lundin 1749c3efd00523a81d0f2b582799fbe67afe44139b2henrik.lundin // Compare with CurrentDelay, which should be identical. 1759c3efd00523a81d0f2b582799fbe67afe44139b2henrik.lundin EXPECT_EQ(stats.current_buffer_size_ms, neteq()->CurrentDelayMs()); 1762c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1772c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1782c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org void RunTest(int num_loops, NetEqNetworkStatsCheck expects) { 1792c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org NetEqOutputType output_type; 1802c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org uint32_t time_now; 1812c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org uint32_t next_send_time; 1822c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 1832c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // Initiate |last_lost_time_|. 1842c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org time_now = next_send_time = last_lost_time_ = 1852c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org rtp_generator_->GetRtpHeader(kPayloadType, frame_size_samples_, 1862c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org &rtp_header_); 1872c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org for (int k = 0; k < num_loops; ++k) { 1882c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // Delay by one frame such that the FEC can come in. 1892c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org while (time_now + kFrameSizeMs >= next_send_time) { 1902c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org next_send_time = rtp_generator_->GetRtpHeader(kPayloadType, 1912c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org frame_size_samples_, 1922c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org &rtp_header_); 1932c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org if (!Lost(next_send_time)) { 194ee2bac26dd3eb4463126098f87701ff66098b288kwiberg InsertPacket(rtp_header_, payload_, next_send_time); 1952c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1962c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 1972c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org GetOutputAudio(kMaxOutputSize, output_, &output_type); 1982c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org time_now += kOutputLengthMs; 1992c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 2002c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org CheckNetworkStatistics(expects); 2012c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org neteq()->FlushBuffers(); 2022c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 2032c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2042c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org void DecodeFecTest() { 2052c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org external_decoder_->set_fec_enabled(false); 2062c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org NetEqNetworkStatsCheck expects = { 2072c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org IGNORE, // current_buffer_size_ms 2082c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org IGNORE, // preferred_buffer_size_ms 2092c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org IGNORE, // jitter_peaks_found 2102c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EQUAL, // packet_loss_rate 2112c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EQUAL, // packet_discard_rate 2122c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EQUAL, // expand_rate 2137d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // voice_expand_rate 2142c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org IGNORE, // preemptive_rate 2152c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EQUAL, // accelerate_rate 2162c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EQUAL, // decoded_fec_rate 2172c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org IGNORE, // clockdrift_ppm 2182c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EQUAL, // added_zero_samples 2197d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 2202c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org }; 2212c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org RunTest(50, expects); 2222c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2232c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // Next we introduce packet losses. 2242c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org SetPacketLossRate(0.1); 2252c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org expects.stats_ref.packet_loss_rate = 1337; 2267d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 1065; 2272c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org RunTest(50, expects); 2282c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2298967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg // Next we enable FEC. 2302c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org external_decoder_->set_fec_enabled(true); 2312c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org // If FEC fills in the lost packets, no packet loss will be counted. 2322c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org expects.stats_ref.packet_loss_rate = 0; 2337d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 0; 2342c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org expects.stats_ref.secondary_decoded_rate = 2006; 2352c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org RunTest(50, expects); 2362c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org } 2372c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2387d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org void NoiseExpansionTest() { 2397d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org NetEqNetworkStatsCheck expects = { 2407d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org IGNORE, // current_buffer_size_ms 2417d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org IGNORE, // preferred_buffer_size_ms 2427d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org IGNORE, // jitter_peaks_found 2437d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // packet_loss_rate 2447d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // packet_discard_rate 2457d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // expand_rate 2467d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // speech_expand_rate 2477d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org IGNORE, // preemptive_rate 2487d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // accelerate_rate 2497d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // decoded_fec_rate 2507d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org IGNORE, // clockdrift_ppm 2517d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EQUAL, // added_zero_samples 2527d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 2537d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org }; 2547d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org RunTest(50, expects); 2557d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org 2567d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org SetPacketLossRate(1); 2577d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org expects.stats_ref.expand_rate = 16384; 2587d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org expects.stats_ref.speech_expand_rate = 5324; 2597d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org RunTest(10, expects); // Lost 10 * 20ms in a row. 2607d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org } 2617d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org 2622c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org private: 2638967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg MockAudioDecoder* external_decoder_; 2642c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org const int samples_per_ms_; 2652c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org const size_t frame_size_samples_; 26600b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<test::RtpGenerator> rtp_generator_; 2672c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org WebRtcRTPHeader rtp_header_; 2682c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org uint32_t last_lost_time_; 2692c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org uint32_t packet_loss_interval_; 2702c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org uint8_t payload_[kPayloadSizeByte]; 2712c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org int16_t output_[kMaxOutputSize]; 2722c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org}; 2732c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2748967183bf79322c5cb3cbd99e9b7aa298228d0a2kwibergTEST(NetEqNetworkStatsTest, DecodeFec) { 2758967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg MockAudioDecoder decoder(1); 276ee1879ca40ffe4af9bb9613e03eacc5c2c4881fckwiberg NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, &decoder); 2772c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org test.DecodeFecTest(); 2782c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EXPECT_CALL(decoder, Die()).Times(1); 2792c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org} 2802c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2818967183bf79322c5cb3cbd99e9b7aa298228d0a2kwibergTEST(NetEqNetworkStatsTest, StereoDecodeFec) { 2828967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg MockAudioDecoder decoder(2); 283ee1879ca40ffe4af9bb9613e03eacc5c2c4881fckwiberg NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, &decoder); 2842c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org test.DecodeFecTest(); 2852c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org EXPECT_CALL(decoder, Die()).Times(1); 2862c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org} 2872c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2887d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.orgTEST(NetEqNetworkStatsTest, NoiseExpansionTest) { 2898967183bf79322c5cb3cbd99e9b7aa298228d0a2kwiberg MockAudioDecoder decoder(1); 290ee1879ca40ffe4af9bb9613e03eacc5c2c4881fckwiberg NetEqNetworkStatsTest test(NetEqDecoder::kDecoderOpus, &decoder); 2917d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org test.NoiseExpansionTest(); 2927d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org EXPECT_CALL(decoder, Die()).Times(1); 2937d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org} 2947d721eea14341db4a75660b4fc42617b65960301minyue@webrtc.org 2952c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org} // namespace test 2962c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org} // namespace webrtc 2972c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2982c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 2992c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 3002c1bcf2cb4a9e19a337e52fd576242e04168d5e9minyue@webrtc.org 301