webrtc/modules/audio_coding/test/EncodeDecodeTest.cc
Niels Möller 87e2d785a0 Prepare for splitting FrameType into AudioFrameType and VideoFrameType
This cl deprecates the FrameType enum, and adds aliases AudioFrameType
and VideoFrameType.

After downstream usage is updated, the enums will be separated
and be moved out of common_types.h.

Bug: webrtc:6883
Change-Id: I2aaf660169da45f22574b4cbb16aea8522cc07a6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/123184
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27011}
2019-03-07 10:12:57 +00:00

270 lines
8.1 KiB
C++

/*
* 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 "modules/audio_coding/test/EncodeDecodeTest.h"
#include <stdio.h>
#include <stdlib.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/include/audio_coding_module.h"
#include "rtc_base/strings/string_builder.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"
namespace webrtc {
TestPacketization::TestPacketization(RTPStream *rtpStream, uint16_t frequency)
: _rtpStream(rtpStream),
_frequency(frequency),
_seqNo(0) {
}
TestPacketization::~TestPacketization() {
}
int32_t TestPacketization::SendData(
const AudioFrameType /* frameType */,
const uint8_t payloadType,
const uint32_t timeStamp,
const uint8_t* payloadData,
const size_t payloadSize,
const RTPFragmentationHeader* /* fragmentation */) {
_rtpStream->Write(payloadType, timeStamp, _seqNo++, payloadData, payloadSize,
_frequency);
return 1;
}
Sender::Sender()
: _acm(NULL),
_pcmFile(),
_audioFrame(),
_packetization(NULL) {
}
void Sender::Setup(AudioCodingModule *acm, RTPStream *rtpStream,
std::string in_file_name, int in_sample_rate,
int payload_type, SdpAudioFormat format) {
// Open input file
const std::string file_name = webrtc::test::ResourcePath(in_file_name, "pcm");
_pcmFile.Open(file_name, in_sample_rate, "rb");
if (format.num_channels == 2) {
_pcmFile.ReadStereo(true);
}
// Set test length to 500 ms (50 blocks of 10 ms each).
_pcmFile.SetNum10MsBlocksToRead(50);
// Fast-forward 1 second (100 blocks) since the file starts with silence.
_pcmFile.FastForward(100);
acm->SetEncoder(CreateBuiltinAudioEncoderFactory()->MakeAudioEncoder(
payload_type, format, absl::nullopt));
_packetization = new TestPacketization(rtpStream, format.clockrate_hz);
EXPECT_EQ(0, acm->RegisterTransportCallback(_packetization));
_acm = acm;
}
void Sender::Teardown() {
_pcmFile.Close();
delete _packetization;
}
bool Sender::Add10MsData() {
if (!_pcmFile.EndOfFile()) {
EXPECT_GT(_pcmFile.Read10MsData(_audioFrame), 0);
int32_t ok = _acm->Add10MsData(_audioFrame);
EXPECT_GE(ok, 0);
return ok >= 0 ? true : false;
}
return false;
}
void Sender::Run() {
while (true) {
if (!Add10MsData()) {
break;
}
}
}
Receiver::Receiver()
: _playoutLengthSmpls(WEBRTC_10MS_PCM_AUDIO),
_payloadSizeBytes(MAX_INCOMING_PAYLOAD) {
}
void Receiver::Setup(AudioCodingModule *acm, RTPStream *rtpStream,
std::string out_file_name, size_t channels, int file_num) {
EXPECT_EQ(0, acm->InitializeReceiver());
if (channels == 1) {
acm->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
{104, {"ISAC", 32000, 1}},
{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"}}}}});
}
int playSampFreq;
std::string file_name;
rtc::StringBuilder file_stream;
file_stream << webrtc::test::OutputPath() << out_file_name << file_num
<< ".pcm";
file_name = file_stream.str();
_rtpStream = rtpStream;
playSampFreq = 32000;
_pcmFile.Open(file_name, 32000, "wb+");
_realPayloadSizeBytes = 0;
_playoutBuffer = new int16_t[WEBRTC_10MS_PCM_AUDIO];
_frequency = playSampFreq;
_acm = acm;
_firstTime = true;
}
void Receiver::Teardown() {
delete[] _playoutBuffer;
_pcmFile.Close();
}
bool Receiver::IncomingPacket() {
if (!_rtpStream->EndOfFile()) {
if (_firstTime) {
_firstTime = false;
_realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
_payloadSizeBytes, &_nextTime);
if (_realPayloadSizeBytes == 0) {
if (_rtpStream->EndOfFile()) {
_firstTime = true;
return true;
} else {
return false;
}
}
}
EXPECT_EQ(0, _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes,
_rtpHeader));
_realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
_payloadSizeBytes, &_nextTime);
if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {
_firstTime = true;
}
}
return true;
}
bool Receiver::PlayoutData() {
AudioFrame audioFrame;
bool muted;
int32_t ok = _acm->PlayoutData10Ms(_frequency, &audioFrame, &muted);
if (muted) {
ADD_FAILURE();
return false;
}
EXPECT_EQ(0, ok);
if (ok < 0){
return false;
}
if (_playoutLengthSmpls == 0) {
return false;
}
_pcmFile.Write10MsData(audioFrame.data(),
audioFrame.samples_per_channel_ * audioFrame.num_channels_);
return true;
}
void Receiver::Run() {
uint8_t counter500Ms = 50;
uint32_t clock = 0;
while (counter500Ms > 0) {
if (clock == 0 || clock >= _nextTime) {
EXPECT_TRUE(IncomingPacket());
if (clock == 0) {
clock = _nextTime;
}
}
if ((clock % 10) == 0) {
if (!PlayoutData()) {
clock++;
continue;
}
}
if (_rtpStream->EndOfFile()) {
counter500Ms--;
}
clock++;
}
}
EncodeDecodeTest::EncodeDecodeTest() = default;
void EncodeDecodeTest::Perform() {
const std::map<int, SdpAudioFormat> send_codecs = {{103, {"ISAC", 16000, 1}},
{104, {"ISAC", 32000, 1}},
{107, {"L16", 8000, 1}},
{108, {"L16", 16000, 1}},
{109, {"L16", 32000, 1}},
{0, {"PCMU", 8000, 1}},
{8, {"PCMA", 8000, 1}},
#ifdef WEBRTC_CODEC_ILBC
{102, {"ILBC", 8000, 1}},
#endif
{9, {"G722", 8000, 1}}};
int file_num = 0;
for (const auto& send_codec : send_codecs) {
RTPFile rtpFile;
std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(
AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())));
std::string fileName = webrtc::test::TempFilename(
webrtc::test::OutputPath(), "encode_decode_rtp");
rtpFile.Open(fileName.c_str(), "wb+");
rtpFile.WriteHeader();
Sender sender;
sender.Setup(acm.get(), &rtpFile, "audio_coding/testfile32kHz", 32000,
send_codec.first, send_codec.second);
sender.Run();
sender.Teardown();
rtpFile.Close();
rtpFile.Open(fileName.c_str(), "rb");
rtpFile.ReadHeader();
Receiver receiver;
receiver.Setup(acm.get(), &rtpFile, "encodeDecode_out", 1, file_num);
receiver.Run();
receiver.Teardown();
rtpFile.Close();
file_num++;
}
}
} // namespace webrtc