diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receive_test.cc b/webrtc/modules/audio_coding/main/acm2/acm_receive_test.cc deleted file mode 100644 index 85678cf220..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receive_test.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_receive_test.h" - -#include -#include - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" -#include "webrtc/modules/audio_coding/neteq/tools/audio_sink.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h" - -namespace webrtc { -namespace test { - -AcmReceiveTest::AcmReceiveTest(PacketSource* packet_source, - AudioSink* audio_sink, - int output_freq_hz, - NumOutputChannels expected_output_channels) - : clock_(0), - packet_source_(packet_source), - audio_sink_(audio_sink), - output_freq_hz_(output_freq_hz), - expected_output_channels_(expected_output_channels) { - webrtc::AudioCoding::Config config; - config.clock = &clock_; - config.playout_frequency_hz = output_freq_hz_; - acm_.reset(webrtc::AudioCoding::Create(config)); -} - -void AcmReceiveTest::RegisterDefaultCodecs() { -#ifdef WEBRTC_CODEC_OPUS - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kOpus, 120)); -#endif -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISAC, 103)); -#endif -#ifdef WEBRTC_CODEC_ISAC - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISACSWB, 104)); -#endif - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16B, 107)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bwb, 108)); - ASSERT_TRUE( - acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bswb32kHz, 109)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16B_2ch, 111)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bwb_2ch, 112)); - ASSERT_TRUE( - acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bswb32kHz_2ch, 113)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMU, 0)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMA, 8)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMU_2ch, 110)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMA_2ch, 118)); -#ifdef WEBRTC_CODEC_ILBC - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kILBC, 102)); -#endif -#ifdef WEBRTC_CODEC_G722 - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kG722, 9)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kG722_2ch, 119)); -#endif - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNNB, 13)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNWB, 98)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNSWB, 99)); -#ifdef WEBRTC_CODEC_RED - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kRED, 127)); -#endif -} - -void AcmReceiveTest::RegisterNetEqTestCodecs() { - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISAC, 103)); -#ifndef WEBRTC_ANDROID - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISACSWB, 104)); -#endif - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16B, 93)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bwb, 94)); - ASSERT_TRUE( - acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bswb32kHz, 95)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMU, 0)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMA, 8)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kILBC, 102)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kG722, 9)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNNB, 13)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNWB, 98)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNSWB, 99)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kRED, 117)); -} - -void AcmReceiveTest::Run() { - for (rtc::scoped_ptr packet(packet_source_->NextPacket()); packet; - packet.reset(packet_source_->NextPacket())) { - // Pull audio until time to insert packet. - while (clock_.TimeInMilliseconds() < packet->time_ms()) { - AudioFrame output_frame; - EXPECT_TRUE(acm_->Get10MsAudio(&output_frame)); - EXPECT_EQ(output_freq_hz_, output_frame.sample_rate_hz_); - const size_t samples_per_block = - static_cast(output_freq_hz_ * 10 / 1000); - EXPECT_EQ(samples_per_block, output_frame.samples_per_channel_); - if (expected_output_channels_ != kArbitraryChannels) { - if (output_frame.speech_type_ == webrtc::AudioFrame::kPLC) { - // Don't check number of channels for PLC output, since each test run - // usually starts with a short period of mono PLC before decoding the - // first packet. - } else { - EXPECT_EQ(expected_output_channels_, output_frame.num_channels_); - } - } - ASSERT_TRUE(audio_sink_->WriteAudioFrame(output_frame)); - clock_.AdvanceTimeMilliseconds(10); - } - - // Insert packet after converting from RTPHeader to WebRtcRTPHeader. - WebRtcRTPHeader header; - header.header = packet->header(); - header.frameType = kAudioFrameSpeech; - memset(&header.type.Audio, 0, sizeof(RTPAudioHeader)); - EXPECT_TRUE(acm_->InsertPacket(packet->payload(), - packet->payload_length_bytes(), - header)) - << "Failure when inserting packet:" << std::endl - << " PT = " << static_cast(header.header.payloadType) << std::endl - << " TS = " << header.header.timestamp << std::endl - << " SN = " << header.header.sequenceNumber; - } -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receive_test.h b/webrtc/modules/audio_coding/main/acm2/acm_receive_test.h deleted file mode 100644 index 80e9fbede6..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receive_test.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_ - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/system_wrappers/interface/clock.h" - -namespace webrtc { -class AudioCoding; -struct CodecInst; - -namespace test { -class AudioSink; -class PacketSource; - -class AcmReceiveTest { - public: - enum NumOutputChannels { - kArbitraryChannels = 0, - kMonoOutput = 1, - kStereoOutput = 2 - }; - - AcmReceiveTest( - PacketSource* packet_source, - AudioSink* audio_sink, - int output_freq_hz, - NumOutputChannels expected_output_channels); - virtual ~AcmReceiveTest() {} - - // Registers the codecs with default parameters from ACM. - void RegisterDefaultCodecs(); - - // Registers codecs with payload types matching the pre-encoded NetEq test - // files. - void RegisterNetEqTestCodecs(); - - // Runs the test and returns true if successful. - void Run(); - - private: - SimulatedClock clock_; - rtc::scoped_ptr acm_; - PacketSource* packet_source_; - AudioSink* audio_sink_; - const int output_freq_hz_; - NumOutputChannels expected_output_channels_; - - RTC_DISALLOW_COPY_AND_ASSIGN(AcmReceiveTest); -}; - -} // namespace test -} // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc deleted file mode 100644 index c6cd6dedb4..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" - -#include // std::min - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h" -#include "webrtc/system_wrappers/interface/clock.h" -#include "webrtc/test/test_suite.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -namespace webrtc { - -namespace acm2 { -namespace { - -bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) { - if (strcmp(codec_a.plname, codec_b.plname) != 0 || - codec_a.plfreq != codec_b.plfreq || - codec_a.pltype != codec_b.pltype || - codec_b.channels != codec_a.channels) - return false; - return true; -} - -} // namespace - -class AcmReceiverTest : public AudioPacketizationCallback, - public ::testing::Test { - protected: - AcmReceiverTest() - : timestamp_(0), - packet_sent_(false), - last_packet_send_timestamp_(timestamp_), - last_frame_type_(kEmptyFrame) { - AudioCoding::Config config; - config.transport = this; - acm_.reset(new AudioCodingImpl(config)); - receiver_.reset(new AcmReceiver(config.ToOldConfig())); - } - - ~AcmReceiverTest() {} - - void SetUp() override { - ASSERT_TRUE(receiver_.get() != NULL); - ASSERT_TRUE(acm_.get() != NULL); - for (int n = 0; n < ACMCodecDB::kNumCodecs; n++) { - ASSERT_EQ(0, ACMCodecDB::Codec(n, &codecs_[n])); - } - - rtp_header_.header.sequenceNumber = 0; - rtp_header_.header.timestamp = 0; - rtp_header_.header.markerBit = false; - rtp_header_.header.ssrc = 0x12345678; // Arbitrary. - rtp_header_.header.numCSRCs = 0; - rtp_header_.header.payloadType = 0; - rtp_header_.frameType = kAudioFrameSpeech; - rtp_header_.type.Audio.isCNG = false; - } - - void TearDown() override {} - - void InsertOnePacketOfSilence(int codec_id) { - CodecInst codec; - ACMCodecDB::Codec(codec_id, &codec); - if (timestamp_ == 0) { // This is the first time inserting audio. - ASSERT_TRUE(acm_->RegisterSendCodec(codec_id, codec.pltype)); - } else { - const CodecInst* current_codec = acm_->GetSenderCodecInst(); - ASSERT_TRUE(current_codec); - if (!CodecsEqual(codec, *current_codec)) - ASSERT_TRUE(acm_->RegisterSendCodec(codec_id, codec.pltype)); - } - AudioFrame frame; - // Frame setup according to the codec. - frame.sample_rate_hz_ = codec.plfreq; - frame.samples_per_channel_ = codec.plfreq / 100; // 10 ms. - frame.num_channels_ = codec.channels; - memset(frame.data_, 0, frame.samples_per_channel_ * frame.num_channels_ * - sizeof(int16_t)); - int num_bytes = 0; - packet_sent_ = false; - last_packet_send_timestamp_ = timestamp_; - while (num_bytes == 0) { - frame.timestamp_ = timestamp_; - timestamp_ += frame.samples_per_channel_; - num_bytes = acm_->Add10MsAudio(frame); - ASSERT_GE(num_bytes, 0); - } - ASSERT_TRUE(packet_sent_); // Sanity check. - } - - // Last element of id should be negative. - void AddSetOfCodecs(const int* id) { - int n = 0; - while (id[n] >= 0) { - ASSERT_EQ(0, receiver_->AddCodec(id[n], codecs_[id[n]].pltype, - codecs_[id[n]].channels, - codecs_[id[n]].plfreq, NULL)); - ++n; - } - } - - int32_t SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) override { - if (frame_type == kEmptyFrame) - return 0; - - rtp_header_.header.payloadType = payload_type; - rtp_header_.frameType = frame_type; - if (frame_type == kAudioFrameSpeech) - rtp_header_.type.Audio.isCNG = false; - else - rtp_header_.type.Audio.isCNG = true; - rtp_header_.header.timestamp = timestamp; - - int ret_val = receiver_->InsertPacket(rtp_header_, payload_data, - payload_len_bytes); - if (ret_val < 0) { - assert(false); - return -1; - } - rtp_header_.header.sequenceNumber++; - packet_sent_ = true; - last_frame_type_ = frame_type; - return 0; - } - - rtc::scoped_ptr receiver_; - CodecInst codecs_[ACMCodecDB::kMaxNumCodecs]; - rtc::scoped_ptr acm_; - WebRtcRTPHeader rtp_header_; - uint32_t timestamp_; - bool packet_sent_; // Set when SendData is called reset when inserting audio. - uint32_t last_packet_send_timestamp_; - FrameType last_frame_type_; -}; - -TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecGetCodec)) { - // Add codec. - for (int n = 0; n < ACMCodecDB::kNumCodecs; ++n) { - if (n & 0x1) // Just add codecs with odd index. - EXPECT_EQ(0, - receiver_->AddCodec(n, codecs_[n].pltype, codecs_[n].channels, - codecs_[n].plfreq, NULL)); - } - // Get codec and compare. - for (int n = 0; n < ACMCodecDB::kNumCodecs; ++n) { - CodecInst my_codec; - if (n & 0x1) { - // Codecs with odd index should match the reference. - EXPECT_EQ(0, receiver_->DecoderByPayloadType(codecs_[n].pltype, - &my_codec)); - EXPECT_TRUE(CodecsEqual(codecs_[n], my_codec)); - } else { - // Codecs with even index are not registered. - EXPECT_EQ(-1, receiver_->DecoderByPayloadType(codecs_[n].pltype, - &my_codec)); - } - } -} - -TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) { - const int codec_id = ACMCodecDB::kPCMA; - CodecInst ref_codec1; - EXPECT_EQ(0, ACMCodecDB::Codec(codec_id, &ref_codec1)); - CodecInst ref_codec2 = ref_codec1; - ++ref_codec2.pltype; - CodecInst test_codec; - - // Register the same codec with different payload types. - EXPECT_EQ( - 0, receiver_->AddCodec(codec_id, ref_codec1.pltype, ref_codec1.channels, - ref_codec1.plfreq, NULL)); - EXPECT_EQ( - 0, receiver_->AddCodec(codec_id, ref_codec2.pltype, ref_codec2.channels, - ref_codec2.plfreq, NULL)); - - // Both payload types should exist. - EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec1.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(ref_codec1, test_codec)); - EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec2.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(ref_codec2, test_codec)); -} - -TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) { - const int codec_id1 = ACMCodecDB::kPCMU; - CodecInst ref_codec1; - EXPECT_EQ(0, ACMCodecDB::Codec(codec_id1, &ref_codec1)); - const int codec_id2 = ACMCodecDB::kPCMA; - CodecInst ref_codec2; - EXPECT_EQ(0, ACMCodecDB::Codec(codec_id2, &ref_codec2)); - ref_codec2.pltype = ref_codec1.pltype; - CodecInst test_codec; - - // Register the same payload type with different codec ID. - EXPECT_EQ( - 0, receiver_->AddCodec(codec_id1, ref_codec1.pltype, ref_codec1.channels, - ref_codec1.plfreq, NULL)); - EXPECT_EQ( - 0, receiver_->AddCodec(codec_id2, ref_codec2.pltype, ref_codec2.channels, - ref_codec2.plfreq, NULL)); - - // Make sure that the last codec is used. - EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec2.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(ref_codec2, test_codec)); -} - -TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) { - CodecInst codec; - const int codec_id = ACMCodecDB::kPCMA; - EXPECT_EQ(0, ACMCodecDB::Codec(codec_id, &codec)); - const int payload_type = codec.pltype; - EXPECT_EQ(0, receiver_->AddCodec(codec_id, codec.pltype, codec.channels, - codec.plfreq, NULL)); - - // Remove non-existing codec should not fail. ACM1 legacy. - EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1)); - - // Remove an existing codec. - EXPECT_EQ(0, receiver_->RemoveCodec(payload_type)); - - // Ask for the removed codec, must fail. - EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &codec)); -} - -TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(SampleRate)) { - const int kCodecId[] = { - ACMCodecDB::kISAC, ACMCodecDB::kISACSWB, - -1 // Terminator. - }; - AddSetOfCodecs(kCodecId); - - AudioFrame frame; - const int kOutSampleRateHz = 8000; // Different than codec sample rate. - int n = 0; - while (kCodecId[n] >= 0) { - const int num_10ms_frames = codecs_[kCodecId[n]].pacsize / - (codecs_[kCodecId[n]].plfreq / 100); - InsertOnePacketOfSilence(kCodecId[n]); - for (int k = 0; k < num_10ms_frames; ++k) { - EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame)); - } - EXPECT_EQ(std::min(32000, codecs_[kCodecId[n]].plfreq), - receiver_->current_sample_rate_hz()); - ++n; - } -} - -TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(PostdecodingVad)) { - receiver_->EnableVad(); - EXPECT_TRUE(receiver_->vad_enabled()); - - const int id = ACMCodecDB::kPCM16Bwb; - ASSERT_EQ(0, receiver_->AddCodec(id, codecs_[id].pltype, codecs_[id].channels, - codecs_[id].plfreq, NULL)); - const int kNumPackets = 5; - const int num_10ms_frames = codecs_[id].pacsize / (codecs_[id].plfreq / 100); - AudioFrame frame; - for (int n = 0; n < kNumPackets; ++n) { - InsertOnePacketOfSilence(id); - for (int k = 0; k < num_10ms_frames; ++k) - ASSERT_EQ(0, receiver_->GetAudio(codecs_[id].plfreq, &frame)); - } - EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_); - - receiver_->DisableVad(); - EXPECT_FALSE(receiver_->vad_enabled()); - - for (int n = 0; n < kNumPackets; ++n) { - InsertOnePacketOfSilence(id); - for (int k = 0; k < num_10ms_frames; ++k) - ASSERT_EQ(0, receiver_->GetAudio(codecs_[id].plfreq, &frame)); - } - EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_); -} - -#ifdef WEBRTC_CODEC_ISAC -#define IF_ISAC_FLOAT(x) x -#else -#define IF_ISAC_FLOAT(x) DISABLED_##x -#endif - -TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(IF_ISAC_FLOAT(LastAudioCodec))) { - const int kCodecId[] = { - ACMCodecDB::kISAC, ACMCodecDB::kPCMA, ACMCodecDB::kISACSWB, - ACMCodecDB::kPCM16Bswb32kHz, - -1 // Terminator. - }; - AddSetOfCodecs(kCodecId); - - const int kCngId[] = { // Not including full-band. - ACMCodecDB::kCNNB, ACMCodecDB::kCNWB, ACMCodecDB::kCNSWB, - -1 // Terminator. - }; - AddSetOfCodecs(kCngId); - - // Register CNG at sender side. - int n = 0; - while (kCngId[n] > 0) { - ASSERT_TRUE(acm_->RegisterSendCodec(kCngId[n], codecs_[kCngId[n]].pltype)); - ++n; - } - - CodecInst codec; - // No audio payload is received. - EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); - - // Start with sending DTX. - ASSERT_TRUE(acm_->SetVad(true, true, VADVeryAggr)); - packet_sent_ = false; - InsertOnePacketOfSilence(kCodecId[0]); // Enough to test with one codec. - ASSERT_TRUE(packet_sent_); - EXPECT_EQ(kAudioFrameCN, last_frame_type_); - - // Has received, only, DTX. Last Audio codec is undefined. - EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); - EXPECT_EQ(-1, receiver_->last_audio_codec_id()); - - n = 0; - while (kCodecId[n] >= 0) { // Loop over codecs. - // Set DTX off to send audio payload. - acm_->SetVad(false, false, VADAggr); - packet_sent_ = false; - InsertOnePacketOfSilence(kCodecId[n]); - - // Sanity check if Actually an audio payload received, and it should be - // of type "speech." - ASSERT_TRUE(packet_sent_); - ASSERT_EQ(kAudioFrameSpeech, last_frame_type_); - EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id()); - - // Set VAD on to send DTX. Then check if the "Last Audio codec" returns - // the expected codec. - acm_->SetVad(true, true, VADAggr); - - // Do as many encoding until a DTX is sent. - while (last_frame_type_ != kAudioFrameCN) { - packet_sent_ = false; - InsertOnePacketOfSilence(kCodecId[n]); - ASSERT_TRUE(packet_sent_); - } - EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id()); - EXPECT_EQ(0, receiver_->LastAudioCodec(&codec)); - EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec)); - ++n; - } -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_send_test.cc b/webrtc/modules/audio_coding/main/acm2/acm_send_test.cc deleted file mode 100644 index b05968645c..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_send_test.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_send_test.h" - -#include -#include -#include - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" -#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet.h" - -namespace webrtc { -namespace test { - -AcmSendTest::AcmSendTest(InputAudioFile* audio_source, - int source_rate_hz, - int test_duration_ms) - : clock_(0), - audio_source_(audio_source), - source_rate_hz_(source_rate_hz), - input_block_size_samples_( - static_cast(source_rate_hz_ * kBlockSizeMs / 1000)), - codec_registered_(false), - test_duration_ms_(test_duration_ms), - frame_type_(kAudioFrameSpeech), - payload_type_(0), - timestamp_(0), - sequence_number_(0) { - webrtc::AudioCoding::Config config; - config.clock = &clock_; - config.transport = this; - acm_.reset(webrtc::AudioCoding::Create(config)); - input_frame_.sample_rate_hz_ = source_rate_hz_; - input_frame_.num_channels_ = 1; - input_frame_.samples_per_channel_ = input_block_size_samples_; - assert(input_block_size_samples_ * input_frame_.num_channels_ <= - AudioFrame::kMaxDataSizeSamples); -} - -bool AcmSendTest::RegisterCodec(int codec_type, - int channels, - int payload_type, - int frame_size_samples) { - codec_registered_ = - acm_->RegisterSendCodec(codec_type, payload_type, frame_size_samples); - input_frame_.num_channels_ = channels; - assert(input_block_size_samples_ * input_frame_.num_channels_ <= - AudioFrame::kMaxDataSizeSamples); - return codec_registered_; -} - -Packet* AcmSendTest::NextPacket() { - assert(codec_registered_); - if (filter_.test(static_cast(payload_type_))) { - // This payload type should be filtered out. Since the payload type is the - // same throughout the whole test run, no packet at all will be delivered. - // We can just as well signal that the test is over by returning NULL. - return NULL; - } - // Insert audio and process until one packet is produced. - while (clock_.TimeInMilliseconds() < test_duration_ms_) { - clock_.AdvanceTimeMilliseconds(kBlockSizeMs); - RTC_CHECK( - audio_source_->Read(input_block_size_samples_, input_frame_.data_)); - if (input_frame_.num_channels_ > 1) { - InputAudioFile::DuplicateInterleaved(input_frame_.data_, - input_block_size_samples_, - input_frame_.num_channels_, - input_frame_.data_); - } - int32_t encoded_bytes = acm_->Add10MsAudio(input_frame_); - EXPECT_GE(encoded_bytes, 0); - input_frame_.timestamp_ += static_cast(input_block_size_samples_); - if (encoded_bytes > 0) { - // Encoded packet received. - return CreatePacket(); - } - } - // Test ended. - return NULL; -} - -// This method receives the callback from ACM when a new packet is produced. -int32_t AcmSendTest::SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) { - // Store the packet locally. - frame_type_ = frame_type; - payload_type_ = payload_type; - timestamp_ = timestamp; - last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes); - assert(last_payload_vec_.size() == payload_len_bytes); - return 0; -} - -Packet* AcmSendTest::CreatePacket() { - const size_t kRtpHeaderSize = 12; - size_t allocated_bytes = last_payload_vec_.size() + kRtpHeaderSize; - uint8_t* packet_memory = new uint8_t[allocated_bytes]; - // Populate the header bytes. - packet_memory[0] = 0x80; - packet_memory[1] = static_cast(payload_type_); - packet_memory[2] = (sequence_number_ >> 8) & 0xFF; - packet_memory[3] = (sequence_number_) & 0xFF; - packet_memory[4] = (timestamp_ >> 24) & 0xFF; - packet_memory[5] = (timestamp_ >> 16) & 0xFF; - packet_memory[6] = (timestamp_ >> 8) & 0xFF; - packet_memory[7] = timestamp_ & 0xFF; - // Set SSRC to 0x12345678. - packet_memory[8] = 0x12; - packet_memory[9] = 0x34; - packet_memory[10] = 0x56; - packet_memory[11] = 0x78; - - ++sequence_number_; - - // Copy the payload data. - memcpy(packet_memory + kRtpHeaderSize, - &last_payload_vec_[0], - last_payload_vec_.size()); - Packet* packet = - new Packet(packet_memory, allocated_bytes, clock_.TimeInMilliseconds()); - assert(packet); - assert(packet->valid_header()); - return packet; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_send_test.h b/webrtc/modules/audio_coding/main/acm2/acm_send_test.h deleted file mode 100644 index b0d26ba63b..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_send_test.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_ - -#include - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h" -#include "webrtc/system_wrappers/interface/clock.h" - -namespace webrtc { - -namespace test { -class InputAudioFile; -class Packet; - -class AcmSendTest : public AudioPacketizationCallback, public PacketSource { - public: - AcmSendTest(InputAudioFile* audio_source, - int source_rate_hz, - int test_duration_ms); - virtual ~AcmSendTest() {} - - // Registers the send codec. Returns true on success, false otherwise. - bool RegisterCodec(int codec_type, - int channels, - int payload_type, - int frame_size_samples); - - // Returns the next encoded packet. Returns NULL if the test duration was - // exceeded. Ownership of the packet is handed over to the caller. - // Inherited from PacketSource. - Packet* NextPacket() override; - - // Inherited from AudioPacketizationCallback. - int32_t SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) override; - - private: - static const int kBlockSizeMs = 10; - - // Creates a Packet object from the last packet produced by ACM (and received - // through the SendData method as a callback). Ownership of the new Packet - // object is transferred to the caller. - Packet* CreatePacket(); - - SimulatedClock clock_; - rtc::scoped_ptr acm_; - InputAudioFile* audio_source_; - int source_rate_hz_; - const size_t input_block_size_samples_; - AudioFrame input_frame_; - bool codec_registered_; - int test_duration_ms_; - // The following member variables are set whenever SendData() is called. - FrameType frame_type_; - int payload_type_; - uint32_t timestamp_; - uint16_t sequence_number_; - std::vector last_payload_vec_; - - RTC_DISALLOW_COPY_AND_ASSIGN(AcmSendTest); -}; - -} // namespace test -} // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc index f502eb3f8c..8a0980e619 100644 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc +++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc @@ -100,18 +100,4 @@ bool AudioCodingModule::IsCodecValid(const CodecInst& codec) { } } -AudioCoding::Config::Config() - : neteq_config(), - clock(Clock::GetRealTimeClock()), - transport(nullptr), - vad_callback(nullptr), - initial_playout_delay_ms(0), - playout_channels(1), - playout_frequency_hz(32000) { -} - -AudioCoding* AudioCoding::Create(const Config& config) { - return new AudioCodingImpl(config); -} - } // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc index 879af49bd2..467e749cce 100644 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc +++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc @@ -803,287 +803,4 @@ void AudioCodingModuleImpl::GetDecodingCallStatistics( } } // namespace acm2 - -AudioCodingImpl::AudioCodingImpl(const Config& config) { - AudioCodingModule::Config config_old = config.ToOldConfig(); - acm_old_.reset(new acm2::AudioCodingModuleImpl(config_old)); - acm_old_->RegisterTransportCallback(config.transport); - acm_old_->RegisterVADCallback(config.vad_callback); - if (config.initial_playout_delay_ms > 0) { - acm_old_->SetInitialPlayoutDelay(config.initial_playout_delay_ms); - } - playout_frequency_hz_ = config.playout_frequency_hz; -} - -AudioCodingImpl::~AudioCodingImpl() = default; - -bool AudioCodingImpl::RegisterSendCodec(AudioEncoder* send_codec) { - FATAL() << "Not implemented yet."; - return false; -} - -bool AudioCodingImpl::RegisterSendCodec(int encoder_type, - uint8_t payload_type, - int frame_size_samples) { - std::string codec_name; - int sample_rate_hz; - int channels; - if (!MapCodecTypeToParameters( - encoder_type, &codec_name, &sample_rate_hz, &channels)) { - return false; - } - webrtc::CodecInst codec; - AudioCodingModule::Codec( - codec_name.c_str(), &codec, sample_rate_hz, channels); - codec.pltype = payload_type; - if (frame_size_samples > 0) { - codec.pacsize = frame_size_samples; - } - return acm_old_->RegisterSendCodec(codec) == 0; -} - -const AudioEncoder* AudioCodingImpl::GetSenderInfo() const { - FATAL() << "Not implemented yet."; - return reinterpret_cast(NULL); -} - -const CodecInst* AudioCodingImpl::GetSenderCodecInst() { - if (acm_old_->SendCodec(¤t_send_codec_) != 0) { - return NULL; - } - return ¤t_send_codec_; -} - -int AudioCodingImpl::Add10MsAudio(const AudioFrame& audio_frame) { - acm2::AudioCodingModuleImpl::InputData input_data; - CriticalSectionScoped lock(acm_old_->acm_crit_sect_.get()); - if (acm_old_->Add10MsDataInternal(audio_frame, &input_data) != 0) - return -1; - return acm_old_->Encode(input_data); -} - -const ReceiverInfo* AudioCodingImpl::GetReceiverInfo() const { - FATAL() << "Not implemented yet."; - return reinterpret_cast(NULL); -} - -bool AudioCodingImpl::RegisterReceiveCodec(AudioDecoder* receive_codec) { - FATAL() << "Not implemented yet."; - return false; -} - -bool AudioCodingImpl::RegisterReceiveCodec(int decoder_type, - uint8_t payload_type) { - std::string codec_name; - int sample_rate_hz; - int channels; - if (!MapCodecTypeToParameters( - decoder_type, &codec_name, &sample_rate_hz, &channels)) { - return false; - } - webrtc::CodecInst codec; - AudioCodingModule::Codec( - codec_name.c_str(), &codec, sample_rate_hz, channels); - codec.pltype = payload_type; - return acm_old_->RegisterReceiveCodec(codec) == 0; -} - -bool AudioCodingImpl::InsertPacket(const uint8_t* incoming_payload, - size_t payload_len_bytes, - const WebRtcRTPHeader& rtp_info) { - return acm_old_->IncomingPacket( - incoming_payload, payload_len_bytes, rtp_info) == 0; -} - -bool AudioCodingImpl::InsertPayload(const uint8_t* incoming_payload, - size_t payload_len_byte, - uint8_t payload_type, - uint32_t timestamp) { - FATAL() << "Not implemented yet."; - return false; -} - -bool AudioCodingImpl::SetMinimumPlayoutDelay(int time_ms) { - FATAL() << "Not implemented yet."; - return false; -} - -bool AudioCodingImpl::SetMaximumPlayoutDelay(int time_ms) { - FATAL() << "Not implemented yet."; - return false; -} - -int AudioCodingImpl::LeastRequiredDelayMs() const { - FATAL() << "Not implemented yet."; - return -1; -} - -bool AudioCodingImpl::PlayoutTimestamp(uint32_t* timestamp) { - FATAL() << "Not implemented yet."; - return false; -} - -bool AudioCodingImpl::Get10MsAudio(AudioFrame* audio_frame) { - return acm_old_->PlayoutData10Ms(playout_frequency_hz_, audio_frame) == 0; -} - -bool AudioCodingImpl::GetNetworkStatistics( - NetworkStatistics* network_statistics) { - FATAL() << "Not implemented yet."; - return false; -} - -bool AudioCodingImpl::EnableNack(size_t max_nack_list_size) { - FATAL() << "Not implemented yet."; - return false; -} - -void AudioCodingImpl::DisableNack() { - // A bug in the linker of Visual Studio 2013 Update 3 prevent us from using - // FATAL() here, if we do so then the linker hang when the WPO is turned on. - // TODO(sebmarchand): Re-evaluate this when we upgrade the toolchain. -} - -bool AudioCodingImpl::SetVad(bool enable_dtx, - bool enable_vad, - ACMVADMode vad_mode) { - return acm_old_->SetVAD(enable_dtx, enable_vad, vad_mode) == 0; -} - -std::vector AudioCodingImpl::GetNackList( - int round_trip_time_ms) const { - return acm_old_->GetNackList(round_trip_time_ms); -} - -void AudioCodingImpl::GetDecodingCallStatistics( - AudioDecodingCallStats* call_stats) const { - acm_old_->GetDecodingCallStatistics(call_stats); -} - -bool AudioCodingImpl::MapCodecTypeToParameters(int codec_type, - std::string* codec_name, - int* sample_rate_hz, - int* channels) { - switch (codec_type) { - case acm2::ACMCodecDB::kPCM16B: - *codec_name = "L16"; - *sample_rate_hz = 8000; - *channels = 1; - break; - case acm2::ACMCodecDB::kPCM16Bwb: - *codec_name = "L16"; - *sample_rate_hz = 16000; - *channels = 1; - break; - case acm2::ACMCodecDB::kPCM16Bswb32kHz: - *codec_name = "L16"; - *sample_rate_hz = 32000; - *channels = 1; - break; - case acm2::ACMCodecDB::kPCM16B_2ch: - *codec_name = "L16"; - *sample_rate_hz = 8000; - *channels = 2; - break; - case acm2::ACMCodecDB::kPCM16Bwb_2ch: - *codec_name = "L16"; - *sample_rate_hz = 16000; - *channels = 2; - break; - case acm2::ACMCodecDB::kPCM16Bswb32kHz_2ch: - *codec_name = "L16"; - *sample_rate_hz = 32000; - *channels = 2; - break; -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) - case acm2::ACMCodecDB::kISAC: - *codec_name = "ISAC"; - *sample_rate_hz = 16000; - *channels = 1; - break; -#endif -#ifdef WEBRTC_CODEC_ISAC - case acm2::ACMCodecDB::kISACSWB: - *codec_name = "ISAC"; - *sample_rate_hz = 32000; - *channels = 1; - break; -#endif -#ifdef WEBRTC_CODEC_ILBC - case acm2::ACMCodecDB::kILBC: - *codec_name = "ILBC"; - *sample_rate_hz = 8000; - *channels = 1; - break; -#endif - case acm2::ACMCodecDB::kPCMA: - *codec_name = "PCMA"; - *sample_rate_hz = 8000; - *channels = 1; - break; - case acm2::ACMCodecDB::kPCMA_2ch: - *codec_name = "PCMA"; - *sample_rate_hz = 8000; - *channels = 2; - break; - case acm2::ACMCodecDB::kPCMU: - *codec_name = "PCMU"; - *sample_rate_hz = 8000; - *channels = 1; - break; - case acm2::ACMCodecDB::kPCMU_2ch: - *codec_name = "PCMU"; - *sample_rate_hz = 8000; - *channels = 2; - break; -#ifdef WEBRTC_CODEC_G722 - case acm2::ACMCodecDB::kG722: - *codec_name = "G722"; - *sample_rate_hz = 16000; - *channels = 1; - break; - case acm2::ACMCodecDB::kG722_2ch: - *codec_name = "G722"; - *sample_rate_hz = 16000; - *channels = 2; - break; -#endif -#ifdef WEBRTC_CODEC_OPUS - case acm2::ACMCodecDB::kOpus: - *codec_name = "opus"; - *sample_rate_hz = 48000; - *channels = 2; - break; -#endif - case acm2::ACMCodecDB::kCNNB: - *codec_name = "CN"; - *sample_rate_hz = 8000; - *channels = 1; - break; - case acm2::ACMCodecDB::kCNWB: - *codec_name = "CN"; - *sample_rate_hz = 16000; - *channels = 1; - break; - case acm2::ACMCodecDB::kCNSWB: - *codec_name = "CN"; - *sample_rate_hz = 32000; - *channels = 1; - break; - case acm2::ACMCodecDB::kRED: - *codec_name = "red"; - *sample_rate_hz = 8000; - *channels = 1; - break; - case acm2::ACMCodecDB::kAVT: - *codec_name = "telephone-event"; - *sample_rate_hz = 8000; - *channels = 1; - break; - default: - FATAL() << "Codec type " << codec_type << " not supported."; - } - return true; -} - } // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h index fe9215bac0..f20861398b 100644 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h +++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h @@ -280,79 +280,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule { }; } // namespace acm2 - -class AudioCodingImpl : public AudioCoding { - public: - AudioCodingImpl(const Config& config); - ~AudioCodingImpl() override; - - bool RegisterSendCodec(AudioEncoder* send_codec) override; - - bool RegisterSendCodec(int encoder_type, - uint8_t payload_type, - int frame_size_samples = 0) override; - - const AudioEncoder* GetSenderInfo() const override; - - const CodecInst* GetSenderCodecInst() override; - - int Add10MsAudio(const AudioFrame& audio_frame) override; - - const ReceiverInfo* GetReceiverInfo() const override; - - bool RegisterReceiveCodec(AudioDecoder* receive_codec) override; - - bool RegisterReceiveCodec(int decoder_type, uint8_t payload_type) override; - - bool InsertPacket(const uint8_t* incoming_payload, - size_t payload_len_bytes, - const WebRtcRTPHeader& rtp_info) override; - - bool InsertPayload(const uint8_t* incoming_payload, - size_t payload_len_byte, - uint8_t payload_type, - uint32_t timestamp) override; - - bool SetMinimumPlayoutDelay(int time_ms) override; - - bool SetMaximumPlayoutDelay(int time_ms) override; - - int LeastRequiredDelayMs() const override; - - bool PlayoutTimestamp(uint32_t* timestamp) override; - - bool Get10MsAudio(AudioFrame* audio_frame) override; - - bool GetNetworkStatistics(NetworkStatistics* network_statistics) override; - - bool EnableNack(size_t max_nack_list_size) override; - - void DisableNack() override; - - bool SetVad(bool enable_dtx, bool enable_vad, ACMVADMode vad_mode) override; - - std::vector GetNackList(int round_trip_time_ms) const override; - - void GetDecodingCallStatistics( - AudioDecodingCallStats* call_stats) const override; - - private: - // Temporary method to be used during redesign phase. - // Maps |codec_type| (a value from the anonymous enum in acm2::ACMCodecDB) to - // |codec_name|, |sample_rate_hz|, and |channels|. - // TODO(henrik.lundin) Remove this when no longer needed. - static bool MapCodecTypeToParameters(int codec_type, - std::string* codec_name, - int* sample_rate_hz, - int* channels); - - int playout_frequency_hz_; - // TODO(henrik.lundin): All members below this line are temporary and should - // be removed after refactoring is completed. - rtc::scoped_ptr acm_old_; - CodecInst current_send_codec_; -}; - } // namespace webrtc #endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc deleted file mode 100644 index c12baf3f40..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/checks.h" -#include "webrtc/base/md5digest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread_annotations.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_receive_test.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_send_test.h" -#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/neteq/tools/audio_checksum.h" -#include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" -#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" -#include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet.h" -#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/system_wrappers/interface/clock.h" -#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" -#include "webrtc/system_wrappers/interface/event_wrapper.h" -#include "webrtc/system_wrappers/interface/sleep.h" -#include "webrtc/system_wrappers/interface/thread_wrapper.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -namespace webrtc { - -const int kSampleRateHz = 16000; -const int kNumSamples10ms = kSampleRateHz / 100; -const int kFrameSizeMs = 10; // Multiple of 10. -const int kFrameSizeSamples = kFrameSizeMs / 10 * kNumSamples10ms; -const size_t kPayloadSizeBytes = kFrameSizeSamples * sizeof(int16_t); -const uint8_t kPayloadType = 111; - -class RtpUtility { - public: - RtpUtility(int samples_per_packet, uint8_t payload_type) - : samples_per_packet_(samples_per_packet), payload_type_(payload_type) {} - - virtual ~RtpUtility() {} - - void Populate(WebRtcRTPHeader* rtp_header) { - rtp_header->header.sequenceNumber = 0xABCD; - rtp_header->header.timestamp = 0xABCDEF01; - rtp_header->header.payloadType = payload_type_; - rtp_header->header.markerBit = false; - rtp_header->header.ssrc = 0x1234; - rtp_header->header.numCSRCs = 0; - rtp_header->frameType = kAudioFrameSpeech; - - rtp_header->header.payload_type_frequency = kSampleRateHz; - rtp_header->type.Audio.channel = 1; - rtp_header->type.Audio.isCNG = false; - } - - void Forward(WebRtcRTPHeader* rtp_header) { - ++rtp_header->header.sequenceNumber; - rtp_header->header.timestamp += samples_per_packet_; - } - - private: - int samples_per_packet_; - uint8_t payload_type_; -}; - -class PacketizationCallbackStub : public AudioPacketizationCallback { - public: - PacketizationCallbackStub() - : num_calls_(0), - crit_sect_(CriticalSectionWrapper::CreateCriticalSection()) {} - - int32_t SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) override { - CriticalSectionScoped lock(crit_sect_.get()); - ++num_calls_; - last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes); - return 0; - } - - int num_calls() const { - CriticalSectionScoped lock(crit_sect_.get()); - return num_calls_; - } - - int last_payload_len_bytes() const { - CriticalSectionScoped lock(crit_sect_.get()); - return last_payload_vec_.size(); - } - - void SwapBuffers(std::vector* payload) { - CriticalSectionScoped lock(crit_sect_.get()); - last_payload_vec_.swap(*payload); - } - - private: - int num_calls_ GUARDED_BY(crit_sect_); - std::vector last_payload_vec_ GUARDED_BY(crit_sect_); - const rtc::scoped_ptr crit_sect_; -}; - -class AudioCodingModuleTest : public ::testing::Test { - protected: - AudioCodingModuleTest() - : rtp_utility_(new RtpUtility(kFrameSizeSamples, kPayloadType)) { - config_.transport = &packet_cb_; - } - - ~AudioCodingModuleTest() {} - - void TearDown() override {} - - void SetUp() override { - rtp_utility_->Populate(&rtp_header_); - - input_frame_.sample_rate_hz_ = kSampleRateHz; - input_frame_.num_channels_ = 1; - input_frame_.samples_per_channel_ = kSampleRateHz * 10 / 1000; // 10 ms. - static_assert(kSampleRateHz * 10 / 1000 <= AudioFrame::kMaxDataSizeSamples, - "audio frame too small"); - memset(input_frame_.data_, - 0, - input_frame_.samples_per_channel_ * sizeof(input_frame_.data_[0])); - } - - void CreateAcm() { - acm_.reset(AudioCoding::Create(config_)); - ASSERT_TRUE(acm_.get() != NULL); - RegisterCodec(); - } - - virtual void RegisterCodec() { - // Register L16 codec in ACM. - int codec_type = acm2::ACMCodecDB::kNone; - switch (kSampleRateHz) { - case 8000: - codec_type = acm2::ACMCodecDB::kPCM16B; - break; - case 16000: - codec_type = acm2::ACMCodecDB::kPCM16Bwb; - break; - case 32000: - codec_type = acm2::ACMCodecDB::kPCM16Bswb32kHz; - break; - default: - FATAL() << "Sample rate not supported in this test."; - } - ASSERT_TRUE(acm_->RegisterSendCodec(codec_type, kPayloadType)); - ASSERT_TRUE(acm_->RegisterReceiveCodec(codec_type, kPayloadType)); - } - - virtual void InsertPacketAndPullAudio() { - InsertPacket(); - PullAudio(); - } - - virtual void InsertPacket() { - const uint8_t kPayload[kPayloadSizeBytes] = {0}; - ASSERT_TRUE(acm_->InsertPacket(kPayload, kPayloadSizeBytes, rtp_header_)); - rtp_utility_->Forward(&rtp_header_); - } - - virtual void PullAudio() { - AudioFrame audio_frame; - ASSERT_TRUE(acm_->Get10MsAudio(&audio_frame)); - } - - virtual void InsertAudio() { - int encoded_bytes = acm_->Add10MsAudio(input_frame_); - ASSERT_GE(encoded_bytes, 0); - input_frame_.timestamp_ += kNumSamples10ms; - } - - AudioCoding::Config config_; - rtc::scoped_ptr rtp_utility_; - rtc::scoped_ptr acm_; - PacketizationCallbackStub packet_cb_; - WebRtcRTPHeader rtp_header_; - AudioFrame input_frame_; -}; - -// Check if the statistics are initialized correctly. Before any call to ACM -// all fields have to be zero. -TEST_F(AudioCodingModuleTest, DISABLED_ON_ANDROID(InitializedToZero)) { - CreateAcm(); - AudioDecodingCallStats stats; - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(0, stats.calls_to_neteq); - EXPECT_EQ(0, stats.calls_to_silence_generator); - EXPECT_EQ(0, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(0, stats.decoded_plc); - EXPECT_EQ(0, stats.decoded_plc_cng); -} - -// Apply an initial playout delay. Calls to AudioCodingModule::PlayoutData10ms() -// should result in generating silence, check the associated field. -TEST_F(AudioCodingModuleTest, DISABLED_ON_ANDROID(SilenceGeneratorCalled)) { - const int kInitialDelay = 100; - config_.initial_playout_delay_ms = kInitialDelay; - CreateAcm(); - AudioDecodingCallStats stats; - - int num_calls = 0; - for (int time_ms = 0; time_ms < kInitialDelay; - time_ms += kFrameSizeMs, ++num_calls) { - InsertPacketAndPullAudio(); - } - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(0, stats.calls_to_neteq); - EXPECT_EQ(num_calls, stats.calls_to_silence_generator); - EXPECT_EQ(0, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(0, stats.decoded_plc); - EXPECT_EQ(0, stats.decoded_plc_cng); -} - -// Insert some packets and pull audio. Check statistics are valid. Then, -// simulate packet loss and check if PLC and PLC-to-CNG statistics are -// correctly updated. -TEST_F(AudioCodingModuleTest, DISABLED_ON_ANDROID(NetEqCalls)) { - CreateAcm(); - AudioDecodingCallStats stats; - const int kNumNormalCalls = 10; - - for (int num_calls = 0; num_calls < kNumNormalCalls; ++num_calls) { - InsertPacketAndPullAudio(); - } - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(kNumNormalCalls, stats.calls_to_neteq); - EXPECT_EQ(0, stats.calls_to_silence_generator); - EXPECT_EQ(kNumNormalCalls, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(0, stats.decoded_plc); - EXPECT_EQ(0, stats.decoded_plc_cng); - - const int kNumPlc = 3; - const int kNumPlcCng = 5; - - // Simulate packet-loss. NetEq first performs PLC then PLC fades to CNG. - for (int n = 0; n < kNumPlc + kNumPlcCng; ++n) { - PullAudio(); - } - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(kNumNormalCalls + kNumPlc + kNumPlcCng, stats.calls_to_neteq); - EXPECT_EQ(0, stats.calls_to_silence_generator); - EXPECT_EQ(kNumNormalCalls, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(kNumPlc, stats.decoded_plc); - EXPECT_EQ(kNumPlcCng, stats.decoded_plc_cng); -} - -TEST_F(AudioCodingModuleTest, VerifyOutputFrame) { - CreateAcm(); - AudioFrame audio_frame; - const int kSampleRateHz = 32000; - EXPECT_TRUE(acm_->Get10MsAudio(&audio_frame)); - EXPECT_EQ(0u, audio_frame.timestamp_); - EXPECT_GT(audio_frame.num_channels_, 0); - EXPECT_EQ(static_cast(kSampleRateHz / 100), - audio_frame.samples_per_channel_); - EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_); -} - -// A multi-threaded test for ACM. This base class is using the PCM16b 16 kHz -// codec, while the derive class AcmIsacMtTest is using iSAC. -class AudioCodingModuleMtTest : public AudioCodingModuleTest { - protected: - static const int kNumPackets = 500; - static const int kNumPullCalls = 500; - - AudioCodingModuleMtTest() - : AudioCodingModuleTest(), - send_thread_(ThreadWrapper::CreateThread(CbSendThread, this, "send")), - insert_packet_thread_(ThreadWrapper::CreateThread( - CbInsertPacketThread, this, "insert_packet")), - pull_audio_thread_(ThreadWrapper::CreateThread( - CbPullAudioThread, this, "pull_audio")), - test_complete_(EventWrapper::Create()), - send_count_(0), - insert_packet_count_(0), - pull_audio_count_(0), - crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - next_insert_packet_time_ms_(0), - fake_clock_(new SimulatedClock(0)) { - config_.clock = fake_clock_.get(); - } - - void SetUp() override { - AudioCodingModuleTest::SetUp(); - CreateAcm(); - StartThreads(); - } - - void StartThreads() { - ASSERT_TRUE(send_thread_->Start()); - send_thread_->SetPriority(kRealtimePriority); - ASSERT_TRUE(insert_packet_thread_->Start()); - insert_packet_thread_->SetPriority(kRealtimePriority); - ASSERT_TRUE(pull_audio_thread_->Start()); - pull_audio_thread_->SetPriority(kRealtimePriority); - } - - void TearDown() override { - AudioCodingModuleTest::TearDown(); - pull_audio_thread_->Stop(); - send_thread_->Stop(); - insert_packet_thread_->Stop(); - } - - EventTypeWrapper RunTest() { - return test_complete_->Wait(10 * 60 * 1000); // 10 minutes' timeout. - } - - virtual bool TestDone() { - if (packet_cb_.num_calls() > kNumPackets) { - CriticalSectionScoped lock(crit_sect_.get()); - if (pull_audio_count_ > kNumPullCalls) { - // Both conditions for completion are met. End the test. - return true; - } - } - return false; - } - - static bool CbSendThread(void* context) { - return reinterpret_cast(context)->CbSendImpl(); - } - - // The send thread doesn't have to care about the current simulated time, - // since only the AcmReceiver is using the clock. - bool CbSendImpl() { - SleepMs(1); - if (HasFatalFailure()) { - // End the test early if a fatal failure (ASSERT_*) has occurred. - test_complete_->Set(); - } - ++send_count_; - InsertAudio(); - if (TestDone()) { - test_complete_->Set(); - } - return true; - } - - static bool CbInsertPacketThread(void* context) { - return reinterpret_cast(context) - ->CbInsertPacketImpl(); - } - - bool CbInsertPacketImpl() { - SleepMs(1); - { - CriticalSectionScoped lock(crit_sect_.get()); - if (fake_clock_->TimeInMilliseconds() < next_insert_packet_time_ms_) { - return true; - } - next_insert_packet_time_ms_ += 10; - } - // Now we're not holding the crit sect when calling ACM. - ++insert_packet_count_; - InsertPacket(); - return true; - } - - static bool CbPullAudioThread(void* context) { - return reinterpret_cast(context) - ->CbPullAudioImpl(); - } - - bool CbPullAudioImpl() { - SleepMs(1); - { - CriticalSectionScoped lock(crit_sect_.get()); - // Don't let the insert thread fall behind. - if (next_insert_packet_time_ms_ < fake_clock_->TimeInMilliseconds()) { - return true; - } - ++pull_audio_count_; - } - // Now we're not holding the crit sect when calling ACM. - PullAudio(); - fake_clock_->AdvanceTimeMilliseconds(10); - return true; - } - - rtc::scoped_ptr send_thread_; - rtc::scoped_ptr insert_packet_thread_; - rtc::scoped_ptr pull_audio_thread_; - const rtc::scoped_ptr test_complete_; - int send_count_; - int insert_packet_count_; - int pull_audio_count_ GUARDED_BY(crit_sect_); - const rtc::scoped_ptr crit_sect_; - int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_); - rtc::scoped_ptr fake_clock_; -}; - -TEST_F(AudioCodingModuleMtTest, DoTest) { - EXPECT_EQ(kEventSignaled, RunTest()); -} - -// This is a multi-threaded ACM test using iSAC. The test encodes audio -// from a PCM file. The most recent encoded frame is used as input to the -// receiving part. Depending on timing, it may happen that the same RTP packet -// is inserted into the receiver multiple times, but this is a valid use-case, -// and simplifies the test code a lot. -class AcmIsacMtTest : public AudioCodingModuleMtTest { - protected: - static const int kNumPackets = 500; - static const int kNumPullCalls = 500; - - AcmIsacMtTest() - : AudioCodingModuleMtTest(), - last_packet_number_(0) {} - - ~AcmIsacMtTest() {} - - void SetUp() override { - AudioCodingModuleTest::SetUp(); - CreateAcm(); - - // Set up input audio source to read from specified file, loop after 5 - // seconds, and deliver blocks of 10 ms. - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/speech_mono_16kHz", "pcm"); - audio_loop_.Init(input_file_name, 5 * kSampleRateHz, kNumSamples10ms); - - // Generate one packet to have something to insert. - int loop_counter = 0; - while (packet_cb_.last_payload_len_bytes() == 0) { - InsertAudio(); - ASSERT_LT(loop_counter++, 10); - } - // Set |last_packet_number_| to one less that |num_calls| so that the packet - // will be fetched in the next InsertPacket() call. - last_packet_number_ = packet_cb_.num_calls() - 1; - - StartThreads(); - } - - void RegisterCodec() override { - static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz"); - - // Register iSAC codec in ACM, effectively unregistering the PCM16B codec - // registered in AudioCodingModuleTest::SetUp(); - ASSERT_TRUE(acm_->RegisterSendCodec(acm2::ACMCodecDB::kISAC, kPayloadType)); - ASSERT_TRUE( - acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISAC, kPayloadType)); - } - - void InsertPacket() override { - int num_calls = packet_cb_.num_calls(); // Store locally for thread safety. - if (num_calls > last_packet_number_) { - // Get the new payload out from the callback handler. - // Note that since we swap buffers here instead of directly inserting - // a pointer to the data in |packet_cb_|, we avoid locking the callback - // for the duration of the IncomingPacket() call. - packet_cb_.SwapBuffers(&last_payload_vec_); - ASSERT_GT(last_payload_vec_.size(), 0u); - rtp_utility_->Forward(&rtp_header_); - last_packet_number_ = num_calls; - } - ASSERT_GT(last_payload_vec_.size(), 0u); - ASSERT_TRUE(acm_->InsertPacket( - &last_payload_vec_[0], last_payload_vec_.size(), rtp_header_)); - } - - void InsertAudio() override { - memcpy(input_frame_.data_, audio_loop_.GetNextBlock(), kNumSamples10ms); - AudioCodingModuleTest::InsertAudio(); - } - - // This method is the same as AudioCodingModuleMtTest::TestDone(), but here - // it is using the constants defined in this class (i.e., shorter test run). - bool TestDone() override { - if (packet_cb_.num_calls() > kNumPackets) { - CriticalSectionScoped lock(crit_sect_.get()); - if (pull_audio_count_ > kNumPullCalls) { - // Both conditions for completion are met. End the test. - return true; - } - } - return false; - } - - int last_packet_number_; - std::vector last_payload_vec_; - test::AudioLoop audio_loop_; -}; - -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) -#define IF_ISAC(x) x -#else -#define IF_ISAC(x) DISABLED_##x -#endif - -TEST_F(AcmIsacMtTest, IF_ISAC(DoTest)) { - EXPECT_EQ(kEventSignaled, RunTest()); -} - -// Disabling all of these tests on iOS for now. -// See https://code.google.com/p/webrtc/issues/detail?id=4768 for details. -#if !defined(WEBRTC_IOS) - -class AcmReceiverBitExactness : public ::testing::Test { - public: - static std::string PlatformChecksum(std::string win64, - std::string android, - std::string others) { -#if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS) - return win64; -#elif defined(WEBRTC_ANDROID) - return android; -#else - return others; -#endif - } - - protected: - void Run(int output_freq_hz, const std::string& checksum_ref) { - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"); - rtc::scoped_ptr packet_source( - test::RtpFileSource::Create(input_file_name)); -#ifdef WEBRTC_ANDROID - // Filter out iLBC and iSAC-swb since they are not supported on Android. - packet_source->FilterOutPayloadType(102); // iLBC. - packet_source->FilterOutPayloadType(104); // iSAC-swb. -#endif - - test::AudioChecksum checksum; - const std::string output_file_name = - webrtc::test::OutputPath() + - ::testing::UnitTest::GetInstance() - ->current_test_info() - ->test_case_name() + - "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() + - "_output.pcm"; - test::OutputAudioFile output_file(output_file_name); - test::AudioSinkFork output(&checksum, &output_file); - - test::AcmReceiveTest test(packet_source.get(), &output, output_freq_hz, - test::AcmReceiveTest::kArbitraryChannels); - ASSERT_NO_FATAL_FAILURE(test.RegisterNetEqTestCodecs()); - test.Run(); - - std::string checksum_string = checksum.Finish(); - EXPECT_EQ(checksum_ref, checksum_string); - } -}; - -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISAC)) && \ - defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722) -#define IF_ALL_CODECS(x) x -#else -#define IF_ALL_CODECS(x) DISABLED_##x -#endif - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_8kHzOutput DISABLED_8kHzOutput -#else -#define MAYBE_8kHzOutput 8kHzOutput -#endif -TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_8kHzOutput)) { - Run(8000, - PlatformChecksum("dcee98c623b147ebe1b40dd30efa896e", - "adc92e173f908f93b96ba5844209815a", - "908002dc01fc4eb1d2be24eb1d3f354b")); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_16kHzOutput DISABLED_16kHzOutput -#else -#define MAYBE_16kHzOutput 16kHzOutput -#endif -TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_16kHzOutput)) { - Run(16000, - PlatformChecksum("f790e7a8cce4e2c8b7bb5e0e4c5dac0d", - "8cffa6abcb3e18e33b9d857666dff66a", - "a909560b5ca49fa472b17b7b277195e9")); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_32kHzOutput DISABLED_32kHzOutput -#else -#define MAYBE_32kHzOutput 32kHzOutput -#endif -TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_32kHzOutput)) { - Run(32000, - PlatformChecksum("306e0d990ee6e92de3fbecc0123ece37", - "3e126fe894720c3f85edadcc91964ba5", - "441aab4b347fb3db4e9244337aca8d8e")); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_48kHzOutput DISABLED_48kHzOutput -#else -#define MAYBE_48kHzOutput 48kHzOutput -#endif -TEST_F(AcmReceiverBitExactness, IF_ALL_CODECS(MAYBE_48kHzOutput)) { - Run(48000, - PlatformChecksum("aa7c232f63a67b2a72703593bdd172e0", - "0155665e93067c4e89256b944dd11999", - "4ee2730fa1daae755e8a8fd3abd779ec")); -} - -// This test verifies bit exactness for the send-side of ACM. The test setup is -// a chain of three different test classes: -// -// test::AcmSendTest -> AcmSenderBitExactness -> test::AcmReceiveTest -// -// The receiver side is driving the test by requesting new packets from -// AcmSenderBitExactness::NextPacket(). This method, in turn, asks for the -// packet from test::AcmSendTest::NextPacket, which inserts audio from the -// input file until one packet is produced. (The input file loops indefinitely.) -// Before passing the packet to the receiver, this test class verifies the -// packet header and updates a payload checksum with the new payload. The -// decoded output from the receiver is also verified with a (separate) checksum. -class AcmSenderBitExactness : public ::testing::Test, - public test::PacketSource { - protected: - static const int kTestDurationMs = 1000; - - AcmSenderBitExactness() - : frame_size_rtp_timestamps_(0), - packet_count_(0), - payload_type_(0), - last_sequence_number_(0), - last_timestamp_(0) {} - - // Sets up the test::AcmSendTest object. Returns true on success, otherwise - // false. - bool SetUpSender() { - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); - // Note that |audio_source_| will loop forever. The test duration is set - // explicitly by |kTestDurationMs|. - audio_source_.reset(new test::InputAudioFile(input_file_name)); - static const int kSourceRateHz = 32000; - send_test_.reset(new test::AcmSendTest( - audio_source_.get(), kSourceRateHz, kTestDurationMs)); - return send_test_.get() != NULL; - } - - // Registers a send codec in the test::AcmSendTest object. Returns true on - // success, false on failure. - bool RegisterSendCodec(int codec_type, - int channels, - int payload_type, - int frame_size_samples, - int frame_size_rtp_timestamps) { - payload_type_ = payload_type; - frame_size_rtp_timestamps_ = frame_size_rtp_timestamps; - return send_test_->RegisterCodec( - codec_type, channels, payload_type, frame_size_samples); - } - - // Runs the test. SetUpSender() and RegisterSendCodec() must have been called - // before calling this method. - void Run(const std::string& audio_checksum_ref, - const std::string& payload_checksum_ref, - int expected_packets, - test::AcmReceiveTest::NumOutputChannels expected_channels) { - // Set up the receiver used to decode the packets and verify the decoded - // output. - test::AudioChecksum audio_checksum; - const std::string output_file_name = - webrtc::test::OutputPath() + - ::testing::UnitTest::GetInstance() - ->current_test_info() - ->test_case_name() + - "_" + - ::testing::UnitTest::GetInstance()->current_test_info()->name() + - "_output.pcm"; - test::OutputAudioFile output_file(output_file_name); - // Have the output audio sent both to file and to the checksum calculator. - test::AudioSinkFork output(&audio_checksum, &output_file); - const int kOutputFreqHz = 8000; - test::AcmReceiveTest receive_test( - this, &output, kOutputFreqHz, expected_channels); - ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs()); - - // This is where the actual test is executed. - receive_test.Run(); - - // Extract and verify the audio checksum. - std::string checksum_string = audio_checksum.Finish(); - EXPECT_EQ(audio_checksum_ref, checksum_string); - - // Extract and verify the payload checksum. - char checksum_result[rtc::Md5Digest::kSize]; - payload_checksum_.Finish(checksum_result, rtc::Md5Digest::kSize); - checksum_string = rtc::hex_encode(checksum_result, rtc::Md5Digest::kSize); - EXPECT_EQ(payload_checksum_ref, checksum_string); - - // Verify number of packets produced. - EXPECT_EQ(expected_packets, packet_count_); - } - - // Returns a pointer to the next packet. Returns NULL if the source is - // depleted (i.e., the test duration is exceeded), or if an error occurred. - // Inherited from test::PacketSource. - test::Packet* NextPacket() override { - // Get the next packet from AcmSendTest. Ownership of |packet| is - // transferred to this method. - test::Packet* packet = send_test_->NextPacket(); - if (!packet) - return NULL; - - VerifyPacket(packet); - // TODO(henrik.lundin) Save the packet to file as well. - - // Pass it on to the caller. The caller becomes the owner of |packet|. - return packet; - } - - // Verifies the packet. - void VerifyPacket(const test::Packet* packet) { - EXPECT_TRUE(packet->valid_header()); - // (We can check the header fields even if valid_header() is false.) - EXPECT_EQ(payload_type_, packet->header().payloadType); - if (packet_count_ > 0) { - // This is not the first packet. - uint16_t sequence_number_diff = - packet->header().sequenceNumber - last_sequence_number_; - EXPECT_EQ(1, sequence_number_diff); - uint32_t timestamp_diff = packet->header().timestamp - last_timestamp_; - EXPECT_EQ(frame_size_rtp_timestamps_, timestamp_diff); - } - ++packet_count_; - last_sequence_number_ = packet->header().sequenceNumber; - last_timestamp_ = packet->header().timestamp; - // Update the checksum. - payload_checksum_.Update(packet->payload(), packet->payload_length_bytes()); - } - - void SetUpTest(int codec_type, - int channels, - int payload_type, - int codec_frame_size_samples, - int codec_frame_size_rtp_timestamps) { - ASSERT_TRUE(SetUpSender()); - ASSERT_TRUE(RegisterSendCodec(codec_type, - channels, - payload_type, - codec_frame_size_samples, - codec_frame_size_rtp_timestamps)); - } - - rtc::scoped_ptr send_test_; - rtc::scoped_ptr audio_source_; - uint32_t frame_size_rtp_timestamps_; - int packet_count_; - uint8_t payload_type_; - uint16_t last_sequence_number_; - uint32_t last_timestamp_; - rtc::Md5Digest payload_checksum_; -}; - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_IsacWb30ms DISABLED_IsacWb30ms -#else -#define MAYBE_IsacWb30ms IsacWb30ms -#endif -TEST_F(AcmSenderBitExactness, IF_ISAC(MAYBE_IsacWb30ms)) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kISAC, 1, 103, 480, 480)); - Run(AcmReceiverBitExactness::PlatformChecksum( - "c7e5bdadfa2871df95639fcc297cf23d", - "0499ca260390769b3172136faad925b9", - "0b58f9eeee43d5891f5f6c75e77984a3"), - AcmReceiverBitExactness::PlatformChecksum( - "d42cb5195463da26c8129bbfe73a22e6", - "83de248aea9c3c2bd680b6952401b4ca", - "3c79f16f34218271f3dca4e2b1dfe1bb"), - 33, - test::AcmReceiveTest::kMonoOutput); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_IsacWb60ms DISABLED_IsacWb60ms -#else -#define MAYBE_IsacWb60ms IsacWb60ms -#endif -TEST_F(AcmSenderBitExactness, IF_ISAC(MAYBE_IsacWb60ms)) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kISAC, 1, 103, 960, 960)); - Run(AcmReceiverBitExactness::PlatformChecksum( - "14d63c5f08127d280e722e3191b73bdd", - "8da003e16c5371af2dc2be79a50f9076", - "1ad29139a04782a33daad8c2b9b35875"), - AcmReceiverBitExactness::PlatformChecksum( - "ebe04a819d3a9d83a83a17f271e1139a", - "97aeef98553b5a4b5a68f8b716e8eaf0", - "9e0a0ab743ad987b55b8e14802769c56"), - 16, - test::AcmReceiveTest::kMonoOutput); -} - -#ifdef WEBRTC_CODEC_ISAC -#define IF_ISAC_FLOAT(x) x -#else -#define IF_ISAC_FLOAT(x) DISABLED_##x -#endif - -TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_ISAC_FLOAT(IsacSwb30ms))) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kISACSWB, 1, 104, 960, 960)); - Run(AcmReceiverBitExactness::PlatformChecksum( - "2b3c387d06f00b7b7aad4c9be56fb83d", - "", - "5683b58da0fbf2063c7adc2e6bfb3fb8"), - AcmReceiverBitExactness::PlatformChecksum( - "bcc2041e7744c7ebd9f701866856849c", - "", - "ce86106a93419aefb063097108ec94ab"), - 33, test::AcmReceiveTest::kMonoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcm16_8000khz_10ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kPCM16B, 1, 107, 80, 80)); - Run("de4a98e1406f8b798d99cd0704e862e2", - "c1edd36339ce0326cc4550041ad719a0", - 100, - test::AcmReceiveTest::kMonoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcm16_16000khz_10ms) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kPCM16Bwb, 1, 108, 160, 160)); - Run("ae646d7b68384a1269cc080dd4501916", - "ad786526383178b08d80d6eee06e9bad", - 100, - test::AcmReceiveTest::kMonoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcm16_32000khz_10ms) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kPCM16Bswb32kHz, 1, 109, 320, 320)); - Run("7fe325e8fbaf755e3c5df0b11a4774fb", - "5ef82ea885e922263606c6fdbc49f651", - 100, - test::AcmReceiveTest::kMonoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcm16_stereo_8000khz_10ms) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kPCM16B_2ch, 2, 111, 80, 80)); - Run("fb263b74e7ac3de915474d77e4744ceb", - "62ce5adb0d4965d0a52ec98ae7f98974", - 100, - test::AcmReceiveTest::kStereoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcm16_stereo_16000khz_10ms) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kPCM16Bwb_2ch, 2, 112, 160, 160)); - Run("d09e9239553649d7ac93e19d304281fd", - "41ca8edac4b8c71cd54fd9f25ec14870", - 100, - test::AcmReceiveTest::kStereoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcm16_stereo_32000khz_10ms) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kPCM16Bswb32kHz_2ch, 2, 113, 320, 320)); - Run("5f025d4f390982cc26b3d92fe02e3044", - "50e58502fb04421bf5b857dda4c96879", - 100, - test::AcmReceiveTest::kStereoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcmu_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kPCMU, 1, 0, 160, 160)); - Run("81a9d4c0bb72e9becc43aef124c981e9", - "8f9b8750bd80fe26b6cbf6659b89f0f9", - 50, - test::AcmReceiveTest::kMonoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcma_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kPCMA, 1, 8, 160, 160)); - Run("39611f798969053925a49dc06d08de29", - "6ad745e55aa48981bfc790d0eeef2dd1", - 50, - test::AcmReceiveTest::kMonoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcmu_stereo_20ms) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kPCMU_2ch, 2, 110, 160, 160)); - Run("437bec032fdc5cbaa0d5175430af7b18", - "60b6f25e8d1e74cb679cfe756dd9bca5", - 50, - test::AcmReceiveTest::kStereoOutput); -} - -TEST_F(AcmSenderBitExactness, Pcma_stereo_20ms) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kPCMA_2ch, 2, 118, 160, 160)); - Run("a5c6d83c5b7cedbeff734238220a4b0c", - "92b282c83efd20e7eeef52ba40842cf7", - 50, - test::AcmReceiveTest::kStereoOutput); -} - -#ifdef WEBRTC_CODEC_ILBC -#define IF_ILBC(x) x -#else -#define IF_ILBC(x) DISABLED_##x -#endif - -TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_ILBC(Ilbc_30ms))) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kILBC, 1, 102, 240, 240)); - Run(AcmReceiverBitExactness::PlatformChecksum( - "7b6ec10910debd9af08011d3ed5249f7", - "android_audio", - "7b6ec10910debd9af08011d3ed5249f7"), - AcmReceiverBitExactness::PlatformChecksum( - "cfae2e9f6aba96e145f2bcdd5050ce78", - "android_payload", - "cfae2e9f6aba96e145f2bcdd5050ce78"), - 33, - test::AcmReceiveTest::kMonoOutput); -} - -#ifdef WEBRTC_CODEC_G722 -#define IF_G722(x) x -#else -#define IF_G722(x) DISABLED_##x -#endif - -TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_G722(G722_20ms))) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kG722, 1, 9, 320, 160)); - Run(AcmReceiverBitExactness::PlatformChecksum( - "7d759436f2533582950d148b5161a36c", - "android_audio", - "7d759436f2533582950d148b5161a36c"), - AcmReceiverBitExactness::PlatformChecksum( - "fc68a87e1380614e658087cb35d5ca10", - "android_payload", - "fc68a87e1380614e658087cb35d5ca10"), - 50, - test::AcmReceiveTest::kMonoOutput); -} - -TEST_F(AcmSenderBitExactness, DISABLED_ON_ANDROID(IF_G722(G722_stereo_20ms))) { - ASSERT_NO_FATAL_FAILURE( - SetUpTest(acm2::ACMCodecDB::kG722_2ch, 2, 119, 320, 160)); - Run(AcmReceiverBitExactness::PlatformChecksum( - "7190ee718ab3d80eca181e5f7140c210", - "android_audio", - "7190ee718ab3d80eca181e5f7140c210"), - AcmReceiverBitExactness::PlatformChecksum( - "66516152eeaa1e650ad94ff85f668dac", - "android_payload", - "66516152eeaa1e650ad94ff85f668dac"), - 50, - test::AcmReceiveTest::kStereoOutput); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_Opus_stereo_20ms DISABLED_Opus_stereo_20ms -#else -#define MAYBE_Opus_stereo_20ms Opus_stereo_20ms -#endif -TEST_F(AcmSenderBitExactness, MAYBE_Opus_stereo_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest(acm2::ACMCodecDB::kOpus, 2, 120, 960, 960)); - Run(AcmReceiverBitExactness::PlatformChecksum( - "855041f2490b887302bce9d544731849", - "1e1a0fce893fef2d66886a7f09e2ebce", - "855041f2490b887302bce9d544731849"), - AcmReceiverBitExactness::PlatformChecksum( - "d781cce1ab986b618d0da87226cdde30", - "1a1fe04dd12e755949987c8d729fb3e0", - "d781cce1ab986b618d0da87226cdde30"), - 50, - test::AcmReceiveTest::kStereoOutput); -} - -#endif - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/audio_coding_module.gypi b/webrtc/modules/audio_coding/main/audio_coding_module.gypi index 7370836e8b..295bccf700 100644 --- a/webrtc/modules/audio_coding/main/audio_coding_module.gypi +++ b/webrtc/modules/audio_coding/main/audio_coding_module.gypi @@ -108,8 +108,6 @@ '<(DEPTH)/testing/gtest.gyp:gtest', ], 'sources': [ - 'acm2/acm_receive_test.cc', - 'acm2/acm_receive_test.h', 'acm2/acm_receive_test_oldapi.cc', 'acm2/acm_receive_test_oldapi.h', ], @@ -127,8 +125,6 @@ '<(DEPTH)/testing/gtest.gyp:gtest', ], 'sources': [ - 'acm2/acm_send_test.cc', - 'acm2/acm_send_test.h', 'acm2/acm_send_test_oldapi.cc', 'acm2/acm_send_test_oldapi.h', ], diff --git a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h index d0b7b03c43..830f1e5b77 100644 --- a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h +++ b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h @@ -753,177 +753,6 @@ class AudioCodingModule { AudioDecodingCallStats* call_stats) const = 0; }; -class AudioEncoder; -class ReceiverInfo; - -class AudioCoding { - public: - struct Config { - Config(); - - AudioCodingModule::Config ToOldConfig() const { - AudioCodingModule::Config old_config; - old_config.id = 0; - old_config.neteq_config = neteq_config; - old_config.clock = clock; - return old_config; - } - - NetEq::Config neteq_config; - Clock* clock; - AudioPacketizationCallback* transport; - ACMVADCallback* vad_callback; - int initial_playout_delay_ms; - int playout_channels; - int playout_frequency_hz; - }; - - static AudioCoding* Create(const Config& config); - virtual ~AudioCoding() {}; - - // Registers a codec, specified by |send_codec|, as sending codec. - // This API can be called multiple times. The last codec registered overwrites - // the previous ones. Returns true if successful, false if not. - // - // Note: If a stereo codec is registered as send codec, VAD/DTX will - // automatically be turned off, since it is not supported for stereo sending. - virtual bool RegisterSendCodec(AudioEncoder* send_codec) = 0; - - // Temporary solution to be used during refactoring: - // |encoder_type| should be from the anonymous enum in acm2::ACMCodecDB. - virtual bool RegisterSendCodec(int encoder_type, - uint8_t payload_type, - int frame_size_samples = 0) = 0; - - // Returns the encoder object currently in use. This is the same as the - // codec that was registered in the latest call to RegisterSendCodec(). - virtual const AudioEncoder* GetSenderInfo() const = 0; - - // Temporary solution to be used during refactoring. - virtual const CodecInst* GetSenderCodecInst() = 0; - - // Adds 10 ms of raw (PCM) audio data to the encoder. If the sampling - // frequency of the audio does not match the sampling frequency of the - // current encoder, ACM will resample the audio. - // - // Return value: - // 0 successfully added the frame. - // -1 some error occurred and data is not added. - // < -1 to add the frame to the buffer n samples had to be - // overwritten, -n is the return value in this case. - // TODO(henrik.lundin): Make a better design for the return values. This one - // is just a copy of the old API. - virtual int Add10MsAudio(const AudioFrame& audio_frame) = 0; - - // Returns a combined info about the currently used decoder(s). - virtual const ReceiverInfo* GetReceiverInfo() const = 0; - - // Registers a codec, specified by |receive_codec|, as receiving codec. - // This API can be called multiple times. If registering with a payload type - // that was already registered in a previous call, the latest call will - // override previous calls. Returns true if successful, false if not. - virtual bool RegisterReceiveCodec(AudioDecoder* receive_codec) = 0; - - // Temporary solution: - // |decoder_type| should be from the anonymous enum in acm2::ACMCodecDB. - virtual bool RegisterReceiveCodec(int decoder_type, uint8_t payload_type) = 0; - - // The following two methods both inserts a new packet to the receiver. - // InsertPacket takes an RTP header input in |rtp_info|, while InsertPayload - // only requires a payload type and a timestamp. The latter assumes that the - // payloads come in the right order, and without any losses. In both cases, - // |incoming_payload| contains the RTP payload after the RTP header. Return - // true if successful, false if not. - virtual bool InsertPacket(const uint8_t* incoming_payload, - size_t payload_len_bytes, - const WebRtcRTPHeader& rtp_info) = 0; - - // TODO(henrik.lundin): Remove this method? - virtual bool InsertPayload(const uint8_t* incoming_payload, - size_t payload_len_byte, - uint8_t payload_type, - uint32_t timestamp) = 0; - - // These two methods set a minimum and maximum jitter buffer delay in - // milliseconds. The pupose is mainly to adjust the delay to synchronize - // audio and video. The preferred jitter buffer size, computed by NetEq based - // on the current channel conditions, is clamped from below and above by these - // two methods. The given delay limits must be non-negative, less than - // 10000 ms, and the minimum must be strictly smaller than the maximum. - // Further, the maximum must be at lest one frame duration. If these - // conditions are not met, false is returned. Giving the value 0 effectively - // unsets the minimum or maximum delay limits. - // Note that calling these methods is optional. If not called, NetEq will - // determine the optimal buffer size based on the network conditions. - virtual bool SetMinimumPlayoutDelay(int time_ms) = 0; - - virtual bool SetMaximumPlayoutDelay(int time_ms) = 0; - - // Returns the current value of the jitter buffer's preferred latency. This - // is computed based on inter-arrival times and playout mode of NetEq. The - // actual target delay is this value clamped from below and above by the - // values specified through SetMinimumPlayoutDelay() and - // SetMaximumPlayoutDelay(), respectively, if provided. - // TODO(henrik.lundin) Rename to PreferredDelayMs? - virtual int LeastRequiredDelayMs() const = 0; - - // The send timestamp of an RTP packet is associated with the decoded - // audio of the packet in question. This function returns the timestamp of - // the latest audio delivered by Get10MsAudio(). Returns false if no timestamp - // can be provided, true otherwise. - virtual bool PlayoutTimestamp(uint32_t* timestamp) = 0; - - // Delivers 10 ms of audio in |audio_frame|. Returns true if successful, - // false otherwise. - virtual bool Get10MsAudio(AudioFrame* audio_frame) = 0; - - // Returns the network statistics. Note that the internal statistics of NetEq - // are reset by this call. Returns true if successful, false otherwise. - virtual bool GetNetworkStatistics(NetworkStatistics* network_statistics) = 0; - - // Enables NACK and sets the maximum size of the NACK list. If NACK is already - // enabled then the maximum NACK list size is modified accordingly. Returns - // true if successful, false otherwise. - // - // If the sequence number of last received packet is N, the sequence numbers - // of NACK list are in the range of [N - |max_nack_list_size|, N). - // - // |max_nack_list_size| should be positive and less than or equal to - // |Nack::kNackListSizeLimit|. - virtual bool EnableNack(size_t max_nack_list_size) = 0; - - // Disables NACK. - virtual void DisableNack() = 0; - - - // Temporary solution to be used during refactoring. - // If DTX is enabled and the codec does not have internal DTX/VAD - // WebRtc VAD will be automatically enabled and |enable_vad| is ignored. - // - // If DTX is disabled but VAD is enabled no DTX packets are sent, - // regardless of whether the codec has internal DTX/VAD or not. In this - // case, WebRtc VAD is running to label frames as active/in-active. - // - // NOTE! VAD/DTX is not supported when sending stereo. - // - // Return true if successful, false otherwise. - virtual bool SetVad(bool enable_dtx, - bool enable_vad, - ACMVADMode vad_mode) = 0; - - // Returns a list of packets to request retransmission of. - // |round_trip_time_ms| is an estimate of the round-trip-time (in - // milliseconds). Missing packets which will be decoded sooner than the - // round-trip-time (with respect to the time this API is called) will not be - // included in the list. - // |round_trip_time_ms| must be non-negative. - virtual std::vector GetNackList(int round_trip_time_ms) const = 0; - - // Returns the timing statistics for calls to Get10MsAudio. - virtual void GetDecodingCallStatistics( - AudioDecodingCallStats* call_stats) const = 0; -}; - } // namespace webrtc #endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_INTERFACE_AUDIO_CODING_MODULE_H_ diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 2c449e4afd..68cf53ea24 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -98,9 +98,7 @@ ], 'sources': [ 'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc', - 'audio_coding/main/acm2/acm_receiver_unittest.cc', 'audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc', - 'audio_coding/main/acm2/audio_coding_module_unittest.cc', 'audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc', 'audio_coding/main/acm2/call_statistics_unittest.cc', 'audio_coding/main/acm2/codec_owner_unittest.cc',