Chromium Code Reviews| Index: webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
| diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
| index 69c3876354776ce309bad9fd6fa8773a51f5ec8a..80661e94fbb21c445db9338203339f0794013176 100644 |
| --- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
| +++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
| @@ -119,6 +119,49 @@ void AddMessage(FILE* file, rtc::MessageDigest* digest, |
| #endif // WEBRTC_NETEQ_UNITTEST_BITEXACT |
| +void LoadDecoders(webrtc::NetEq* neteq) { |
| + // Load PCMu. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderPCMu, |
| + "pcmu", 0)); |
| + // Load PCMa. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderPCMa, |
| + "pcma", 8)); |
| +#ifdef WEBRTC_CODEC_ILBC |
| + // Load iLBC. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderILBC, |
| + "ilbc", 102)); |
| +#endif |
| +#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) |
| + // Load iSAC. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderISAC, |
| + "isac", 103)); |
| +#endif |
| +#ifdef WEBRTC_CODEC_ISAC |
| + // Load iSAC SWB. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderISACswb, |
| + "isac-swb", 104)); |
| +#endif |
| +#ifdef WEBRTC_CODEC_OPUS |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderOpus, |
| + "opus", 111)); |
| +#endif |
| + // Load PCM16B nb. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderPCM16B, |
| + "pcm16-nb", 93)); |
| + // Load PCM16B wb. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType( |
| + webrtc::NetEqDecoder::kDecoderPCM16Bwb, "pcm16-wb", 94)); |
| + // Load PCM16B swb32. |
| + ASSERT_EQ( |
| + 0, neteq->RegisterPayloadType( |
| + webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz, "pcm16-swb32", 95)); |
| + // Load CNG 8 kHz. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderCNGnb, |
| + "cng-nb", 13)); |
| + // Load CNG 16 kHz. |
| + ASSERT_EQ(0, neteq->RegisterPayloadType(webrtc::NetEqDecoder::kDecoderCNGwb, |
| + "cng-wb", 98)); |
| +} |
| } // namespace |
| namespace webrtc { |
| @@ -213,7 +256,6 @@ class NetEqDecodingTest : public ::testing::Test { |
| virtual void SetUp(); |
| virtual void TearDown(); |
| void SelectDecoders(NetEqDecoder* used_codec); |
| - void LoadDecoders(); |
| void OpenInputFile(const std::string &rtp_file); |
| void Process(); |
| @@ -278,56 +320,13 @@ void NetEqDecodingTest::SetUp() { |
| ASSERT_EQ(0, neteq_->NetworkStatistics(&stat)); |
| algorithmic_delay_ms_ = stat.current_buffer_size_ms; |
| ASSERT_TRUE(neteq_); |
| - LoadDecoders(); |
| + LoadDecoders(neteq_); |
| } |
| void NetEqDecodingTest::TearDown() { |
| delete neteq_; |
| } |
| -void NetEqDecodingTest::LoadDecoders() { |
| - // Load PCMu. |
| - ASSERT_EQ(0, |
| - neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCMu, "pcmu", 0)); |
| - // Load PCMa. |
| - ASSERT_EQ(0, |
| - neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCMa, "pcma", 8)); |
| -#ifdef WEBRTC_CODEC_ILBC |
| - // Load iLBC. |
| - ASSERT_EQ( |
| - 0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderILBC, "ilbc", 102)); |
| -#endif |
| -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) |
| - // Load iSAC. |
| - ASSERT_EQ( |
| - 0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISAC, "isac", 103)); |
| -#endif |
| -#ifdef WEBRTC_CODEC_ISAC |
| - // Load iSAC SWB. |
| - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISACswb, |
| - "isac-swb", 104)); |
| -#endif |
| -#ifdef WEBRTC_CODEC_OPUS |
| - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderOpus, |
| - "opus", 111)); |
| -#endif |
| - // Load PCM16B nb. |
| - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16B, |
| - "pcm16-nb", 93)); |
| - // Load PCM16B wb. |
| - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bwb, |
| - "pcm16-wb", 94)); |
| - // Load PCM16B swb32. |
| - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bswb32kHz, |
| - "pcm16-swb32", 95)); |
| - // Load CNG 8 kHz. |
| - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGnb, |
| - "cng-nb", 13)); |
| - // Load CNG 16 kHz. |
| - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGwb, |
| - "cng-wb", 98)); |
| -} |
| - |
| void NetEqDecodingTest::OpenInputFile(const std::string &rtp_file) { |
| rtp_source_.reset(test::RtpFileSource::Create(rtp_file)); |
| } |
| @@ -354,7 +353,9 @@ void NetEqDecodingTest::Process() { |
| } |
| // Get audio from NetEq. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + bool muted_output; |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| + ASSERT_FALSE(muted_output); |
| ASSERT_TRUE((out_frame_.samples_per_channel_ == kBlockSize8kHz) || |
| (out_frame_.samples_per_channel_ == kBlockSize16kHz) || |
| (out_frame_.samples_per_channel_ == kBlockSize32kHz) || |
| @@ -545,7 +546,8 @@ TEST_F(NetEqDecodingTestFaxMode, TestFrameWaitingTimeStatistics) { |
| } |
| // Pull out all data. |
| for (size_t i = 0; i < num_frames; ++i) { |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + bool muted_output; |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| } |
| @@ -586,7 +588,8 @@ TEST_F(NetEqDecodingTest, TestAverageInterArrivalTimeNegative) { |
| } |
| // Pull out data once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + bool muted_output; |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| } |
| @@ -613,7 +616,8 @@ TEST_F(NetEqDecodingTest, TestAverageInterArrivalTimePositive) { |
| } |
| // Pull out data once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + bool muted_output; |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| } |
| @@ -634,6 +638,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, |
| const size_t kPayloadBytes = kSamples * 2; |
| double next_input_time_ms = 0.0; |
| double t_ms; |
| + bool muted_output; |
| // Insert speech for 5 seconds. |
| const int kSpeechDurationMs = 5000; |
| @@ -650,7 +655,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, |
| next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor; |
| } |
| // Pull out data once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| } |
| @@ -679,7 +684,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, |
| next_input_time_ms += static_cast<double>(kCngPeriodMs) * drift_factor; |
| } |
| // Pull out data once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| } |
| @@ -692,7 +697,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, |
| const double loop_end_time = t_ms + network_freeze_ms; |
| for (; t_ms < loop_end_time; t_ms += 10) { |
| // Pull out data once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_); |
| } |
| @@ -704,7 +709,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, |
| if (pull_once && next_input_time_ms >= pull_time_ms) { |
| pull_once = false; |
| // Pull out data once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_); |
| t_ms += 10; |
| @@ -738,7 +743,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, |
| next_input_time_ms += kFrameSizeMs * drift_factor; |
| } |
| // Pull out data once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| // Increase clock. |
| t_ms += 10; |
| @@ -866,7 +871,9 @@ TEST_F(NetEqDecodingTest, MAYBE_DecoderError) { |
| for (size_t i = 0; i < AudioFrame::kMaxDataSizeSamples; ++i) { |
| out_frame_.data_[i] = 1; |
| } |
| - EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&out_frame_)); |
| + bool muted_output; |
| + EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&out_frame_, &muted_output)); |
| + ASSERT_FALSE(muted_output); |
|
minyue-webrtc
2016/05/11 11:29:54
does this need to be assert? + all similar places
hlundin-webrtc
2016/05/12 07:44:40
I choose to use ASSERT in all places where the tes
minyue-webrtc
2016/05/12 10:56:06
True, and with this regards, many EXPECT can becom
|
| // Verify that there is a decoder error to check. |
| EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError()); |
| @@ -903,7 +910,9 @@ TEST_F(NetEqDecodingTest, GetAudioBeforeInsertPacket) { |
| for (size_t i = 0; i < AudioFrame::kMaxDataSizeSamples; ++i) { |
| out_frame_.data_[i] = 1; |
| } |
| - EXPECT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + bool muted_output; |
| + EXPECT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| + ASSERT_FALSE(muted_output); |
| // Verify that the first block of samples is set to 0. |
| static const int kExpectedOutputLength = |
| kInitSampleRateHz / 100; // 10 ms at initial sample rate. |
| @@ -955,6 +964,7 @@ class NetEqBgnTest : public NetEqDecodingTest { |
| rtp_info.header.payloadType = payload_type; |
| uint32_t receive_timestamp = 0; |
| + bool muted_output; |
| for (int n = 0; n < 10; ++n) { // Insert few packets and get audio. |
| auto block = input.GetNextBlock(); |
| ASSERT_EQ(expected_samples_per_channel, block.size()); |
| @@ -966,7 +976,7 @@ class NetEqBgnTest : public NetEqDecodingTest { |
| payload, enc_len_bytes), |
| receive_timestamp)); |
| output.Reset(); |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| ASSERT_EQ(1u, output.num_channels_); |
| ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_); |
| ASSERT_EQ(AudioFrame::kNormalSpeech, output.speech_type_); |
| @@ -982,7 +992,7 @@ class NetEqBgnTest : public NetEqDecodingTest { |
| // Get audio without inserting packets, expecting PLC and PLC-to-CNG. Pull |
| // one frame without checking speech-type. This is the first frame pulled |
| // without inserting any packet, and might not be labeled as PLC. |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| ASSERT_EQ(1u, output.num_channels_); |
| ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_); |
| @@ -997,7 +1007,8 @@ class NetEqBgnTest : public NetEqDecodingTest { |
| for (int n = 0; n < kFadingThreshold + kNumPlcToCngTestFrames; ++n) { |
| output.Reset(); |
| memset(output.data_, 1, sizeof(output.data_)); // Set to non-zero. |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| + ASSERT_FALSE(muted_output); |
| ASSERT_EQ(1u, output.num_channels_); |
| ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_); |
| if (output.speech_type_ == AudioFrame::kPLCCNG) { |
| @@ -1171,9 +1182,10 @@ TEST_F(NetEqDecodingTest, SyncPacketDecode) { |
| // Insert some packets which decode to noise. We are not interested in |
| // actual decoded values. |
| uint32_t receive_timestamp = 0; |
| + bool muted_output; |
| for (int n = 0; n < 100; ++n) { |
| ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| ASSERT_EQ(1u, output.num_channels_); |
| @@ -1189,7 +1201,8 @@ TEST_F(NetEqDecodingTest, SyncPacketDecode) { |
| // Insert sync-packets, the decoded sequence should be all-zero. |
| for (int n = 0; n < kNumSyncPackets; ++n) { |
| ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| + ASSERT_FALSE(muted_output); |
| ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| ASSERT_EQ(1u, output.num_channels_); |
| if (n > algorithmic_frame_delay) { |
| @@ -1205,7 +1218,8 @@ TEST_F(NetEqDecodingTest, SyncPacketDecode) { |
| // network statistics would show some packet loss. |
| for (int n = 0; n <= algorithmic_frame_delay + 10; ++n) { |
| ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| + ASSERT_FALSE(muted_output); |
| if (n >= algorithmic_frame_delay + 1) { |
| // Expect that this frame contain samples from regular RTP. |
| EXPECT_TRUE(IsAllNonZero( |
| @@ -1241,9 +1255,10 @@ TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { |
| // actual decoded values. |
| uint32_t receive_timestamp = 0; |
| int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; |
| + bool muted_output; |
| for (int n = 0; n < algorithmic_frame_delay; ++n) { |
| ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| ASSERT_EQ(1u, output.num_channels_); |
| rtp_info.header.sequenceNumber++; |
| @@ -1280,7 +1295,8 @@ TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { |
| // Decode. |
| for (int n = 0; n < kNumSyncPackets; ++n) { |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| + ASSERT_FALSE(muted_output); |
| ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| ASSERT_EQ(1u, output.num_channels_); |
| EXPECT_TRUE(IsAllNonZero( |
| @@ -1347,7 +1363,8 @@ void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, |
| } |
| // Pull out data once. |
| AudioFrame output; |
| - ASSERT_EQ(0, neteq_->GetAudio(&output)); |
| + bool muted_output; |
| + ASSERT_EQ(0, neteq_->GetAudio(&output, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| ASSERT_EQ(1u, output.num_channels_); |
| @@ -1403,6 +1420,7 @@ void NetEqDecodingTest::DuplicateCng() { |
| // correct. |
| uint8_t payload[kPayloadBytes] = {0}; |
| WebRtcRTPHeader rtp_info; |
| + bool muted_output; |
| for (int i = 0; i < 3; ++i) { |
| PopulateRtpInfo(seq_no, timestamp, &rtp_info); |
| ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| @@ -1410,7 +1428,7 @@ void NetEqDecodingTest::DuplicateCng() { |
| timestamp += kSamples; |
| // Pull audio once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| } |
| // Verify speech output. |
| @@ -1427,7 +1445,7 @@ void NetEqDecodingTest::DuplicateCng() { |
| rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); |
| // Pull audio once and make sure CNG is played. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_); |
| EXPECT_FALSE(PlayoutTimestamp()); // Returns empty value during CNG. |
| @@ -1443,7 +1461,7 @@ void NetEqDecodingTest::DuplicateCng() { |
| // Pull audio until we have played |kCngPeriodMs| of CNG. Start at 10 ms since |
| // we have already pulled out CNG once. |
| for (int cng_time_ms = 10; cng_time_ms < kCngPeriodMs; cng_time_ms += 10) { |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_); |
| EXPECT_FALSE(PlayoutTimestamp()); // Returns empty value during CNG. |
| @@ -1458,7 +1476,7 @@ void NetEqDecodingTest::DuplicateCng() { |
| ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| // Pull audio once and verify that the output is speech again. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_); |
| rtc::Optional<uint32_t> playout_timestamp = PlayoutTimestamp(); |
| @@ -1496,7 +1514,8 @@ TEST_F(NetEqDecodingTest, CngFirst) { |
| timestamp += kCngPeriodSamples; |
| // Pull audio once and make sure CNG is played. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + bool muted_output; |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| EXPECT_EQ(AudioFrame::kCNG, out_frame_.speech_type_); |
| @@ -1508,10 +1527,196 @@ TEST_F(NetEqDecodingTest, CngFirst) { |
| timestamp += kSamples; |
| // Pull audio once. |
| - ASSERT_EQ(0, neteq_->GetAudio(&out_frame_)); |
| + ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| } |
| // Verify speech output. |
| EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_); |
| } |
| + |
| +class NetEqDecodingTestWithMutedState : public NetEqDecodingTest { |
| + public: |
| + NetEqDecodingTestWithMutedState() : NetEqDecodingTest() { |
| + config_.enable_muted_state = true; |
| + } |
| +}; |
| + |
| +// Verifies that NetEq goes in and out of muted state as expected. |
| +TEST_F(NetEqDecodingTestWithMutedState, MutedState) { |
| + const size_t kSamples = 10 * 16; |
| + const size_t kPayloadBytes = kSamples * 2; |
| + // Insert one speech packet. |
| + uint8_t payload[kPayloadBytes] = {0}; |
| + WebRtcRTPHeader rtp_info; |
| + PopulateRtpInfo(0, 0, &rtp_info); |
| + EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| + |
| + // Pull out data once. |
| + bool muted_output; |
| + EXPECT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| + EXPECT_FALSE(muted_output); |
| + |
| + // Pull data until expand starts. |
| + int counter = 0; |
| + while (out_frame_.speech_type_ != AudioFrame::kPLC) { |
| + EXPECT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| + EXPECT_FALSE(muted_output); |
| + ASSERT_LT(counter++, 1000) << "Test timed out"; |
| + } |
| + |
| + // Pull data until faded out. |
| + while (!muted_output) { |
| + EXPECT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| + ASSERT_LT(counter++, 1000) << "Test timed out"; |
| + } |
| + |
| + // Verify that output audio is not written during muted mode. Other parameters |
|
minyue-webrtc
2016/05/11 11:29:54
is this important?
hlundin-webrtc
2016/05/12 07:44:40
Yes. One of the points with muted state is that we
minyue-webrtc
2016/05/12 10:56:07
But this is not sufficient in checking the efficie
hlundin-webrtc
2016/05/12 12:06:20
I updated the comment in neteq.h regarding this. S
|
| + // should be correct, though. |
| + AudioFrame new_frame; |
| + for (auto& d : new_frame.data_) { |
|
minyue-webrtc
2016/05/11 11:29:54
and how about memset and memcmp
hlundin-webrtc
2016/05/12 07:44:40
I cannot set a non-zero value to elements wider th
|
| + d = 17; |
| + } |
| + EXPECT_EQ(0, neteq_->GetAudio(&new_frame, &muted_output)); |
| + EXPECT_TRUE(muted_output); |
| + for (auto d : new_frame.data_) { |
| + EXPECT_EQ(17, d); |
| + } |
| + EXPECT_EQ(out_frame_.timestamp_ + out_frame_.samples_per_channel_, |
| + new_frame.timestamp_); |
| + EXPECT_EQ(out_frame_.samples_per_channel_, new_frame.samples_per_channel_); |
| + EXPECT_EQ(out_frame_.sample_rate_hz_, new_frame.sample_rate_hz_); |
| + EXPECT_EQ(out_frame_.num_channels_, new_frame.num_channels_); |
| + EXPECT_EQ(out_frame_.speech_type_, new_frame.speech_type_); |
| + EXPECT_EQ(out_frame_.vad_activity_, new_frame.vad_activity_); |
| + |
| + // Insert new data. Timestamp is corrected for the time elapsed since the last |
| + // packet. |
| + PopulateRtpInfo(0, 16 * 10 * counter, &rtp_info); |
|
minyue-webrtc
2016/05/11 11:29:54
what if the timestamp is not 16 * 10 * counter
hlundin-webrtc
2016/05/12 07:44:40
I changed to kSamples to be consistent within the
|
| + EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| + |
| + while (out_frame_.speech_type_ != AudioFrame::kNormalSpeech) { |
| + EXPECT_EQ(0, neteq_->GetAudio(&out_frame_, &muted_output)); |
| + ASSERT_LT(counter++, 1000) << "Test timed out"; |
| + } |
| + EXPECT_FALSE(muted_output); |
| +} |
| + |
| +class NetEqDecodingTestTwoInstances : public NetEqDecodingTest { |
| + public: |
| + NetEqDecodingTestTwoInstances() : NetEqDecodingTest() {} |
| + |
| + void SetUp() override { |
| + NetEqDecodingTest::SetUp(); |
| + config2_ = config_; |
| + } |
| + |
| + void CreateSecondInstance() { |
| + neteq2_.reset(NetEq::Create(config2_)); |
| + ASSERT_TRUE(neteq2_); |
| + LoadDecoders(neteq2_.get()); |
| + } |
| + |
| + protected: |
| + std::unique_ptr<NetEq> neteq2_; |
| + NetEq::Config config2_; |
| +}; |
| + |
| +namespace { |
| +::testing::AssertionResult AudioFramesEqualExceptData(const AudioFrame& a, |
| + const AudioFrame& b) { |
| + if (a.timestamp_ != b.timestamp_) |
| + return ::testing::AssertionFailure() << "timestamp_ diff (" << a.timestamp_ |
| + << " != " << b.timestamp_ << ")"; |
| + if (a.sample_rate_hz_ != b.sample_rate_hz_) |
| + return ::testing::AssertionFailure() << "sample_rate_hz_ diff (" |
| + << a.sample_rate_hz_ |
| + << " != " << b.sample_rate_hz_ << ")"; |
| + if (a.samples_per_channel_ != b.samples_per_channel_) |
| + return ::testing::AssertionFailure() |
| + << "samples_per_channel_ diff (" << a.samples_per_channel_ |
| + << " != " << b.samples_per_channel_ << ")"; |
| + if (a.num_channels_ != b.num_channels_) |
| + return ::testing::AssertionFailure() << "num_channels_ diff (" |
| + << a.num_channels_ |
| + << " != " << b.num_channels_ << ")"; |
| + if (a.speech_type_ != b.speech_type_) |
| + return ::testing::AssertionFailure() << "speech_type_ diff (" |
| + << a.speech_type_ |
| + << " != " << b.speech_type_ << ")"; |
| + if (a.vad_activity_ != b.vad_activity_) |
| + return ::testing::AssertionFailure() << "vad_activity_ diff (" |
| + << a.vad_activity_ |
| + << " != " << b.vad_activity_ << ")"; |
| + return ::testing::AssertionSuccess(); |
| +} |
| + |
| +::testing::AssertionResult AudioFramesEqual(const AudioFrame& a, |
| + const AudioFrame& b) { |
| + ::testing::AssertionResult res = AudioFramesEqualExceptData(a, b); |
| + if (!res) |
| + return res; |
| + if (memcmp(a.data_, b.data_, a.samples_per_channel_ * a.num_channels_ * |
| + sizeof(a.data_[0])) != 0) { |
|
minyue-webrtc
2016/05/11 11:29:54
weird wrapping
hlundin-webrtc
2016/05/12 07:44:40
Better?
minyue-webrtc
2016/05/12 10:56:07
yes
|
| + return ::testing::AssertionFailure() << "data_ diff"; |
| + } |
| + return ::testing::AssertionSuccess(); |
| +} |
| + |
| +} // namespace |
| + |
| +TEST_F(NetEqDecodingTestTwoInstances, CompareMutedStateOnOff) { |
| + ASSERT_FALSE(config_.enable_muted_state); |
| + config2_.enable_muted_state = true; |
| + CreateSecondInstance(); |
| + |
| + // Insert one speech packet into both NetEqs. |
| + const size_t kSamples = 10 * 16; |
| + const size_t kPayloadBytes = kSamples * 2; |
| + uint8_t payload[kPayloadBytes] = {0}; |
| + WebRtcRTPHeader rtp_info; |
| + PopulateRtpInfo(0, 0, &rtp_info); |
| + EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| + EXPECT_EQ(0, neteq2_->InsertPacket(rtp_info, payload, 0)); |
| + |
| + AudioFrame out_frame1, out_frame2; |
| + bool muted_output; |
| + for (int i = 0; i < 1000; ++i) { |
| + std::ostringstream ss; |
| + ss << "i = " << i; |
| + SCOPED_TRACE(ss.str()); // Print out the loop iterator on failure. |
| + EXPECT_EQ(0, neteq_->GetAudio(&out_frame1, &muted_output)); |
| + EXPECT_FALSE(muted_output); |
| + EXPECT_EQ(0, neteq2_->GetAudio(&out_frame2, &muted_output)); |
| + if (muted_output) { |
| + EXPECT_TRUE(AudioFramesEqualExceptData(out_frame1, out_frame2)); |
| + } else { |
| + EXPECT_TRUE(AudioFramesEqual(out_frame1, out_frame2)); |
| + } |
| + } |
| + EXPECT_TRUE(muted_output); |
| + |
| + // Insert new data. Timestamp is corrected for the time elapsed since the last |
| + // packet. |
| + PopulateRtpInfo(0, 16 * 10 * 1000, &rtp_info); |
| + EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| + EXPECT_EQ(0, neteq2_->InsertPacket(rtp_info, payload, 0)); |
| + |
| + int counter = 0; |
| + while (out_frame1.speech_type_ != AudioFrame::kNormalSpeech) { |
| + ASSERT_LT(counter++, 1000) << "Test timed out"; |
| + std::ostringstream ss; |
| + ss << "counter = " << counter; |
| + SCOPED_TRACE(ss.str()); // Print out the loop iterator on failure. |
| + EXPECT_EQ(0, neteq_->GetAudio(&out_frame1, &muted_output)); |
| + EXPECT_FALSE(muted_output); |
| + EXPECT_EQ(0, neteq2_->GetAudio(&out_frame2, &muted_output)); |
| + if (muted_output) { |
| + EXPECT_TRUE(AudioFramesEqualExceptData(out_frame1, out_frame2)); |
| + } else { |
| + EXPECT_TRUE(AudioFramesEqual(out_frame1, out_frame2)); |
| + } |
| + } |
| + EXPECT_FALSE(muted_output); |
| +} |
| + |
| } // namespace webrtc |