Removing AudioCoding class, a.k.a the new ACM API
We have decided not to do a switch from old (AudioCodingModule) to new (AudioCoding) API. Instead, we will gradually evolve the old API to meet the new design goals. As a consequence of this decision, the AudioCoding and AudioCodingImpl classes are deleted. Also removing associated unit test sources. No test coverage is lost with this operation, since the tests for the "old" API are testing more than the deleted tests did. BUG=webrtc:3520 Review URL: https://codereview.webrtc.org/1415163002 Cr-Commit-Position: refs/heads/master@{#10406}
This commit is contained in:

committed by
Commit bot

parent
f054819e25
commit
e9eca8f5ae
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_coding/main/acm2/acm_receive_test.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/audio_sink.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
AcmReceiveTest::AcmReceiveTest(PacketSource* packet_source,
|
||||
AudioSink* audio_sink,
|
||||
int output_freq_hz,
|
||||
NumOutputChannels expected_output_channels)
|
||||
: clock_(0),
|
||||
packet_source_(packet_source),
|
||||
audio_sink_(audio_sink),
|
||||
output_freq_hz_(output_freq_hz),
|
||||
expected_output_channels_(expected_output_channels) {
|
||||
webrtc::AudioCoding::Config config;
|
||||
config.clock = &clock_;
|
||||
config.playout_frequency_hz = output_freq_hz_;
|
||||
acm_.reset(webrtc::AudioCoding::Create(config));
|
||||
}
|
||||
|
||||
void AcmReceiveTest::RegisterDefaultCodecs() {
|
||||
#ifdef WEBRTC_CODEC_OPUS
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kOpus, 120));
|
||||
#endif
|
||||
#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISAC, 103));
|
||||
#endif
|
||||
#ifdef WEBRTC_CODEC_ISAC
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISACSWB, 104));
|
||||
#endif
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16B, 107));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bwb, 108));
|
||||
ASSERT_TRUE(
|
||||
acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bswb32kHz, 109));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16B_2ch, 111));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bwb_2ch, 112));
|
||||
ASSERT_TRUE(
|
||||
acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bswb32kHz_2ch, 113));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMU, 0));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMA, 8));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMU_2ch, 110));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMA_2ch, 118));
|
||||
#ifdef WEBRTC_CODEC_ILBC
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kILBC, 102));
|
||||
#endif
|
||||
#ifdef WEBRTC_CODEC_G722
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kG722, 9));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kG722_2ch, 119));
|
||||
#endif
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNNB, 13));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNWB, 98));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNSWB, 99));
|
||||
#ifdef WEBRTC_CODEC_RED
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kRED, 127));
|
||||
#endif
|
||||
}
|
||||
|
||||
void AcmReceiveTest::RegisterNetEqTestCodecs() {
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISAC, 103));
|
||||
#ifndef WEBRTC_ANDROID
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kISACSWB, 104));
|
||||
#endif
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16B, 93));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bwb, 94));
|
||||
ASSERT_TRUE(
|
||||
acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCM16Bswb32kHz, 95));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMU, 0));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kPCMA, 8));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kILBC, 102));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kG722, 9));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNNB, 13));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNWB, 98));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kCNSWB, 99));
|
||||
ASSERT_TRUE(acm_->RegisterReceiveCodec(acm2::ACMCodecDB::kRED, 117));
|
||||
}
|
||||
|
||||
void AcmReceiveTest::Run() {
|
||||
for (rtc::scoped_ptr<Packet> packet(packet_source_->NextPacket()); packet;
|
||||
packet.reset(packet_source_->NextPacket())) {
|
||||
// Pull audio until time to insert packet.
|
||||
while (clock_.TimeInMilliseconds() < packet->time_ms()) {
|
||||
AudioFrame output_frame;
|
||||
EXPECT_TRUE(acm_->Get10MsAudio(&output_frame));
|
||||
EXPECT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
|
||||
const size_t samples_per_block =
|
||||
static_cast<size_t>(output_freq_hz_ * 10 / 1000);
|
||||
EXPECT_EQ(samples_per_block, output_frame.samples_per_channel_);
|
||||
if (expected_output_channels_ != kArbitraryChannels) {
|
||||
if (output_frame.speech_type_ == webrtc::AudioFrame::kPLC) {
|
||||
// Don't check number of channels for PLC output, since each test run
|
||||
// usually starts with a short period of mono PLC before decoding the
|
||||
// first packet.
|
||||
} else {
|
||||
EXPECT_EQ(expected_output_channels_, output_frame.num_channels_);
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(audio_sink_->WriteAudioFrame(output_frame));
|
||||
clock_.AdvanceTimeMilliseconds(10);
|
||||
}
|
||||
|
||||
// Insert packet after converting from RTPHeader to WebRtcRTPHeader.
|
||||
WebRtcRTPHeader header;
|
||||
header.header = packet->header();
|
||||
header.frameType = kAudioFrameSpeech;
|
||||
memset(&header.type.Audio, 0, sizeof(RTPAudioHeader));
|
||||
EXPECT_TRUE(acm_->InsertPacket(packet->payload(),
|
||||
packet->payload_length_bytes(),
|
||||
header))
|
||||
<< "Failure when inserting packet:" << std::endl
|
||||
<< " PT = " << static_cast<int>(header.header.payloadType) << std::endl
|
||||
<< " TS = " << header.header.timestamp << std::endl
|
||||
<< " SN = " << header.header.sequenceNumber;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
class AudioCoding;
|
||||
struct CodecInst;
|
||||
|
||||
namespace test {
|
||||
class AudioSink;
|
||||
class PacketSource;
|
||||
|
||||
class AcmReceiveTest {
|
||||
public:
|
||||
enum NumOutputChannels {
|
||||
kArbitraryChannels = 0,
|
||||
kMonoOutput = 1,
|
||||
kStereoOutput = 2
|
||||
};
|
||||
|
||||
AcmReceiveTest(
|
||||
PacketSource* packet_source,
|
||||
AudioSink* audio_sink,
|
||||
int output_freq_hz,
|
||||
NumOutputChannels expected_output_channels);
|
||||
virtual ~AcmReceiveTest() {}
|
||||
|
||||
// Registers the codecs with default parameters from ACM.
|
||||
void RegisterDefaultCodecs();
|
||||
|
||||
// Registers codecs with payload types matching the pre-encoded NetEq test
|
||||
// files.
|
||||
void RegisterNetEqTestCodecs();
|
||||
|
||||
// Runs the test and returns true if successful.
|
||||
void Run();
|
||||
|
||||
private:
|
||||
SimulatedClock clock_;
|
||||
rtc::scoped_ptr<AudioCoding> acm_;
|
||||
PacketSource* packet_source_;
|
||||
AudioSink* audio_sink_;
|
||||
const int output_freq_hz_;
|
||||
NumOutputChannels expected_output_channels_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AcmReceiveTest);
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_
|
@ -1,370 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h"
|
||||
|
||||
#include <algorithm> // std::min
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
|
||||
#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h"
|
||||
#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
#include "webrtc/test/test_suite.h"
|
||||
#include "webrtc/test/testsupport/fileutils.h"
|
||||
#include "webrtc/test/testsupport/gtest_disable.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace acm2 {
|
||||
namespace {
|
||||
|
||||
bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) {
|
||||
if (strcmp(codec_a.plname, codec_b.plname) != 0 ||
|
||||
codec_a.plfreq != codec_b.plfreq ||
|
||||
codec_a.pltype != codec_b.pltype ||
|
||||
codec_b.channels != codec_a.channels)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class AcmReceiverTest : public AudioPacketizationCallback,
|
||||
public ::testing::Test {
|
||||
protected:
|
||||
AcmReceiverTest()
|
||||
: timestamp_(0),
|
||||
packet_sent_(false),
|
||||
last_packet_send_timestamp_(timestamp_),
|
||||
last_frame_type_(kEmptyFrame) {
|
||||
AudioCoding::Config config;
|
||||
config.transport = this;
|
||||
acm_.reset(new AudioCodingImpl(config));
|
||||
receiver_.reset(new AcmReceiver(config.ToOldConfig()));
|
||||
}
|
||||
|
||||
~AcmReceiverTest() {}
|
||||
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(receiver_.get() != NULL);
|
||||
ASSERT_TRUE(acm_.get() != NULL);
|
||||
for (int n = 0; n < ACMCodecDB::kNumCodecs; n++) {
|
||||
ASSERT_EQ(0, ACMCodecDB::Codec(n, &codecs_[n]));
|
||||
}
|
||||
|
||||
rtp_header_.header.sequenceNumber = 0;
|
||||
rtp_header_.header.timestamp = 0;
|
||||
rtp_header_.header.markerBit = false;
|
||||
rtp_header_.header.ssrc = 0x12345678; // Arbitrary.
|
||||
rtp_header_.header.numCSRCs = 0;
|
||||
rtp_header_.header.payloadType = 0;
|
||||
rtp_header_.frameType = kAudioFrameSpeech;
|
||||
rtp_header_.type.Audio.isCNG = false;
|
||||
}
|
||||
|
||||
void TearDown() override {}
|
||||
|
||||
void InsertOnePacketOfSilence(int codec_id) {
|
||||
CodecInst codec;
|
||||
ACMCodecDB::Codec(codec_id, &codec);
|
||||
if (timestamp_ == 0) { // This is the first time inserting audio.
|
||||
ASSERT_TRUE(acm_->RegisterSendCodec(codec_id, codec.pltype));
|
||||
} else {
|
||||
const CodecInst* current_codec = acm_->GetSenderCodecInst();
|
||||
ASSERT_TRUE(current_codec);
|
||||
if (!CodecsEqual(codec, *current_codec))
|
||||
ASSERT_TRUE(acm_->RegisterSendCodec(codec_id, codec.pltype));
|
||||
}
|
||||
AudioFrame frame;
|
||||
// Frame setup according to the codec.
|
||||
frame.sample_rate_hz_ = codec.plfreq;
|
||||
frame.samples_per_channel_ = codec.plfreq / 100; // 10 ms.
|
||||
frame.num_channels_ = codec.channels;
|
||||
memset(frame.data_, 0, frame.samples_per_channel_ * frame.num_channels_ *
|
||||
sizeof(int16_t));
|
||||
int num_bytes = 0;
|
||||
packet_sent_ = false;
|
||||
last_packet_send_timestamp_ = timestamp_;
|
||||
while (num_bytes == 0) {
|
||||
frame.timestamp_ = timestamp_;
|
||||
timestamp_ += frame.samples_per_channel_;
|
||||
num_bytes = acm_->Add10MsAudio(frame);
|
||||
ASSERT_GE(num_bytes, 0);
|
||||
}
|
||||
ASSERT_TRUE(packet_sent_); // Sanity check.
|
||||
}
|
||||
|
||||
// Last element of id should be negative.
|
||||
void AddSetOfCodecs(const int* id) {
|
||||
int n = 0;
|
||||
while (id[n] >= 0) {
|
||||
ASSERT_EQ(0, receiver_->AddCodec(id[n], codecs_[id[n]].pltype,
|
||||
codecs_[id[n]].channels,
|
||||
codecs_[id[n]].plfreq, NULL));
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t SendData(FrameType frame_type,
|
||||
uint8_t payload_type,
|
||||
uint32_t timestamp,
|
||||
const uint8_t* payload_data,
|
||||
size_t payload_len_bytes,
|
||||
const RTPFragmentationHeader* fragmentation) override {
|
||||
if (frame_type == kEmptyFrame)
|
||||
return 0;
|
||||
|
||||
rtp_header_.header.payloadType = payload_type;
|
||||
rtp_header_.frameType = frame_type;
|
||||
if (frame_type == kAudioFrameSpeech)
|
||||
rtp_header_.type.Audio.isCNG = false;
|
||||
else
|
||||
rtp_header_.type.Audio.isCNG = true;
|
||||
rtp_header_.header.timestamp = timestamp;
|
||||
|
||||
int ret_val = receiver_->InsertPacket(rtp_header_, payload_data,
|
||||
payload_len_bytes);
|
||||
if (ret_val < 0) {
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
rtp_header_.header.sequenceNumber++;
|
||||
packet_sent_ = true;
|
||||
last_frame_type_ = frame_type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rtc::scoped_ptr<AcmReceiver> receiver_;
|
||||
CodecInst codecs_[ACMCodecDB::kMaxNumCodecs];
|
||||
rtc::scoped_ptr<AudioCoding> acm_;
|
||||
WebRtcRTPHeader rtp_header_;
|
||||
uint32_t timestamp_;
|
||||
bool packet_sent_; // Set when SendData is called reset when inserting audio.
|
||||
uint32_t last_packet_send_timestamp_;
|
||||
FrameType last_frame_type_;
|
||||
};
|
||||
|
||||
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecGetCodec)) {
|
||||
// Add codec.
|
||||
for (int n = 0; n < ACMCodecDB::kNumCodecs; ++n) {
|
||||
if (n & 0x1) // Just add codecs with odd index.
|
||||
EXPECT_EQ(0,
|
||||
receiver_->AddCodec(n, codecs_[n].pltype, codecs_[n].channels,
|
||||
codecs_[n].plfreq, NULL));
|
||||
}
|
||||
// Get codec and compare.
|
||||
for (int n = 0; n < ACMCodecDB::kNumCodecs; ++n) {
|
||||
CodecInst my_codec;
|
||||
if (n & 0x1) {
|
||||
// Codecs with odd index should match the reference.
|
||||
EXPECT_EQ(0, receiver_->DecoderByPayloadType(codecs_[n].pltype,
|
||||
&my_codec));
|
||||
EXPECT_TRUE(CodecsEqual(codecs_[n], my_codec));
|
||||
} else {
|
||||
// Codecs with even index are not registered.
|
||||
EXPECT_EQ(-1, receiver_->DecoderByPayloadType(codecs_[n].pltype,
|
||||
&my_codec));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) {
|
||||
const int codec_id = ACMCodecDB::kPCMA;
|
||||
CodecInst ref_codec1;
|
||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id, &ref_codec1));
|
||||
CodecInst ref_codec2 = ref_codec1;
|
||||
++ref_codec2.pltype;
|
||||
CodecInst test_codec;
|
||||
|
||||
// Register the same codec with different payload types.
|
||||
EXPECT_EQ(
|
||||
0, receiver_->AddCodec(codec_id, ref_codec1.pltype, ref_codec1.channels,
|
||||
ref_codec1.plfreq, NULL));
|
||||
EXPECT_EQ(
|
||||
0, receiver_->AddCodec(codec_id, ref_codec2.pltype, ref_codec2.channels,
|
||||
ref_codec2.plfreq, NULL));
|
||||
|
||||
// Both payload types should exist.
|
||||
EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec1.pltype, &test_codec));
|
||||
EXPECT_EQ(true, CodecsEqual(ref_codec1, test_codec));
|
||||
EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec2.pltype, &test_codec));
|
||||
EXPECT_EQ(true, CodecsEqual(ref_codec2, test_codec));
|
||||
}
|
||||
|
||||
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) {
|
||||
const int codec_id1 = ACMCodecDB::kPCMU;
|
||||
CodecInst ref_codec1;
|
||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id1, &ref_codec1));
|
||||
const int codec_id2 = ACMCodecDB::kPCMA;
|
||||
CodecInst ref_codec2;
|
||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id2, &ref_codec2));
|
||||
ref_codec2.pltype = ref_codec1.pltype;
|
||||
CodecInst test_codec;
|
||||
|
||||
// Register the same payload type with different codec ID.
|
||||
EXPECT_EQ(
|
||||
0, receiver_->AddCodec(codec_id1, ref_codec1.pltype, ref_codec1.channels,
|
||||
ref_codec1.plfreq, NULL));
|
||||
EXPECT_EQ(
|
||||
0, receiver_->AddCodec(codec_id2, ref_codec2.pltype, ref_codec2.channels,
|
||||
ref_codec2.plfreq, NULL));
|
||||
|
||||
// Make sure that the last codec is used.
|
||||
EXPECT_EQ(0, receiver_->DecoderByPayloadType(ref_codec2.pltype, &test_codec));
|
||||
EXPECT_EQ(true, CodecsEqual(ref_codec2, test_codec));
|
||||
}
|
||||
|
||||
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) {
|
||||
CodecInst codec;
|
||||
const int codec_id = ACMCodecDB::kPCMA;
|
||||
EXPECT_EQ(0, ACMCodecDB::Codec(codec_id, &codec));
|
||||
const int payload_type = codec.pltype;
|
||||
EXPECT_EQ(0, receiver_->AddCodec(codec_id, codec.pltype, codec.channels,
|
||||
codec.plfreq, NULL));
|
||||
|
||||
// Remove non-existing codec should not fail. ACM1 legacy.
|
||||
EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1));
|
||||
|
||||
// Remove an existing codec.
|
||||
EXPECT_EQ(0, receiver_->RemoveCodec(payload_type));
|
||||
|
||||
// Ask for the removed codec, must fail.
|
||||
EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &codec));
|
||||
}
|
||||
|
||||
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(SampleRate)) {
|
||||
const int kCodecId[] = {
|
||||
ACMCodecDB::kISAC, ACMCodecDB::kISACSWB,
|
||||
-1 // Terminator.
|
||||
};
|
||||
AddSetOfCodecs(kCodecId);
|
||||
|
||||
AudioFrame frame;
|
||||
const int kOutSampleRateHz = 8000; // Different than codec sample rate.
|
||||
int n = 0;
|
||||
while (kCodecId[n] >= 0) {
|
||||
const int num_10ms_frames = codecs_[kCodecId[n]].pacsize /
|
||||
(codecs_[kCodecId[n]].plfreq / 100);
|
||||
InsertOnePacketOfSilence(kCodecId[n]);
|
||||
for (int k = 0; k < num_10ms_frames; ++k) {
|
||||
EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame));
|
||||
}
|
||||
EXPECT_EQ(std::min(32000, codecs_[kCodecId[n]].plfreq),
|
||||
receiver_->current_sample_rate_hz());
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(PostdecodingVad)) {
|
||||
receiver_->EnableVad();
|
||||
EXPECT_TRUE(receiver_->vad_enabled());
|
||||
|
||||
const int id = ACMCodecDB::kPCM16Bwb;
|
||||
ASSERT_EQ(0, receiver_->AddCodec(id, codecs_[id].pltype, codecs_[id].channels,
|
||||
codecs_[id].plfreq, NULL));
|
||||
const int kNumPackets = 5;
|
||||
const int num_10ms_frames = codecs_[id].pacsize / (codecs_[id].plfreq / 100);
|
||||
AudioFrame frame;
|
||||
for (int n = 0; n < kNumPackets; ++n) {
|
||||
InsertOnePacketOfSilence(id);
|
||||
for (int k = 0; k < num_10ms_frames; ++k)
|
||||
ASSERT_EQ(0, receiver_->GetAudio(codecs_[id].plfreq, &frame));
|
||||
}
|
||||
EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
|
||||
|
||||
receiver_->DisableVad();
|
||||
EXPECT_FALSE(receiver_->vad_enabled());
|
||||
|
||||
for (int n = 0; n < kNumPackets; ++n) {
|
||||
InsertOnePacketOfSilence(id);
|
||||
for (int k = 0; k < num_10ms_frames; ++k)
|
||||
ASSERT_EQ(0, receiver_->GetAudio(codecs_[id].plfreq, &frame));
|
||||
}
|
||||
EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
|
||||
}
|
||||
|
||||
#ifdef WEBRTC_CODEC_ISAC
|
||||
#define IF_ISAC_FLOAT(x) x
|
||||
#else
|
||||
#define IF_ISAC_FLOAT(x) DISABLED_##x
|
||||
#endif
|
||||
|
||||
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(IF_ISAC_FLOAT(LastAudioCodec))) {
|
||||
const int kCodecId[] = {
|
||||
ACMCodecDB::kISAC, ACMCodecDB::kPCMA, ACMCodecDB::kISACSWB,
|
||||
ACMCodecDB::kPCM16Bswb32kHz,
|
||||
-1 // Terminator.
|
||||
};
|
||||
AddSetOfCodecs(kCodecId);
|
||||
|
||||
const int kCngId[] = { // Not including full-band.
|
||||
ACMCodecDB::kCNNB, ACMCodecDB::kCNWB, ACMCodecDB::kCNSWB,
|
||||
-1 // Terminator.
|
||||
};
|
||||
AddSetOfCodecs(kCngId);
|
||||
|
||||
// Register CNG at sender side.
|
||||
int n = 0;
|
||||
while (kCngId[n] > 0) {
|
||||
ASSERT_TRUE(acm_->RegisterSendCodec(kCngId[n], codecs_[kCngId[n]].pltype));
|
||||
++n;
|
||||
}
|
||||
|
||||
CodecInst codec;
|
||||
// No audio payload is received.
|
||||
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
||||
|
||||
// Start with sending DTX.
|
||||
ASSERT_TRUE(acm_->SetVad(true, true, VADVeryAggr));
|
||||
packet_sent_ = false;
|
||||
InsertOnePacketOfSilence(kCodecId[0]); // Enough to test with one codec.
|
||||
ASSERT_TRUE(packet_sent_);
|
||||
EXPECT_EQ(kAudioFrameCN, last_frame_type_);
|
||||
|
||||
// Has received, only, DTX. Last Audio codec is undefined.
|
||||
EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
|
||||
EXPECT_EQ(-1, receiver_->last_audio_codec_id());
|
||||
|
||||
n = 0;
|
||||
while (kCodecId[n] >= 0) { // Loop over codecs.
|
||||
// Set DTX off to send audio payload.
|
||||
acm_->SetVad(false, false, VADAggr);
|
||||
packet_sent_ = false;
|
||||
InsertOnePacketOfSilence(kCodecId[n]);
|
||||
|
||||
// Sanity check if Actually an audio payload received, and it should be
|
||||
// of type "speech."
|
||||
ASSERT_TRUE(packet_sent_);
|
||||
ASSERT_EQ(kAudioFrameSpeech, last_frame_type_);
|
||||
EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
|
||||
|
||||
// Set VAD on to send DTX. Then check if the "Last Audio codec" returns
|
||||
// the expected codec.
|
||||
acm_->SetVad(true, true, VADAggr);
|
||||
|
||||
// Do as many encoding until a DTX is sent.
|
||||
while (last_frame_type_ != kAudioFrameCN) {
|
||||
packet_sent_ = false;
|
||||
InsertOnePacketOfSilence(kCodecId[n]);
|
||||
ASSERT_TRUE(packet_sent_);
|
||||
}
|
||||
EXPECT_EQ(kCodecId[n], receiver_->last_audio_codec_id());
|
||||
EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
|
||||
EXPECT_TRUE(CodecsEqual(codecs_[kCodecId[n]], codec));
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace acm2
|
||||
|
||||
} // namespace webrtc
|
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_coding/main/acm2/acm_send_test.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
AcmSendTest::AcmSendTest(InputAudioFile* audio_source,
|
||||
int source_rate_hz,
|
||||
int test_duration_ms)
|
||||
: clock_(0),
|
||||
audio_source_(audio_source),
|
||||
source_rate_hz_(source_rate_hz),
|
||||
input_block_size_samples_(
|
||||
static_cast<size_t>(source_rate_hz_ * kBlockSizeMs / 1000)),
|
||||
codec_registered_(false),
|
||||
test_duration_ms_(test_duration_ms),
|
||||
frame_type_(kAudioFrameSpeech),
|
||||
payload_type_(0),
|
||||
timestamp_(0),
|
||||
sequence_number_(0) {
|
||||
webrtc::AudioCoding::Config config;
|
||||
config.clock = &clock_;
|
||||
config.transport = this;
|
||||
acm_.reset(webrtc::AudioCoding::Create(config));
|
||||
input_frame_.sample_rate_hz_ = source_rate_hz_;
|
||||
input_frame_.num_channels_ = 1;
|
||||
input_frame_.samples_per_channel_ = input_block_size_samples_;
|
||||
assert(input_block_size_samples_ * input_frame_.num_channels_ <=
|
||||
AudioFrame::kMaxDataSizeSamples);
|
||||
}
|
||||
|
||||
bool AcmSendTest::RegisterCodec(int codec_type,
|
||||
int channels,
|
||||
int payload_type,
|
||||
int frame_size_samples) {
|
||||
codec_registered_ =
|
||||
acm_->RegisterSendCodec(codec_type, payload_type, frame_size_samples);
|
||||
input_frame_.num_channels_ = channels;
|
||||
assert(input_block_size_samples_ * input_frame_.num_channels_ <=
|
||||
AudioFrame::kMaxDataSizeSamples);
|
||||
return codec_registered_;
|
||||
}
|
||||
|
||||
Packet* AcmSendTest::NextPacket() {
|
||||
assert(codec_registered_);
|
||||
if (filter_.test(static_cast<size_t>(payload_type_))) {
|
||||
// This payload type should be filtered out. Since the payload type is the
|
||||
// same throughout the whole test run, no packet at all will be delivered.
|
||||
// We can just as well signal that the test is over by returning NULL.
|
||||
return NULL;
|
||||
}
|
||||
// Insert audio and process until one packet is produced.
|
||||
while (clock_.TimeInMilliseconds() < test_duration_ms_) {
|
||||
clock_.AdvanceTimeMilliseconds(kBlockSizeMs);
|
||||
RTC_CHECK(
|
||||
audio_source_->Read(input_block_size_samples_, input_frame_.data_));
|
||||
if (input_frame_.num_channels_ > 1) {
|
||||
InputAudioFile::DuplicateInterleaved(input_frame_.data_,
|
||||
input_block_size_samples_,
|
||||
input_frame_.num_channels_,
|
||||
input_frame_.data_);
|
||||
}
|
||||
int32_t encoded_bytes = acm_->Add10MsAudio(input_frame_);
|
||||
EXPECT_GE(encoded_bytes, 0);
|
||||
input_frame_.timestamp_ += static_cast<uint32_t>(input_block_size_samples_);
|
||||
if (encoded_bytes > 0) {
|
||||
// Encoded packet received.
|
||||
return CreatePacket();
|
||||
}
|
||||
}
|
||||
// Test ended.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This method receives the callback from ACM when a new packet is produced.
|
||||
int32_t AcmSendTest::SendData(FrameType frame_type,
|
||||
uint8_t payload_type,
|
||||
uint32_t timestamp,
|
||||
const uint8_t* payload_data,
|
||||
size_t payload_len_bytes,
|
||||
const RTPFragmentationHeader* fragmentation) {
|
||||
// Store the packet locally.
|
||||
frame_type_ = frame_type;
|
||||
payload_type_ = payload_type;
|
||||
timestamp_ = timestamp;
|
||||
last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes);
|
||||
assert(last_payload_vec_.size() == payload_len_bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Packet* AcmSendTest::CreatePacket() {
|
||||
const size_t kRtpHeaderSize = 12;
|
||||
size_t allocated_bytes = last_payload_vec_.size() + kRtpHeaderSize;
|
||||
uint8_t* packet_memory = new uint8_t[allocated_bytes];
|
||||
// Populate the header bytes.
|
||||
packet_memory[0] = 0x80;
|
||||
packet_memory[1] = static_cast<uint8_t>(payload_type_);
|
||||
packet_memory[2] = (sequence_number_ >> 8) & 0xFF;
|
||||
packet_memory[3] = (sequence_number_) & 0xFF;
|
||||
packet_memory[4] = (timestamp_ >> 24) & 0xFF;
|
||||
packet_memory[5] = (timestamp_ >> 16) & 0xFF;
|
||||
packet_memory[6] = (timestamp_ >> 8) & 0xFF;
|
||||
packet_memory[7] = timestamp_ & 0xFF;
|
||||
// Set SSRC to 0x12345678.
|
||||
packet_memory[8] = 0x12;
|
||||
packet_memory[9] = 0x34;
|
||||
packet_memory[10] = 0x56;
|
||||
packet_memory[11] = 0x78;
|
||||
|
||||
++sequence_number_;
|
||||
|
||||
// Copy the payload data.
|
||||
memcpy(packet_memory + kRtpHeaderSize,
|
||||
&last_payload_vec_[0],
|
||||
last_payload_vec_.size());
|
||||
Packet* packet =
|
||||
new Packet(packet_memory, allocated_bytes, clock_.TimeInMilliseconds());
|
||||
assert(packet);
|
||||
assert(packet->valid_header());
|
||||
return packet;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace test {
|
||||
class InputAudioFile;
|
||||
class Packet;
|
||||
|
||||
class AcmSendTest : public AudioPacketizationCallback, public PacketSource {
|
||||
public:
|
||||
AcmSendTest(InputAudioFile* audio_source,
|
||||
int source_rate_hz,
|
||||
int test_duration_ms);
|
||||
virtual ~AcmSendTest() {}
|
||||
|
||||
// Registers the send codec. Returns true on success, false otherwise.
|
||||
bool RegisterCodec(int codec_type,
|
||||
int channels,
|
||||
int payload_type,
|
||||
int frame_size_samples);
|
||||
|
||||
// Returns the next encoded packet. Returns NULL if the test duration was
|
||||
// exceeded. Ownership of the packet is handed over to the caller.
|
||||
// Inherited from PacketSource.
|
||||
Packet* NextPacket() override;
|
||||
|
||||
// Inherited from AudioPacketizationCallback.
|
||||
int32_t SendData(FrameType frame_type,
|
||||
uint8_t payload_type,
|
||||
uint32_t timestamp,
|
||||
const uint8_t* payload_data,
|
||||
size_t payload_len_bytes,
|
||||
const RTPFragmentationHeader* fragmentation) override;
|
||||
|
||||
private:
|
||||
static const int kBlockSizeMs = 10;
|
||||
|
||||
// Creates a Packet object from the last packet produced by ACM (and received
|
||||
// through the SendData method as a callback). Ownership of the new Packet
|
||||
// object is transferred to the caller.
|
||||
Packet* CreatePacket();
|
||||
|
||||
SimulatedClock clock_;
|
||||
rtc::scoped_ptr<AudioCoding> acm_;
|
||||
InputAudioFile* audio_source_;
|
||||
int source_rate_hz_;
|
||||
const size_t input_block_size_samples_;
|
||||
AudioFrame input_frame_;
|
||||
bool codec_registered_;
|
||||
int test_duration_ms_;
|
||||
// The following member variables are set whenever SendData() is called.
|
||||
FrameType frame_type_;
|
||||
int payload_type_;
|
||||
uint32_t timestamp_;
|
||||
uint16_t sequence_number_;
|
||||
std::vector<uint8_t> last_payload_vec_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AcmSendTest);
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_
|
@ -100,18 +100,4 @@ bool AudioCodingModule::IsCodecValid(const CodecInst& codec) {
|
||||
}
|
||||
}
|
||||
|
||||
AudioCoding::Config::Config()
|
||||
: neteq_config(),
|
||||
clock(Clock::GetRealTimeClock()),
|
||||
transport(nullptr),
|
||||
vad_callback(nullptr),
|
||||
initial_playout_delay_ms(0),
|
||||
playout_channels(1),
|
||||
playout_frequency_hz(32000) {
|
||||
}
|
||||
|
||||
AudioCoding* AudioCoding::Create(const Config& config) {
|
||||
return new AudioCodingImpl(config);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -803,287 +803,4 @@ void AudioCodingModuleImpl::GetDecodingCallStatistics(
|
||||
}
|
||||
|
||||
} // namespace acm2
|
||||
|
||||
AudioCodingImpl::AudioCodingImpl(const Config& config) {
|
||||
AudioCodingModule::Config config_old = config.ToOldConfig();
|
||||
acm_old_.reset(new acm2::AudioCodingModuleImpl(config_old));
|
||||
acm_old_->RegisterTransportCallback(config.transport);
|
||||
acm_old_->RegisterVADCallback(config.vad_callback);
|
||||
if (config.initial_playout_delay_ms > 0) {
|
||||
acm_old_->SetInitialPlayoutDelay(config.initial_playout_delay_ms);
|
||||
}
|
||||
playout_frequency_hz_ = config.playout_frequency_hz;
|
||||
}
|
||||
|
||||
AudioCodingImpl::~AudioCodingImpl() = default;
|
||||
|
||||
bool AudioCodingImpl::RegisterSendCodec(AudioEncoder* send_codec) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::RegisterSendCodec(int encoder_type,
|
||||
uint8_t payload_type,
|
||||
int frame_size_samples) {
|
||||
std::string codec_name;
|
||||
int sample_rate_hz;
|
||||
int channels;
|
||||
if (!MapCodecTypeToParameters(
|
||||
encoder_type, &codec_name, &sample_rate_hz, &channels)) {
|
||||
return false;
|
||||
}
|
||||
webrtc::CodecInst codec;
|
||||
AudioCodingModule::Codec(
|
||||
codec_name.c_str(), &codec, sample_rate_hz, channels);
|
||||
codec.pltype = payload_type;
|
||||
if (frame_size_samples > 0) {
|
||||
codec.pacsize = frame_size_samples;
|
||||
}
|
||||
return acm_old_->RegisterSendCodec(codec) == 0;
|
||||
}
|
||||
|
||||
const AudioEncoder* AudioCodingImpl::GetSenderInfo() const {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return reinterpret_cast<const AudioEncoder*>(NULL);
|
||||
}
|
||||
|
||||
const CodecInst* AudioCodingImpl::GetSenderCodecInst() {
|
||||
if (acm_old_->SendCodec(¤t_send_codec_) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
return ¤t_send_codec_;
|
||||
}
|
||||
|
||||
int AudioCodingImpl::Add10MsAudio(const AudioFrame& audio_frame) {
|
||||
acm2::AudioCodingModuleImpl::InputData input_data;
|
||||
CriticalSectionScoped lock(acm_old_->acm_crit_sect_.get());
|
||||
if (acm_old_->Add10MsDataInternal(audio_frame, &input_data) != 0)
|
||||
return -1;
|
||||
return acm_old_->Encode(input_data);
|
||||
}
|
||||
|
||||
const ReceiverInfo* AudioCodingImpl::GetReceiverInfo() const {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return reinterpret_cast<const ReceiverInfo*>(NULL);
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::RegisterReceiveCodec(AudioDecoder* receive_codec) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::RegisterReceiveCodec(int decoder_type,
|
||||
uint8_t payload_type) {
|
||||
std::string codec_name;
|
||||
int sample_rate_hz;
|
||||
int channels;
|
||||
if (!MapCodecTypeToParameters(
|
||||
decoder_type, &codec_name, &sample_rate_hz, &channels)) {
|
||||
return false;
|
||||
}
|
||||
webrtc::CodecInst codec;
|
||||
AudioCodingModule::Codec(
|
||||
codec_name.c_str(), &codec, sample_rate_hz, channels);
|
||||
codec.pltype = payload_type;
|
||||
return acm_old_->RegisterReceiveCodec(codec) == 0;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::InsertPacket(const uint8_t* incoming_payload,
|
||||
size_t payload_len_bytes,
|
||||
const WebRtcRTPHeader& rtp_info) {
|
||||
return acm_old_->IncomingPacket(
|
||||
incoming_payload, payload_len_bytes, rtp_info) == 0;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::InsertPayload(const uint8_t* incoming_payload,
|
||||
size_t payload_len_byte,
|
||||
uint8_t payload_type,
|
||||
uint32_t timestamp) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::SetMinimumPlayoutDelay(int time_ms) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::SetMaximumPlayoutDelay(int time_ms) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
int AudioCodingImpl::LeastRequiredDelayMs() const {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::PlayoutTimestamp(uint32_t* timestamp) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::Get10MsAudio(AudioFrame* audio_frame) {
|
||||
return acm_old_->PlayoutData10Ms(playout_frequency_hz_, audio_frame) == 0;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::GetNetworkStatistics(
|
||||
NetworkStatistics* network_statistics) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::EnableNack(size_t max_nack_list_size) {
|
||||
FATAL() << "Not implemented yet.";
|
||||
return false;
|
||||
}
|
||||
|
||||
void AudioCodingImpl::DisableNack() {
|
||||
// A bug in the linker of Visual Studio 2013 Update 3 prevent us from using
|
||||
// FATAL() here, if we do so then the linker hang when the WPO is turned on.
|
||||
// TODO(sebmarchand): Re-evaluate this when we upgrade the toolchain.
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::SetVad(bool enable_dtx,
|
||||
bool enable_vad,
|
||||
ACMVADMode vad_mode) {
|
||||
return acm_old_->SetVAD(enable_dtx, enable_vad, vad_mode) == 0;
|
||||
}
|
||||
|
||||
std::vector<uint16_t> AudioCodingImpl::GetNackList(
|
||||
int round_trip_time_ms) const {
|
||||
return acm_old_->GetNackList(round_trip_time_ms);
|
||||
}
|
||||
|
||||
void AudioCodingImpl::GetDecodingCallStatistics(
|
||||
AudioDecodingCallStats* call_stats) const {
|
||||
acm_old_->GetDecodingCallStatistics(call_stats);
|
||||
}
|
||||
|
||||
bool AudioCodingImpl::MapCodecTypeToParameters(int codec_type,
|
||||
std::string* codec_name,
|
||||
int* sample_rate_hz,
|
||||
int* channels) {
|
||||
switch (codec_type) {
|
||||
case acm2::ACMCodecDB::kPCM16B:
|
||||
*codec_name = "L16";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCM16Bwb:
|
||||
*codec_name = "L16";
|
||||
*sample_rate_hz = 16000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCM16Bswb32kHz:
|
||||
*codec_name = "L16";
|
||||
*sample_rate_hz = 32000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCM16B_2ch:
|
||||
*codec_name = "L16";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 2;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCM16Bwb_2ch:
|
||||
*codec_name = "L16";
|
||||
*sample_rate_hz = 16000;
|
||||
*channels = 2;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCM16Bswb32kHz_2ch:
|
||||
*codec_name = "L16";
|
||||
*sample_rate_hz = 32000;
|
||||
*channels = 2;
|
||||
break;
|
||||
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
|
||||
case acm2::ACMCodecDB::kISAC:
|
||||
*codec_name = "ISAC";
|
||||
*sample_rate_hz = 16000;
|
||||
*channels = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WEBRTC_CODEC_ISAC
|
||||
case acm2::ACMCodecDB::kISACSWB:
|
||||
*codec_name = "ISAC";
|
||||
*sample_rate_hz = 32000;
|
||||
*channels = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WEBRTC_CODEC_ILBC
|
||||
case acm2::ACMCodecDB::kILBC:
|
||||
*codec_name = "ILBC";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 1;
|
||||
break;
|
||||
#endif
|
||||
case acm2::ACMCodecDB::kPCMA:
|
||||
*codec_name = "PCMA";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCMA_2ch:
|
||||
*codec_name = "PCMA";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 2;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCMU:
|
||||
*codec_name = "PCMU";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kPCMU_2ch:
|
||||
*codec_name = "PCMU";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 2;
|
||||
break;
|
||||
#ifdef WEBRTC_CODEC_G722
|
||||
case acm2::ACMCodecDB::kG722:
|
||||
*codec_name = "G722";
|
||||
*sample_rate_hz = 16000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kG722_2ch:
|
||||
*codec_name = "G722";
|
||||
*sample_rate_hz = 16000;
|
||||
*channels = 2;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WEBRTC_CODEC_OPUS
|
||||
case acm2::ACMCodecDB::kOpus:
|
||||
*codec_name = "opus";
|
||||
*sample_rate_hz = 48000;
|
||||
*channels = 2;
|
||||
break;
|
||||
#endif
|
||||
case acm2::ACMCodecDB::kCNNB:
|
||||
*codec_name = "CN";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kCNWB:
|
||||
*codec_name = "CN";
|
||||
*sample_rate_hz = 16000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kCNSWB:
|
||||
*codec_name = "CN";
|
||||
*sample_rate_hz = 32000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kRED:
|
||||
*codec_name = "red";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 1;
|
||||
break;
|
||||
case acm2::ACMCodecDB::kAVT:
|
||||
*codec_name = "telephone-event";
|
||||
*sample_rate_hz = 8000;
|
||||
*channels = 1;
|
||||
break;
|
||||
default:
|
||||
FATAL() << "Codec type " << codec_type << " not supported.";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -280,79 +280,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
|
||||
};
|
||||
|
||||
} // namespace acm2
|
||||
|
||||
class AudioCodingImpl : public AudioCoding {
|
||||
public:
|
||||
AudioCodingImpl(const Config& config);
|
||||
~AudioCodingImpl() override;
|
||||
|
||||
bool RegisterSendCodec(AudioEncoder* send_codec) override;
|
||||
|
||||
bool RegisterSendCodec(int encoder_type,
|
||||
uint8_t payload_type,
|
||||
int frame_size_samples = 0) override;
|
||||
|
||||
const AudioEncoder* GetSenderInfo() const override;
|
||||
|
||||
const CodecInst* GetSenderCodecInst() override;
|
||||
|
||||
int Add10MsAudio(const AudioFrame& audio_frame) override;
|
||||
|
||||
const ReceiverInfo* GetReceiverInfo() const override;
|
||||
|
||||
bool RegisterReceiveCodec(AudioDecoder* receive_codec) override;
|
||||
|
||||
bool RegisterReceiveCodec(int decoder_type, uint8_t payload_type) override;
|
||||
|
||||
bool InsertPacket(const uint8_t* incoming_payload,
|
||||
size_t payload_len_bytes,
|
||||
const WebRtcRTPHeader& rtp_info) override;
|
||||
|
||||
bool InsertPayload(const uint8_t* incoming_payload,
|
||||
size_t payload_len_byte,
|
||||
uint8_t payload_type,
|
||||
uint32_t timestamp) override;
|
||||
|
||||
bool SetMinimumPlayoutDelay(int time_ms) override;
|
||||
|
||||
bool SetMaximumPlayoutDelay(int time_ms) override;
|
||||
|
||||
int LeastRequiredDelayMs() const override;
|
||||
|
||||
bool PlayoutTimestamp(uint32_t* timestamp) override;
|
||||
|
||||
bool Get10MsAudio(AudioFrame* audio_frame) override;
|
||||
|
||||
bool GetNetworkStatistics(NetworkStatistics* network_statistics) override;
|
||||
|
||||
bool EnableNack(size_t max_nack_list_size) override;
|
||||
|
||||
void DisableNack() override;
|
||||
|
||||
bool SetVad(bool enable_dtx, bool enable_vad, ACMVADMode vad_mode) override;
|
||||
|
||||
std::vector<uint16_t> GetNackList(int round_trip_time_ms) const override;
|
||||
|
||||
void GetDecodingCallStatistics(
|
||||
AudioDecodingCallStats* call_stats) const override;
|
||||
|
||||
private:
|
||||
// Temporary method to be used during redesign phase.
|
||||
// Maps |codec_type| (a value from the anonymous enum in acm2::ACMCodecDB) to
|
||||
// |codec_name|, |sample_rate_hz|, and |channels|.
|
||||
// TODO(henrik.lundin) Remove this when no longer needed.
|
||||
static bool MapCodecTypeToParameters(int codec_type,
|
||||
std::string* codec_name,
|
||||
int* sample_rate_hz,
|
||||
int* channels);
|
||||
|
||||
int playout_frequency_hz_;
|
||||
// TODO(henrik.lundin): All members below this line are temporary and should
|
||||
// be removed after refactoring is completed.
|
||||
rtc::scoped_ptr<acm2::AudioCodingModuleImpl> acm_old_;
|
||||
CodecInst current_send_codec_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -108,8 +108,6 @@
|
||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||
],
|
||||
'sources': [
|
||||
'acm2/acm_receive_test.cc',
|
||||
'acm2/acm_receive_test.h',
|
||||
'acm2/acm_receive_test_oldapi.cc',
|
||||
'acm2/acm_receive_test_oldapi.h',
|
||||
],
|
||||
@ -127,8 +125,6 @@
|
||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||
],
|
||||
'sources': [
|
||||
'acm2/acm_send_test.cc',
|
||||
'acm2/acm_send_test.h',
|
||||
'acm2/acm_send_test_oldapi.cc',
|
||||
'acm2/acm_send_test_oldapi.h',
|
||||
],
|
||||
|
@ -753,177 +753,6 @@ class AudioCodingModule {
|
||||
AudioDecodingCallStats* call_stats) const = 0;
|
||||
};
|
||||
|
||||
class AudioEncoder;
|
||||
class ReceiverInfo;
|
||||
|
||||
class AudioCoding {
|
||||
public:
|
||||
struct Config {
|
||||
Config();
|
||||
|
||||
AudioCodingModule::Config ToOldConfig() const {
|
||||
AudioCodingModule::Config old_config;
|
||||
old_config.id = 0;
|
||||
old_config.neteq_config = neteq_config;
|
||||
old_config.clock = clock;
|
||||
return old_config;
|
||||
}
|
||||
|
||||
NetEq::Config neteq_config;
|
||||
Clock* clock;
|
||||
AudioPacketizationCallback* transport;
|
||||
ACMVADCallback* vad_callback;
|
||||
int initial_playout_delay_ms;
|
||||
int playout_channels;
|
||||
int playout_frequency_hz;
|
||||
};
|
||||
|
||||
static AudioCoding* Create(const Config& config);
|
||||
virtual ~AudioCoding() {};
|
||||
|
||||
// Registers a codec, specified by |send_codec|, as sending codec.
|
||||
// This API can be called multiple times. The last codec registered overwrites
|
||||
// the previous ones. Returns true if successful, false if not.
|
||||
//
|
||||
// Note: If a stereo codec is registered as send codec, VAD/DTX will
|
||||
// automatically be turned off, since it is not supported for stereo sending.
|
||||
virtual bool RegisterSendCodec(AudioEncoder* send_codec) = 0;
|
||||
|
||||
// Temporary solution to be used during refactoring:
|
||||
// |encoder_type| should be from the anonymous enum in acm2::ACMCodecDB.
|
||||
virtual bool RegisterSendCodec(int encoder_type,
|
||||
uint8_t payload_type,
|
||||
int frame_size_samples = 0) = 0;
|
||||
|
||||
// Returns the encoder object currently in use. This is the same as the
|
||||
// codec that was registered in the latest call to RegisterSendCodec().
|
||||
virtual const AudioEncoder* GetSenderInfo() const = 0;
|
||||
|
||||
// Temporary solution to be used during refactoring.
|
||||
virtual const CodecInst* GetSenderCodecInst() = 0;
|
||||
|
||||
// Adds 10 ms of raw (PCM) audio data to the encoder. If the sampling
|
||||
// frequency of the audio does not match the sampling frequency of the
|
||||
// current encoder, ACM will resample the audio.
|
||||
//
|
||||
// Return value:
|
||||
// 0 successfully added the frame.
|
||||
// -1 some error occurred and data is not added.
|
||||
// < -1 to add the frame to the buffer n samples had to be
|
||||
// overwritten, -n is the return value in this case.
|
||||
// TODO(henrik.lundin): Make a better design for the return values. This one
|
||||
// is just a copy of the old API.
|
||||
virtual int Add10MsAudio(const AudioFrame& audio_frame) = 0;
|
||||
|
||||
// Returns a combined info about the currently used decoder(s).
|
||||
virtual const ReceiverInfo* GetReceiverInfo() const = 0;
|
||||
|
||||
// Registers a codec, specified by |receive_codec|, as receiving codec.
|
||||
// This API can be called multiple times. If registering with a payload type
|
||||
// that was already registered in a previous call, the latest call will
|
||||
// override previous calls. Returns true if successful, false if not.
|
||||
virtual bool RegisterReceiveCodec(AudioDecoder* receive_codec) = 0;
|
||||
|
||||
// Temporary solution:
|
||||
// |decoder_type| should be from the anonymous enum in acm2::ACMCodecDB.
|
||||
virtual bool RegisterReceiveCodec(int decoder_type, uint8_t payload_type) = 0;
|
||||
|
||||
// The following two methods both inserts a new packet to the receiver.
|
||||
// InsertPacket takes an RTP header input in |rtp_info|, while InsertPayload
|
||||
// only requires a payload type and a timestamp. The latter assumes that the
|
||||
// payloads come in the right order, and without any losses. In both cases,
|
||||
// |incoming_payload| contains the RTP payload after the RTP header. Return
|
||||
// true if successful, false if not.
|
||||
virtual bool InsertPacket(const uint8_t* incoming_payload,
|
||||
size_t payload_len_bytes,
|
||||
const WebRtcRTPHeader& rtp_info) = 0;
|
||||
|
||||
// TODO(henrik.lundin): Remove this method?
|
||||
virtual bool InsertPayload(const uint8_t* incoming_payload,
|
||||
size_t payload_len_byte,
|
||||
uint8_t payload_type,
|
||||
uint32_t timestamp) = 0;
|
||||
|
||||
// These two methods set a minimum and maximum jitter buffer delay in
|
||||
// milliseconds. The pupose is mainly to adjust the delay to synchronize
|
||||
// audio and video. The preferred jitter buffer size, computed by NetEq based
|
||||
// on the current channel conditions, is clamped from below and above by these
|
||||
// two methods. The given delay limits must be non-negative, less than
|
||||
// 10000 ms, and the minimum must be strictly smaller than the maximum.
|
||||
// Further, the maximum must be at lest one frame duration. If these
|
||||
// conditions are not met, false is returned. Giving the value 0 effectively
|
||||
// unsets the minimum or maximum delay limits.
|
||||
// Note that calling these methods is optional. If not called, NetEq will
|
||||
// determine the optimal buffer size based on the network conditions.
|
||||
virtual bool SetMinimumPlayoutDelay(int time_ms) = 0;
|
||||
|
||||
virtual bool SetMaximumPlayoutDelay(int time_ms) = 0;
|
||||
|
||||
// Returns the current value of the jitter buffer's preferred latency. This
|
||||
// is computed based on inter-arrival times and playout mode of NetEq. The
|
||||
// actual target delay is this value clamped from below and above by the
|
||||
// values specified through SetMinimumPlayoutDelay() and
|
||||
// SetMaximumPlayoutDelay(), respectively, if provided.
|
||||
// TODO(henrik.lundin) Rename to PreferredDelayMs?
|
||||
virtual int LeastRequiredDelayMs() const = 0;
|
||||
|
||||
// The send timestamp of an RTP packet is associated with the decoded
|
||||
// audio of the packet in question. This function returns the timestamp of
|
||||
// the latest audio delivered by Get10MsAudio(). Returns false if no timestamp
|
||||
// can be provided, true otherwise.
|
||||
virtual bool PlayoutTimestamp(uint32_t* timestamp) = 0;
|
||||
|
||||
// Delivers 10 ms of audio in |audio_frame|. Returns true if successful,
|
||||
// false otherwise.
|
||||
virtual bool Get10MsAudio(AudioFrame* audio_frame) = 0;
|
||||
|
||||
// Returns the network statistics. Note that the internal statistics of NetEq
|
||||
// are reset by this call. Returns true if successful, false otherwise.
|
||||
virtual bool GetNetworkStatistics(NetworkStatistics* network_statistics) = 0;
|
||||
|
||||
// Enables NACK and sets the maximum size of the NACK list. If NACK is already
|
||||
// enabled then the maximum NACK list size is modified accordingly. Returns
|
||||
// true if successful, false otherwise.
|
||||
//
|
||||
// If the sequence number of last received packet is N, the sequence numbers
|
||||
// of NACK list are in the range of [N - |max_nack_list_size|, N).
|
||||
//
|
||||
// |max_nack_list_size| should be positive and less than or equal to
|
||||
// |Nack::kNackListSizeLimit|.
|
||||
virtual bool EnableNack(size_t max_nack_list_size) = 0;
|
||||
|
||||
// Disables NACK.
|
||||
virtual void DisableNack() = 0;
|
||||
|
||||
|
||||
// Temporary solution to be used during refactoring.
|
||||
// If DTX is enabled and the codec does not have internal DTX/VAD
|
||||
// WebRtc VAD will be automatically enabled and |enable_vad| is ignored.
|
||||
//
|
||||
// If DTX is disabled but VAD is enabled no DTX packets are sent,
|
||||
// regardless of whether the codec has internal DTX/VAD or not. In this
|
||||
// case, WebRtc VAD is running to label frames as active/in-active.
|
||||
//
|
||||
// NOTE! VAD/DTX is not supported when sending stereo.
|
||||
//
|
||||
// Return true if successful, false otherwise.
|
||||
virtual bool SetVad(bool enable_dtx,
|
||||
bool enable_vad,
|
||||
ACMVADMode vad_mode) = 0;
|
||||
|
||||
// Returns a list of packets to request retransmission of.
|
||||
// |round_trip_time_ms| is an estimate of the round-trip-time (in
|
||||
// milliseconds). Missing packets which will be decoded sooner than the
|
||||
// round-trip-time (with respect to the time this API is called) will not be
|
||||
// included in the list.
|
||||
// |round_trip_time_ms| must be non-negative.
|
||||
virtual std::vector<uint16_t> GetNackList(int round_trip_time_ms) const = 0;
|
||||
|
||||
// Returns the timing statistics for calls to Get10MsAudio.
|
||||
virtual void GetDecodingCallStatistics(
|
||||
AudioDecodingCallStats* call_stats) const = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_INTERFACE_AUDIO_CODING_MODULE_H_
|
||||
|
@ -98,9 +98,7 @@
|
||||
],
|
||||
'sources': [
|
||||
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
|
||||
'audio_coding/main/acm2/acm_receiver_unittest.cc',
|
||||
'audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc',
|
||||
'audio_coding/main/acm2/audio_coding_module_unittest.cc',
|
||||
'audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc',
|
||||
'audio_coding/main/acm2/call_statistics_unittest.cc',
|
||||
'audio_coding/main/acm2/codec_owner_unittest.cc',
|
||||
|
Reference in New Issue
Block a user