diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc index 94d51b770..9cfef3a8f 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc +++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc @@ -47,9 +47,10 @@ class AcmReceiverTest : public AudioPacketizationCallback, packet_sent_(false), last_packet_send_timestamp_(timestamp_), last_frame_type_(kFrameEmpty) { - AudioCodingModule::Config config; - acm_.reset(new AudioCodingModuleImpl(config)); - receiver_.reset(new AcmReceiver(config)); + AudioCoding::Config config; + config.transport = this; + acm_.reset(new AudioCodingImpl(config)); + receiver_.reset(new AcmReceiver(config.ToOldConfig())); } ~AcmReceiverTest() {} @@ -61,10 +62,6 @@ class AcmReceiverTest : public AudioPacketizationCallback, ASSERT_EQ(0, ACMCodecDB::Codec(n, &codecs_[n])); } - acm_->InitializeReceiver(); - acm_->InitializeSender(); - acm_->RegisterTransportCallback(this); - rtp_header_.header.sequenceNumber = 0; rtp_header_.header.timestamp = 0; rtp_header_.header.markerBit = false; @@ -82,12 +79,12 @@ class AcmReceiverTest : public AudioPacketizationCallback, CodecInst codec; ACMCodecDB::Codec(codec_id, &codec); if (timestamp_ == 0) { // This is the first time inserting audio. - ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); + ASSERT_TRUE(acm_->RegisterSendCodec(codec_id, codec.pltype)); } else { - CodecInst current_codec; - ASSERT_EQ(0, acm_->SendCodec(¤t_codec)); - if (!CodecsEqual(codec, current_codec)) - ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); + 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. @@ -102,8 +99,7 @@ class AcmReceiverTest : public AudioPacketizationCallback, while (num_bytes == 0) { frame.timestamp_ = timestamp_; timestamp_ += frame.samples_per_channel_; - ASSERT_EQ(0, acm_->Add10MsData(frame)); - num_bytes = acm_->Process(); + num_bytes = acm_->Add10MsAudio(frame); ASSERT_GE(num_bytes, 0); } ASSERT_TRUE(packet_sent_); // Sanity check. @@ -151,7 +147,7 @@ class AcmReceiverTest : public AudioPacketizationCallback, scoped_ptr receiver_; CodecInst codecs_[ACMCodecDB::kMaxNumCodecs]; - scoped_ptr acm_; + scoped_ptr acm_; WebRtcRTPHeader rtp_header_; uint32_t timestamp_; bool packet_sent_; // Set when SendData is called reset when inserting audio. @@ -307,7 +303,7 @@ TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(LastAudioCodec)) { // Register CNG at sender side. int n = 0; while (kCngId[n] > 0) { - ASSERT_EQ(0, acm_->RegisterSendCodec(codecs_[kCngId[n]])); + ASSERT_TRUE(acm_->RegisterSendCodec(kCngId[n], codecs_[kCngId[n]].pltype)); ++n; } @@ -316,7 +312,7 @@ TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(LastAudioCodec)) { EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); // Start with sending DTX. - ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr)); + ASSERT_TRUE(acm_->SetVad(true, true, VADVeryAggr)); packet_sent_ = false; InsertOnePacketOfSilence(kCodecId[0]); // Enough to test with one codec. ASSERT_TRUE(packet_sent_); @@ -330,7 +326,7 @@ TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(LastAudioCodec)) { n = 0; while (kCodecId[n] >= 0) { // Loop over codecs. // Set DTX off to send audio payload. - acm_->SetVAD(false, false, VADAggr); + acm_->SetVad(false, false, VADAggr); packet_sent_ = false; InsertOnePacketOfSilence(kCodecId[n]); @@ -342,7 +338,7 @@ TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(LastAudioCodec)) { // Set VAD on to send DTX. Then check if the "Last Audio codec" returns // the expected codec. - acm_->SetVAD(true, true, VADAggr); + acm_->SetVad(true, true, VADAggr); // Do as many encoding until a DTX is sent. while (last_frame_type_ != kAudioFrameCN) { diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc new file mode 100644 index 000000000..ef890ecb3 --- /dev/null +++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc @@ -0,0 +1,364 @@ +/* + * 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/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/system_wrappers/interface/scoped_ptr.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 AcmReceiverTestOldApi : public AudioPacketizationCallback, + public ::testing::Test { + protected: + AcmReceiverTestOldApi() + : timestamp_(0), + packet_sent_(false), + last_packet_send_timestamp_(timestamp_), + last_frame_type_(kFrameEmpty) { + AudioCodingModule::Config config; + acm_.reset(new AudioCodingModuleImpl(config)); + receiver_.reset(new AcmReceiver(config)); + } + + ~AcmReceiverTestOldApi() {} + + virtual 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])); + } + + acm_->InitializeReceiver(); + acm_->InitializeSender(); + acm_->RegisterTransportCallback(this); + + 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; + } + + virtual 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_EQ(0, acm_->RegisterSendCodec(codec)); + } else { + CodecInst current_codec; + ASSERT_EQ(0, acm_->SendCodec(¤t_codec)); + if (!CodecsEqual(codec, current_codec)) + ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); + } + 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_; + ASSERT_EQ(0, acm_->Add10MsData(frame)); + num_bytes = acm_->Process(); + 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, NULL)); + ++n; + } + } + + virtual int SendData( + FrameType frame_type, + uint8_t payload_type, + uint32_t timestamp, + const uint8_t* payload_data, + uint16_t payload_len_bytes, + const RTPFragmentationHeader* fragmentation) OVERRIDE { + if (frame_type == kFrameEmpty) + 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; + } + + scoped_ptr receiver_; + CodecInst codecs_[ACMCodecDB::kMaxNumCodecs]; + 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(AcmReceiverTestOldApi, 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, 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(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) { + CodecInst ref_codec; + const int codec_id = ACMCodecDB::kPCMA; + EXPECT_EQ(0, ACMCodecDB::Codec(codec_id, &ref_codec)); + const int payload_type = ref_codec.pltype; + EXPECT_EQ(0, receiver_->AddCodec(codec_id, ref_codec.pltype, + ref_codec.channels, NULL)); + CodecInst test_codec; + EXPECT_EQ(0, receiver_->DecoderByPayloadType(payload_type, &test_codec)); + EXPECT_EQ(true, CodecsEqual(ref_codec, test_codec)); + + // Re-register the same codec with different payload. + ref_codec.pltype = payload_type + 1; + EXPECT_EQ(0, receiver_->AddCodec(codec_id, ref_codec.pltype, + ref_codec.channels, NULL)); + + // Payload type |payload_type| should not exist. + EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &test_codec)); + + // Payload type |payload_type + 1| should exist. + EXPECT_EQ(0, receiver_->DecoderByPayloadType(payload_type + 1, &test_codec)); + EXPECT_TRUE(CodecsEqual(test_codec, ref_codec)); +} + +TEST_F(AcmReceiverTestOldApi, 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, 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(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(SampleRate)) { + const int kCodecId[] = { + ACMCodecDB::kISAC, ACMCodecDB::kISACSWB, ACMCodecDB::kISACFB, + -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; + } +} + +// Verify that the playout mode is set correctly. +TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PlayoutMode)) { + receiver_->SetPlayoutMode(voice); + EXPECT_EQ(voice, receiver_->PlayoutMode()); + + receiver_->SetPlayoutMode(streaming); + EXPECT_EQ(streaming, receiver_->PlayoutMode()); + + receiver_->SetPlayoutMode(fax); + EXPECT_EQ(fax, receiver_->PlayoutMode()); + + receiver_->SetPlayoutMode(off); + EXPECT_EQ(off, receiver_->PlayoutMode()); +} + +TEST_F(AcmReceiverTestOldApi, 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, + 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_); +} + +TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(LastAudioCodec)) { + const int kCodecId[] = { + ACMCodecDB::kISAC, ACMCodecDB::kPCMA, ACMCodecDB::kISACSWB, + ACMCodecDB::kPCM16Bswb32kHz, ACMCodecDB::kG722_1C_48, + -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_EQ(0, acm_->RegisterSendCodec(codecs_[kCngId[n]])); + ++n; + } + + CodecInst codec; + // No audio payload is received. + EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); + + // Start with sending DTX. + ASSERT_EQ(0, 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()); + EXPECT_EQ(-1, receiver_->last_audio_payload_type()); + + 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(codecs_[kCodecId[n]].pltype, + receiver_->last_audio_payload_type()); + 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/audio_coding_module_impl.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc index 2212f83c3..687c5b810 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 @@ -2073,6 +2073,13 @@ const AudioEncoder* AudioCodingImpl::GetSenderInfo() const { FATAL() << "Not implemented yet."; } +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) { if (acm_old_->Add10MsData(audio_frame) != 0) { return -1; @@ -2151,6 +2158,12 @@ void AudioCodingImpl::DisableNack() { FATAL() << "Not implemented yet."; } +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); 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 93fd96bec..6e03e5e61 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 @@ -390,10 +390,7 @@ class AudioCodingModuleImpl : public AudioCodingModule { class AudioCodingImpl : public AudioCoding { public: AudioCodingImpl(const Config& config) { - AudioCodingModule::Config config_old; - config_old.id = 0; - config_old.neteq_config = config.neteq_config; - config_old.clock = config.clock; + 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); @@ -414,6 +411,8 @@ class AudioCodingImpl : public AudioCoding { virtual const AudioEncoder* GetSenderInfo() const OVERRIDE; + virtual const CodecInst* GetSenderCodecInst() OVERRIDE; + virtual int Add10MsAudio(const AudioFrame& audio_frame) OVERRIDE; virtual const ReceiverInfo* GetReceiverInfo() const OVERRIDE; @@ -449,6 +448,10 @@ class AudioCodingImpl : public AudioCoding { virtual void DisableNack() OVERRIDE; + virtual bool SetVad(bool enable_dtx, + bool enable_vad, + ACMVADMode vad_mode) OVERRIDE; + virtual std::vector GetNackList( int round_trip_time_ms) const OVERRIDE; @@ -465,8 +468,11 @@ class AudioCodingImpl : public AudioCoding { int* sample_rate_hz, int* channels); - scoped_ptr acm_old_; int playout_frequency_hz_; + // TODO(henrik.lundin): All members below this line are temporary and should + // be removed after refactoring is completed. + scoped_ptr acm_old_; + CodecInst current_send_codec_; }; } // namespace webrtc 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 389b93fe7..8d73285a5 100644 --- a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h +++ b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h @@ -1015,6 +1015,14 @@ class AudioCoding { playout_channels(1), playout_frequency_hz(32000) {} + 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; @@ -1046,6 +1054,9 @@ class AudioCoding { // 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. @@ -1139,6 +1150,22 @@ class AudioCoding { // 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 diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 79af1baba..777523aba 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -104,6 +104,7 @@ 'sources': [ 'audio_coding/main/acm2/acm_opus_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',