Update NetEq Quality Test.
1. move channel number of input file to the base class 2. limit channel number to be 1, since the resampler support only mono at the moment 3. adding a logging function 4. adding more switch to neteq_opus_quality_test BUG=2692 R=henrik.lundin@webrtc.org Review URL: https://webrtc-codereview.appspot.com/47239004 Cr-Commit-Position: refs/heads/master@{#9260}
This commit is contained in:
parent
915df4fc30
commit
f761d10393
@ -47,11 +47,15 @@ class NetEqIlbcQualityTest : public NetEqQualityTest {
|
||||
: NetEqQualityTest(FLAGS_frame_size_ms,
|
||||
kInputSampleRateKhz,
|
||||
kOutputSampleRateKhz,
|
||||
kDecoderILBC,
|
||||
1) {
|
||||
kDecoderILBC) {
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
ASSERT_EQ(1, channels_) << "iLBC supports only mono audio.";
|
||||
AudioEncoderIlbc::Config config;
|
||||
config.frame_size_ms = FLAGS_frame_size_ms;
|
||||
encoder_.reset(new AudioEncoderIlbc(config));
|
||||
NetEqQualityTest::SetUp();
|
||||
}
|
||||
|
||||
int EncodeBlock(int16_t* in_data,
|
||||
|
||||
@ -54,13 +54,13 @@ NetEqIsacQualityTest::NetEqIsacQualityTest()
|
||||
: NetEqQualityTest(kIsacBlockDurationMs,
|
||||
kIsacInputSamplingKhz,
|
||||
kIsacOutputSamplingKhz,
|
||||
kDecoderISAC,
|
||||
1),
|
||||
kDecoderISAC),
|
||||
isac_encoder_(NULL),
|
||||
bit_rate_kbps_(FLAGS_bit_rate_kbps) {
|
||||
}
|
||||
|
||||
void NetEqIsacQualityTest::SetUp() {
|
||||
ASSERT_EQ(1, channels_) << "iSAC supports only mono audio.";
|
||||
// Create encoder memory.
|
||||
WebRtcIsacfix_Create(&isac_encoder_);
|
||||
ASSERT_TRUE(isac_encoder_ != NULL);
|
||||
|
||||
@ -24,34 +24,6 @@ namespace {
|
||||
static const int kOpusBlockDurationMs = 20;
|
||||
static const int kOpusSamplingKhz = 48;
|
||||
|
||||
// Define switch for sample rate.
|
||||
static bool ValidateSampleRate(const char* flagname, int32_t value) {
|
||||
if (value == 8000 || value == 16000 || value == 32000 || value == 48000)
|
||||
return true;
|
||||
printf("Invalid sample rate should be 8000, 16000, 32000 or 48000 Hz.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_int32(input_sample_rate,
|
||||
kOpusSamplingKhz * 1000,
|
||||
"Sample rate of input file.");
|
||||
|
||||
static const bool sample_rate_dummy =
|
||||
RegisterFlagValidator(&FLAGS_input_sample_rate, &ValidateSampleRate);
|
||||
|
||||
// Define switch for channels.
|
||||
static bool ValidateChannels(const char* flagname, int32_t value) {
|
||||
if (value == 1 || value == 2)
|
||||
return true;
|
||||
printf("Invalid number of channels, should be either 1 or 2.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_int32(channels, 1, "Number of channels in input audio.");
|
||||
|
||||
static const bool channels_dummy =
|
||||
RegisterFlagValidator(&FLAGS_channels, &ValidateChannels);
|
||||
|
||||
// Define switch for bit rate.
|
||||
static bool ValidateBitRate(const char* flagname, int32_t value) {
|
||||
if (value >= 6 && value <= 510)
|
||||
@ -65,6 +37,37 @@ DEFINE_int32(bit_rate_kbps, 32, "Target bit rate (kbps).");
|
||||
static const bool bit_rate_dummy =
|
||||
RegisterFlagValidator(&FLAGS_bit_rate_kbps, &ValidateBitRate);
|
||||
|
||||
// Define switch for complexity.
|
||||
static bool ValidateComplexity(const char* flagname, int32_t value) {
|
||||
if (value >= -1 && value <= 10)
|
||||
return true;
|
||||
printf("Invalid complexity setting, should be between 0 and 10.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_int32(complexity, 10, "Complexity: 0 ~ 10 -- defined as in Opus"
|
||||
"specification.");
|
||||
|
||||
static const bool complexity_dummy =
|
||||
RegisterFlagValidator(&FLAGS_complexity, &ValidateComplexity);
|
||||
|
||||
// Define switch for maxplaybackrate
|
||||
DEFINE_int32(maxplaybackrate, 48000, "Maximum playback rate (Hz).");
|
||||
|
||||
// Define switch for application mode.
|
||||
static bool ValidateApplication(const char* flagname, int32_t value) {
|
||||
if (value != 0 && value != 1) {
|
||||
printf("Invalid application mode, should be 0 or 1.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DEFINE_int32(application, 0, "Application mode: 0 -- VOIP, 1 -- Audio.");
|
||||
|
||||
static const bool application_dummy =
|
||||
RegisterFlagValidator(&FLAGS_application, &ValidateApplication);
|
||||
|
||||
// Define switch for reported packet loss rate.
|
||||
static bool ValidatePacketLossRate(const char* flagname, int32_t value) {
|
||||
if (value >= 0 && value <= 100)
|
||||
@ -106,36 +109,41 @@ class NetEqOpusQualityTest : public NetEqQualityTest {
|
||||
WebRtcOpusEncInst* opus_encoder_;
|
||||
OpusRepacketizer* repacketizer_;
|
||||
int sub_block_size_samples_;
|
||||
int channels_;
|
||||
int bit_rate_kbps_;
|
||||
bool fec_;
|
||||
bool dtx_;
|
||||
int complexity_;
|
||||
int maxplaybackrate_;
|
||||
int target_loss_rate_;
|
||||
int sub_packets_;
|
||||
int application_;
|
||||
};
|
||||
|
||||
NetEqOpusQualityTest::NetEqOpusQualityTest()
|
||||
: NetEqQualityTest(kOpusBlockDurationMs * FLAGS_sub_packets,
|
||||
kOpusSamplingKhz,
|
||||
kOpusSamplingKhz,
|
||||
(FLAGS_channels == 1) ? kDecoderOpus : kDecoderOpus_2ch,
|
||||
FLAGS_channels),
|
||||
kDecoderOpus),
|
||||
opus_encoder_(NULL),
|
||||
repacketizer_(NULL),
|
||||
sub_block_size_samples_(kOpusBlockDurationMs * kOpusSamplingKhz),
|
||||
channels_(FLAGS_channels),
|
||||
bit_rate_kbps_(FLAGS_bit_rate_kbps),
|
||||
fec_(FLAGS_fec),
|
||||
dtx_(FLAGS_dtx),
|
||||
complexity_(FLAGS_complexity),
|
||||
maxplaybackrate_(FLAGS_maxplaybackrate),
|
||||
target_loss_rate_(FLAGS_reported_loss_rate),
|
||||
sub_packets_(FLAGS_sub_packets) {
|
||||
// Redefine decoder type if input is stereo.
|
||||
if (channels_ > 1) {
|
||||
decoder_type_ = kDecoderOpus_2ch;
|
||||
}
|
||||
application_ = FLAGS_application;
|
||||
}
|
||||
|
||||
void NetEqOpusQualityTest::SetUp() {
|
||||
// If channels_ == 1, use Opus VOIP mode, otherwise, audio mode.
|
||||
int app = channels_ == 1 ? 0 : 1;
|
||||
// Create encoder memory.
|
||||
WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, app);
|
||||
WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, application_);
|
||||
ASSERT_TRUE(opus_encoder_);
|
||||
|
||||
// Create repacketizer.
|
||||
@ -150,6 +158,8 @@ void NetEqOpusQualityTest::SetUp() {
|
||||
if (dtx_) {
|
||||
EXPECT_EQ(0, WebRtcOpus_EnableDtx(opus_encoder_));
|
||||
}
|
||||
EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, complexity_));
|
||||
EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, maxplaybackrate_));
|
||||
EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(opus_encoder_,
|
||||
target_loss_rate_));
|
||||
NetEqQualityTest::SetUp();
|
||||
@ -172,6 +182,9 @@ int NetEqOpusQualityTest::EncodeBlock(int16_t* in_data,
|
||||
for (int idx = 0; idx < sub_packets_; idx++) {
|
||||
value = WebRtcOpus_Encode(opus_encoder_, pointer, sub_block_size_samples_,
|
||||
max_bytes, payload);
|
||||
Log() << "Encoded a frame with Opus mode "
|
||||
<< (value == 0 ? 0 : payload[0] >> 3)
|
||||
<< std::endl;
|
||||
if (OPUS_OK != opus_repacketizer_cat(repacketizer_, payload, value)) {
|
||||
opus_repacketizer_init(repacketizer_);
|
||||
// If the repacketization fails, we discard this frame.
|
||||
|
||||
@ -47,11 +47,15 @@ class NetEqPcmuQualityTest : public NetEqQualityTest {
|
||||
: NetEqQualityTest(FLAGS_frame_size_ms,
|
||||
kInputSampleRateKhz,
|
||||
kOutputSampleRateKhz,
|
||||
kDecoderPCMu,
|
||||
1) {
|
||||
kDecoderPCMu) {
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
ASSERT_EQ(1, channels_) << "PCMu supports only mono audio.";
|
||||
AudioEncoderPcmU::Config config;
|
||||
config.frame_size_ms = FLAGS_frame_size_ms;
|
||||
encoder_.reset(new AudioEncoderPcmU(config));
|
||||
NetEqQualityTest::SetUp();
|
||||
}
|
||||
|
||||
int EncodeBlock(int16_t* in_data,
|
||||
|
||||
@ -48,7 +48,8 @@ static bool ValidateInFilename(const char* flagname, const string& value) {
|
||||
DEFINE_string(
|
||||
in_filename,
|
||||
ResourcePath("audio_coding/speech_mono_16kHz", "pcm"),
|
||||
"Filename for input audio (specify sample rate with --input_sample_rate).");
|
||||
"Filename for input audio (specify sample rate with --input_sample_rate ,"
|
||||
"and channels with --channels).");
|
||||
|
||||
static const bool in_filename_dummy =
|
||||
RegisterFlagValidator(&FLAGS_in_filename, &ValidateInFilename);
|
||||
@ -66,6 +67,19 @@ DEFINE_int32(input_sample_rate, 16000, "Sample rate of input file in Hz.");
|
||||
static const bool sample_rate_dummy =
|
||||
RegisterFlagValidator(&FLAGS_input_sample_rate, &ValidateSampleRate);
|
||||
|
||||
// Define switch for channels.
|
||||
static bool ValidateChannels(const char* flagname, int32_t value) {
|
||||
if (value == 1)
|
||||
return true;
|
||||
printf("Invalid number of channels, current support only 1.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_int32(channels, 1, "Number of channels in input audio.");
|
||||
|
||||
static const bool channels_dummy =
|
||||
RegisterFlagValidator(&FLAGS_channels, &ValidateChannels);
|
||||
|
||||
// Define switch for output file name.
|
||||
static bool ValidateOutFilename(const char* flagname, const string& value) {
|
||||
if (!ValidateFilename(value, true)) {
|
||||
@ -194,17 +208,16 @@ static double ProbTrans00Solver(int units, double loss_rate,
|
||||
NetEqQualityTest::NetEqQualityTest(int block_duration_ms,
|
||||
int in_sampling_khz,
|
||||
int out_sampling_khz,
|
||||
enum NetEqDecoder decoder_type,
|
||||
int channels)
|
||||
: decoded_time_ms_(0),
|
||||
enum NetEqDecoder decoder_type)
|
||||
: decoder_type_(decoder_type),
|
||||
channels_(FLAGS_channels),
|
||||
decoded_time_ms_(0),
|
||||
decodable_time_ms_(0),
|
||||
drift_factor_(FLAGS_drift_factor),
|
||||
packet_loss_rate_(FLAGS_packet_loss_rate),
|
||||
block_duration_ms_(block_duration_ms),
|
||||
in_sampling_khz_(in_sampling_khz),
|
||||
out_sampling_khz_(out_sampling_khz),
|
||||
decoder_type_(decoder_type),
|
||||
channels_(channels),
|
||||
in_size_samples_(in_sampling_khz_ * block_duration_ms_),
|
||||
out_size_samples_(out_sampling_khz_ * kOutputSizeMs),
|
||||
payload_size_bytes_(0),
|
||||
@ -212,14 +225,13 @@ NetEqQualityTest::NetEqQualityTest(int block_duration_ms,
|
||||
in_file_(new ResampleInputAudioFile(FLAGS_in_filename,
|
||||
FLAGS_input_sample_rate,
|
||||
in_sampling_khz * 1000)),
|
||||
log_file_(NULL),
|
||||
rtp_generator_(
|
||||
new RtpGenerator(in_sampling_khz_, 0, 0, decodable_time_ms_)),
|
||||
total_payload_size_bytes_(0) {
|
||||
const std::string out_filename = FLAGS_out_filename;
|
||||
const std::string log_filename = out_filename + ".log";
|
||||
log_file_ = fopen(log_filename.c_str(), "wt");
|
||||
CHECK(log_file_);
|
||||
log_file_.open(log_filename.c_str(), std::ofstream::out);
|
||||
CHECK(log_file_.is_open());
|
||||
|
||||
if (out_filename.size() >= 4 &&
|
||||
out_filename.substr(out_filename.size() - 4) == ".wav") {
|
||||
@ -240,6 +252,10 @@ NetEqQualityTest::NetEqQualityTest(int block_duration_ms,
|
||||
out_data_.reset(new int16_t[out_size_samples_ * channels_]);
|
||||
}
|
||||
|
||||
NetEqQualityTest::~NetEqQualityTest() {
|
||||
log_file_.close();
|
||||
}
|
||||
|
||||
bool NoLoss::Lost() {
|
||||
return false;
|
||||
}
|
||||
@ -328,6 +344,10 @@ void NetEqQualityTest::SetUp() {
|
||||
srand(kInitSeed);
|
||||
}
|
||||
|
||||
std::ofstream& NetEqQualityTest::Log() {
|
||||
return log_file_;
|
||||
}
|
||||
|
||||
bool NetEqQualityTest::PacketLost() {
|
||||
int cycles = block_duration_ms_ / kPacketLossTimeUnitMs;
|
||||
|
||||
@ -349,19 +369,24 @@ int NetEqQualityTest::Transmit() {
|
||||
int packet_input_time_ms =
|
||||
rtp_generator_->GetRtpHeader(kPayloadType, in_size_samples_,
|
||||
&rtp_header_);
|
||||
Log() << "Packet of size "
|
||||
<< payload_size_bytes_
|
||||
<< " bytes, for frame at "
|
||||
<< packet_input_time_ms
|
||||
<< " ms ";
|
||||
if (payload_size_bytes_ > 0) {
|
||||
fprintf(log_file_, "Packet at %d ms", packet_input_time_ms);
|
||||
if (!PacketLost()) {
|
||||
int ret = neteq_->InsertPacket(rtp_header_, &payload_[0],
|
||||
payload_size_bytes_,
|
||||
packet_input_time_ms * in_sampling_khz_);
|
||||
if (ret != NetEq::kOK)
|
||||
return -1;
|
||||
fprintf(log_file_, " OK.\n");
|
||||
Log() << "was sent.";
|
||||
} else {
|
||||
fprintf(log_file_, " Lost.\n");
|
||||
Log() << "was lost.";
|
||||
}
|
||||
}
|
||||
Log() << std::endl;
|
||||
return packet_input_time_ms;
|
||||
}
|
||||
|
||||
@ -399,7 +424,10 @@ void NetEqQualityTest::Simulate() {
|
||||
decoded_time_ms_ += audio_size_samples / out_sampling_khz_;
|
||||
}
|
||||
}
|
||||
fprintf(log_file_, "%f", 8.0f * total_payload_size_bytes_ / FLAGS_runtime_ms);
|
||||
Log() << "Average bit rate was "
|
||||
<< 8.0f * total_payload_size_bytes_ / FLAGS_runtime_ms
|
||||
<< " kbps"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <gflags/gflags.h>
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
@ -65,8 +66,9 @@ class NetEqQualityTest : public ::testing::Test {
|
||||
NetEqQualityTest(int block_duration_ms,
|
||||
int in_sampling_khz,
|
||||
int out_sampling_khz,
|
||||
enum NetEqDecoder decoder_type,
|
||||
int channels);
|
||||
enum NetEqDecoder decoder_type);
|
||||
virtual ~NetEqQualityTest();
|
||||
|
||||
void SetUp() override;
|
||||
|
||||
// EncodeBlock(...) does the following:
|
||||
@ -93,6 +95,12 @@ class NetEqQualityTest : public ::testing::Test {
|
||||
// Runs encoding / transmitting / decoding.
|
||||
void Simulate();
|
||||
|
||||
// Write to log file. Usage Log() << ...
|
||||
std::ofstream& Log();
|
||||
|
||||
enum NetEqDecoder decoder_type_;
|
||||
const int channels_;
|
||||
|
||||
private:
|
||||
int decoded_time_ms_;
|
||||
int decodable_time_ms_;
|
||||
@ -101,8 +109,6 @@ class NetEqQualityTest : public ::testing::Test {
|
||||
const int block_duration_ms_;
|
||||
const int in_sampling_khz_;
|
||||
const int out_sampling_khz_;
|
||||
const enum NetEqDecoder decoder_type_;
|
||||
const int channels_;
|
||||
|
||||
// Number of samples per channel in a frame.
|
||||
const int in_size_samples_;
|
||||
@ -115,7 +121,7 @@ class NetEqQualityTest : public ::testing::Test {
|
||||
|
||||
rtc::scoped_ptr<InputAudioFile> in_file_;
|
||||
rtc::scoped_ptr<AudioSink> output_;
|
||||
FILE* log_file_;
|
||||
std::ofstream log_file_;
|
||||
|
||||
rtc::scoped_ptr<RtpGenerator> rtp_generator_;
|
||||
rtc::scoped_ptr<NetEq> neteq_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user