iSAC unit test: test encode/decode via API wrapper
Unit test to test the iSAC webrtc API wrapper, plus a minor change in the c iSAC wrapper. Bug: webrtc:10584 Change-Id: Iecbf6f3e7db5b3bdba41f8428254ae6a6a73e24a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168492 Commit-Queue: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30514}
This commit is contained in:

committed by
Commit Bot

parent
d428ddd8f1
commit
b3548bf287
@ -744,7 +744,8 @@ rtc_library("webrtc_opus") {
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
public_deps = [ ":webrtc_opus_wrapper" ] # no-presubmit-check TODO(webrtc:8603)
|
||||
public_deps = # no-presubmit-check TODO(webrtc:8603)
|
||||
[ ":webrtc_opus_wrapper" ]
|
||||
|
||||
defines = audio_codec_defines
|
||||
|
||||
@ -780,7 +781,8 @@ rtc_library("webrtc_multiopus") {
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
public_deps = [ ":webrtc_opus_wrapper" ] # no-presubmit-check TODO(webrtc:8603)
|
||||
public_deps = # no-presubmit-check TODO(webrtc:8603)
|
||||
[ ":webrtc_opus_wrapper" ]
|
||||
|
||||
defines = audio_codec_defines
|
||||
|
||||
@ -865,7 +867,8 @@ rtc_library("audio_network_adaptor") {
|
||||
"audio_network_adaptor/util/threshold_curve.h",
|
||||
]
|
||||
|
||||
public_deps = [ ":audio_network_adaptor_config" ] # no-presubmit-check TODO(webrtc:8603)
|
||||
public_deps = # no-presubmit-check TODO(webrtc:8603)
|
||||
[ ":audio_network_adaptor_config" ]
|
||||
|
||||
deps = [
|
||||
"../../api/audio_codecs:audio_codecs_api",
|
||||
@ -1160,7 +1163,8 @@ if (rtc_enable_protobuf) {
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
public_deps = [ "../../logging:rtc_event_log_proto" ] # no-presubmit-check TODO(webrtc:8603)
|
||||
public_deps = # no-presubmit-check TODO(webrtc:8603)
|
||||
[ "../../logging:rtc_event_log_proto" ]
|
||||
}
|
||||
|
||||
# Only used for test purpose. Since we want to use it from chromium
|
||||
@ -1911,6 +1915,7 @@ if (rtc_include_tests) {
|
||||
"codecs/isac/fix/source/filters_unittest.cc",
|
||||
"codecs/isac/fix/source/lpc_masking_model_unittest.cc",
|
||||
"codecs/isac/fix/source/transform_unittest.cc",
|
||||
"codecs/isac/isac_webrtc_api_test.cc",
|
||||
"codecs/isac/main/source/audio_encoder_isac_unittest.cc",
|
||||
"codecs/isac/main/source/isac_unittest.cc",
|
||||
"codecs/legacy_encoded_audio_frame_unittest.cc",
|
||||
@ -1976,6 +1981,7 @@ if (rtc_include_tests) {
|
||||
":ilbc",
|
||||
":isac",
|
||||
":isac_c",
|
||||
":isac_common",
|
||||
":isac_fix",
|
||||
":legacy_encoded_audio_frame",
|
||||
":mocks",
|
||||
@ -1988,10 +1994,15 @@ if (rtc_include_tests) {
|
||||
":webrtc_opus",
|
||||
"..:module_api",
|
||||
"..:module_api_public",
|
||||
"../../api:array_view",
|
||||
"../../api/audio:audio_frame_api",
|
||||
"../../api/audio_codecs:audio_codecs_api",
|
||||
"../../api/audio_codecs:builtin_audio_decoder_factory",
|
||||
"../../api/audio_codecs:builtin_audio_encoder_factory",
|
||||
"../../api/audio_codecs/isac:audio_decoder_isac_fix",
|
||||
"../../api/audio_codecs/isac:audio_decoder_isac_float",
|
||||
"../../api/audio_codecs/isac:audio_encoder_isac_fix",
|
||||
"../../api/audio_codecs/isac:audio_encoder_isac_float",
|
||||
"../../api/audio_codecs/opus:audio_decoder_multiopus",
|
||||
"../../api/audio_codecs/opus:audio_decoder_opus",
|
||||
"../../api/audio_codecs/opus:audio_encoder_multiopus",
|
||||
|
145
modules/audio_coding/codecs/isac/isac_webrtc_api_test.cc
Normal file
145
modules/audio_coding/codecs/isac/isac_webrtc_api_test.cc
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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 <array>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h"
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_float.h"
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h"
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
|
||||
#include "rtc_base/random.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
constexpr int kPayloadType = 42;
|
||||
constexpr int kBitrateBps = 20000;
|
||||
|
||||
enum class IsacImpl { kFixed, kFloat };
|
||||
|
||||
std::vector<int16_t> GetRandomSamplesVector(size_t size) {
|
||||
constexpr int32_t kMin = std::numeric_limits<int16_t>::min();
|
||||
constexpr int32_t kMax = std::numeric_limits<int16_t>::max();
|
||||
std::vector<int16_t> v(size);
|
||||
Random gen(/*seed=*/42);
|
||||
for (auto& x : v) {
|
||||
x = static_cast<int16_t>(gen.Rand(kMin, kMax));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
class IsacApiTest
|
||||
: public testing::TestWithParam<std::tuple<int, int, IsacImpl, IsacImpl>> {
|
||||
protected:
|
||||
IsacApiTest() : input_frame_(GetRandomSamplesVector(GetInputFrameLength())) {}
|
||||
rtc::ArrayView<const int16_t> GetInputFrame() { return input_frame_; }
|
||||
int GetSampleRateHz() const { return std::get<0>(GetParam()); }
|
||||
int GetEncoderFrameLenght() const {
|
||||
return GetEncoderFrameLenghtMs() * GetSampleRateHz() / 1000;
|
||||
}
|
||||
std::unique_ptr<AudioEncoder> CreateEncoder() const {
|
||||
switch (GetEncoderIsacImpl()) {
|
||||
case IsacImpl::kFixed: {
|
||||
AudioEncoderIsacFix::Config config;
|
||||
config.frame_size_ms = GetEncoderFrameLenghtMs();
|
||||
RTC_CHECK_EQ(16000, GetSampleRateHz());
|
||||
return AudioEncoderIsacFix::MakeAudioEncoder(config, kPayloadType);
|
||||
}
|
||||
case IsacImpl::kFloat: {
|
||||
AudioEncoderIsacFloat::Config config;
|
||||
config.bit_rate = kBitrateBps;
|
||||
config.frame_size_ms = GetEncoderFrameLenghtMs();
|
||||
config.sample_rate_hz = GetSampleRateHz();
|
||||
return AudioEncoderIsacFloat::MakeAudioEncoder(config, kPayloadType);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::unique_ptr<AudioDecoder> CreateDecoder() const {
|
||||
switch (GetDecoderIsacImpl()) {
|
||||
case IsacImpl::kFixed: {
|
||||
webrtc::AudioDecoderIsacFix::Config config;
|
||||
RTC_CHECK_EQ(16000, GetSampleRateHz());
|
||||
return webrtc::AudioDecoderIsacFix::MakeAudioDecoder(config);
|
||||
}
|
||||
case IsacImpl::kFloat: {
|
||||
webrtc::AudioDecoderIsacFloat::Config config;
|
||||
config.sample_rate_hz = GetSampleRateHz();
|
||||
return webrtc::AudioDecoderIsacFloat::MakeAudioDecoder(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<int16_t> input_frame_;
|
||||
int GetInputFrameLength() const {
|
||||
return rtc::CheckedDivExact(std::get<0>(GetParam()), 100); // 10 ms.
|
||||
}
|
||||
int GetEncoderFrameLenghtMs() const {
|
||||
int frame_size_ms = std::get<1>(GetParam());
|
||||
RTC_CHECK(frame_size_ms == 30 || frame_size_ms == 60);
|
||||
return frame_size_ms;
|
||||
}
|
||||
IsacImpl GetEncoderIsacImpl() const { return std::get<2>(GetParam()); }
|
||||
IsacImpl GetDecoderIsacImpl() const { return std::get<3>(GetParam()); }
|
||||
};
|
||||
|
||||
// Checks that the number of encoded and decoded samples match.
|
||||
TEST_P(IsacApiTest, EncodeDecode) {
|
||||
auto encoder = CreateEncoder();
|
||||
auto decoder = CreateDecoder();
|
||||
const int encoder_frame_length = GetEncoderFrameLenght();
|
||||
std::vector<int16_t> out(encoder_frame_length);
|
||||
size_t num_encoded_samples = 0;
|
||||
size_t num_decoded_samples = 0;
|
||||
constexpr int kNumFrames = 12;
|
||||
for (int i = 0; i < kNumFrames; ++i) {
|
||||
rtc::Buffer encoded;
|
||||
auto in = GetInputFrame();
|
||||
encoder->Encode(/*rtp_timestamp=*/0, in, &encoded);
|
||||
num_encoded_samples += in.size();
|
||||
if (encoded.empty()) {
|
||||
continue;
|
||||
}
|
||||
// Decode.
|
||||
const std::vector<AudioDecoder::ParseResult> parse_result =
|
||||
decoder->ParsePayload(std::move(encoded), /*timestamp=*/0);
|
||||
EXPECT_EQ(parse_result.size(), size_t{1});
|
||||
auto decode_result = parse_result[0].frame->Decode(out);
|
||||
EXPECT_TRUE(decode_result.has_value());
|
||||
EXPECT_EQ(out.size(), decode_result->num_decoded_samples);
|
||||
num_decoded_samples += decode_result->num_decoded_samples;
|
||||
}
|
||||
EXPECT_EQ(num_encoded_samples, num_decoded_samples);
|
||||
}
|
||||
|
||||
// Creates tests for different encoder frame lengths and different
|
||||
// encoder/decoder implementations.
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
AllTest,
|
||||
IsacApiTest,
|
||||
::testing::ValuesIn([] {
|
||||
std::vector<std::tuple<int, int, IsacImpl, IsacImpl>> cases;
|
||||
for (int frame_length_ms : {30, 60}) {
|
||||
for (IsacImpl enc : {IsacImpl::kFloat, IsacImpl::kFixed}) {
|
||||
for (IsacImpl dec : {IsacImpl::kFloat, IsacImpl::kFixed}) {
|
||||
cases.push_back({16000, frame_length_ms, enc, dec});
|
||||
}
|
||||
}
|
||||
}
|
||||
cases.push_back({32000, 30, IsacImpl::kFloat, IsacImpl::kFloat});
|
||||
return cases;
|
||||
}()));
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
@ -252,7 +252,7 @@ int16_t WebRtcIsac_ControlBwe(ISACStruct* ISAC_main_inst,
|
||||
*
|
||||
*/
|
||||
|
||||
int16_t WebRtcIsac_ReadFrameLen(ISACStruct* ISAC_main_inst,
|
||||
int16_t WebRtcIsac_ReadFrameLen(const ISACStruct* ISAC_main_inst,
|
||||
const uint8_t* encoded,
|
||||
int16_t* frameLength);
|
||||
|
||||
|
@ -1719,7 +1719,7 @@ int16_t WebRtcIsac_ReadBwIndex(const uint8_t* encoded,
|
||||
* - frameLength : Length of frame in packet (in samples)
|
||||
*
|
||||
*/
|
||||
int16_t WebRtcIsac_ReadFrameLen(ISACStruct* ISAC_main_inst,
|
||||
int16_t WebRtcIsac_ReadFrameLen(const ISACStruct* ISAC_main_inst,
|
||||
const uint8_t* encoded,
|
||||
int16_t* frameLength) {
|
||||
Bitstr streamdata;
|
||||
|
Reference in New Issue
Block a user