This CL is to add Opus complexity knob and to test it.
As a by-product, a generic tool for testing and comparing the complexity of codecs is added, and new audio files are added to the resources. Three complexity tests are included 1. Default Opus complexity 2. Opus complexity knob 3. Default iSAC complexity (to compare with Opus) The complexity tests are only meant for development reasons and not to be run at bots. The .isolate file is only needed for the APK packaging and test execution on Android. TEST=passes all trybots BUG= R=kjellander@webrtc.org, tina.legrand@webrtc.org, turaj@webrtc.org Review URL: https://webrtc-codereview.appspot.com/8969004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5655 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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/codecs/tools/audio_codec_speed_test.h"
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/test/testsupport/fileutils.h"
|
||||
|
||||
using ::std::tr1::get;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
AudioCodecSpeedTest::AudioCodecSpeedTest(int block_duration_ms,
|
||||
int input_sampling_khz,
|
||||
int output_sampling_khz)
|
||||
: block_duration_ms_(block_duration_ms),
|
||||
input_sampling_khz_(input_sampling_khz),
|
||||
output_sampling_khz_(output_sampling_khz),
|
||||
input_length_sample_(block_duration_ms_ * input_sampling_khz_),
|
||||
output_length_sample_(block_duration_ms_ * output_sampling_khz_),
|
||||
data_pointer_(0),
|
||||
loop_length_samples_(0),
|
||||
max_bytes_(0),
|
||||
encoded_bytes_(0),
|
||||
encoding_time_ms_(0.0),
|
||||
decoding_time_ms_(0.0),
|
||||
out_file_(NULL) {
|
||||
}
|
||||
|
||||
void AudioCodecSpeedTest::SetUp() {
|
||||
channels_ = get<0>(GetParam());
|
||||
bit_rate_ = get<1>(GetParam());
|
||||
in_filename_ = test::ResourcePath(get<2>(GetParam()), get<3>(GetParam()));
|
||||
save_out_data_ = get<4>(GetParam());
|
||||
|
||||
FILE* fp = fopen(in_filename_.c_str(), "rb");
|
||||
assert(fp != NULL);
|
||||
|
||||
// Obtain file size.
|
||||
fseek(fp, 0, SEEK_END);
|
||||
loop_length_samples_ = ftell(fp) / sizeof(int16_t);
|
||||
rewind(fp);
|
||||
|
||||
// Allocate memory to contain the whole file.
|
||||
in_data_.reset(new int16_t[loop_length_samples_ +
|
||||
input_length_sample_ * channels_]);
|
||||
|
||||
data_pointer_ = 0;
|
||||
|
||||
// Copy the file into the buffer.
|
||||
ASSERT_EQ(fread(&in_data_[0], sizeof(int16_t), loop_length_samples_, fp),
|
||||
loop_length_samples_);
|
||||
fclose(fp);
|
||||
|
||||
// Add an extra block length of samples to the end of the array, starting
|
||||
// over again from the beginning of the array. This is done to simplify
|
||||
// the reading process when reading over the end of the loop.
|
||||
memcpy(&in_data_[loop_length_samples_], &in_data_[0],
|
||||
input_length_sample_ * channels_ * sizeof(int16_t));
|
||||
|
||||
max_bytes_ = input_length_sample_ * channels_ * sizeof(int16_t);
|
||||
out_data_.reset(new int16_t[output_length_sample_ * channels_]);
|
||||
bit_stream_.reset(new uint8_t[max_bytes_]);
|
||||
|
||||
if (save_out_data_) {
|
||||
std::string out_filename =
|
||||
::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||
|
||||
// Erase '/'
|
||||
size_t found;
|
||||
while ((found = out_filename.find('/')) != std::string::npos)
|
||||
out_filename.replace(found, 1, "_");
|
||||
|
||||
out_filename = test::OutputPath() + out_filename + ".pcm";
|
||||
|
||||
out_file_ = fopen(out_filename.c_str(), "wb");
|
||||
assert(out_file_ != NULL);
|
||||
|
||||
printf("Output to be saved in %s.\n", out_filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AudioCodecSpeedTest::TearDown() {
|
||||
if (save_out_data_) {
|
||||
fclose(out_file_);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioCodecSpeedTest::EncodeDecode(size_t audio_duration_sec) {
|
||||
size_t time_now_ms = 0;
|
||||
float time_ms;
|
||||
|
||||
printf("Coding %d kHz-sampled %d-channel audio at %d bps ...\n",
|
||||
input_sampling_khz_, channels_, bit_rate_);
|
||||
|
||||
while (time_now_ms < audio_duration_sec * 1000) {
|
||||
// Encode & decode.
|
||||
time_ms = EncodeABlock(&in_data_[data_pointer_], &bit_stream_[0],
|
||||
max_bytes_, &encoded_bytes_);
|
||||
encoding_time_ms_ += time_ms;
|
||||
time_ms = DecodeABlock(&bit_stream_[0], encoded_bytes_, &out_data_[0]);
|
||||
decoding_time_ms_ += time_ms;
|
||||
if (save_out_data_) {
|
||||
fwrite(&out_data_[0], sizeof(int16_t),
|
||||
output_length_sample_ * channels_, out_file_);
|
||||
}
|
||||
data_pointer_ = (data_pointer_ + input_length_sample_ * channels_) %
|
||||
loop_length_samples_;
|
||||
time_now_ms += block_duration_ms_;
|
||||
}
|
||||
|
||||
printf("Encoding: %.2f%% real time,\nDecoding: %.2f%% real time.\n",
|
||||
encoding_time_ms_ / audio_duration_sec / 10.0,
|
||||
decoding_time_ms_ / audio_duration_sec / 10.0);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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_CODECS_TOOLS_AUDIO_CODEC_SPEED_TEST_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_TOOLS_AUDIO_CODEC_SPEED_TEST_H_
|
||||
|
||||
#include <string>
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
using ::std::string;
|
||||
using ::std::tr1::tuple;
|
||||
using ::testing::TestWithParam;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Define coding parameter as
|
||||
// <channels, bit_rate, file_name, extension, if_save_output>.
|
||||
typedef tuple<int, int, string, string, bool> coding_param;
|
||||
|
||||
class AudioCodecSpeedTest : public TestWithParam<coding_param> {
|
||||
protected:
|
||||
AudioCodecSpeedTest(int block_duration_ms,
|
||||
int input_sampling_khz,
|
||||
int output_sampling_khz);
|
||||
virtual void SetUp();
|
||||
virtual void TearDown();
|
||||
|
||||
// EncodeABlock(...) does the following:
|
||||
// 1. encodes a block of audio, saved in |in_data|,
|
||||
// 2. save the bit stream to |bit_stream| of |max_bytes| bytes in size,
|
||||
// 3. assign |encoded_bytes| with the length of the bit stream (in bytes),
|
||||
// 4. return the cost of time (in millisecond) spent on actual encoding.
|
||||
virtual float EncodeABlock(int16_t* in_data, uint8_t* bit_stream,
|
||||
int max_bytes, int* encoded_bytes) = 0;
|
||||
|
||||
// DecodeABlock(...) does the following:
|
||||
// 1. decodes the bit stream in |bit_stream| with a length of |encoded_bytes|
|
||||
// (in bytes),
|
||||
// 2. save the decoded audio in |out_data|,
|
||||
// 3. return the cost of time (in millisecond) spent on actual decoding.
|
||||
virtual float DecodeABlock(const uint8_t* bit_stream, int encoded_bytes,
|
||||
int16_t* out_data) = 0;
|
||||
|
||||
// Encoding and decode an audio of |audio_duration| (in seconds) and
|
||||
// record the runtime for encoding and decoding separately.
|
||||
void EncodeDecode(size_t audio_duration);
|
||||
|
||||
int block_duration_ms_;
|
||||
int input_sampling_khz_;
|
||||
int output_sampling_khz_;
|
||||
|
||||
// Number of samples-per-channel in a frame.
|
||||
int input_length_sample_;
|
||||
|
||||
// Expected output number of samples-per-channel in a frame.
|
||||
int output_length_sample_;
|
||||
|
||||
scoped_ptr<int16_t[]> in_data_;
|
||||
scoped_ptr<int16_t[]> out_data_;
|
||||
size_t data_pointer_;
|
||||
size_t loop_length_samples_;
|
||||
scoped_ptr<uint8_t[]> bit_stream_;
|
||||
|
||||
// Maximum number of bytes in output bitstream for a frame of audio.
|
||||
int max_bytes_;
|
||||
|
||||
int encoded_bytes_;
|
||||
float encoding_time_ms_;
|
||||
float decoding_time_ms_;
|
||||
FILE* out_file_;
|
||||
|
||||
int channels_;
|
||||
|
||||
// Bit rate is in bit-per-second.
|
||||
int bit_rate_;
|
||||
|
||||
string in_filename_;
|
||||
|
||||
// Determines whether to save the output to file.
|
||||
bool save_out_data_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_TOOLS_AUDIO_CODEC_SPEED_TEST_H_
|
||||
@@ -0,0 +1,71 @@
|
||||
# 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.
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'audio_codec_speed_tests',
|
||||
'type': '<(gtest_target_type)',
|
||||
'dependencies': [
|
||||
'audio_processing',
|
||||
'iSACFix',
|
||||
'webrtc_opus',
|
||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
|
||||
'<(webrtc_root)/test/test.gyp:test_support_main',
|
||||
],
|
||||
'sources': [
|
||||
'audio_codec_speed_test.h',
|
||||
'audio_codec_speed_test.cc',
|
||||
'<(webrtc_root)/modules/audio_coding/codecs/opus/opus_speed_test.cc',
|
||||
'<(webrtc_root)/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc',
|
||||
],
|
||||
'conditions': [
|
||||
# TODO(henrike): remove build_with_chromium==1 when the bots are
|
||||
# using Chromium's buildbots.
|
||||
['build_with_chromium==1 and OS=="android" and gtest_target_type=="shared_library"', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/testing/android/native_test.gyp:native_test_native_code',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
'conditions': [
|
||||
# TODO(henrike): remove build_with_chromium==1 when the bots are using
|
||||
# Chromium's buildbots.
|
||||
['build_with_chromium==1 and OS=="android" and gtest_target_type=="shared_library"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'audio_codec_speed_tests_apk_target',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'<(apk_tests_path):audio_codec_speed_tests_apk',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
['test_isolation_mode != "noop"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'audio_codec_speed_tests_run',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'audio_codec_speed_tests',
|
||||
],
|
||||
'includes': [
|
||||
'../../../../build/isolate.gypi',
|
||||
'audio_codec_speed_tests.isolate',
|
||||
],
|
||||
'sources': [
|
||||
'audio_codec_speed_tests.isolate',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
# 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.
|
||||
{
|
||||
'conditions': [
|
||||
['OS=="android"', {
|
||||
# When doing Android builds, the WebRTC code is put in third_party/webrtc
|
||||
# of a Chromium checkout, this is one level above the standalone build.
|
||||
'variables': {
|
||||
'isolate_dependency_untracked': [
|
||||
'../../../../../../resources/',
|
||||
'../../../../../../data/',
|
||||
],
|
||||
},
|
||||
}],
|
||||
['OS=="linux" or OS=="mac" or OS=="win"', {
|
||||
'variables': {
|
||||
'command': [
|
||||
'../../../../../testing/test_env.py',
|
||||
'<(PRODUCT_DIR)/audio_codec_speed_tests<(EXECUTABLE_SUFFIX)',
|
||||
],
|
||||
'isolate_dependency_touched': [
|
||||
'../../../../../DEPS',
|
||||
],
|
||||
'isolate_dependency_tracked': [
|
||||
'../../../../../resources/audio_coding/music_stereo_48kHz.pcm',
|
||||
'../../../../../resources/audio_coding/speech_mono_16kHz.pcm',
|
||||
'../../../../../resources/audio_coding/speech_mono_32_48kHz.pcm',
|
||||
'../../../../../testing/test_env.py',
|
||||
'<(PRODUCT_DIR)/audio_codec_speed_tests<(EXECUTABLE_SUFFIX)',
|
||||
],
|
||||
'isolate_dependency_untracked': [
|
||||
'../../../../../tools/swarming_client/',
|
||||
],
|
||||
},
|
||||
}],
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user