| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include <memory> | 22 #include <memory> |
| 23 #include <set> | 23 #include <set> |
| 24 #include <string> | 24 #include <string> |
| 25 #include <vector> | 25 #include <vector> |
| 26 | 26 |
| 27 #include "gflags/gflags.h" | 27 #include "gflags/gflags.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 29 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" | 29 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" |
| 30 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" | 30 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" |
| 31 #include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" | 31 #include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" |
| 32 #include "webrtc/modules/include/module_common_types.h" |
| 32 #include "webrtc/test/testsupport/fileutils.h" | 33 #include "webrtc/test/testsupport/fileutils.h" |
| 33 #include "webrtc/typedefs.h" | 34 #include "webrtc/typedefs.h" |
| 34 | 35 |
| 35 #ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT | 36 #ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT |
| 36 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD | 37 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD |
| 37 #include "external/webrtc/webrtc/modules/audio_coding/neteq/neteq_unittest.pb.h" | 38 #include "external/webrtc/webrtc/modules/audio_coding/neteq/neteq_unittest.pb.h" |
| 38 #else | 39 #else |
| 39 #include "webrtc/audio_coding/neteq/neteq_unittest.pb.h" | 40 #include "webrtc/audio_coding/neteq/neteq_unittest.pb.h" |
| 40 #endif | 41 #endif |
| 41 #endif | 42 #endif |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 | 273 |
| 273 class NetEqDecodingTest : public ::testing::Test { | 274 class NetEqDecodingTest : public ::testing::Test { |
| 274 protected: | 275 protected: |
| 275 // NetEQ must be polled for data once every 10 ms. Thus, neither of the | 276 // NetEQ must be polled for data once every 10 ms. Thus, neither of the |
| 276 // constants below can be changed. | 277 // constants below can be changed. |
| 277 static const int kTimeStepMs = 10; | 278 static const int kTimeStepMs = 10; |
| 278 static const size_t kBlockSize8kHz = kTimeStepMs * 8; | 279 static const size_t kBlockSize8kHz = kTimeStepMs * 8; |
| 279 static const size_t kBlockSize16kHz = kTimeStepMs * 16; | 280 static const size_t kBlockSize16kHz = kTimeStepMs * 16; |
| 280 static const size_t kBlockSize32kHz = kTimeStepMs * 32; | 281 static const size_t kBlockSize32kHz = kTimeStepMs * 32; |
| 281 static const size_t kBlockSize48kHz = kTimeStepMs * 48; | 282 static const size_t kBlockSize48kHz = kTimeStepMs * 48; |
| 282 static const size_t kMaxBlockSize = kBlockSize48kHz; | |
| 283 static const int kInitSampleRateHz = 8000; | 283 static const int kInitSampleRateHz = 8000; |
| 284 | 284 |
| 285 NetEqDecodingTest(); | 285 NetEqDecodingTest(); |
| 286 virtual void SetUp(); | 286 virtual void SetUp(); |
| 287 virtual void TearDown(); | 287 virtual void TearDown(); |
| 288 void SelectDecoders(NetEqDecoder* used_codec); | 288 void SelectDecoders(NetEqDecoder* used_codec); |
| 289 void LoadDecoders(); | 289 void LoadDecoders(); |
| 290 void OpenInputFile(const std::string &rtp_file); | 290 void OpenInputFile(const std::string &rtp_file); |
| 291 void Process(size_t* out_len); | 291 void Process(); |
| 292 | 292 |
| 293 void DecodeAndCompare(const std::string& rtp_file, | 293 void DecodeAndCompare(const std::string& rtp_file, |
| 294 const std::string& ref_file, | 294 const std::string& ref_file, |
| 295 const std::string& stat_ref_file, | 295 const std::string& stat_ref_file, |
| 296 const std::string& rtcp_ref_file); | 296 const std::string& rtcp_ref_file); |
| 297 | 297 |
| 298 static void PopulateRtpInfo(int frame_index, | 298 static void PopulateRtpInfo(int frame_index, |
| 299 int timestamp, | 299 int timestamp, |
| 300 WebRtcRTPHeader* rtp_info); | 300 WebRtcRTPHeader* rtp_info); |
| 301 static void PopulateCng(int frame_index, | 301 static void PopulateCng(int frame_index, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 316 | 316 |
| 317 void DuplicateCng(); | 317 void DuplicateCng(); |
| 318 | 318 |
| 319 uint32_t PlayoutTimestamp(); | 319 uint32_t PlayoutTimestamp(); |
| 320 | 320 |
| 321 NetEq* neteq_; | 321 NetEq* neteq_; |
| 322 NetEq::Config config_; | 322 NetEq::Config config_; |
| 323 std::unique_ptr<test::RtpFileSource> rtp_source_; | 323 std::unique_ptr<test::RtpFileSource> rtp_source_; |
| 324 std::unique_ptr<test::Packet> packet_; | 324 std::unique_ptr<test::Packet> packet_; |
| 325 unsigned int sim_clock_; | 325 unsigned int sim_clock_; |
| 326 int16_t out_data_[kMaxBlockSize]; | 326 AudioFrame out_frame_; |
| 327 int output_sample_rate_; | 327 int output_sample_rate_; |
| 328 int algorithmic_delay_ms_; | 328 int algorithmic_delay_ms_; |
| 329 }; | 329 }; |
| 330 | 330 |
| 331 // Allocating the static const so that it can be passed by reference. | 331 // Allocating the static const so that it can be passed by reference. |
| 332 const int NetEqDecodingTest::kTimeStepMs; | 332 const int NetEqDecodingTest::kTimeStepMs; |
| 333 const size_t NetEqDecodingTest::kBlockSize8kHz; | 333 const size_t NetEqDecodingTest::kBlockSize8kHz; |
| 334 const size_t NetEqDecodingTest::kBlockSize16kHz; | 334 const size_t NetEqDecodingTest::kBlockSize16kHz; |
| 335 const size_t NetEqDecodingTest::kBlockSize32kHz; | 335 const size_t NetEqDecodingTest::kBlockSize32kHz; |
| 336 const size_t NetEqDecodingTest::kMaxBlockSize; | |
| 337 const int NetEqDecodingTest::kInitSampleRateHz; | 336 const int NetEqDecodingTest::kInitSampleRateHz; |
| 338 | 337 |
| 339 NetEqDecodingTest::NetEqDecodingTest() | 338 NetEqDecodingTest::NetEqDecodingTest() |
| 340 : neteq_(NULL), | 339 : neteq_(NULL), |
| 341 config_(), | 340 config_(), |
| 342 sim_clock_(0), | 341 sim_clock_(0), |
| 343 output_sample_rate_(kInitSampleRateHz), | 342 output_sample_rate_(kInitSampleRateHz), |
| 344 algorithmic_delay_ms_(0) { | 343 algorithmic_delay_ms_(0) { |
| 345 config_.sample_rate_hz = kInitSampleRateHz; | 344 config_.sample_rate_hz = kInitSampleRateHz; |
| 346 memset(out_data_, 0, sizeof(out_data_)); | |
| 347 } | 345 } |
| 348 | 346 |
| 349 void NetEqDecodingTest::SetUp() { | 347 void NetEqDecodingTest::SetUp() { |
| 350 neteq_ = NetEq::Create(config_); | 348 neteq_ = NetEq::Create(config_); |
| 351 NetEqNetworkStatistics stat; | 349 NetEqNetworkStatistics stat; |
| 352 ASSERT_EQ(0, neteq_->NetworkStatistics(&stat)); | 350 ASSERT_EQ(0, neteq_->NetworkStatistics(&stat)); |
| 353 algorithmic_delay_ms_ = stat.current_buffer_size_ms; | 351 algorithmic_delay_ms_ = stat.current_buffer_size_ms; |
| 354 ASSERT_TRUE(neteq_); | 352 ASSERT_TRUE(neteq_); |
| 355 LoadDecoders(); | 353 LoadDecoders(); |
| 356 } | 354 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 "cng-nb", 13)); | 397 "cng-nb", 13)); |
| 400 // Load CNG 16 kHz. | 398 // Load CNG 16 kHz. |
| 401 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGwb, | 399 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGwb, |
| 402 "cng-wb", 98)); | 400 "cng-wb", 98)); |
| 403 } | 401 } |
| 404 | 402 |
| 405 void NetEqDecodingTest::OpenInputFile(const std::string &rtp_file) { | 403 void NetEqDecodingTest::OpenInputFile(const std::string &rtp_file) { |
| 406 rtp_source_.reset(test::RtpFileSource::Create(rtp_file)); | 404 rtp_source_.reset(test::RtpFileSource::Create(rtp_file)); |
| 407 } | 405 } |
| 408 | 406 |
| 409 void NetEqDecodingTest::Process(size_t* out_len) { | 407 void NetEqDecodingTest::Process() { |
| 410 // Check if time to receive. | 408 // Check if time to receive. |
| 411 while (packet_ && sim_clock_ >= packet_->time_ms()) { | 409 while (packet_ && sim_clock_ >= packet_->time_ms()) { |
| 412 if (packet_->payload_length_bytes() > 0) { | 410 if (packet_->payload_length_bytes() > 0) { |
| 413 WebRtcRTPHeader rtp_header; | 411 WebRtcRTPHeader rtp_header; |
| 414 packet_->ConvertHeader(&rtp_header); | 412 packet_->ConvertHeader(&rtp_header); |
| 415 #ifndef WEBRTC_CODEC_ISAC | 413 #ifndef WEBRTC_CODEC_ISAC |
| 416 // Ignore payload type 104 (iSAC-swb) if ISAC is not supported. | 414 // Ignore payload type 104 (iSAC-swb) if ISAC is not supported. |
| 417 if (rtp_header.header.payloadType != 104) | 415 if (rtp_header.header.payloadType != 104) |
| 418 #endif | 416 #endif |
| 419 ASSERT_EQ(0, neteq_->InsertPacket( | 417 ASSERT_EQ(0, neteq_->InsertPacket( |
| 420 rtp_header, | 418 rtp_header, |
| 421 rtc::ArrayView<const uint8_t>( | 419 rtc::ArrayView<const uint8_t>( |
| 422 packet_->payload(), packet_->payload_length_bytes()), | 420 packet_->payload(), packet_->payload_length_bytes()), |
| 423 static_cast<uint32_t>(packet_->time_ms() * | 421 static_cast<uint32_t>(packet_->time_ms() * |
| 424 (output_sample_rate_ / 1000)))); | 422 (output_sample_rate_ / 1000)))); |
| 425 } | 423 } |
| 426 // Get next packet. | 424 // Get next packet. |
| 427 packet_.reset(rtp_source_->NextPacket()); | 425 packet_.reset(rtp_source_->NextPacket()); |
| 428 } | 426 } |
| 429 | 427 |
| 430 // Get audio from NetEq. | 428 // Get audio from NetEq. |
| 431 NetEqOutputType type; | 429 NetEqOutputType type; |
| 432 size_t num_channels; | 430 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 433 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, out_len, | 431 ASSERT_TRUE((out_frame_.samples_per_channel_ == kBlockSize8kHz) || |
| 434 &num_channels, &type)); | 432 (out_frame_.samples_per_channel_ == kBlockSize16kHz) || |
| 435 ASSERT_TRUE((*out_len == kBlockSize8kHz) || | 433 (out_frame_.samples_per_channel_ == kBlockSize32kHz) || |
| 436 (*out_len == kBlockSize16kHz) || | 434 (out_frame_.samples_per_channel_ == kBlockSize48kHz)); |
| 437 (*out_len == kBlockSize32kHz) || | 435 output_sample_rate_ = out_frame_.sample_rate_hz_; |
| 438 (*out_len == kBlockSize48kHz)); | |
| 439 output_sample_rate_ = static_cast<int>(*out_len / 10 * 1000); | |
| 440 EXPECT_EQ(output_sample_rate_, neteq_->last_output_sample_rate_hz()); | 436 EXPECT_EQ(output_sample_rate_, neteq_->last_output_sample_rate_hz()); |
| 441 | 437 |
| 442 // Increase time. | 438 // Increase time. |
| 443 sim_clock_ += kTimeStepMs; | 439 sim_clock_ += kTimeStepMs; |
| 444 } | 440 } |
| 445 | 441 |
| 446 void NetEqDecodingTest::DecodeAndCompare(const std::string& rtp_file, | 442 void NetEqDecodingTest::DecodeAndCompare(const std::string& rtp_file, |
| 447 const std::string& ref_file, | 443 const std::string& ref_file, |
| 448 const std::string& stat_ref_file, | 444 const std::string& stat_ref_file, |
| 449 const std::string& rtcp_ref_file) { | 445 const std::string& rtcp_ref_file) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 466 rtcp_out_file = webrtc::test::OutputPath() + "neteq_rtcp_stats.dat"; | 462 rtcp_out_file = webrtc::test::OutputPath() + "neteq_rtcp_stats.dat"; |
| 467 } | 463 } |
| 468 RefFiles rtcp_stat_files(rtcp_ref_file, rtcp_out_file); | 464 RefFiles rtcp_stat_files(rtcp_ref_file, rtcp_out_file); |
| 469 | 465 |
| 470 packet_.reset(rtp_source_->NextPacket()); | 466 packet_.reset(rtp_source_->NextPacket()); |
| 471 int i = 0; | 467 int i = 0; |
| 472 while (packet_) { | 468 while (packet_) { |
| 473 std::ostringstream ss; | 469 std::ostringstream ss; |
| 474 ss << "Lap number " << i++ << " in DecodeAndCompare while loop"; | 470 ss << "Lap number " << i++ << " in DecodeAndCompare while loop"; |
| 475 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. | 471 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. |
| 476 size_t out_len = 0; | 472 ASSERT_NO_FATAL_FAILURE(Process()); |
| 477 ASSERT_NO_FATAL_FAILURE(Process(&out_len)); | 473 ASSERT_NO_FATAL_FAILURE(ref_files.ProcessReference( |
| 478 ASSERT_NO_FATAL_FAILURE(ref_files.ProcessReference(out_data_, out_len)); | 474 out_frame_.data_, out_frame_.samples_per_channel_)); |
| 479 | 475 |
| 480 // Query the network statistics API once per second | 476 // Query the network statistics API once per second |
| 481 if (sim_clock_ % 1000 == 0) { | 477 if (sim_clock_ % 1000 == 0) { |
| 482 // Process NetworkStatistics. | 478 // Process NetworkStatistics. |
| 483 NetEqNetworkStatistics network_stats; | 479 NetEqNetworkStatistics network_stats; |
| 484 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); | 480 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); |
| 485 ASSERT_NO_FATAL_FAILURE( | 481 ASSERT_NO_FATAL_FAILURE( |
| 486 network_stat_files.ProcessReference(network_stats)); | 482 network_stat_files.ProcessReference(network_stats)); |
| 487 // Compare with CurrentDelay, which should be identical. | 483 // Compare with CurrentDelay, which should be identical. |
| 488 EXPECT_EQ(network_stats.current_buffer_size_ms, neteq_->CurrentDelayMs()); | 484 EXPECT_EQ(network_stats.current_buffer_size_ms, neteq_->CurrentDelayMs()); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 WebRtcRTPHeader rtp_info; | 604 WebRtcRTPHeader rtp_info; |
| 609 rtp_info.header.sequenceNumber = i; | 605 rtp_info.header.sequenceNumber = i; |
| 610 rtp_info.header.timestamp = i * kSamples; | 606 rtp_info.header.timestamp = i * kSamples; |
| 611 rtp_info.header.ssrc = 0x1234; // Just an arbitrary SSRC. | 607 rtp_info.header.ssrc = 0x1234; // Just an arbitrary SSRC. |
| 612 rtp_info.header.payloadType = 94; // PCM16b WB codec. | 608 rtp_info.header.payloadType = 94; // PCM16b WB codec. |
| 613 rtp_info.header.markerBit = 0; | 609 rtp_info.header.markerBit = 0; |
| 614 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 610 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 615 } | 611 } |
| 616 // Pull out all data. | 612 // Pull out all data. |
| 617 for (size_t i = 0; i < num_frames; ++i) { | 613 for (size_t i = 0; i < num_frames; ++i) { |
| 618 size_t out_len; | |
| 619 size_t num_channels; | |
| 620 NetEqOutputType type; | 614 NetEqOutputType type; |
| 621 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 615 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 622 &num_channels, &type)); | 616 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 623 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 624 } | 617 } |
| 625 | 618 |
| 626 NetEqNetworkStatistics stats; | 619 NetEqNetworkStatistics stats; |
| 627 EXPECT_EQ(0, neteq_->NetworkStatistics(&stats)); | 620 EXPECT_EQ(0, neteq_->NetworkStatistics(&stats)); |
| 628 // Since all frames are dumped into NetEQ at once, but pulled out with 10 ms | 621 // Since all frames are dumped into NetEQ at once, but pulled out with 10 ms |
| 629 // spacing (per definition), we expect the delay to increase with 10 ms for | 622 // spacing (per definition), we expect the delay to increase with 10 ms for |
| 630 // each packet. Thus, we are calculating the statistics for a series from 10 | 623 // each packet. Thus, we are calculating the statistics for a series from 10 |
| 631 // to 300, in steps of 10 ms. | 624 // to 300, in steps of 10 ms. |
| 632 EXPECT_EQ(155, stats.mean_waiting_time_ms); | 625 EXPECT_EQ(155, stats.mean_waiting_time_ms); |
| 633 EXPECT_EQ(155, stats.median_waiting_time_ms); | 626 EXPECT_EQ(155, stats.median_waiting_time_ms); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 653 int num_packets = (frame_index % 10 == 0 ? 2 : 1); | 646 int num_packets = (frame_index % 10 == 0 ? 2 : 1); |
| 654 for (int n = 0; n < num_packets; ++n) { | 647 for (int n = 0; n < num_packets; ++n) { |
| 655 uint8_t payload[kPayloadBytes] = {0}; | 648 uint8_t payload[kPayloadBytes] = {0}; |
| 656 WebRtcRTPHeader rtp_info; | 649 WebRtcRTPHeader rtp_info; |
| 657 PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info); | 650 PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info); |
| 658 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 651 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 659 ++frame_index; | 652 ++frame_index; |
| 660 } | 653 } |
| 661 | 654 |
| 662 // Pull out data once. | 655 // Pull out data once. |
| 663 size_t out_len; | |
| 664 size_t num_channels; | |
| 665 NetEqOutputType type; | 656 NetEqOutputType type; |
| 666 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 657 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 667 &num_channels, &type)); | 658 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 668 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 669 } | 659 } |
| 670 | 660 |
| 671 NetEqNetworkStatistics network_stats; | 661 NetEqNetworkStatistics network_stats; |
| 672 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); | 662 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); |
| 673 EXPECT_EQ(-103196, network_stats.clockdrift_ppm); | 663 EXPECT_EQ(-103196, network_stats.clockdrift_ppm); |
| 674 } | 664 } |
| 675 | 665 |
| 676 TEST_F(NetEqDecodingTest, TestAverageInterArrivalTimePositive) { | 666 TEST_F(NetEqDecodingTest, TestAverageInterArrivalTimePositive) { |
| 677 const int kNumFrames = 5000; // Needed for convergence. | 667 const int kNumFrames = 5000; // Needed for convergence. |
| 678 int frame_index = 0; | 668 int frame_index = 0; |
| 679 const size_t kSamples = 10 * 16; | 669 const size_t kSamples = 10 * 16; |
| 680 const size_t kPayloadBytes = kSamples * 2; | 670 const size_t kPayloadBytes = kSamples * 2; |
| 681 for (int i = 0; i < kNumFrames; ++i) { | 671 for (int i = 0; i < kNumFrames; ++i) { |
| 682 // Insert one packet each time, except every 10th time where we don't insert | 672 // Insert one packet each time, except every 10th time where we don't insert |
| 683 // any packet. This will create a positive clock-drift of approx. 11%. | 673 // any packet. This will create a positive clock-drift of approx. 11%. |
| 684 int num_packets = (i % 10 == 9 ? 0 : 1); | 674 int num_packets = (i % 10 == 9 ? 0 : 1); |
| 685 for (int n = 0; n < num_packets; ++n) { | 675 for (int n = 0; n < num_packets; ++n) { |
| 686 uint8_t payload[kPayloadBytes] = {0}; | 676 uint8_t payload[kPayloadBytes] = {0}; |
| 687 WebRtcRTPHeader rtp_info; | 677 WebRtcRTPHeader rtp_info; |
| 688 PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info); | 678 PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info); |
| 689 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 679 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 690 ++frame_index; | 680 ++frame_index; |
| 691 } | 681 } |
| 692 | 682 |
| 693 // Pull out data once. | 683 // Pull out data once. |
| 694 size_t out_len; | |
| 695 size_t num_channels; | |
| 696 NetEqOutputType type; | 684 NetEqOutputType type; |
| 697 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 685 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 698 &num_channels, &type)); | 686 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 699 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 700 } | 687 } |
| 701 | 688 |
| 702 NetEqNetworkStatistics network_stats; | 689 NetEqNetworkStatistics network_stats; |
| 703 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); | 690 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); |
| 704 EXPECT_EQ(110946, network_stats.clockdrift_ppm); | 691 EXPECT_EQ(110946, network_stats.clockdrift_ppm); |
| 705 } | 692 } |
| 706 | 693 |
| 707 void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, | 694 void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, |
| 708 double network_freeze_ms, | 695 double network_freeze_ms, |
| 709 bool pull_audio_during_freeze, | 696 bool pull_audio_during_freeze, |
| 710 int delay_tolerance_ms, | 697 int delay_tolerance_ms, |
| 711 int max_time_to_speech_ms) { | 698 int max_time_to_speech_ms) { |
| 712 uint16_t seq_no = 0; | 699 uint16_t seq_no = 0; |
| 713 uint32_t timestamp = 0; | 700 uint32_t timestamp = 0; |
| 714 const int kFrameSizeMs = 30; | 701 const int kFrameSizeMs = 30; |
| 715 const size_t kSamples = kFrameSizeMs * 16; | 702 const size_t kSamples = kFrameSizeMs * 16; |
| 716 const size_t kPayloadBytes = kSamples * 2; | 703 const size_t kPayloadBytes = kSamples * 2; |
| 717 double next_input_time_ms = 0.0; | 704 double next_input_time_ms = 0.0; |
| 718 double t_ms; | 705 double t_ms; |
| 719 size_t out_len; | |
| 720 size_t num_channels; | |
| 721 NetEqOutputType type; | 706 NetEqOutputType type; |
| 722 | 707 |
| 723 // Insert speech for 5 seconds. | 708 // Insert speech for 5 seconds. |
| 724 const int kSpeechDurationMs = 5000; | 709 const int kSpeechDurationMs = 5000; |
| 725 for (t_ms = 0; t_ms < kSpeechDurationMs; t_ms += 10) { | 710 for (t_ms = 0; t_ms < kSpeechDurationMs; t_ms += 10) { |
| 726 // Each turn in this for loop is 10 ms. | 711 // Each turn in this for loop is 10 ms. |
| 727 while (next_input_time_ms <= t_ms) { | 712 while (next_input_time_ms <= t_ms) { |
| 728 // Insert one 30 ms speech frame. | 713 // Insert one 30 ms speech frame. |
| 729 uint8_t payload[kPayloadBytes] = {0}; | 714 uint8_t payload[kPayloadBytes] = {0}; |
| 730 WebRtcRTPHeader rtp_info; | 715 WebRtcRTPHeader rtp_info; |
| 731 PopulateRtpInfo(seq_no, timestamp, &rtp_info); | 716 PopulateRtpInfo(seq_no, timestamp, &rtp_info); |
| 732 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 717 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 733 ++seq_no; | 718 ++seq_no; |
| 734 timestamp += kSamples; | 719 timestamp += kSamples; |
| 735 next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor; | 720 next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor; |
| 736 } | 721 } |
| 737 // Pull out data once. | 722 // Pull out data once. |
| 738 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 723 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 739 &num_channels, &type)); | 724 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 740 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 741 } | 725 } |
| 742 | 726 |
| 743 EXPECT_EQ(kOutputNormal, type); | 727 EXPECT_EQ(kOutputNormal, type); |
| 744 int32_t delay_before = timestamp - PlayoutTimestamp(); | 728 int32_t delay_before = timestamp - PlayoutTimestamp(); |
| 745 | 729 |
| 746 // Insert CNG for 1 minute (= 60000 ms). | 730 // Insert CNG for 1 minute (= 60000 ms). |
| 747 const int kCngPeriodMs = 100; | 731 const int kCngPeriodMs = 100; |
| 748 const int kCngPeriodSamples = kCngPeriodMs * 16; // Period in 16 kHz samples. | 732 const int kCngPeriodSamples = kCngPeriodMs * 16; // Period in 16 kHz samples. |
| 749 const int kCngDurationMs = 60000; | 733 const int kCngDurationMs = 60000; |
| 750 for (; t_ms < kSpeechDurationMs + kCngDurationMs; t_ms += 10) { | 734 for (; t_ms < kSpeechDurationMs + kCngDurationMs; t_ms += 10) { |
| 751 // Each turn in this for loop is 10 ms. | 735 // Each turn in this for loop is 10 ms. |
| 752 while (next_input_time_ms <= t_ms) { | 736 while (next_input_time_ms <= t_ms) { |
| 753 // Insert one CNG frame each 100 ms. | 737 // Insert one CNG frame each 100 ms. |
| 754 uint8_t payload[kPayloadBytes]; | 738 uint8_t payload[kPayloadBytes]; |
| 755 size_t payload_len; | 739 size_t payload_len; |
| 756 WebRtcRTPHeader rtp_info; | 740 WebRtcRTPHeader rtp_info; |
| 757 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); | 741 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); |
| 758 ASSERT_EQ(0, neteq_->InsertPacket( | 742 ASSERT_EQ(0, neteq_->InsertPacket( |
| 759 rtp_info, | 743 rtp_info, |
| 760 rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); | 744 rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); |
| 761 ++seq_no; | 745 ++seq_no; |
| 762 timestamp += kCngPeriodSamples; | 746 timestamp += kCngPeriodSamples; |
| 763 next_input_time_ms += static_cast<double>(kCngPeriodMs) * drift_factor; | 747 next_input_time_ms += static_cast<double>(kCngPeriodMs) * drift_factor; |
| 764 } | 748 } |
| 765 // Pull out data once. | 749 // Pull out data once. |
| 766 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 750 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 767 &num_channels, &type)); | 751 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 768 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 769 } | 752 } |
| 770 | 753 |
| 771 EXPECT_EQ(kOutputCNG, type); | 754 EXPECT_EQ(kOutputCNG, type); |
| 772 | 755 |
| 773 if (network_freeze_ms > 0) { | 756 if (network_freeze_ms > 0) { |
| 774 // First keep pulling audio for |network_freeze_ms| without inserting | 757 // First keep pulling audio for |network_freeze_ms| without inserting |
| 775 // any data, then insert CNG data corresponding to |network_freeze_ms| | 758 // any data, then insert CNG data corresponding to |network_freeze_ms| |
| 776 // without pulling any output audio. | 759 // without pulling any output audio. |
| 777 const double loop_end_time = t_ms + network_freeze_ms; | 760 const double loop_end_time = t_ms + network_freeze_ms; |
| 778 for (; t_ms < loop_end_time; t_ms += 10) { | 761 for (; t_ms < loop_end_time; t_ms += 10) { |
| 779 // Pull out data once. | 762 // Pull out data once. |
| 780 ASSERT_EQ(0, | 763 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 781 neteq_->GetAudio( | 764 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 782 kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); | |
| 783 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 784 EXPECT_EQ(kOutputCNG, type); | 765 EXPECT_EQ(kOutputCNG, type); |
| 785 } | 766 } |
| 786 bool pull_once = pull_audio_during_freeze; | 767 bool pull_once = pull_audio_during_freeze; |
| 787 // If |pull_once| is true, GetAudio will be called once half-way through | 768 // If |pull_once| is true, GetAudio will be called once half-way through |
| 788 // the network recovery period. | 769 // the network recovery period. |
| 789 double pull_time_ms = (t_ms + next_input_time_ms) / 2; | 770 double pull_time_ms = (t_ms + next_input_time_ms) / 2; |
| 790 while (next_input_time_ms <= t_ms) { | 771 while (next_input_time_ms <= t_ms) { |
| 791 if (pull_once && next_input_time_ms >= pull_time_ms) { | 772 if (pull_once && next_input_time_ms >= pull_time_ms) { |
| 792 pull_once = false; | 773 pull_once = false; |
| 793 // Pull out data once. | 774 // Pull out data once. |
| 794 ASSERT_EQ( | 775 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 795 0, | 776 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 796 neteq_->GetAudio( | |
| 797 kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); | |
| 798 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 799 EXPECT_EQ(kOutputCNG, type); | 777 EXPECT_EQ(kOutputCNG, type); |
| 800 t_ms += 10; | 778 t_ms += 10; |
| 801 } | 779 } |
| 802 // Insert one CNG frame each 100 ms. | 780 // Insert one CNG frame each 100 ms. |
| 803 uint8_t payload[kPayloadBytes]; | 781 uint8_t payload[kPayloadBytes]; |
| 804 size_t payload_len; | 782 size_t payload_len; |
| 805 WebRtcRTPHeader rtp_info; | 783 WebRtcRTPHeader rtp_info; |
| 806 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); | 784 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); |
| 807 ASSERT_EQ(0, neteq_->InsertPacket( | 785 ASSERT_EQ(0, neteq_->InsertPacket( |
| 808 rtp_info, | 786 rtp_info, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 821 // Insert one 30 ms speech frame. | 799 // Insert one 30 ms speech frame. |
| 822 uint8_t payload[kPayloadBytes] = {0}; | 800 uint8_t payload[kPayloadBytes] = {0}; |
| 823 WebRtcRTPHeader rtp_info; | 801 WebRtcRTPHeader rtp_info; |
| 824 PopulateRtpInfo(seq_no, timestamp, &rtp_info); | 802 PopulateRtpInfo(seq_no, timestamp, &rtp_info); |
| 825 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 803 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 826 ++seq_no; | 804 ++seq_no; |
| 827 timestamp += kSamples; | 805 timestamp += kSamples; |
| 828 next_input_time_ms += kFrameSizeMs * drift_factor; | 806 next_input_time_ms += kFrameSizeMs * drift_factor; |
| 829 } | 807 } |
| 830 // Pull out data once. | 808 // Pull out data once. |
| 831 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 809 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 832 &num_channels, &type)); | 810 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 833 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 834 // Increase clock. | 811 // Increase clock. |
| 835 t_ms += 10; | 812 t_ms += 10; |
| 836 } | 813 } |
| 837 | 814 |
| 838 // Check that the speech starts again within reasonable time. | 815 // Check that the speech starts again within reasonable time. |
| 839 double time_until_speech_returns_ms = t_ms - speech_restart_time_ms; | 816 double time_until_speech_returns_ms = t_ms - speech_restart_time_ms; |
| 840 EXPECT_LT(time_until_speech_returns_ms, max_time_to_speech_ms); | 817 EXPECT_LT(time_until_speech_returns_ms, max_time_to_speech_ms); |
| 841 int32_t delay_after = timestamp - PlayoutTimestamp(); | 818 int32_t delay_after = timestamp - PlayoutTimestamp(); |
| 842 // Compare delay before and after, and make sure it differs less than 20 ms. | 819 // Compare delay before and after, and make sure it differs less than 20 ms. |
| 843 EXPECT_LE(delay_after, delay_before + delay_tolerance_ms * 16); | 820 EXPECT_LE(delay_after, delay_before + delay_tolerance_ms * 16); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 TEST_F(NetEqDecodingTest, MAYBE_DecoderError) { | 923 TEST_F(NetEqDecodingTest, MAYBE_DecoderError) { |
| 947 const size_t kPayloadBytes = 100; | 924 const size_t kPayloadBytes = 100; |
| 948 uint8_t payload[kPayloadBytes] = {0}; | 925 uint8_t payload[kPayloadBytes] = {0}; |
| 949 WebRtcRTPHeader rtp_info; | 926 WebRtcRTPHeader rtp_info; |
| 950 PopulateRtpInfo(0, 0, &rtp_info); | 927 PopulateRtpInfo(0, 0, &rtp_info); |
| 951 rtp_info.header.payloadType = 103; // iSAC, but the payload is invalid. | 928 rtp_info.header.payloadType = 103; // iSAC, but the payload is invalid. |
| 952 EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 929 EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 953 NetEqOutputType type; | 930 NetEqOutputType type; |
| 954 // Set all of |out_data_| to 1, and verify that it was set to 0 by the call | 931 // Set all of |out_data_| to 1, and verify that it was set to 0 by the call |
| 955 // to GetAudio. | 932 // to GetAudio. |
| 956 for (size_t i = 0; i < kMaxBlockSize; ++i) { | 933 for (size_t i = 0; i < AudioFrame::kMaxDataSizeSamples; ++i) { |
| 957 out_data_[i] = 1; | 934 out_frame_.data_[i] = 1; |
| 958 } | 935 } |
| 959 size_t num_channels; | 936 EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&out_frame_, &type)); |
| 960 size_t samples_per_channel; | |
| 961 EXPECT_EQ(NetEq::kFail, | |
| 962 neteq_->GetAudio(kMaxBlockSize, out_data_, | |
| 963 &samples_per_channel, &num_channels, &type)); | |
| 964 // Verify that there is a decoder error to check. | 937 // Verify that there is a decoder error to check. |
| 965 EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError()); | 938 EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError()); |
| 966 | 939 |
| 967 enum NetEqDecoderError { | 940 enum NetEqDecoderError { |
| 968 ISAC_LENGTH_MISMATCH = 6730, | 941 ISAC_LENGTH_MISMATCH = 6730, |
| 969 ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH = 6640 | 942 ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH = 6640 |
| 970 }; | 943 }; |
| 971 #if defined(WEBRTC_CODEC_ISAC) | 944 #if defined(WEBRTC_CODEC_ISAC) |
| 972 EXPECT_EQ(ISAC_LENGTH_MISMATCH, neteq_->LastDecoderError()); | 945 EXPECT_EQ(ISAC_LENGTH_MISMATCH, neteq_->LastDecoderError()); |
| 973 #elif defined(WEBRTC_CODEC_ISACFX) | 946 #elif defined(WEBRTC_CODEC_ISACFX) |
| 974 EXPECT_EQ(ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH, neteq_->LastDecoderError()); | 947 EXPECT_EQ(ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH, neteq_->LastDecoderError()); |
| 975 #endif | 948 #endif |
| 976 // Verify that the first 160 samples are set to 0, and that the remaining | 949 // Verify that the first 160 samples are set to 0, and that the remaining |
| 977 // samples are left unmodified. | 950 // samples are left unmodified. |
| 978 static const int kExpectedOutputLength = 160; // 10 ms at 16 kHz sample rate. | 951 static const int kExpectedOutputLength = 160; // 10 ms at 16 kHz sample rate. |
| 979 for (int i = 0; i < kExpectedOutputLength; ++i) { | 952 for (int i = 0; i < kExpectedOutputLength; ++i) { |
| 980 std::ostringstream ss; | 953 std::ostringstream ss; |
| 981 ss << "i = " << i; | 954 ss << "i = " << i; |
| 982 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. | 955 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. |
| 983 EXPECT_EQ(0, out_data_[i]); | 956 EXPECT_EQ(0, out_frame_.data_[i]); |
| 984 } | 957 } |
| 985 for (size_t i = kExpectedOutputLength; i < kMaxBlockSize; ++i) { | 958 for (size_t i = kExpectedOutputLength; i < AudioFrame::kMaxDataSizeSamples; |
| 959 ++i) { |
| 986 std::ostringstream ss; | 960 std::ostringstream ss; |
| 987 ss << "i = " << i; | 961 ss << "i = " << i; |
| 988 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. | 962 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. |
| 989 EXPECT_EQ(1, out_data_[i]); | 963 EXPECT_EQ(1, out_frame_.data_[i]); |
| 990 } | 964 } |
| 991 } | 965 } |
| 992 | 966 |
| 993 TEST_F(NetEqDecodingTest, GetAudioBeforeInsertPacket) { | 967 TEST_F(NetEqDecodingTest, GetAudioBeforeInsertPacket) { |
| 994 NetEqOutputType type; | 968 NetEqOutputType type; |
| 995 // Set all of |out_data_| to 1, and verify that it was set to 0 by the call | 969 // Set all of |out_data_| to 1, and verify that it was set to 0 by the call |
| 996 // to GetAudio. | 970 // to GetAudio. |
| 997 for (size_t i = 0; i < kMaxBlockSize; ++i) { | 971 for (size_t i = 0; i < AudioFrame::kMaxDataSizeSamples; ++i) { |
| 998 out_data_[i] = 1; | 972 out_frame_.data_[i] = 1; |
| 999 } | 973 } |
| 1000 size_t num_channels; | 974 EXPECT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 1001 size_t samples_per_channel; | |
| 1002 EXPECT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, | |
| 1003 &samples_per_channel, | |
| 1004 &num_channels, &type)); | |
| 1005 // Verify that the first block of samples is set to 0. | 975 // Verify that the first block of samples is set to 0. |
| 1006 static const int kExpectedOutputLength = | 976 static const int kExpectedOutputLength = |
| 1007 kInitSampleRateHz / 100; // 10 ms at initial sample rate. | 977 kInitSampleRateHz / 100; // 10 ms at initial sample rate. |
| 1008 for (int i = 0; i < kExpectedOutputLength; ++i) { | 978 for (int i = 0; i < kExpectedOutputLength; ++i) { |
| 1009 std::ostringstream ss; | 979 std::ostringstream ss; |
| 1010 ss << "i = " << i; | 980 ss << "i = " << i; |
| 1011 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. | 981 SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. |
| 1012 EXPECT_EQ(0, out_data_[i]); | 982 EXPECT_EQ(0, out_frame_.data_[i]); |
| 1013 } | 983 } |
| 1014 // Verify that the sample rate did not change from the initial configuration. | 984 // Verify that the sample rate did not change from the initial configuration. |
| 1015 EXPECT_EQ(config_.sample_rate_hz, neteq_->last_output_sample_rate_hz()); | 985 EXPECT_EQ(config_.sample_rate_hz, neteq_->last_output_sample_rate_hz()); |
| 1016 } | 986 } |
| 1017 | 987 |
| 1018 class NetEqBgnTest : public NetEqDecodingTest { | 988 class NetEqBgnTest : public NetEqDecodingTest { |
| 1019 protected: | 989 protected: |
| 1020 virtual void TestCondition(double sum_squared_noise, | 990 virtual void TestCondition(double sum_squared_noise, |
| 1021 bool should_be_faded) = 0; | 991 bool should_be_faded) = 0; |
| 1022 | 992 |
| 1023 void CheckBgn(int sampling_rate_hz) { | 993 void CheckBgn(int sampling_rate_hz) { |
| 1024 size_t expected_samples_per_channel = 0; | 994 size_t expected_samples_per_channel = 0; |
| 1025 uint8_t payload_type = 0xFF; // Invalid. | 995 uint8_t payload_type = 0xFF; // Invalid. |
| 1026 if (sampling_rate_hz == 8000) { | 996 if (sampling_rate_hz == 8000) { |
| 1027 expected_samples_per_channel = kBlockSize8kHz; | 997 expected_samples_per_channel = kBlockSize8kHz; |
| 1028 payload_type = 93; // PCM 16, 8 kHz. | 998 payload_type = 93; // PCM 16, 8 kHz. |
| 1029 } else if (sampling_rate_hz == 16000) { | 999 } else if (sampling_rate_hz == 16000) { |
| 1030 expected_samples_per_channel = kBlockSize16kHz; | 1000 expected_samples_per_channel = kBlockSize16kHz; |
| 1031 payload_type = 94; // PCM 16, 16 kHZ. | 1001 payload_type = 94; // PCM 16, 16 kHZ. |
| 1032 } else if (sampling_rate_hz == 32000) { | 1002 } else if (sampling_rate_hz == 32000) { |
| 1033 expected_samples_per_channel = kBlockSize32kHz; | 1003 expected_samples_per_channel = kBlockSize32kHz; |
| 1034 payload_type = 95; // PCM 16, 32 kHz. | 1004 payload_type = 95; // PCM 16, 32 kHz. |
| 1035 } else { | 1005 } else { |
| 1036 ASSERT_TRUE(false); // Unsupported test case. | 1006 ASSERT_TRUE(false); // Unsupported test case. |
| 1037 } | 1007 } |
| 1038 | 1008 |
| 1039 NetEqOutputType type; | 1009 NetEqOutputType type; |
| 1040 int16_t output[kBlockSize32kHz]; // Maximum size is chosen. | 1010 AudioFrame output; |
| 1041 test::AudioLoop input; | 1011 test::AudioLoop input; |
| 1042 // We are using the same 32 kHz input file for all tests, regardless of | 1012 // We are using the same 32 kHz input file for all tests, regardless of |
| 1043 // |sampling_rate_hz|. The output may sound weird, but the test is still | 1013 // |sampling_rate_hz|. The output may sound weird, but the test is still |
| 1044 // valid. | 1014 // valid. |
| 1045 ASSERT_TRUE(input.Init( | 1015 ASSERT_TRUE(input.Init( |
| 1046 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"), | 1016 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"), |
| 1047 10 * sampling_rate_hz, // Max 10 seconds loop length. | 1017 10 * sampling_rate_hz, // Max 10 seconds loop length. |
| 1048 expected_samples_per_channel)); | 1018 expected_samples_per_channel)); |
| 1049 | 1019 |
| 1050 // Payload of 10 ms of PCM16 32 kHz. | 1020 // Payload of 10 ms of PCM16 32 kHz. |
| 1051 uint8_t payload[kBlockSize32kHz * sizeof(int16_t)]; | 1021 uint8_t payload[kBlockSize32kHz * sizeof(int16_t)]; |
| 1052 WebRtcRTPHeader rtp_info; | 1022 WebRtcRTPHeader rtp_info; |
| 1053 PopulateRtpInfo(0, 0, &rtp_info); | 1023 PopulateRtpInfo(0, 0, &rtp_info); |
| 1054 rtp_info.header.payloadType = payload_type; | 1024 rtp_info.header.payloadType = payload_type; |
| 1055 | 1025 |
| 1056 size_t number_channels = 0; | |
| 1057 size_t samples_per_channel = 0; | |
| 1058 | |
| 1059 uint32_t receive_timestamp = 0; | 1026 uint32_t receive_timestamp = 0; |
| 1060 for (int n = 0; n < 10; ++n) { // Insert few packets and get audio. | 1027 for (int n = 0; n < 10; ++n) { // Insert few packets and get audio. |
| 1061 auto block = input.GetNextBlock(); | 1028 auto block = input.GetNextBlock(); |
| 1062 ASSERT_EQ(expected_samples_per_channel, block.size()); | 1029 ASSERT_EQ(expected_samples_per_channel, block.size()); |
| 1063 size_t enc_len_bytes = | 1030 size_t enc_len_bytes = |
| 1064 WebRtcPcm16b_Encode(block.data(), block.size(), payload); | 1031 WebRtcPcm16b_Encode(block.data(), block.size(), payload); |
| 1065 ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2); | 1032 ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2); |
| 1066 | 1033 |
| 1067 number_channels = 0; | |
| 1068 samples_per_channel = 0; | |
| 1069 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( | 1034 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( |
| 1070 payload, enc_len_bytes), | 1035 payload, enc_len_bytes), |
| 1071 receive_timestamp)); | 1036 receive_timestamp)); |
| 1072 ASSERT_EQ(0, | 1037 output.Reset(); |
| 1073 neteq_->GetAudio(kBlockSize32kHz, | 1038 ASSERT_EQ(0, neteq_->GetAudio(&output, &type)); |
| 1074 output, | 1039 ASSERT_EQ(1u, output.num_channels_); |
| 1075 &samples_per_channel, | 1040 ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_); |
| 1076 &number_channels, | |
| 1077 &type)); | |
| 1078 ASSERT_EQ(1u, number_channels); | |
| 1079 ASSERT_EQ(expected_samples_per_channel, samples_per_channel); | |
| 1080 ASSERT_EQ(kOutputNormal, type); | 1041 ASSERT_EQ(kOutputNormal, type); |
| 1081 | 1042 |
| 1082 // Next packet. | 1043 // Next packet. |
| 1083 rtp_info.header.timestamp += expected_samples_per_channel; | 1044 rtp_info.header.timestamp += expected_samples_per_channel; |
| 1084 rtp_info.header.sequenceNumber++; | 1045 rtp_info.header.sequenceNumber++; |
| 1085 receive_timestamp += expected_samples_per_channel; | 1046 receive_timestamp += expected_samples_per_channel; |
| 1086 } | 1047 } |
| 1087 | 1048 |
| 1088 number_channels = 0; | 1049 output.Reset(); |
| 1089 samples_per_channel = 0; | |
| 1090 | 1050 |
| 1091 // Get audio without inserting packets, expecting PLC and PLC-to-CNG. Pull | 1051 // Get audio without inserting packets, expecting PLC and PLC-to-CNG. Pull |
| 1092 // one frame without checking speech-type. This is the first frame pulled | 1052 // one frame without checking speech-type. This is the first frame pulled |
| 1093 // without inserting any packet, and might not be labeled as PLC. | 1053 // without inserting any packet, and might not be labeled as PLC. |
| 1094 ASSERT_EQ(0, | 1054 ASSERT_EQ(0, neteq_->GetAudio(&output, &type)); |
| 1095 neteq_->GetAudio(kBlockSize32kHz, | 1055 ASSERT_EQ(1u, output.num_channels_); |
| 1096 output, | 1056 ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_); |
| 1097 &samples_per_channel, | |
| 1098 &number_channels, | |
| 1099 &type)); | |
| 1100 ASSERT_EQ(1u, number_channels); | |
| 1101 ASSERT_EQ(expected_samples_per_channel, samples_per_channel); | |
| 1102 | 1057 |
| 1103 // To be able to test the fading of background noise we need at lease to | 1058 // To be able to test the fading of background noise we need at lease to |
| 1104 // pull 611 frames. | 1059 // pull 611 frames. |
| 1105 const int kFadingThreshold = 611; | 1060 const int kFadingThreshold = 611; |
| 1106 | 1061 |
| 1107 // Test several CNG-to-PLC packet for the expected behavior. The number 20 | 1062 // Test several CNG-to-PLC packet for the expected behavior. The number 20 |
| 1108 // is arbitrary, but sufficiently large to test enough number of frames. | 1063 // is arbitrary, but sufficiently large to test enough number of frames. |
| 1109 const int kNumPlcToCngTestFrames = 20; | 1064 const int kNumPlcToCngTestFrames = 20; |
| 1110 bool plc_to_cng = false; | 1065 bool plc_to_cng = false; |
| 1111 for (int n = 0; n < kFadingThreshold + kNumPlcToCngTestFrames; ++n) { | 1066 for (int n = 0; n < kFadingThreshold + kNumPlcToCngTestFrames; ++n) { |
| 1112 number_channels = 0; | 1067 output.Reset(); |
| 1113 samples_per_channel = 0; | 1068 memset(output.data_, 1, sizeof(output.data_)); // Set to non-zero. |
| 1114 memset(output, 1, sizeof(output)); // Set to non-zero. | 1069 ASSERT_EQ(0, neteq_->GetAudio(&output, &type)); |
| 1115 ASSERT_EQ(0, | 1070 ASSERT_EQ(1u, output.num_channels_); |
| 1116 neteq_->GetAudio(kBlockSize32kHz, | 1071 ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_); |
| 1117 output, | |
| 1118 &samples_per_channel, | |
| 1119 &number_channels, | |
| 1120 &type)); | |
| 1121 ASSERT_EQ(1u, number_channels); | |
| 1122 ASSERT_EQ(expected_samples_per_channel, samples_per_channel); | |
| 1123 if (type == kOutputPLCtoCNG) { | 1072 if (type == kOutputPLCtoCNG) { |
| 1124 plc_to_cng = true; | 1073 plc_to_cng = true; |
| 1125 double sum_squared = 0; | 1074 double sum_squared = 0; |
| 1126 for (size_t k = 0; k < number_channels * samples_per_channel; ++k) | 1075 for (size_t k = 0; |
| 1127 sum_squared += output[k] * output[k]; | 1076 k < output.num_channels_ * output.samples_per_channel_; ++k) |
| 1077 sum_squared += output.data_[k] * output.data_[k]; |
| 1128 TestCondition(sum_squared, n > kFadingThreshold); | 1078 TestCondition(sum_squared, n > kFadingThreshold); |
| 1129 } else { | 1079 } else { |
| 1130 EXPECT_EQ(kOutputPLC, type); | 1080 EXPECT_EQ(kOutputPLC, type); |
| 1131 } | 1081 } |
| 1132 } | 1082 } |
| 1133 EXPECT_TRUE(plc_to_cng); // Just to be sure that PLC-to-CNG has occurred. | 1083 EXPECT_TRUE(plc_to_cng); // Just to be sure that PLC-to-CNG has occurred. |
| 1134 } | 1084 } |
| 1135 }; | 1085 }; |
| 1136 | 1086 |
| 1137 class NetEqBgnTestOn : public NetEqBgnTest { | 1087 class NetEqBgnTestOn : public NetEqBgnTest { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 // packets should not produce error, statistics should not show any packet loss | 1225 // packets should not produce error, statistics should not show any packet loss |
| 1276 // and sync-packets should decode to zero. | 1226 // and sync-packets should decode to zero. |
| 1277 // TODO(turajs) we will have a better test if we have a referece NetEq, and | 1227 // TODO(turajs) we will have a better test if we have a referece NetEq, and |
| 1278 // when Sync packets are inserted in "test" NetEq we insert all-zero payload | 1228 // when Sync packets are inserted in "test" NetEq we insert all-zero payload |
| 1279 // in reference NetEq and compare the output of those two. | 1229 // in reference NetEq and compare the output of those two. |
| 1280 TEST_F(NetEqDecodingTest, SyncPacketDecode) { | 1230 TEST_F(NetEqDecodingTest, SyncPacketDecode) { |
| 1281 WebRtcRTPHeader rtp_info; | 1231 WebRtcRTPHeader rtp_info; |
| 1282 PopulateRtpInfo(0, 0, &rtp_info); | 1232 PopulateRtpInfo(0, 0, &rtp_info); |
| 1283 const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); | 1233 const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); |
| 1284 uint8_t payload[kPayloadBytes]; | 1234 uint8_t payload[kPayloadBytes]; |
| 1285 int16_t decoded[kBlockSize16kHz]; | 1235 AudioFrame output; |
| 1286 int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; | 1236 int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; |
| 1287 for (size_t n = 0; n < kPayloadBytes; ++n) { | 1237 for (size_t n = 0; n < kPayloadBytes; ++n) { |
| 1288 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence. | 1238 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence. |
| 1289 } | 1239 } |
| 1290 // Insert some packets which decode to noise. We are not interested in | 1240 // Insert some packets which decode to noise. We are not interested in |
| 1291 // actual decoded values. | 1241 // actual decoded values. |
| 1292 NetEqOutputType output_type; | 1242 NetEqOutputType output_type; |
| 1293 size_t num_channels; | |
| 1294 size_t samples_per_channel; | |
| 1295 uint32_t receive_timestamp = 0; | 1243 uint32_t receive_timestamp = 0; |
| 1296 for (int n = 0; n < 100; ++n) { | 1244 for (int n = 0; n < 100; ++n) { |
| 1297 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | 1245 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); |
| 1298 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, | 1246 ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type)); |
| 1299 &samples_per_channel, &num_channels, | 1247 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| 1300 &output_type)); | 1248 ASSERT_EQ(1u, output.num_channels_); |
| 1301 ASSERT_EQ(kBlockSize16kHz, samples_per_channel); | |
| 1302 ASSERT_EQ(1u, num_channels); | |
| 1303 | 1249 |
| 1304 rtp_info.header.sequenceNumber++; | 1250 rtp_info.header.sequenceNumber++; |
| 1305 rtp_info.header.timestamp += kBlockSize16kHz; | 1251 rtp_info.header.timestamp += kBlockSize16kHz; |
| 1306 receive_timestamp += kBlockSize16kHz; | 1252 receive_timestamp += kBlockSize16kHz; |
| 1307 } | 1253 } |
| 1308 const int kNumSyncPackets = 10; | 1254 const int kNumSyncPackets = 10; |
| 1309 | 1255 |
| 1310 // Make sure sufficient number of sync packets are inserted that we can | 1256 // Make sure sufficient number of sync packets are inserted that we can |
| 1311 // conduct a test. | 1257 // conduct a test. |
| 1312 ASSERT_GT(kNumSyncPackets, algorithmic_frame_delay); | 1258 ASSERT_GT(kNumSyncPackets, algorithmic_frame_delay); |
| 1313 // Insert sync-packets, the decoded sequence should be all-zero. | 1259 // Insert sync-packets, the decoded sequence should be all-zero. |
| 1314 for (int n = 0; n < kNumSyncPackets; ++n) { | 1260 for (int n = 0; n < kNumSyncPackets; ++n) { |
| 1315 ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | 1261 ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); |
| 1316 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, | 1262 ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type)); |
| 1317 &samples_per_channel, &num_channels, | 1263 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| 1318 &output_type)); | 1264 ASSERT_EQ(1u, output.num_channels_); |
| 1319 ASSERT_EQ(kBlockSize16kHz, samples_per_channel); | |
| 1320 ASSERT_EQ(1u, num_channels); | |
| 1321 if (n > algorithmic_frame_delay) { | 1265 if (n > algorithmic_frame_delay) { |
| 1322 EXPECT_TRUE(IsAllZero(decoded, samples_per_channel * num_channels)); | 1266 EXPECT_TRUE(IsAllZero( |
| 1267 output.data_, output.samples_per_channel_ * output.num_channels_)); |
| 1323 } | 1268 } |
| 1324 rtp_info.header.sequenceNumber++; | 1269 rtp_info.header.sequenceNumber++; |
| 1325 rtp_info.header.timestamp += kBlockSize16kHz; | 1270 rtp_info.header.timestamp += kBlockSize16kHz; |
| 1326 receive_timestamp += kBlockSize16kHz; | 1271 receive_timestamp += kBlockSize16kHz; |
| 1327 } | 1272 } |
| 1328 | 1273 |
| 1329 // We insert regular packets, if sync packet are not correctly buffered then | 1274 // We insert regular packets, if sync packet are not correctly buffered then |
| 1330 // network statistics would show some packet loss. | 1275 // network statistics would show some packet loss. |
| 1331 for (int n = 0; n <= algorithmic_frame_delay + 10; ++n) { | 1276 for (int n = 0; n <= algorithmic_frame_delay + 10; ++n) { |
| 1332 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | 1277 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); |
| 1333 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, | 1278 ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type)); |
| 1334 &samples_per_channel, &num_channels, | |
| 1335 &output_type)); | |
| 1336 if (n >= algorithmic_frame_delay + 1) { | 1279 if (n >= algorithmic_frame_delay + 1) { |
| 1337 // Expect that this frame contain samples from regular RTP. | 1280 // Expect that this frame contain samples from regular RTP. |
| 1338 EXPECT_TRUE(IsAllNonZero(decoded, samples_per_channel * num_channels)); | 1281 EXPECT_TRUE(IsAllNonZero( |
| 1282 output.data_, output.samples_per_channel_ * output.num_channels_)); |
| 1339 } | 1283 } |
| 1340 rtp_info.header.sequenceNumber++; | 1284 rtp_info.header.sequenceNumber++; |
| 1341 rtp_info.header.timestamp += kBlockSize16kHz; | 1285 rtp_info.header.timestamp += kBlockSize16kHz; |
| 1342 receive_timestamp += kBlockSize16kHz; | 1286 receive_timestamp += kBlockSize16kHz; |
| 1343 } | 1287 } |
| 1344 NetEqNetworkStatistics network_stats; | 1288 NetEqNetworkStatistics network_stats; |
| 1345 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); | 1289 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); |
| 1346 // Expecting a "clean" network. | 1290 // Expecting a "clean" network. |
| 1347 EXPECT_EQ(0, network_stats.packet_loss_rate); | 1291 EXPECT_EQ(0, network_stats.packet_loss_rate); |
| 1348 EXPECT_EQ(0, network_stats.expand_rate); | 1292 EXPECT_EQ(0, network_stats.expand_rate); |
| 1349 EXPECT_EQ(0, network_stats.accelerate_rate); | 1293 EXPECT_EQ(0, network_stats.accelerate_rate); |
| 1350 EXPECT_LE(network_stats.preemptive_rate, 150); | 1294 EXPECT_LE(network_stats.preemptive_rate, 150); |
| 1351 } | 1295 } |
| 1352 | 1296 |
| 1353 // Test if the size of the packet buffer reported correctly when containing | 1297 // Test if the size of the packet buffer reported correctly when containing |
| 1354 // sync packets. Also, test if network packets override sync packets. That is to | 1298 // sync packets. Also, test if network packets override sync packets. That is to |
| 1355 // prefer decoding a network packet to a sync packet, if both have same sequence | 1299 // prefer decoding a network packet to a sync packet, if both have same sequence |
| 1356 // number and timestamp. | 1300 // number and timestamp. |
| 1357 TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { | 1301 TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { |
| 1358 WebRtcRTPHeader rtp_info; | 1302 WebRtcRTPHeader rtp_info; |
| 1359 PopulateRtpInfo(0, 0, &rtp_info); | 1303 PopulateRtpInfo(0, 0, &rtp_info); |
| 1360 const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); | 1304 const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); |
| 1361 uint8_t payload[kPayloadBytes]; | 1305 uint8_t payload[kPayloadBytes]; |
| 1362 int16_t decoded[kBlockSize16kHz]; | 1306 AudioFrame output; |
| 1363 for (size_t n = 0; n < kPayloadBytes; ++n) { | 1307 for (size_t n = 0; n < kPayloadBytes; ++n) { |
| 1364 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence. | 1308 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence. |
| 1365 } | 1309 } |
| 1366 // Insert some packets which decode to noise. We are not interested in | 1310 // Insert some packets which decode to noise. We are not interested in |
| 1367 // actual decoded values. | 1311 // actual decoded values. |
| 1368 NetEqOutputType output_type; | 1312 NetEqOutputType output_type; |
| 1369 size_t num_channels; | |
| 1370 size_t samples_per_channel; | |
| 1371 uint32_t receive_timestamp = 0; | 1313 uint32_t receive_timestamp = 0; |
| 1372 int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; | 1314 int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; |
| 1373 for (int n = 0; n < algorithmic_frame_delay; ++n) { | 1315 for (int n = 0; n < algorithmic_frame_delay; ++n) { |
| 1374 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | 1316 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); |
| 1375 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, | 1317 ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type)); |
| 1376 &samples_per_channel, &num_channels, | 1318 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| 1377 &output_type)); | 1319 ASSERT_EQ(1u, output.num_channels_); |
| 1378 ASSERT_EQ(kBlockSize16kHz, samples_per_channel); | |
| 1379 ASSERT_EQ(1u, num_channels); | |
| 1380 rtp_info.header.sequenceNumber++; | 1320 rtp_info.header.sequenceNumber++; |
| 1381 rtp_info.header.timestamp += kBlockSize16kHz; | 1321 rtp_info.header.timestamp += kBlockSize16kHz; |
| 1382 receive_timestamp += kBlockSize16kHz; | 1322 receive_timestamp += kBlockSize16kHz; |
| 1383 } | 1323 } |
| 1384 const int kNumSyncPackets = 10; | 1324 const int kNumSyncPackets = 10; |
| 1385 | 1325 |
| 1386 WebRtcRTPHeader first_sync_packet_rtp_info; | 1326 WebRtcRTPHeader first_sync_packet_rtp_info; |
| 1387 memcpy(&first_sync_packet_rtp_info, &rtp_info, sizeof(rtp_info)); | 1327 memcpy(&first_sync_packet_rtp_info, &rtp_info, sizeof(rtp_info)); |
| 1388 | 1328 |
| 1389 // Insert sync-packets, but no decoding. | 1329 // Insert sync-packets, but no decoding. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1404 // Insert. | 1344 // Insert. |
| 1405 for (int n = 0; n < kNumSyncPackets; ++n) { | 1345 for (int n = 0; n < kNumSyncPackets; ++n) { |
| 1406 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | 1346 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); |
| 1407 rtp_info.header.sequenceNumber++; | 1347 rtp_info.header.sequenceNumber++; |
| 1408 rtp_info.header.timestamp += kBlockSize16kHz; | 1348 rtp_info.header.timestamp += kBlockSize16kHz; |
| 1409 receive_timestamp += kBlockSize16kHz; | 1349 receive_timestamp += kBlockSize16kHz; |
| 1410 } | 1350 } |
| 1411 | 1351 |
| 1412 // Decode. | 1352 // Decode. |
| 1413 for (int n = 0; n < kNumSyncPackets; ++n) { | 1353 for (int n = 0; n < kNumSyncPackets; ++n) { |
| 1414 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, | 1354 ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type)); |
| 1415 &samples_per_channel, &num_channels, | 1355 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| 1416 &output_type)); | 1356 ASSERT_EQ(1u, output.num_channels_); |
| 1417 ASSERT_EQ(kBlockSize16kHz, samples_per_channel); | 1357 EXPECT_TRUE(IsAllNonZero( |
| 1418 ASSERT_EQ(1u, num_channels); | 1358 output.data_, output.samples_per_channel_ * output.num_channels_)); |
| 1419 EXPECT_TRUE(IsAllNonZero(decoded, samples_per_channel * num_channels)); | |
| 1420 } | 1359 } |
| 1421 } | 1360 } |
| 1422 | 1361 |
| 1423 void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, | 1362 void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, |
| 1424 uint32_t start_timestamp, | 1363 uint32_t start_timestamp, |
| 1425 const std::set<uint16_t>& drop_seq_numbers, | 1364 const std::set<uint16_t>& drop_seq_numbers, |
| 1426 bool expect_seq_no_wrap, | 1365 bool expect_seq_no_wrap, |
| 1427 bool expect_timestamp_wrap) { | 1366 bool expect_timestamp_wrap) { |
| 1428 uint16_t seq_no = start_seq_no; | 1367 uint16_t seq_no = start_seq_no; |
| 1429 uint32_t timestamp = start_timestamp; | 1368 uint32_t timestamp = start_timestamp; |
| 1430 const int kBlocksPerFrame = 3; // Number of 10 ms blocks per frame. | 1369 const int kBlocksPerFrame = 3; // Number of 10 ms blocks per frame. |
| 1431 const int kFrameSizeMs = kBlocksPerFrame * kTimeStepMs; | 1370 const int kFrameSizeMs = kBlocksPerFrame * kTimeStepMs; |
| 1432 const int kSamples = kBlockSize16kHz * kBlocksPerFrame; | 1371 const int kSamples = kBlockSize16kHz * kBlocksPerFrame; |
| 1433 const size_t kPayloadBytes = kSamples * sizeof(int16_t); | 1372 const size_t kPayloadBytes = kSamples * sizeof(int16_t); |
| 1434 double next_input_time_ms = 0.0; | 1373 double next_input_time_ms = 0.0; |
| 1435 int16_t decoded[kBlockSize16kHz]; | |
| 1436 size_t num_channels; | |
| 1437 size_t samples_per_channel; | |
| 1438 NetEqOutputType output_type; | |
| 1439 uint32_t receive_timestamp = 0; | 1374 uint32_t receive_timestamp = 0; |
| 1440 | 1375 |
| 1441 // Insert speech for 2 seconds. | 1376 // Insert speech for 2 seconds. |
| 1442 const int kSpeechDurationMs = 2000; | 1377 const int kSpeechDurationMs = 2000; |
| 1443 int packets_inserted = 0; | 1378 int packets_inserted = 0; |
| 1444 uint16_t last_seq_no; | 1379 uint16_t last_seq_no; |
| 1445 uint32_t last_timestamp; | 1380 uint32_t last_timestamp; |
| 1446 bool timestamp_wrapped = false; | 1381 bool timestamp_wrapped = false; |
| 1447 bool seq_no_wrapped = false; | 1382 bool seq_no_wrapped = false; |
| 1448 for (double t_ms = 0; t_ms < kSpeechDurationMs; t_ms += 10) { | 1383 for (double t_ms = 0; t_ms < kSpeechDurationMs; t_ms += 10) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1475 | 1410 |
| 1476 ++seq_no; | 1411 ++seq_no; |
| 1477 timestamp += kSamples; | 1412 timestamp += kSamples; |
| 1478 receive_timestamp += kSamples; | 1413 receive_timestamp += kSamples; |
| 1479 next_input_time_ms += static_cast<double>(kFrameSizeMs); | 1414 next_input_time_ms += static_cast<double>(kFrameSizeMs); |
| 1480 | 1415 |
| 1481 seq_no_wrapped |= seq_no < last_seq_no; | 1416 seq_no_wrapped |= seq_no < last_seq_no; |
| 1482 timestamp_wrapped |= timestamp < last_timestamp; | 1417 timestamp_wrapped |= timestamp < last_timestamp; |
| 1483 } | 1418 } |
| 1484 // Pull out data once. | 1419 // Pull out data once. |
| 1485 ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, | 1420 AudioFrame output; |
| 1486 &samples_per_channel, &num_channels, | 1421 NetEqOutputType output_type; |
| 1487 &output_type)); | 1422 ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type)); |
| 1488 ASSERT_EQ(kBlockSize16kHz, samples_per_channel); | 1423 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); |
| 1489 ASSERT_EQ(1u, num_channels); | 1424 ASSERT_EQ(1u, output.num_channels_); |
| 1490 | 1425 |
| 1491 // Expect delay (in samples) to be less than 2 packets. | 1426 // Expect delay (in samples) to be less than 2 packets. |
| 1492 EXPECT_LE(timestamp - PlayoutTimestamp(), | 1427 EXPECT_LE(timestamp - PlayoutTimestamp(), |
| 1493 static_cast<uint32_t>(kSamples * 2)); | 1428 static_cast<uint32_t>(kSamples * 2)); |
| 1494 } | 1429 } |
| 1495 // Make sure we have actually tested wrap-around. | 1430 // Make sure we have actually tested wrap-around. |
| 1496 ASSERT_EQ(expect_seq_no_wrap, seq_no_wrapped); | 1431 ASSERT_EQ(expect_seq_no_wrap, seq_no_wrapped); |
| 1497 ASSERT_EQ(expect_timestamp_wrap, timestamp_wrapped); | 1432 ASSERT_EQ(expect_timestamp_wrap, timestamp_wrapped); |
| 1498 } | 1433 } |
| 1499 | 1434 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1529 uint32_t timestamp = 0; | 1464 uint32_t timestamp = 0; |
| 1530 const int kFrameSizeMs = 10; | 1465 const int kFrameSizeMs = 10; |
| 1531 const int kSampleRateKhz = 16; | 1466 const int kSampleRateKhz = 16; |
| 1532 const int kSamples = kFrameSizeMs * kSampleRateKhz; | 1467 const int kSamples = kFrameSizeMs * kSampleRateKhz; |
| 1533 const size_t kPayloadBytes = kSamples * 2; | 1468 const size_t kPayloadBytes = kSamples * 2; |
| 1534 | 1469 |
| 1535 const int algorithmic_delay_samples = std::max( | 1470 const int algorithmic_delay_samples = std::max( |
| 1536 algorithmic_delay_ms_ * kSampleRateKhz, 5 * kSampleRateKhz / 8); | 1471 algorithmic_delay_ms_ * kSampleRateKhz, 5 * kSampleRateKhz / 8); |
| 1537 // Insert three speech packets. Three are needed to get the frame length | 1472 // Insert three speech packets. Three are needed to get the frame length |
| 1538 // correct. | 1473 // correct. |
| 1539 size_t out_len; | |
| 1540 size_t num_channels; | |
| 1541 NetEqOutputType type; | 1474 NetEqOutputType type; |
| 1542 uint8_t payload[kPayloadBytes] = {0}; | 1475 uint8_t payload[kPayloadBytes] = {0}; |
| 1543 WebRtcRTPHeader rtp_info; | 1476 WebRtcRTPHeader rtp_info; |
| 1544 for (int i = 0; i < 3; ++i) { | 1477 for (int i = 0; i < 3; ++i) { |
| 1545 PopulateRtpInfo(seq_no, timestamp, &rtp_info); | 1478 PopulateRtpInfo(seq_no, timestamp, &rtp_info); |
| 1546 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 1479 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 1547 ++seq_no; | 1480 ++seq_no; |
| 1548 timestamp += kSamples; | 1481 timestamp += kSamples; |
| 1549 | 1482 |
| 1550 // Pull audio once. | 1483 // Pull audio once. |
| 1551 ASSERT_EQ(0, | 1484 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 1552 neteq_->GetAudio( | 1485 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 1553 kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); | |
| 1554 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 1555 } | 1486 } |
| 1556 // Verify speech output. | 1487 // Verify speech output. |
| 1557 EXPECT_EQ(kOutputNormal, type); | 1488 EXPECT_EQ(kOutputNormal, type); |
| 1558 | 1489 |
| 1559 // Insert same CNG packet twice. | 1490 // Insert same CNG packet twice. |
| 1560 const int kCngPeriodMs = 100; | 1491 const int kCngPeriodMs = 100; |
| 1561 const int kCngPeriodSamples = kCngPeriodMs * kSampleRateKhz; | 1492 const int kCngPeriodSamples = kCngPeriodMs * kSampleRateKhz; |
| 1562 size_t payload_len; | 1493 size_t payload_len; |
| 1563 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); | 1494 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); |
| 1564 // This is the first time this CNG packet is inserted. | 1495 // This is the first time this CNG packet is inserted. |
| 1565 ASSERT_EQ( | 1496 ASSERT_EQ( |
| 1566 0, neteq_->InsertPacket( | 1497 0, neteq_->InsertPacket( |
| 1567 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); | 1498 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); |
| 1568 | 1499 |
| 1569 // Pull audio once and make sure CNG is played. | 1500 // Pull audio once and make sure CNG is played. |
| 1570 ASSERT_EQ(0, | 1501 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 1571 neteq_->GetAudio( | 1502 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 1572 kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); | |
| 1573 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 1574 EXPECT_EQ(kOutputCNG, type); | 1503 EXPECT_EQ(kOutputCNG, type); |
| 1575 EXPECT_EQ(timestamp - algorithmic_delay_samples, PlayoutTimestamp()); | 1504 EXPECT_EQ(timestamp - algorithmic_delay_samples, PlayoutTimestamp()); |
| 1576 | 1505 |
| 1577 // Insert the same CNG packet again. Note that at this point it is old, since | 1506 // Insert the same CNG packet again. Note that at this point it is old, since |
| 1578 // we have already decoded the first copy of it. | 1507 // we have already decoded the first copy of it. |
| 1579 ASSERT_EQ( | 1508 ASSERT_EQ( |
| 1580 0, neteq_->InsertPacket( | 1509 0, neteq_->InsertPacket( |
| 1581 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); | 1510 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); |
| 1582 | 1511 |
| 1583 // Pull audio until we have played |kCngPeriodMs| of CNG. Start at 10 ms since | 1512 // Pull audio until we have played |kCngPeriodMs| of CNG. Start at 10 ms since |
| 1584 // we have already pulled out CNG once. | 1513 // we have already pulled out CNG once. |
| 1585 for (int cng_time_ms = 10; cng_time_ms < kCngPeriodMs; cng_time_ms += 10) { | 1514 for (int cng_time_ms = 10; cng_time_ms < kCngPeriodMs; cng_time_ms += 10) { |
| 1586 ASSERT_EQ(0, | 1515 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 1587 neteq_->GetAudio( | 1516 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 1588 kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); | |
| 1589 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 1590 EXPECT_EQ(kOutputCNG, type); | 1517 EXPECT_EQ(kOutputCNG, type); |
| 1591 EXPECT_EQ(timestamp - algorithmic_delay_samples, | 1518 EXPECT_EQ(timestamp - algorithmic_delay_samples, |
| 1592 PlayoutTimestamp()); | 1519 PlayoutTimestamp()); |
| 1593 } | 1520 } |
| 1594 | 1521 |
| 1595 // Insert speech again. | 1522 // Insert speech again. |
| 1596 ++seq_no; | 1523 ++seq_no; |
| 1597 timestamp += kCngPeriodSamples; | 1524 timestamp += kCngPeriodSamples; |
| 1598 PopulateRtpInfo(seq_no, timestamp, &rtp_info); | 1525 PopulateRtpInfo(seq_no, timestamp, &rtp_info); |
| 1599 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 1526 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 1600 | 1527 |
| 1601 // Pull audio once and verify that the output is speech again. | 1528 // Pull audio once and verify that the output is speech again. |
| 1602 ASSERT_EQ(0, | 1529 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 1603 neteq_->GetAudio( | 1530 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 1604 kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); | |
| 1605 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 1606 EXPECT_EQ(kOutputNormal, type); | 1531 EXPECT_EQ(kOutputNormal, type); |
| 1607 EXPECT_EQ(timestamp + kSamples - algorithmic_delay_samples, | 1532 EXPECT_EQ(timestamp + kSamples - algorithmic_delay_samples, |
| 1608 PlayoutTimestamp()); | 1533 PlayoutTimestamp()); |
| 1609 } | 1534 } |
| 1610 | 1535 |
| 1611 uint32_t NetEqDecodingTest::PlayoutTimestamp() { | 1536 uint32_t NetEqDecodingTest::PlayoutTimestamp() { |
| 1612 uint32_t playout_timestamp = 0; | 1537 uint32_t playout_timestamp = 0; |
| 1613 EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&playout_timestamp)); | 1538 EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&playout_timestamp)); |
| 1614 return playout_timestamp; | 1539 return playout_timestamp; |
| 1615 } | 1540 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1632 | 1557 |
| 1633 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); | 1558 PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); |
| 1634 ASSERT_EQ( | 1559 ASSERT_EQ( |
| 1635 NetEq::kOK, | 1560 NetEq::kOK, |
| 1636 neteq_->InsertPacket( | 1561 neteq_->InsertPacket( |
| 1637 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); | 1562 rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); |
| 1638 ++seq_no; | 1563 ++seq_no; |
| 1639 timestamp += kCngPeriodSamples; | 1564 timestamp += kCngPeriodSamples; |
| 1640 | 1565 |
| 1641 // Pull audio once and make sure CNG is played. | 1566 // Pull audio once and make sure CNG is played. |
| 1642 size_t out_len; | |
| 1643 size_t num_channels; | |
| 1644 NetEqOutputType type; | 1567 NetEqOutputType type; |
| 1645 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 1568 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 1646 &num_channels, &type)); | 1569 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 1647 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 1648 EXPECT_EQ(kOutputCNG, type); | 1570 EXPECT_EQ(kOutputCNG, type); |
| 1649 | 1571 |
| 1650 // Insert some speech packets. | 1572 // Insert some speech packets. |
| 1651 for (int i = 0; i < 3; ++i) { | 1573 for (int i = 0; i < 3; ++i) { |
| 1652 PopulateRtpInfo(seq_no, timestamp, &rtp_info); | 1574 PopulateRtpInfo(seq_no, timestamp, &rtp_info); |
| 1653 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); | 1575 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); |
| 1654 ++seq_no; | 1576 ++seq_no; |
| 1655 timestamp += kSamples; | 1577 timestamp += kSamples; |
| 1656 | 1578 |
| 1657 // Pull audio once. | 1579 // Pull audio once. |
| 1658 ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, | 1580 ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type)); |
| 1659 &num_channels, &type)); | 1581 ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_); |
| 1660 ASSERT_EQ(kBlockSize16kHz, out_len); | |
| 1661 } | 1582 } |
| 1662 // Verify speech output. | 1583 // Verify speech output. |
| 1663 EXPECT_EQ(kOutputNormal, type); | 1584 EXPECT_EQ(kOutputNormal, type); |
| 1664 } | 1585 } |
| 1665 | 1586 |
| 1666 } // namespace webrtc | 1587 } // namespace webrtc |
| OLD | NEW |