Break apart AudioCodingModule and AcmReceiver
This change makes AudioCodingModule a pure sender and AcmReceiver a pure receiver. The Config struct is in practice no longer used by AudioCodingModule, so a new definition is included in AcmReceiver. The old definition remains in AudioCodingModule while downstream clients are being updated. Bug: webrtc:14867 Change-Id: If0d0b4214c5aa278cf6c85c5b62c6da644de20e0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291533 Reviewed-by: Tomas Lundqvist <tomasl@google.com> Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org> Reviewed-by: Jakob Ivarsson <jakobi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39244}
This commit is contained in:
parent
c5455e7b53
commit
84f75699c6
@ -65,13 +65,13 @@ constexpr double kAudioSampleDurationSeconds = 0.01;
|
||||
constexpr int kVoiceEngineMinMinPlayoutDelayMs = 0;
|
||||
constexpr int kVoiceEngineMaxMinPlayoutDelayMs = 10000;
|
||||
|
||||
AudioCodingModule::Config AcmConfig(
|
||||
acm2::AcmReceiver::Config AcmConfig(
|
||||
NetEqFactory* neteq_factory,
|
||||
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id,
|
||||
size_t jitter_buffer_max_packets,
|
||||
bool jitter_buffer_fast_playout) {
|
||||
AudioCodingModule::Config acm_config;
|
||||
acm2::AcmReceiver::Config acm_config;
|
||||
acm_config.neteq_factory = neteq_factory;
|
||||
acm_config.decoder_factory = decoder_factory;
|
||||
acm_config.neteq_config.codec_pair_id = codec_pair_id;
|
||||
|
||||
@ -472,7 +472,7 @@ ChannelSend::ChannelSend(
|
||||
encoder_queue_(task_queue_factory->CreateTaskQueue(
|
||||
"AudioEncoder",
|
||||
TaskQueueFactory::Priority::NORMAL)) {
|
||||
audio_coding_.reset(AudioCodingModule::Create(AudioCodingModule::Config()));
|
||||
audio_coding_ = AudioCodingModule::Create();
|
||||
|
||||
RtpRtcpInterface::Configuration configuration;
|
||||
configuration.bandwidth_callback = rtcp_observer_.get();
|
||||
|
||||
@ -22,7 +22,7 @@ AudioEgress::AudioEgress(RtpRtcpInterface* rtp_rtcp,
|
||||
TaskQueueFactory* task_queue_factory)
|
||||
: rtp_rtcp_(rtp_rtcp),
|
||||
rtp_sender_audio_(clock, rtp_rtcp_->RtpSender()),
|
||||
audio_coding_(AudioCodingModule::Create(AudioCodingModule::Config())),
|
||||
audio_coding_(AudioCodingModule::Create()),
|
||||
encoder_queue_(task_queue_factory->CreateTaskQueue(
|
||||
"AudioEncoder",
|
||||
TaskQueueFactory::Priority::NORMAL)) {
|
||||
|
||||
@ -29,9 +29,9 @@ namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
AudioCodingModule::Config CreateAcmConfig(
|
||||
acm2::AcmReceiver::Config CreateAcmConfig(
|
||||
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
|
||||
AudioCodingModule::Config acm_config;
|
||||
acm2::AcmReceiver::Config acm_config;
|
||||
acm_config.neteq_config.enable_muted_state = true;
|
||||
acm_config.decoder_factory = decoder_factory;
|
||||
return acm_config;
|
||||
|
||||
@ -1082,8 +1082,6 @@ if (rtc_include_tests) {
|
||||
"test/TestVADDTX.cc",
|
||||
"test/TestVADDTX.h",
|
||||
"test/Tester.cc",
|
||||
"test/TwoWayCommunication.cc",
|
||||
"test/TwoWayCommunication.h",
|
||||
"test/target_delay_unittest.cc",
|
||||
]
|
||||
deps = [
|
||||
|
||||
@ -25,10 +25,10 @@ namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
namespace {
|
||||
AudioCodingModule::Config MakeAcmConfig(
|
||||
Clock* clock,
|
||||
acm2::AcmReceiver::Config MakeAcmConfig(
|
||||
Clock& clock,
|
||||
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
|
||||
AudioCodingModule::Config config;
|
||||
acm2::AcmReceiver::Config config;
|
||||
config.clock = clock;
|
||||
config.decoder_factory = std::move(decoder_factory);
|
||||
return config;
|
||||
@ -42,8 +42,8 @@ AcmReceiveTestOldApi::AcmReceiveTestOldApi(
|
||||
NumOutputChannels exptected_output_channels,
|
||||
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
|
||||
: clock_(0),
|
||||
acm_(webrtc::AudioCodingModule::Create(
|
||||
MakeAcmConfig(&clock_, std::move(decoder_factory)))),
|
||||
acm_receiver_(std::make_unique<acm2::AcmReceiver>(
|
||||
MakeAcmConfig(clock_, std::move(decoder_factory)))),
|
||||
packet_source_(packet_source),
|
||||
audio_sink_(audio_sink),
|
||||
output_freq_hz_(output_freq_hz),
|
||||
@ -52,43 +52,43 @@ AcmReceiveTestOldApi::AcmReceiveTestOldApi(
|
||||
AcmReceiveTestOldApi::~AcmReceiveTestOldApi() = default;
|
||||
|
||||
void AcmReceiveTestOldApi::RegisterDefaultCodecs() {
|
||||
acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
|
||||
{104, {"ISAC", 32000, 1}},
|
||||
{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
acm_receiver_->SetCodecs({{103, {"ISAC", 16000, 1}},
|
||||
{104, {"ISAC", 32000, 1}},
|
||||
{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
}
|
||||
|
||||
// Remaps payload types from ACM's default to those used in the resource file
|
||||
// neteq_universal_new.rtp.
|
||||
void AcmReceiveTestOldApi::RegisterNetEqTestCodecs() {
|
||||
acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
|
||||
{104, {"ISAC", 32000, 1}},
|
||||
{93, {"L16", 8000, 1}},
|
||||
{94, {"L16", 16000, 1}},
|
||||
{95, {"L16", 32000, 1}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{120, {"OPUS", 48000, 2}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
acm_receiver_->SetCodecs({{103, {"ISAC", 16000, 1}},
|
||||
{104, {"ISAC", 32000, 1}},
|
||||
{93, {"L16", 8000, 1}},
|
||||
{94, {"L16", 16000, 1}},
|
||||
{95, {"L16", 32000, 1}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{120, {"OPUS", 48000, 2}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
}
|
||||
|
||||
void AcmReceiveTestOldApi::Run() {
|
||||
@ -98,8 +98,8 @@ void AcmReceiveTestOldApi::Run() {
|
||||
while (clock_.TimeInMilliseconds() < packet->time_ms()) {
|
||||
AudioFrame output_frame;
|
||||
bool muted;
|
||||
EXPECT_EQ(0,
|
||||
acm_->PlayoutData10Ms(output_freq_hz_, &output_frame, &muted));
|
||||
EXPECT_EQ(
|
||||
0, acm_receiver_->GetAudio(output_freq_hz_, &output_frame, &muted));
|
||||
ASSERT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
|
||||
ASSERT_FALSE(muted);
|
||||
const size_t samples_per_block =
|
||||
@ -119,10 +119,10 @@ void AcmReceiveTestOldApi::Run() {
|
||||
AfterGetAudio();
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, acm_->IncomingPacket(
|
||||
packet->payload(),
|
||||
static_cast<int32_t>(packet->payload_length_bytes()),
|
||||
packet->header()))
|
||||
EXPECT_EQ(0, acm_receiver_->InsertPacket(
|
||||
packet->header(),
|
||||
rtc::ArrayView<const uint8_t>(
|
||||
packet->payload(), packet->payload_length_bytes())))
|
||||
<< "Failure when inserting packet:" << std::endl
|
||||
<< " PT = " << static_cast<int>(packet->header().payloadType)
|
||||
<< std::endl
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -57,14 +58,12 @@ class AcmReceiveTestOldApi {
|
||||
// Runs the test and returns true if successful.
|
||||
void Run();
|
||||
|
||||
AudioCodingModule* get_acm() { return acm_.get(); }
|
||||
|
||||
protected:
|
||||
// Method is called after each block of output audio is received from ACM.
|
||||
virtual void AfterGetAudio() {}
|
||||
|
||||
SimulatedClock clock_;
|
||||
std::unique_ptr<AudioCodingModule> acm_;
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
|
||||
PacketSource* packet_source_;
|
||||
AudioSink* audio_sink_;
|
||||
int output_freq_hz_;
|
||||
|
||||
@ -56,11 +56,6 @@ AcmReceiver::Config::Config(
|
||||
neteq_config.enable_post_decode_vad = true;
|
||||
}
|
||||
|
||||
AcmReceiver::Config::Config(const AudioCodingModule::Config& acm_config)
|
||||
: neteq_config(acm_config.neteq_config),
|
||||
clock(*acm_config.clock),
|
||||
decoder_factory(acm_config.decoder_factory) {}
|
||||
|
||||
AcmReceiver::Config::Config(const Config&) = default;
|
||||
AcmReceiver::Config::~Config() = default;
|
||||
|
||||
@ -76,9 +71,6 @@ AcmReceiver::AcmReceiver(const Config& config)
|
||||
sizeof(int16_t) * AudioFrame::kMaxDataSizeSamples);
|
||||
}
|
||||
|
||||
AcmReceiver::AcmReceiver(const AudioCodingModule::Config& acm_config)
|
||||
: AcmReceiver(Config(acm_config)) {}
|
||||
|
||||
AcmReceiver::~AcmReceiver() = default;
|
||||
|
||||
int AcmReceiver::SetMinimumDelay(int delay_ms) {
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
#include "api/neteq/neteq_factory.h"
|
||||
#include "modules/audio_coding/acm2/acm_resampler.h"
|
||||
#include "modules/audio_coding/acm2/call_statistics.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
@ -46,7 +45,6 @@ class AcmReceiver {
|
||||
struct Config {
|
||||
explicit Config(
|
||||
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory = nullptr);
|
||||
explicit Config(const AudioCodingModule::Config& acm_config);
|
||||
Config(const Config&);
|
||||
~Config();
|
||||
|
||||
@ -58,9 +56,6 @@ class AcmReceiver {
|
||||
|
||||
// Constructor of the class
|
||||
explicit AcmReceiver(const Config& config);
|
||||
// Deprecated constructor.
|
||||
// TODO(webrtc:14867): Remove when downstream projects are ready.
|
||||
explicit AcmReceiver(const AudioCodingModule::Config& acm_config);
|
||||
|
||||
// Destructor of the class.
|
||||
~AcmReceiver();
|
||||
|
||||
@ -44,11 +44,10 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
||||
~AcmReceiverTestOldApi() {}
|
||||
|
||||
void SetUp() override {
|
||||
acm_.reset(AudioCodingModule::Create(config_));
|
||||
acm_ = AudioCodingModule::Create();
|
||||
receiver_.reset(new AcmReceiver(config_));
|
||||
ASSERT_TRUE(receiver_.get() != NULL);
|
||||
ASSERT_TRUE(acm_.get() != NULL);
|
||||
acm_->InitializeReceiver();
|
||||
acm_->RegisterTransportCallback(this);
|
||||
|
||||
rtp_header_.sequenceNumber = 0;
|
||||
@ -135,7 +134,7 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
|
||||
CreateBuiltinAudioEncoderFactory();
|
||||
const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_ =
|
||||
CreateBuiltinAudioDecoderFactory();
|
||||
AudioCodingModule::Config config_;
|
||||
acm2::AcmReceiver::Config config_;
|
||||
std::unique_ptr<AcmReceiver> receiver_;
|
||||
std::unique_ptr<AudioCodingModule> acm_;
|
||||
RTPHeader rtp_header_;
|
||||
@ -383,6 +382,24 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_InitializedToZero) {
|
||||
EXPECT_EQ(0, stats.decoded_muted_output);
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
#define MAYBE_VerifyOutputFrame DISABLED_VerifyOutputFrame
|
||||
#else
|
||||
#define MAYBE_VerifyOutputFrame VerifyOutputFrame
|
||||
#endif
|
||||
TEST_F(AcmReceiverTestOldApi, MAYBE_VerifyOutputFrame) {
|
||||
AudioFrame audio_frame;
|
||||
const int kSampleRateHz = 32000;
|
||||
bool muted;
|
||||
EXPECT_EQ(0, receiver_->GetAudio(kSampleRateHz, &audio_frame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
EXPECT_EQ(0u, audio_frame.timestamp_);
|
||||
EXPECT_GT(audio_frame.num_channels_, 0u);
|
||||
EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100),
|
||||
audio_frame.samples_per_channel_);
|
||||
EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_);
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
@ -32,12 +32,7 @@ AcmSendTestOldApi::AcmSendTestOldApi(InputAudioFile* audio_source,
|
||||
int source_rate_hz,
|
||||
int test_duration_ms)
|
||||
: clock_(0),
|
||||
acm_(webrtc::AudioCodingModule::Create([this] {
|
||||
AudioCodingModule::Config config;
|
||||
config.clock = &clock_;
|
||||
config.decoder_factory = CreateBuiltinAudioDecoderFactory();
|
||||
return config;
|
||||
}())),
|
||||
acm_(webrtc::AudioCodingModule::Create()),
|
||||
audio_source_(audio_source),
|
||||
source_rate_hz_(source_rate_hz),
|
||||
input_block_size_samples_(
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/acm2/acm_remixing.h"
|
||||
#include "modules/audio_coding/acm2/acm_resampler.h"
|
||||
#include "modules/include/module_common_types.h"
|
||||
@ -41,7 +40,7 @@ constexpr int32_t kMaxInputSampleRateHz = 192000;
|
||||
|
||||
class AudioCodingModuleImpl final : public AudioCodingModule {
|
||||
public:
|
||||
explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config);
|
||||
explicit AudioCodingModuleImpl();
|
||||
~AudioCodingModuleImpl() override;
|
||||
|
||||
/////////////////////////////////////////
|
||||
@ -65,32 +64,10 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
|
||||
// Set target packet loss rate
|
||||
int SetPacketLossRate(int loss_rate) override;
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Receiver
|
||||
//
|
||||
|
||||
// Initialize receiver, resets codec database etc.
|
||||
int InitializeReceiver() override;
|
||||
|
||||
void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
|
||||
|
||||
// Incoming packet from network parsed and ready for decode.
|
||||
int IncomingPacket(const uint8_t* incoming_payload,
|
||||
const size_t payload_length,
|
||||
const RTPHeader& rtp_info) override;
|
||||
|
||||
// Get 10 milliseconds of raw audio data to play out, and
|
||||
// automatic resample to the requested frequency if > 0.
|
||||
int PlayoutData10Ms(int desired_freq_hz,
|
||||
AudioFrame* audio_frame,
|
||||
bool* muted) override;
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Statistics
|
||||
//
|
||||
|
||||
int GetNetworkStatistics(NetworkStatistics* statistics) override;
|
||||
|
||||
ANAStats GetANAStats() const override;
|
||||
|
||||
int GetTargetBitrate() const override;
|
||||
@ -134,8 +111,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
|
||||
absl::optional<int64_t> absolute_capture_timestamp_ms)
|
||||
RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_mutex_);
|
||||
|
||||
int InitializeReceiverSafe() RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_mutex_);
|
||||
|
||||
bool HaveValidEncoder(absl::string_view caller_name) const
|
||||
RTC_EXCLUSIVE_LOCKS_REQUIRED(acm_mutex_);
|
||||
|
||||
@ -163,7 +138,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
|
||||
uint32_t expected_codec_ts_ RTC_GUARDED_BY(acm_mutex_);
|
||||
uint32_t expected_in_ts_ RTC_GUARDED_BY(acm_mutex_);
|
||||
acm2::ACMResampler resampler_ RTC_GUARDED_BY(acm_mutex_);
|
||||
acm2::AcmReceiver receiver_; // AcmReceiver has it's own internal lock.
|
||||
ChangeLogger bitrate_logger_ RTC_GUARDED_BY(acm_mutex_);
|
||||
|
||||
// Current encoder stack, provided by a call to RegisterEncoder.
|
||||
@ -172,8 +146,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
|
||||
// This is to keep track of CN instances where we can send DTMFs.
|
||||
uint8_t previous_pltype_ RTC_GUARDED_BY(acm_mutex_);
|
||||
|
||||
bool receiver_initialized_ RTC_GUARDED_BY(acm_mutex_);
|
||||
|
||||
AudioFrame preprocess_frame_ RTC_GUARDED_BY(acm_mutex_);
|
||||
bool first_10ms_data_ RTC_GUARDED_BY(acm_mutex_);
|
||||
|
||||
@ -206,23 +178,17 @@ void AudioCodingModuleImpl::ChangeLogger::MaybeLog(int value) {
|
||||
}
|
||||
}
|
||||
|
||||
AudioCodingModuleImpl::AudioCodingModuleImpl(
|
||||
const AudioCodingModule::Config& config)
|
||||
AudioCodingModuleImpl::AudioCodingModuleImpl()
|
||||
: expected_codec_ts_(0xD87F3F9F),
|
||||
expected_in_ts_(0xD87F3F9F),
|
||||
receiver_(config),
|
||||
bitrate_logger_("WebRTC.Audio.TargetBitrateInKbps"),
|
||||
encoder_stack_(nullptr),
|
||||
previous_pltype_(255),
|
||||
receiver_initialized_(false),
|
||||
first_10ms_data_(false),
|
||||
first_frame_(true),
|
||||
packetization_callback_(NULL),
|
||||
codec_histogram_bins_log_(),
|
||||
number_of_consecutive_empty_packets_(0) {
|
||||
if (InitializeReceiverSafe() < 0) {
|
||||
RTC_LOG(LS_ERROR) << "Cannot initialize receiver";
|
||||
}
|
||||
RTC_LOG(LS_INFO) << "Created";
|
||||
}
|
||||
|
||||
@ -528,68 +494,10 @@ int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Receiver
|
||||
//
|
||||
|
||||
int AudioCodingModuleImpl::InitializeReceiver() {
|
||||
MutexLock lock(&acm_mutex_);
|
||||
return InitializeReceiverSafe();
|
||||
}
|
||||
|
||||
// Initialize receiver, resets codec database etc.
|
||||
int AudioCodingModuleImpl::InitializeReceiverSafe() {
|
||||
// If the receiver is already initialized then we want to destroy any
|
||||
// existing decoders. After a call to this function, we should have a clean
|
||||
// start-up.
|
||||
if (receiver_initialized_)
|
||||
receiver_.RemoveAllCodecs();
|
||||
receiver_.FlushBuffers();
|
||||
|
||||
receiver_initialized_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AudioCodingModuleImpl::SetReceiveCodecs(
|
||||
const std::map<int, SdpAudioFormat>& codecs) {
|
||||
MutexLock lock(&acm_mutex_);
|
||||
receiver_.SetCodecs(codecs);
|
||||
}
|
||||
|
||||
// Incoming packet from network parsed and ready for decode.
|
||||
int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
|
||||
const size_t payload_length,
|
||||
const RTPHeader& rtp_header) {
|
||||
RTC_DCHECK_EQ(payload_length == 0, incoming_payload == nullptr);
|
||||
return receiver_.InsertPacket(
|
||||
rtp_header,
|
||||
rtc::ArrayView<const uint8_t>(incoming_payload, payload_length));
|
||||
}
|
||||
|
||||
// Get 10 milliseconds of raw audio data to play out.
|
||||
// Automatic resample to the requested frequency.
|
||||
int AudioCodingModuleImpl::PlayoutData10Ms(int desired_freq_hz,
|
||||
AudioFrame* audio_frame,
|
||||
bool* muted) {
|
||||
// GetAudio always returns 10 ms, at the requested sample rate.
|
||||
if (receiver_.GetAudio(desired_freq_hz, audio_frame, muted) != 0) {
|
||||
RTC_LOG(LS_ERROR) << "PlayoutData failed, RecOut Failed";
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Statistics
|
||||
//
|
||||
|
||||
// TODO(turajs) change the return value to void. Also change the corresponding
|
||||
// NetEq function.
|
||||
int AudioCodingModuleImpl::GetNetworkStatistics(NetworkStatistics* statistics) {
|
||||
receiver_.GetNetworkStatistics(statistics);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AudioCodingModuleImpl::HaveValidEncoder(
|
||||
absl::string_view caller_name) const {
|
||||
if (!encoder_stack_) {
|
||||
@ -617,21 +525,12 @@ int AudioCodingModuleImpl::GetTargetBitrate() const {
|
||||
|
||||
} // namespace
|
||||
|
||||
AudioCodingModule::Config::Config(
|
||||
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
|
||||
: neteq_config(),
|
||||
clock(Clock::GetRealTimeClock()),
|
||||
decoder_factory(decoder_factory) {
|
||||
// Post-decode VAD is disabled by default in NetEq, however, Audio
|
||||
// Conference Mixer relies on VAD decisions and fails without them.
|
||||
neteq_config.enable_post_decode_vad = true;
|
||||
std::unique_ptr<AudioCodingModule> AudioCodingModule::Create() {
|
||||
return std::make_unique<AudioCodingModuleImpl>();
|
||||
}
|
||||
|
||||
AudioCodingModule::Config::Config(const Config&) = default;
|
||||
AudioCodingModule::Config::~Config() = default;
|
||||
|
||||
AudioCodingModule* AudioCodingModule::Create(const Config& config) {
|
||||
return new AudioCodingModuleImpl(config);
|
||||
return new AudioCodingModuleImpl();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -172,12 +172,11 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
|
||||
void TearDown() {}
|
||||
|
||||
void SetUp() {
|
||||
acm_.reset(AudioCodingModule::Create([this] {
|
||||
AudioCodingModule::Config config;
|
||||
config.clock = clock_;
|
||||
config.decoder_factory = CreateBuiltinAudioDecoderFactory();
|
||||
return config;
|
||||
}()));
|
||||
acm_ = AudioCodingModule::Create();
|
||||
acm2::AcmReceiver::Config config;
|
||||
config.clock = *clock_;
|
||||
config.decoder_factory = CreateBuiltinAudioDecoderFactory();
|
||||
acm_receiver_ = std::make_unique<acm2::AcmReceiver>(config);
|
||||
|
||||
rtp_utility_->Populate(&rtp_header_);
|
||||
|
||||
@ -200,7 +199,7 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
|
||||
}
|
||||
|
||||
virtual void RegisterCodec() {
|
||||
acm_->SetReceiveCodecs({{kPayloadType, *audio_format_}});
|
||||
acm_receiver_->SetCodecs({{kPayloadType, *audio_format_}});
|
||||
acm_->SetEncoder(CreateBuiltinAudioEncoderFactory()->MakeAudioEncoder(
|
||||
kPayloadType, *audio_format_, absl::nullopt));
|
||||
}
|
||||
@ -212,15 +211,16 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
|
||||
|
||||
virtual void InsertPacket() {
|
||||
const uint8_t kPayload[kPayloadSizeBytes] = {0};
|
||||
ASSERT_EQ(0,
|
||||
acm_->IncomingPacket(kPayload, kPayloadSizeBytes, rtp_header_));
|
||||
ASSERT_EQ(0, acm_receiver_->InsertPacket(rtp_header_,
|
||||
rtc::ArrayView<const uint8_t>(
|
||||
kPayload, kPayloadSizeBytes)));
|
||||
rtp_utility_->Forward(&rtp_header_);
|
||||
}
|
||||
|
||||
virtual void PullAudio() {
|
||||
AudioFrame audio_frame;
|
||||
bool muted;
|
||||
ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &audio_frame, &muted));
|
||||
ASSERT_EQ(0, acm_receiver_->GetAudio(-1, &audio_frame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
}
|
||||
|
||||
@ -242,6 +242,7 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
|
||||
|
||||
std::unique_ptr<RtpData> rtp_utility_;
|
||||
std::unique_ptr<AudioCodingModule> acm_;
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
|
||||
PacketizationCallbackStubOldApi packet_cb_;
|
||||
RTPHeader rtp_header_;
|
||||
AudioFrame input_frame_;
|
||||
@ -255,19 +256,6 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
|
||||
class AudioCodingModuleTestOldApiDeathTest
|
||||
: public AudioCodingModuleTestOldApi {};
|
||||
|
||||
TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) {
|
||||
AudioFrame audio_frame;
|
||||
const int kSampleRateHz = 32000;
|
||||
bool muted;
|
||||
EXPECT_EQ(0, acm_->PlayoutData10Ms(kSampleRateHz, &audio_frame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
EXPECT_EQ(0u, audio_frame.timestamp_);
|
||||
EXPECT_GT(audio_frame.num_channels_, 0u);
|
||||
EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100),
|
||||
audio_frame.samples_per_channel_);
|
||||
EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_);
|
||||
}
|
||||
|
||||
// The below test is temporarily disabled on Windows due to problems
|
||||
// with clang debug builds.
|
||||
// TODO(tommi): Re-enable when we've figured out what the problem is.
|
||||
@ -277,7 +265,7 @@ TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) {
|
||||
TEST_F(AudioCodingModuleTestOldApiDeathTest, FailOnZeroDesiredFrequency) {
|
||||
AudioFrame audio_frame;
|
||||
bool muted;
|
||||
RTC_EXPECT_DEATH(acm_->PlayoutData10Ms(0, &audio_frame, &muted),
|
||||
RTC_EXPECT_DEATH(acm_receiver_->GetAudio(0, &audio_frame, &muted),
|
||||
"dst_sample_rate_hz");
|
||||
}
|
||||
#endif
|
||||
@ -310,8 +298,8 @@ class AudioCodingModuleTestWithComfortNoiseOldApi
|
||||
: public AudioCodingModuleTestOldApi {
|
||||
protected:
|
||||
void RegisterCngCodec(int rtp_payload_type) {
|
||||
acm_->SetReceiveCodecs({{kPayloadType, *audio_format_},
|
||||
{rtp_payload_type, {"cn", kSampleRateHz, 1}}});
|
||||
acm_receiver_->SetCodecs({{kPayloadType, *audio_format_},
|
||||
{rtp_payload_type, {"cn", kSampleRateHz, 1}}});
|
||||
acm_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* enc) {
|
||||
AudioEncoderCngConfig config;
|
||||
config.speech_encoder = std::move(*enc);
|
||||
|
||||
@ -64,11 +64,11 @@ class AudioCodingModule {
|
||||
AudioCodingModule() {}
|
||||
|
||||
public:
|
||||
// Deprecated. Will be deleted when downlink clients have migrated off it.
|
||||
struct Config {
|
||||
explicit Config(
|
||||
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory = nullptr);
|
||||
Config(const Config&);
|
||||
~Config();
|
||||
Config() = default;
|
||||
Config(const Config&) = default;
|
||||
~Config() = default;
|
||||
|
||||
NetEq::Config neteq_config;
|
||||
Clock* clock;
|
||||
@ -76,13 +76,12 @@ class AudioCodingModule {
|
||||
NetEqFactory* neteq_factory = nullptr;
|
||||
};
|
||||
|
||||
static std::unique_ptr<AudioCodingModule> Create();
|
||||
// Deprecated. Will be deleted when downlink clients have migrated to the
|
||||
// above method.
|
||||
static AudioCodingModule* Create(const Config& config);
|
||||
virtual ~AudioCodingModule() = default;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Sender
|
||||
//
|
||||
|
||||
// `modifier` is called exactly once with one argument: a pointer to the
|
||||
// unique_ptr that holds the current encoder (which is null if there is no
|
||||
// current encoder). For the duration of the call, `modifier` has exclusive
|
||||
@ -152,90 +151,10 @@ class AudioCodingModule {
|
||||
// TODO(minyue): Remove it when possible.
|
||||
virtual int SetPacketLossRate(int packet_loss_rate) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Receiver
|
||||
//
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// int32_t InitializeReceiver()
|
||||
// Any decoder-related state of ACM will be initialized to the
|
||||
// same state when ACM is created. This will not interrupt or
|
||||
// effect encoding functionality of ACM. ACM would lose all the
|
||||
// decoding-related settings by calling this function.
|
||||
// For instance, all registered codecs are deleted and have to be
|
||||
// registered again.
|
||||
//
|
||||
// Return value:
|
||||
// -1 if failed to initialize,
|
||||
// 0 if succeeded.
|
||||
//
|
||||
virtual int32_t InitializeReceiver() = 0;
|
||||
|
||||
// Replace any existing decoders with the given payload type -> decoder map.
|
||||
virtual void SetReceiveCodecs(
|
||||
const std::map<int, SdpAudioFormat>& codecs) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// int32_t IncomingPacket()
|
||||
// Call this function to insert a parsed RTP packet into ACM.
|
||||
//
|
||||
// Inputs:
|
||||
// -incoming_payload : received payload.
|
||||
// -payload_len_bytes : the length of payload in bytes.
|
||||
// -rtp_info : the relevant information retrieved from RTP
|
||||
// header.
|
||||
//
|
||||
// Return value:
|
||||
// -1 if failed to push in the payload
|
||||
// 0 if payload is successfully pushed in.
|
||||
//
|
||||
virtual int32_t IncomingPacket(const uint8_t* incoming_payload,
|
||||
size_t payload_len_bytes,
|
||||
const RTPHeader& rtp_header) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// int32_t PlayoutData10Ms(
|
||||
// Get 10 milliseconds of raw audio data for playout, at the given sampling
|
||||
// frequency. ACM will perform a resampling if required.
|
||||
//
|
||||
// Input:
|
||||
// -desired_freq_hz : the desired sampling frequency, in Hertz, of the
|
||||
// output audio. If set to -1, the function returns
|
||||
// the audio at the current sampling frequency.
|
||||
//
|
||||
// Output:
|
||||
// -audio_frame : output audio frame which contains raw audio data
|
||||
// and other relevant parameters.
|
||||
// -muted : if true, the sample data in audio_frame is not
|
||||
// populated, and must be interpreted as all zero.
|
||||
//
|
||||
// Return value:
|
||||
// -1 if the function fails,
|
||||
// 0 if the function succeeds.
|
||||
//
|
||||
virtual int32_t PlayoutData10Ms(int32_t desired_freq_hz,
|
||||
AudioFrame* audio_frame,
|
||||
bool* muted) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// statistics
|
||||
//
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// int32_t GetNetworkStatistics()
|
||||
// Get network statistics. Note that the internal statistics of NetEq are
|
||||
// reset by this call.
|
||||
//
|
||||
// Input:
|
||||
// -network_statistics : a structure that contains network statistics.
|
||||
//
|
||||
// Return value:
|
||||
// -1 if failed to set the network statistics,
|
||||
// 0 if statistics are set successfully.
|
||||
//
|
||||
virtual int32_t GetNetworkStatistics(
|
||||
NetworkStatistics* network_statistics) = 0;
|
||||
|
||||
virtual ANAStats GetANAStats() const = 0;
|
||||
|
||||
virtual int GetTargetBitrate() const = 0;
|
||||
|
||||
@ -307,8 +307,7 @@ int RunRtpEncode(int argc, char* argv[]) {
|
||||
|
||||
// Set up ACM.
|
||||
const int timestamp_rate_hz = codec->RtpTimestampRateHz();
|
||||
AudioCodingModule::Config config;
|
||||
std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(config));
|
||||
auto acm(AudioCodingModule::Create());
|
||||
acm->SetEncoder(std::move(codec));
|
||||
|
||||
// Open files.
|
||||
|
||||
@ -82,8 +82,8 @@ int32_t Channel::SendData(AudioFrameType frameType,
|
||||
return 0;
|
||||
}
|
||||
|
||||
status =
|
||||
_receiverACM->IncomingPacket(_payloadData, payloadDataSize, rtp_header);
|
||||
status = _receiverACM->InsertPacket(
|
||||
rtp_header, rtc::ArrayView<const uint8_t>(_payloadData, payloadDataSize));
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -228,8 +228,8 @@ Channel::Channel(int16_t chID)
|
||||
|
||||
Channel::~Channel() {}
|
||||
|
||||
void Channel::RegisterReceiverACM(AudioCodingModule* acm) {
|
||||
_receiverACM = acm;
|
||||
void Channel::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
|
||||
_receiverACM = acm_receiver;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module.h"
|
||||
#include "modules/include/module_common_types.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
@ -54,7 +55,7 @@ class Channel : public AudioPacketizationCallback {
|
||||
size_t payloadSize,
|
||||
int64_t absolute_capture_timestamp_ms) override;
|
||||
|
||||
void RegisterReceiverACM(AudioCodingModule* acm);
|
||||
void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
|
||||
|
||||
void ResetStats();
|
||||
|
||||
@ -83,7 +84,7 @@ class Channel : public AudioPacketizationCallback {
|
||||
private:
|
||||
void CalcStatistics(const RTPHeader& rtp_header, size_t payloadSize);
|
||||
|
||||
AudioCodingModule* _receiverACM;
|
||||
acm2::AcmReceiver* _receiverACM;
|
||||
uint16_t _seqNo;
|
||||
// 60msec * 32 sample(max)/msec * 2 description (maybe) * 2 bytes/sample
|
||||
uint8_t _payloadData[60 * 32 * 2 * 2];
|
||||
|
||||
@ -102,34 +102,32 @@ Receiver::Receiver()
|
||||
: _playoutLengthSmpls(kWebRtc10MsPcmAudio),
|
||||
_payloadSizeBytes(MAX_INCOMING_PAYLOAD) {}
|
||||
|
||||
void Receiver::Setup(AudioCodingModule* acm,
|
||||
void Receiver::Setup(acm2::AcmReceiver* acm_receiver,
|
||||
RTPStream* rtpStream,
|
||||
absl::string_view out_file_name,
|
||||
size_t channels,
|
||||
int file_num) {
|
||||
EXPECT_EQ(0, acm->InitializeReceiver());
|
||||
|
||||
if (channels == 1) {
|
||||
acm->SetReceiveCodecs({{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{120, {"OPUS", 48000, 2}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
acm_receiver->SetCodecs({{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{120, {"OPUS", 48000, 2}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
} else {
|
||||
ASSERT_EQ(channels, 2u);
|
||||
acm->SetReceiveCodecs({{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
|
||||
acm_receiver->SetCodecs({{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
|
||||
}
|
||||
|
||||
int playSampFreq;
|
||||
@ -146,7 +144,7 @@ void Receiver::Setup(AudioCodingModule* acm,
|
||||
_realPayloadSizeBytes = 0;
|
||||
_playoutBuffer = new int16_t[kWebRtc10MsPcmAudio];
|
||||
_frequency = playSampFreq;
|
||||
_acm = acm;
|
||||
_acm_receiver = acm_receiver;
|
||||
_firstTime = true;
|
||||
}
|
||||
|
||||
@ -171,8 +169,9 @@ bool Receiver::IncomingPacket() {
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes,
|
||||
_rtpHeader));
|
||||
EXPECT_EQ(0, _acm_receiver->InsertPacket(
|
||||
_rtpHeader, rtc::ArrayView<const uint8_t>(
|
||||
_incomingPayload, _realPayloadSizeBytes)));
|
||||
_realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
|
||||
_payloadSizeBytes, &_nextTime);
|
||||
if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {
|
||||
@ -185,7 +184,7 @@ bool Receiver::IncomingPacket() {
|
||||
bool Receiver::PlayoutData() {
|
||||
AudioFrame audioFrame;
|
||||
bool muted;
|
||||
int32_t ok = _acm->PlayoutData10Ms(_frequency, &audioFrame, &muted);
|
||||
int32_t ok = _acm_receiver->GetAudio(_frequency, &audioFrame, &muted);
|
||||
if (muted) {
|
||||
ADD_FAILURE();
|
||||
return false;
|
||||
@ -240,8 +239,7 @@ void EncodeDecodeTest::Perform() {
|
||||
int file_num = 0;
|
||||
for (const auto& send_codec : send_codecs) {
|
||||
RTPFile rtpFile;
|
||||
std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())));
|
||||
std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create());
|
||||
|
||||
std::string fileName = webrtc::test::TempFilename(
|
||||
webrtc::test::OutputPath(), "encode_decode_rtp");
|
||||
@ -256,8 +254,12 @@ void EncodeDecodeTest::Perform() {
|
||||
|
||||
rtpFile.Open(fileName.c_str(), "rb");
|
||||
rtpFile.ReadHeader();
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_receiver(
|
||||
std::make_unique<acm2::AcmReceiver>(
|
||||
acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory())));
|
||||
Receiver receiver;
|
||||
receiver.Setup(acm.get(), &rtpFile, "encodeDecode_out", 1, file_num);
|
||||
receiver.Setup(acm_receiver.get(), &rtpFile, "encodeDecode_out", 1,
|
||||
file_num);
|
||||
receiver.Run();
|
||||
receiver.Teardown();
|
||||
rtpFile.Close();
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module.h"
|
||||
#include "modules/audio_coding/test/PCMFile.h"
|
||||
#include "modules/audio_coding/test/RTPFile.h"
|
||||
@ -73,7 +74,7 @@ class Receiver {
|
||||
public:
|
||||
Receiver();
|
||||
virtual ~Receiver() {}
|
||||
void Setup(AudioCodingModule* acm,
|
||||
void Setup(acm2::AcmReceiver* acm_receiver,
|
||||
RTPStream* rtpStream,
|
||||
absl::string_view out_file_name,
|
||||
size_t channels,
|
||||
@ -91,7 +92,7 @@ class Receiver {
|
||||
bool _firstTime;
|
||||
|
||||
protected:
|
||||
AudioCodingModule* _acm;
|
||||
acm2::AcmReceiver* _acm_receiver;
|
||||
uint8_t _incomingPayload[MAX_INCOMING_PAYLOAD];
|
||||
RTPStream* _rtpStream;
|
||||
RTPHeader _rtpHeader;
|
||||
|
||||
@ -27,7 +27,7 @@ ReceiverWithPacketLoss::ReceiverWithPacketLoss()
|
||||
lost_packet_counter_(0),
|
||||
burst_lost_counter_(burst_length_) {}
|
||||
|
||||
void ReceiverWithPacketLoss::Setup(AudioCodingModule* acm,
|
||||
void ReceiverWithPacketLoss::Setup(acm2::AcmReceiver* acm_receiver,
|
||||
RTPStream* rtpStream,
|
||||
absl::string_view out_file_name,
|
||||
int channels,
|
||||
@ -39,7 +39,7 @@ void ReceiverWithPacketLoss::Setup(AudioCodingModule* acm,
|
||||
burst_lost_counter_ = burst_length_; // To prevent first packet gets lost.
|
||||
rtc::StringBuilder ss;
|
||||
ss << out_file_name << "_" << loss_rate_ << "_" << burst_length_ << "_";
|
||||
Receiver::Setup(acm, rtpStream, ss.str(), channels, file_num);
|
||||
Receiver::Setup(acm_receiver, rtpStream, ss.str(), channels, file_num);
|
||||
}
|
||||
|
||||
bool ReceiverWithPacketLoss::IncomingPacket() {
|
||||
@ -58,7 +58,9 @@ bool ReceiverWithPacketLoss::IncomingPacket() {
|
||||
}
|
||||
|
||||
if (!PacketLost()) {
|
||||
_acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes, _rtpHeader);
|
||||
_acm_receiver->InsertPacket(
|
||||
_rtpHeader, rtc::ArrayView<const uint8_t>(_incomingPayload,
|
||||
_realPayloadSizeBytes));
|
||||
}
|
||||
packet_counter_++;
|
||||
_realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
|
||||
@ -135,8 +137,7 @@ void PacketLossTest::Perform() {
|
||||
return;
|
||||
#else
|
||||
RTPFile rtpFile;
|
||||
std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())));
|
||||
std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create());
|
||||
SdpAudioFormat send_format = SdpAudioFormat("opus", 48000, 2);
|
||||
if (channels_ == 2) {
|
||||
send_format.parameters = {{"stereo", "1"}};
|
||||
@ -155,8 +156,11 @@ void PacketLossTest::Perform() {
|
||||
|
||||
rtpFile.Open(fileName.c_str(), "rb");
|
||||
rtpFile.ReadHeader();
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_receiver(
|
||||
std::make_unique<acm2::AcmReceiver>(
|
||||
acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory())));
|
||||
ReceiverWithPacketLoss receiver;
|
||||
receiver.Setup(acm.get(), &rtpFile, "packetLoss_out", channels_, 15,
|
||||
receiver.Setup(acm_receiver.get(), &rtpFile, "packetLoss_out", channels_, 15,
|
||||
actual_loss_rate_, burst_length_);
|
||||
receiver.Run();
|
||||
receiver.Teardown();
|
||||
|
||||
@ -21,7 +21,7 @@ namespace webrtc {
|
||||
class ReceiverWithPacketLoss : public Receiver {
|
||||
public:
|
||||
ReceiverWithPacketLoss();
|
||||
void Setup(AudioCodingModule* acm,
|
||||
void Setup(acm2::AcmReceiver* acm_receiver,
|
||||
RTPStream* rtpStream,
|
||||
absl::string_view out_file_name,
|
||||
int channels,
|
||||
|
||||
@ -55,8 +55,8 @@ TestPack::TestPack()
|
||||
|
||||
TestPack::~TestPack() {}
|
||||
|
||||
void TestPack::RegisterReceiverACM(AudioCodingModule* acm) {
|
||||
receiver_acm_ = acm;
|
||||
void TestPack::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
|
||||
receiver_acm_ = acm_receiver;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -83,8 +83,8 @@ int32_t TestPack::SendData(AudioFrameType frame_type,
|
||||
// Only run mono for all test cases.
|
||||
memcpy(payload_data_, payload_data, payload_size);
|
||||
|
||||
status =
|
||||
receiver_acm_->IncomingPacket(payload_data_, payload_size, rtp_header);
|
||||
status = receiver_acm_->InsertPacket(
|
||||
rtp_header, rtc::ArrayView<const uint8_t>(payload_data_, payload_size));
|
||||
|
||||
payload_size_ = payload_size;
|
||||
timestamp_diff_ = timestamp - last_in_timestamp_;
|
||||
@ -106,10 +106,9 @@ void TestPack::reset_payload_size() {
|
||||
}
|
||||
|
||||
TestAllCodecs::TestAllCodecs()
|
||||
: acm_a_(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
acm_b_(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
: acm_a_(AudioCodingModule::Create()),
|
||||
acm_b_(std::make_unique<acm2::AcmReceiver>(
|
||||
acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
channel_a_to_b_(NULL),
|
||||
test_count_(0),
|
||||
packet_size_samples_(0),
|
||||
@ -127,26 +126,23 @@ void TestAllCodecs::Perform() {
|
||||
webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
|
||||
infile_a_.Open(file_name, 32000, "rb");
|
||||
|
||||
acm_a_->InitializeReceiver();
|
||||
acm_b_->InitializeReceiver();
|
||||
|
||||
acm_b_->SetReceiveCodecs({{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
acm_b_->SetCodecs({{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
|
||||
// Create and connect the channel
|
||||
channel_a_to_b_ = new TestPack;
|
||||
@ -158,113 +154,113 @@ void TestAllCodecs::Perform() {
|
||||
test_count_++;
|
||||
OpenOutFile(test_count_);
|
||||
char codec_g722[] = "G722";
|
||||
RegisterSendCodec('A', codec_g722, 16000, 64000, 160, 0);
|
||||
RegisterSendCodec(codec_g722, 16000, 64000, 160, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_g722, 16000, 64000, 320, 0);
|
||||
RegisterSendCodec(codec_g722, 16000, 64000, 320, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_g722, 16000, 64000, 480, 0);
|
||||
RegisterSendCodec(codec_g722, 16000, 64000, 480, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_g722, 16000, 64000, 640, 0);
|
||||
RegisterSendCodec(codec_g722, 16000, 64000, 640, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_g722, 16000, 64000, 800, 0);
|
||||
RegisterSendCodec(codec_g722, 16000, 64000, 800, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_g722, 16000, 64000, 960, 0);
|
||||
RegisterSendCodec(codec_g722, 16000, 64000, 960, 0);
|
||||
Run(channel_a_to_b_);
|
||||
outfile_b_.Close();
|
||||
#ifdef WEBRTC_CODEC_ILBC
|
||||
test_count_++;
|
||||
OpenOutFile(test_count_);
|
||||
char codec_ilbc[] = "ILBC";
|
||||
RegisterSendCodec('A', codec_ilbc, 8000, 13300, 240, 0);
|
||||
RegisterSendCodec(codec_ilbc, 8000, 13300, 240, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_ilbc, 8000, 13300, 480, 0);
|
||||
RegisterSendCodec(codec_ilbc, 8000, 13300, 480, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_ilbc, 8000, 15200, 160, 0);
|
||||
RegisterSendCodec(codec_ilbc, 8000, 15200, 160, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_ilbc, 8000, 15200, 320, 0);
|
||||
RegisterSendCodec(codec_ilbc, 8000, 15200, 320, 0);
|
||||
Run(channel_a_to_b_);
|
||||
outfile_b_.Close();
|
||||
#endif
|
||||
test_count_++;
|
||||
OpenOutFile(test_count_);
|
||||
char codec_l16[] = "L16";
|
||||
RegisterSendCodec('A', codec_l16, 8000, 128000, 80, 0);
|
||||
RegisterSendCodec(codec_l16, 8000, 128000, 80, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_l16, 8000, 128000, 160, 0);
|
||||
RegisterSendCodec(codec_l16, 8000, 128000, 160, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_l16, 8000, 128000, 240, 0);
|
||||
RegisterSendCodec(codec_l16, 8000, 128000, 240, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_l16, 8000, 128000, 320, 0);
|
||||
RegisterSendCodec(codec_l16, 8000, 128000, 320, 0);
|
||||
Run(channel_a_to_b_);
|
||||
outfile_b_.Close();
|
||||
|
||||
test_count_++;
|
||||
OpenOutFile(test_count_);
|
||||
RegisterSendCodec('A', codec_l16, 16000, 256000, 160, 0);
|
||||
RegisterSendCodec(codec_l16, 16000, 256000, 160, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_l16, 16000, 256000, 320, 0);
|
||||
RegisterSendCodec(codec_l16, 16000, 256000, 320, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_l16, 16000, 256000, 480, 0);
|
||||
RegisterSendCodec(codec_l16, 16000, 256000, 480, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_l16, 16000, 256000, 640, 0);
|
||||
RegisterSendCodec(codec_l16, 16000, 256000, 640, 0);
|
||||
Run(channel_a_to_b_);
|
||||
outfile_b_.Close();
|
||||
|
||||
test_count_++;
|
||||
OpenOutFile(test_count_);
|
||||
RegisterSendCodec('A', codec_l16, 32000, 512000, 320, 0);
|
||||
RegisterSendCodec(codec_l16, 32000, 512000, 320, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_l16, 32000, 512000, 640, 0);
|
||||
RegisterSendCodec(codec_l16, 32000, 512000, 640, 0);
|
||||
Run(channel_a_to_b_);
|
||||
outfile_b_.Close();
|
||||
|
||||
test_count_++;
|
||||
OpenOutFile(test_count_);
|
||||
char codec_pcma[] = "PCMA";
|
||||
RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, 0);
|
||||
RegisterSendCodec(codec_pcma, 8000, 64000, 80, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcma, 8000, 64000, 160, 0);
|
||||
RegisterSendCodec(codec_pcma, 8000, 64000, 160, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcma, 8000, 64000, 240, 0);
|
||||
RegisterSendCodec(codec_pcma, 8000, 64000, 240, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcma, 8000, 64000, 320, 0);
|
||||
RegisterSendCodec(codec_pcma, 8000, 64000, 320, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcma, 8000, 64000, 400, 0);
|
||||
RegisterSendCodec(codec_pcma, 8000, 64000, 400, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcma, 8000, 64000, 480, 0);
|
||||
RegisterSendCodec(codec_pcma, 8000, 64000, 480, 0);
|
||||
Run(channel_a_to_b_);
|
||||
|
||||
char codec_pcmu[] = "PCMU";
|
||||
RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, 0);
|
||||
RegisterSendCodec(codec_pcmu, 8000, 64000, 80, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcmu, 8000, 64000, 160, 0);
|
||||
RegisterSendCodec(codec_pcmu, 8000, 64000, 160, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcmu, 8000, 64000, 240, 0);
|
||||
RegisterSendCodec(codec_pcmu, 8000, 64000, 240, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcmu, 8000, 64000, 320, 0);
|
||||
RegisterSendCodec(codec_pcmu, 8000, 64000, 320, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcmu, 8000, 64000, 400, 0);
|
||||
RegisterSendCodec(codec_pcmu, 8000, 64000, 400, 0);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_pcmu, 8000, 64000, 480, 0);
|
||||
RegisterSendCodec(codec_pcmu, 8000, 64000, 480, 0);
|
||||
Run(channel_a_to_b_);
|
||||
outfile_b_.Close();
|
||||
#ifdef WEBRTC_CODEC_OPUS
|
||||
test_count_++;
|
||||
OpenOutFile(test_count_);
|
||||
char codec_opus[] = "OPUS";
|
||||
RegisterSendCodec('A', codec_opus, 48000, 6000, 480, kVariableSize);
|
||||
RegisterSendCodec(codec_opus, 48000, 6000, 480, kVariableSize);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_opus, 48000, 20000, 480 * 2, kVariableSize);
|
||||
RegisterSendCodec(codec_opus, 48000, 20000, 480 * 2, kVariableSize);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_opus, 48000, 32000, 480 * 4, kVariableSize);
|
||||
RegisterSendCodec(codec_opus, 48000, 32000, 480 * 4, kVariableSize);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_opus, 48000, 48000, 480, kVariableSize);
|
||||
RegisterSendCodec(codec_opus, 48000, 48000, 480, kVariableSize);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_opus, 48000, 64000, 480 * 4, kVariableSize);
|
||||
RegisterSendCodec(codec_opus, 48000, 64000, 480 * 4, kVariableSize);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_opus, 48000, 96000, 480 * 6, kVariableSize);
|
||||
RegisterSendCodec(codec_opus, 48000, 96000, 480 * 6, kVariableSize);
|
||||
Run(channel_a_to_b_);
|
||||
RegisterSendCodec('A', codec_opus, 48000, 500000, 480 * 2, kVariableSize);
|
||||
RegisterSendCodec(codec_opus, 48000, 500000, 480 * 2, kVariableSize);
|
||||
Run(channel_a_to_b_);
|
||||
outfile_b_.Close();
|
||||
#endif
|
||||
@ -272,8 +268,7 @@ void TestAllCodecs::Perform() {
|
||||
|
||||
// Register Codec to use in the test
|
||||
//
|
||||
// Input: side - which ACM to use, 'A' or 'B'
|
||||
// codec_name - name to use when register the codec
|
||||
// Input: codec_name - name to use when register the codec
|
||||
// sampling_freq_hz - sampling frequency in Herz
|
||||
// rate - bitrate in bytes
|
||||
// packet_size - packet size in samples
|
||||
@ -281,8 +276,7 @@ void TestAllCodecs::Perform() {
|
||||
// used when registering, can be an internal header
|
||||
// set to kVariableSize if the codec is a variable
|
||||
// rate codec
|
||||
void TestAllCodecs::RegisterSendCodec(char side,
|
||||
char* codec_name,
|
||||
void TestAllCodecs::RegisterSendCodec(char* codec_name,
|
||||
int32_t sampling_freq_hz,
|
||||
int rate,
|
||||
int packet_size,
|
||||
@ -316,29 +310,12 @@ void TestAllCodecs::RegisterSendCodec(char side,
|
||||
packet_size_bytes_ = kVariableSize;
|
||||
}
|
||||
|
||||
// Set pointer to the ACM where to register the codec.
|
||||
AudioCodingModule* my_acm = NULL;
|
||||
switch (side) {
|
||||
case 'A': {
|
||||
my_acm = acm_a_.get();
|
||||
break;
|
||||
}
|
||||
case 'B': {
|
||||
my_acm = acm_b_.get();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(my_acm != NULL);
|
||||
|
||||
auto factory = CreateBuiltinAudioEncoderFactory();
|
||||
constexpr int payload_type = 17;
|
||||
SdpAudioFormat format = {codec_name, clockrate_hz, num_channels};
|
||||
format.parameters["ptime"] = rtc::ToString(rtc::CheckedDivExact(
|
||||
packet_size, rtc::CheckedDivExact(sampling_freq_hz, 1000)));
|
||||
my_acm->SetEncoder(
|
||||
acm_a_->SetEncoder(
|
||||
factory->MakeAudioEncoder(payload_type, format, absl::nullopt));
|
||||
}
|
||||
|
||||
@ -381,7 +358,7 @@ void TestAllCodecs::Run(TestPack* channel) {
|
||||
|
||||
// Run received side of ACM.
|
||||
bool muted;
|
||||
CHECK_ERROR(acm_b_->PlayoutData10Ms(out_freq_hz, &audio_frame, &muted));
|
||||
CHECK_ERROR(acm_b_->GetAudio(out_freq_hz, &audio_frame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
|
||||
// Write output speech to file.
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module.h"
|
||||
#include "modules/audio_coding/test/PCMFile.h"
|
||||
|
||||
@ -23,7 +24,7 @@ class TestPack : public AudioPacketizationCallback {
|
||||
TestPack();
|
||||
~TestPack();
|
||||
|
||||
void RegisterReceiverACM(AudioCodingModule* acm);
|
||||
void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
|
||||
|
||||
int32_t SendData(AudioFrameType frame_type,
|
||||
uint8_t payload_type,
|
||||
@ -37,7 +38,7 @@ class TestPack : public AudioPacketizationCallback {
|
||||
void reset_payload_size();
|
||||
|
||||
private:
|
||||
AudioCodingModule* receiver_acm_;
|
||||
acm2::AcmReceiver* receiver_acm_;
|
||||
uint16_t sequence_number_;
|
||||
uint8_t payload_data_[60 * 32 * 2 * 2];
|
||||
uint32_t timestamp_diff_;
|
||||
@ -58,8 +59,7 @@ class TestAllCodecs {
|
||||
// codec name, and a sampling frequency matching is not required.
|
||||
// This is useful for codecs which support several sampling frequency.
|
||||
// Note! Only mono mode is tested in this test.
|
||||
void RegisterSendCodec(char side,
|
||||
char* codec_name,
|
||||
void RegisterSendCodec(char* codec_name,
|
||||
int32_t sampling_freq_hz,
|
||||
int rate,
|
||||
int packet_size,
|
||||
@ -69,7 +69,7 @@ class TestAllCodecs {
|
||||
void OpenOutFile(int test_number);
|
||||
|
||||
std::unique_ptr<AudioCodingModule> acm_a_;
|
||||
std::unique_ptr<AudioCodingModule> acm_b_;
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_b_;
|
||||
TestPack* channel_a_to_b_;
|
||||
PCMFile infile_a_;
|
||||
PCMFile outfile_b_;
|
||||
|
||||
@ -42,10 +42,9 @@ TestRedFec::TestRedFec()
|
||||
AudioDecoderG722,
|
||||
AudioDecoderL16,
|
||||
AudioDecoderOpus>()),
|
||||
_acmA(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(decoder_factory_))),
|
||||
_acmB(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(decoder_factory_))),
|
||||
_acmA(AudioCodingModule::Create()),
|
||||
_acm_receiver(std::make_unique<acm2::AcmReceiver>(
|
||||
acm2::AcmReceiver::Config(decoder_factory_))),
|
||||
_channelA2B(NULL),
|
||||
_testCntr(0) {}
|
||||
|
||||
@ -61,13 +60,10 @@ void TestRedFec::Perform() {
|
||||
webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
|
||||
_inFileA.Open(file_name, 32000, "rb");
|
||||
|
||||
ASSERT_EQ(0, _acmA->InitializeReceiver());
|
||||
ASSERT_EQ(0, _acmB->InitializeReceiver());
|
||||
|
||||
// Create and connect the channel
|
||||
_channelA2B = new Channel;
|
||||
_acmA->RegisterTransportCallback(_channelA2B);
|
||||
_channelA2B->RegisterReceiverACM(_acmB.get());
|
||||
_channelA2B->RegisterReceiverACM(_acm_receiver.get());
|
||||
|
||||
RegisterSendCodec(_acmA, {"L16", 8000, 1}, Vad::kVadAggressive, true);
|
||||
|
||||
@ -136,7 +132,6 @@ void TestRedFec::RegisterSendCodec(
|
||||
absl::optional<Vad::Aggressiveness> vad_mode,
|
||||
bool use_red) {
|
||||
constexpr int payload_type = 17, cn_payload_type = 27, red_payload_type = 37;
|
||||
const auto& other_acm = &acm == &_acmA ? _acmB : _acmA;
|
||||
|
||||
auto encoder = encoder_factory_->MakeAudioEncoder(payload_type, codec_format,
|
||||
absl::nullopt);
|
||||
@ -165,7 +160,7 @@ void TestRedFec::RegisterSendCodec(
|
||||
}
|
||||
}
|
||||
acm->SetEncoder(std::move(encoder));
|
||||
other_acm->SetReceiveCodecs(receive_codecs);
|
||||
_acm_receiver->SetCodecs(receive_codecs);
|
||||
}
|
||||
|
||||
void TestRedFec::Run() {
|
||||
@ -180,7 +175,7 @@ void TestRedFec::Run() {
|
||||
EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
|
||||
EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
|
||||
bool muted;
|
||||
EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
|
||||
EXPECT_EQ(0, _acm_receiver->GetAudio(outFreqHzB, &audioFrame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
_outFileB.Write10MsData(audioFrame.data(), audioFrame.samples_per_channel_);
|
||||
}
|
||||
|
||||
@ -17,13 +17,14 @@
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
#include "api/audio_codecs/audio_encoder_factory.h"
|
||||
#include "common_audio/vad/include/vad.h"
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/test/Channel.h"
|
||||
#include "modules/audio_coding/test/PCMFile.h"
|
||||
#include "test/scoped_key_value_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class TestRedFec {
|
||||
class TestRedFec final {
|
||||
public:
|
||||
explicit TestRedFec();
|
||||
~TestRedFec();
|
||||
@ -42,7 +43,7 @@ class TestRedFec {
|
||||
const rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
|
||||
const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
|
||||
std::unique_ptr<AudioCodingModule> _acmA;
|
||||
std::unique_ptr<AudioCodingModule> _acmB;
|
||||
std::unique_ptr<acm2::AcmReceiver> _acm_receiver;
|
||||
|
||||
Channel* _channelA2B;
|
||||
|
||||
|
||||
@ -35,8 +35,8 @@ TestPackStereo::TestPackStereo()
|
||||
|
||||
TestPackStereo::~TestPackStereo() {}
|
||||
|
||||
void TestPackStereo::RegisterReceiverACM(AudioCodingModule* acm) {
|
||||
receiver_acm_ = acm;
|
||||
void TestPackStereo::RegisterReceiverACM(acm2::AcmReceiver* acm_receiver) {
|
||||
receiver_acm_ = acm_receiver;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -60,8 +60,8 @@ int32_t TestPackStereo::SendData(const AudioFrameType frame_type,
|
||||
}
|
||||
|
||||
if (lost_packet_ == false) {
|
||||
status =
|
||||
receiver_acm_->IncomingPacket(payload_data, payload_size, rtp_header);
|
||||
status = receiver_acm_->InsertPacket(
|
||||
rtp_header, rtc::ArrayView<const uint8_t>(payload_data, payload_size));
|
||||
|
||||
if (frame_type != AudioFrameType::kAudioFrameCN) {
|
||||
payload_size_ = static_cast<int>(payload_size);
|
||||
@ -97,10 +97,9 @@ void TestPackStereo::set_lost_packet(bool lost) {
|
||||
}
|
||||
|
||||
TestStereo::TestStereo()
|
||||
: acm_a_(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
acm_b_(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
: acm_a_(AudioCodingModule::Create()),
|
||||
acm_b_(std::make_unique<acm2::AcmReceiver>(
|
||||
acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
channel_a2b_(NULL),
|
||||
test_cntr_(0),
|
||||
pack_size_samp_(0),
|
||||
@ -134,28 +133,27 @@ void TestStereo::Perform() {
|
||||
|
||||
// Create and initialize two ACMs, one for each side of a one-to-one call.
|
||||
ASSERT_TRUE((acm_a_.get() != NULL) && (acm_b_.get() != NULL));
|
||||
EXPECT_EQ(0, acm_a_->InitializeReceiver());
|
||||
EXPECT_EQ(0, acm_b_->InitializeReceiver());
|
||||
acm_b_->FlushBuffers();
|
||||
|
||||
acm_b_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
|
||||
{104, {"ISAC", 32000, 1}},
|
||||
{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
acm_b_->SetCodecs({{103, {"ISAC", 16000, 1}},
|
||||
{104, {"ISAC", 32000, 1}},
|
||||
{107, {"L16", 8000, 1}},
|
||||
{108, {"L16", 16000, 1}},
|
||||
{109, {"L16", 32000, 1}},
|
||||
{111, {"L16", 8000, 2}},
|
||||
{112, {"L16", 16000, 2}},
|
||||
{113, {"L16", 32000, 2}},
|
||||
{0, {"PCMU", 8000, 1}},
|
||||
{110, {"PCMU", 8000, 2}},
|
||||
{8, {"PCMA", 8000, 1}},
|
||||
{118, {"PCMA", 8000, 2}},
|
||||
{102, {"ILBC", 8000, 1}},
|
||||
{9, {"G722", 8000, 1}},
|
||||
{119, {"G722", 8000, 2}},
|
||||
{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
|
||||
{13, {"CN", 8000, 1}},
|
||||
{98, {"CN", 16000, 1}},
|
||||
{99, {"CN", 32000, 1}}});
|
||||
|
||||
// Create and connect the channel.
|
||||
channel_a2b_ = new TestPackStereo;
|
||||
@ -389,7 +387,7 @@ void TestStereo::Perform() {
|
||||
OpenOutFile(test_cntr_);
|
||||
// Encode and decode in mono.
|
||||
RegisterSendCodec('A', codec_opus, 48000, 32000, 960, codec_channels);
|
||||
acm_b_->SetReceiveCodecs({{120, {"OPUS", 48000, 2}}});
|
||||
acm_b_->SetCodecs({{120, {"OPUS", 48000, 2}}});
|
||||
Run(channel_a2b_, audio_channels, codec_channels);
|
||||
|
||||
// Encode in stereo, decode in mono.
|
||||
@ -408,13 +406,13 @@ void TestStereo::Perform() {
|
||||
// Decode in stereo.
|
||||
test_cntr_++;
|
||||
OpenOutFile(test_cntr_);
|
||||
acm_b_->SetReceiveCodecs({{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
|
||||
acm_b_->SetCodecs({{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
|
||||
Run(channel_a2b_, audio_channels, 2);
|
||||
out_file_.Close();
|
||||
// Decode in mono.
|
||||
test_cntr_++;
|
||||
OpenOutFile(test_cntr_);
|
||||
acm_b_->SetReceiveCodecs({{120, {"OPUS", 48000, 2}}});
|
||||
acm_b_->SetCodecs({{120, {"OPUS", 48000, 2}}});
|
||||
Run(channel_a2b_, audio_channels, codec_channels);
|
||||
out_file_.Close();
|
||||
#endif
|
||||
@ -455,7 +453,9 @@ void TestStereo::RegisterSendCodec(char side,
|
||||
break;
|
||||
}
|
||||
case 'B': {
|
||||
my_acm = acm_b_.get();
|
||||
// We no longer use this case. Refactor code to avoid the switch.
|
||||
ASSERT_TRUE(false);
|
||||
// my_acm = acm_b_.get();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -559,7 +559,7 @@ void TestStereo::Run(TestPackStereo* channel,
|
||||
|
||||
// Run receive side of ACM
|
||||
bool muted;
|
||||
EXPECT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame, &muted));
|
||||
EXPECT_EQ(0, acm_b_->GetAudio(out_freq_hz_b, &audio_frame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
|
||||
// Write output speech to file
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module.h"
|
||||
#include "modules/audio_coding/test/PCMFile.h"
|
||||
|
||||
@ -29,7 +30,7 @@ class TestPackStereo : public AudioPacketizationCallback {
|
||||
TestPackStereo();
|
||||
~TestPackStereo();
|
||||
|
||||
void RegisterReceiverACM(AudioCodingModule* acm);
|
||||
void RegisterReceiverACM(acm2::AcmReceiver* acm_receiver);
|
||||
|
||||
int32_t SendData(AudioFrameType frame_type,
|
||||
uint8_t payload_type,
|
||||
@ -45,7 +46,7 @@ class TestPackStereo : public AudioPacketizationCallback {
|
||||
void set_lost_packet(bool lost);
|
||||
|
||||
private:
|
||||
AudioCodingModule* receiver_acm_;
|
||||
acm2::AcmReceiver* receiver_acm_;
|
||||
int16_t seq_no_;
|
||||
uint32_t timestamp_diff_;
|
||||
uint32_t last_in_timestamp_;
|
||||
@ -81,7 +82,7 @@ class TestStereo {
|
||||
void OpenOutFile(int16_t test_number);
|
||||
|
||||
std::unique_ptr<AudioCodingModule> acm_a_;
|
||||
std::unique_ptr<AudioCodingModule> acm_b_;
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_b_;
|
||||
|
||||
TestPackStereo* channel_a2b_;
|
||||
|
||||
|
||||
@ -70,10 +70,9 @@ TestVadDtx::TestVadDtx()
|
||||
CreateAudioEncoderFactory<AudioEncoderIlbc, AudioEncoderOpus>()),
|
||||
decoder_factory_(
|
||||
CreateAudioDecoderFactory<AudioDecoderIlbc, AudioDecoderOpus>()),
|
||||
acm_send_(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(decoder_factory_))),
|
||||
acm_receive_(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(decoder_factory_))),
|
||||
acm_send_(AudioCodingModule::Create()),
|
||||
acm_receive_(std::make_unique<acm2::AcmReceiver>(
|
||||
acm2::AcmReceiver::Config(decoder_factory_))),
|
||||
channel_(std::make_unique<Channel>()),
|
||||
packetization_callback_(
|
||||
std::make_unique<MonitoringAudioPacketizationCallback>(
|
||||
@ -104,7 +103,7 @@ bool TestVadDtx::RegisterCodec(const SdpAudioFormat& codec_format,
|
||||
acm_send_->SetEncoder(std::move(encoder));
|
||||
|
||||
std::map<int, SdpAudioFormat> receive_codecs = {{payload_type, codec_format}};
|
||||
acm_receive_->SetReceiveCodecs(receive_codecs);
|
||||
acm_receive_->SetCodecs(receive_codecs);
|
||||
|
||||
return added_comfort_noise;
|
||||
}
|
||||
@ -143,7 +142,7 @@ void TestVadDtx::Run(absl::string_view in_filename,
|
||||
time_stamp_ += frame_size_samples;
|
||||
EXPECT_GE(acm_send_->Add10MsData(audio_frame), 0);
|
||||
bool muted;
|
||||
acm_receive_->PlayoutData10Ms(kOutputFreqHz, &audio_frame, &muted);
|
||||
acm_receive_->GetAudio(kOutputFreqHz, &audio_frame, &muted);
|
||||
ASSERT_FALSE(muted);
|
||||
out_file.Write10MsData(audio_frame);
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
#include "api/audio_codecs/audio_encoder_factory.h"
|
||||
#include "common_audio/vad/include/vad.h"
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
|
||||
#include "modules/audio_coding/test/Channel.h"
|
||||
@ -84,7 +85,7 @@ class TestVadDtx {
|
||||
const rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
|
||||
const rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
|
||||
std::unique_ptr<AudioCodingModule> acm_send_;
|
||||
std::unique_ptr<AudioCodingModule> acm_receive_;
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_receive_;
|
||||
std::unique_ptr<Channel> channel_;
|
||||
std::unique_ptr<MonitoringAudioPacketizationCallback> packetization_callback_;
|
||||
uint32_t time_stamp_ = 0x12345678;
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#include "modules/audio_coding/test/TestRedFec.h"
|
||||
#include "modules/audio_coding/test/TestStereo.h"
|
||||
#include "modules/audio_coding/test/TestVADDTX.h"
|
||||
#include "modules/audio_coding/test/TwoWayCommunication.h"
|
||||
#include "modules/audio_coding/test/opus_test.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/testsupport/file_utils.h"
|
||||
|
||||
@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 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 "TwoWayCommunication.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
|
||||
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
|
||||
#include "modules/audio_coding/test/PCMFile.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/testsupport/file_utils.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
#define MAX_FILE_NAME_LENGTH_BYTE 500
|
||||
|
||||
TwoWayCommunication::TwoWayCommunication()
|
||||
: _acmA(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
_acmRefA(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {
|
||||
AudioCodingModule::Config config;
|
||||
// The clicks will be more obvious if time-stretching is not allowed.
|
||||
// TODO(henrik.lundin) Really?
|
||||
config.neteq_config.for_test_no_time_stretching = true;
|
||||
config.decoder_factory = CreateBuiltinAudioDecoderFactory();
|
||||
_acmB.reset(AudioCodingModule::Create(config));
|
||||
_acmRefB.reset(AudioCodingModule::Create(config));
|
||||
}
|
||||
|
||||
TwoWayCommunication::~TwoWayCommunication() {
|
||||
delete _channel_A2B;
|
||||
delete _channel_B2A;
|
||||
delete _channelRef_A2B;
|
||||
delete _channelRef_B2A;
|
||||
_inFileA.Close();
|
||||
_inFileB.Close();
|
||||
_outFileA.Close();
|
||||
_outFileB.Close();
|
||||
_outFileRefA.Close();
|
||||
_outFileRefB.Close();
|
||||
}
|
||||
|
||||
void TwoWayCommunication::SetUpAutotest(
|
||||
AudioEncoderFactory* const encoder_factory,
|
||||
const SdpAudioFormat& format1,
|
||||
const int payload_type1,
|
||||
const SdpAudioFormat& format2,
|
||||
const int payload_type2) {
|
||||
//--- Set A codecs
|
||||
_acmA->SetEncoder(
|
||||
encoder_factory->MakeAudioEncoder(payload_type1, format1, absl::nullopt));
|
||||
_acmA->SetReceiveCodecs({{payload_type2, format2}});
|
||||
|
||||
//--- Set ref-A codecs
|
||||
_acmRefA->SetEncoder(
|
||||
encoder_factory->MakeAudioEncoder(payload_type1, format1, absl::nullopt));
|
||||
_acmRefA->SetReceiveCodecs({{payload_type2, format2}});
|
||||
|
||||
//--- Set B codecs
|
||||
_acmB->SetEncoder(
|
||||
encoder_factory->MakeAudioEncoder(payload_type2, format2, absl::nullopt));
|
||||
_acmB->SetReceiveCodecs({{payload_type1, format1}});
|
||||
|
||||
//--- Set ref-B codecs
|
||||
_acmRefB->SetEncoder(
|
||||
encoder_factory->MakeAudioEncoder(payload_type2, format2, absl::nullopt));
|
||||
_acmRefB->SetReceiveCodecs({{payload_type1, format1}});
|
||||
|
||||
uint16_t frequencyHz;
|
||||
|
||||
//--- Input A and B
|
||||
std::string in_file_name =
|
||||
webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
|
||||
frequencyHz = 16000;
|
||||
_inFileA.Open(in_file_name, frequencyHz, "rb");
|
||||
_inFileB.Open(in_file_name, frequencyHz, "rb");
|
||||
|
||||
//--- Output A
|
||||
std::string output_file_a = webrtc::test::OutputPath() + "outAutotestA.pcm";
|
||||
frequencyHz = 16000;
|
||||
_outFileA.Open(output_file_a, frequencyHz, "wb");
|
||||
std::string output_ref_file_a =
|
||||
webrtc::test::OutputPath() + "ref_outAutotestA.pcm";
|
||||
_outFileRefA.Open(output_ref_file_a, frequencyHz, "wb");
|
||||
|
||||
//--- Output B
|
||||
std::string output_file_b = webrtc::test::OutputPath() + "outAutotestB.pcm";
|
||||
frequencyHz = 16000;
|
||||
_outFileB.Open(output_file_b, frequencyHz, "wb");
|
||||
std::string output_ref_file_b =
|
||||
webrtc::test::OutputPath() + "ref_outAutotestB.pcm";
|
||||
_outFileRefB.Open(output_ref_file_b, frequencyHz, "wb");
|
||||
|
||||
//--- Set A-to-B channel
|
||||
_channel_A2B = new Channel;
|
||||
_acmA->RegisterTransportCallback(_channel_A2B);
|
||||
_channel_A2B->RegisterReceiverACM(_acmB.get());
|
||||
//--- Do the same for the reference
|
||||
_channelRef_A2B = new Channel;
|
||||
_acmRefA->RegisterTransportCallback(_channelRef_A2B);
|
||||
_channelRef_A2B->RegisterReceiverACM(_acmRefB.get());
|
||||
|
||||
//--- Set B-to-A channel
|
||||
_channel_B2A = new Channel;
|
||||
_acmB->RegisterTransportCallback(_channel_B2A);
|
||||
_channel_B2A->RegisterReceiverACM(_acmA.get());
|
||||
//--- Do the same for reference
|
||||
_channelRef_B2A = new Channel;
|
||||
_acmRefB->RegisterTransportCallback(_channelRef_B2A);
|
||||
_channelRef_B2A->RegisterReceiverACM(_acmRefA.get());
|
||||
}
|
||||
|
||||
void TwoWayCommunication::Perform() {
|
||||
const SdpAudioFormat format1("ISAC", 16000, 1);
|
||||
const SdpAudioFormat format2("L16", 8000, 1);
|
||||
constexpr int payload_type1 = 17, payload_type2 = 18;
|
||||
|
||||
auto encoder_factory = CreateBuiltinAudioEncoderFactory();
|
||||
|
||||
SetUpAutotest(encoder_factory.get(), format1, payload_type1, format2,
|
||||
payload_type2);
|
||||
|
||||
unsigned int msecPassed = 0;
|
||||
unsigned int secPassed = 0;
|
||||
|
||||
int32_t outFreqHzA = _outFileA.SamplingFrequency();
|
||||
int32_t outFreqHzB = _outFileB.SamplingFrequency();
|
||||
|
||||
AudioFrame audioFrame;
|
||||
|
||||
// In the following loop we tests that the code can handle misuse of the APIs.
|
||||
// In the middle of a session with data flowing between two sides, called A
|
||||
// and B, APIs will be called, and the code should continue to run, and be
|
||||
// able to recover.
|
||||
while (!_inFileA.EndOfFile() && !_inFileB.EndOfFile()) {
|
||||
msecPassed += 10;
|
||||
EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
|
||||
EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
|
||||
EXPECT_GE(_acmRefA->Add10MsData(audioFrame), 0);
|
||||
|
||||
EXPECT_GT(_inFileB.Read10MsData(audioFrame), 0);
|
||||
|
||||
EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
|
||||
EXPECT_GE(_acmRefB->Add10MsData(audioFrame), 0);
|
||||
bool muted;
|
||||
EXPECT_EQ(0, _acmA->PlayoutData10Ms(outFreqHzA, &audioFrame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
_outFileA.Write10MsData(audioFrame);
|
||||
EXPECT_EQ(0, _acmRefA->PlayoutData10Ms(outFreqHzA, &audioFrame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
_outFileRefA.Write10MsData(audioFrame);
|
||||
EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
_outFileB.Write10MsData(audioFrame);
|
||||
EXPECT_EQ(0, _acmRefB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
_outFileRefB.Write10MsData(audioFrame);
|
||||
|
||||
// Update time counters each time a second of data has passed.
|
||||
if (msecPassed >= 1000) {
|
||||
msecPassed = 0;
|
||||
secPassed++;
|
||||
}
|
||||
// Re-register send codec on side B.
|
||||
if (((secPassed % 5) == 4) && (msecPassed >= 990)) {
|
||||
_acmB->SetEncoder(encoder_factory->MakeAudioEncoder(
|
||||
payload_type2, format2, absl::nullopt));
|
||||
}
|
||||
// Initialize receiver on side A.
|
||||
if (((secPassed % 7) == 6) && (msecPassed == 0))
|
||||
EXPECT_EQ(0, _acmA->InitializeReceiver());
|
||||
// Re-register codec on side A.
|
||||
if (((secPassed % 7) == 6) && (msecPassed >= 990)) {
|
||||
_acmA->SetReceiveCodecs({{payload_type2, format2}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 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 MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_
|
||||
#define MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/audio_codecs/audio_encoder_factory.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "modules/audio_coding/include/audio_coding_module.h"
|
||||
#include "modules/audio_coding/test/Channel.h"
|
||||
#include "modules/audio_coding/test/PCMFile.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class TwoWayCommunication {
|
||||
public:
|
||||
TwoWayCommunication();
|
||||
~TwoWayCommunication();
|
||||
|
||||
void Perform();
|
||||
|
||||
private:
|
||||
void SetUpAutotest(AudioEncoderFactory* const encoder_factory,
|
||||
const SdpAudioFormat& format1,
|
||||
int payload_type1,
|
||||
const SdpAudioFormat& format2,
|
||||
int payload_type2);
|
||||
|
||||
std::unique_ptr<AudioCodingModule> _acmA;
|
||||
std::unique_ptr<AudioCodingModule> _acmB;
|
||||
|
||||
std::unique_ptr<AudioCodingModule> _acmRefA;
|
||||
std::unique_ptr<AudioCodingModule> _acmRefB;
|
||||
|
||||
Channel* _channel_A2B;
|
||||
Channel* _channel_B2A;
|
||||
|
||||
Channel* _channelRef_A2B;
|
||||
Channel* _channelRef_B2A;
|
||||
|
||||
PCMFile _inFileA;
|
||||
PCMFile _inFileB;
|
||||
|
||||
PCMFile _outFileA;
|
||||
PCMFile _outFileB;
|
||||
|
||||
PCMFile _outFileRefA;
|
||||
PCMFile _outFileRefB;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_
|
||||
@ -22,8 +22,8 @@
|
||||
namespace webrtc {
|
||||
|
||||
OpusTest::OpusTest()
|
||||
: acm_receiver_(AudioCodingModule::Create(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
: acm_receiver_(std::make_unique<acm2::AcmReceiver>(
|
||||
acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory()))),
|
||||
channel_a2b_(NULL),
|
||||
counter_(0),
|
||||
payload_type_(255),
|
||||
@ -83,13 +83,13 @@ void OpusTest::Perform() {
|
||||
WebRtcOpus_DecoderInit(opus_stereo_decoder_);
|
||||
|
||||
ASSERT_TRUE(acm_receiver_.get() != NULL);
|
||||
EXPECT_EQ(0, acm_receiver_->InitializeReceiver());
|
||||
acm_receiver_->FlushBuffers();
|
||||
|
||||
// Register Opus stereo as receiving codec.
|
||||
constexpr int kOpusPayloadType = 120;
|
||||
const SdpAudioFormat kOpusFormatStereo("opus", 48000, 2, {{"stereo", "1"}});
|
||||
payload_type_ = kOpusPayloadType;
|
||||
acm_receiver_->SetReceiveCodecs({{kOpusPayloadType, kOpusFormatStereo}});
|
||||
acm_receiver_->SetCodecs({{kOpusPayloadType, kOpusFormatStereo}});
|
||||
|
||||
// Create and connect the channel.
|
||||
channel_a2b_ = new TestPackStereo;
|
||||
@ -154,7 +154,7 @@ void OpusTest::Perform() {
|
||||
|
||||
// Register Opus mono as receiving codec.
|
||||
const SdpAudioFormat kOpusFormatMono("opus", 48000, 2);
|
||||
acm_receiver_->SetReceiveCodecs({{kOpusPayloadType, kOpusFormatMono}});
|
||||
acm_receiver_->SetCodecs({{kOpusPayloadType, kOpusFormatMono}});
|
||||
|
||||
// Run Opus with 2.5 ms frame size.
|
||||
Run(channel_a2b_, audio_channels, 32000, 120);
|
||||
@ -353,8 +353,7 @@ void OpusTest::Run(TestPackStereo* channel,
|
||||
|
||||
// Run received side of ACM.
|
||||
bool muted;
|
||||
ASSERT_EQ(
|
||||
0, acm_receiver_->PlayoutData10Ms(out_freq_hz_b, &audio_frame, &muted));
|
||||
ASSERT_EQ(0, acm_receiver_->GetAudio(out_freq_hz_b, &audio_frame, &muted));
|
||||
ASSERT_FALSE(muted);
|
||||
|
||||
// Write output speech to file.
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "modules/audio_coding/acm2/acm_receiver.h"
|
||||
#include "modules/audio_coding/acm2/acm_resampler.h"
|
||||
#include "modules/audio_coding/codecs/opus/opus_interface.h"
|
||||
#include "modules/audio_coding/test/PCMFile.h"
|
||||
@ -38,7 +39,7 @@ class OpusTest {
|
||||
|
||||
void OpenOutFile(int test_number);
|
||||
|
||||
std::unique_ptr<AudioCodingModule> acm_receiver_;
|
||||
std::unique_ptr<acm2::AcmReceiver> acm_receiver_;
|
||||
TestPackStereo* channel_a2b_;
|
||||
PCMFile in_file_stereo_;
|
||||
PCMFile in_file_mono_;
|
||||
|
||||
@ -25,7 +25,7 @@ class TargetDelayTest : public ::testing::Test {
|
||||
protected:
|
||||
TargetDelayTest()
|
||||
: receiver_(
|
||||
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())) {}
|
||||
acm2::AcmReceiver::Config(CreateBuiltinAudioDecoderFactory())) {}
|
||||
|
||||
~TargetDelayTest() {}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user