Re-implementing AcmOpusTest as AcmGenericCodecOpusTest
The old AcmOpusTest depends on the ACMOpus class, but this class was obsoleted by AudioEncoderOpus. In this CL, the test code is re-written to use AudioEncoderOpus and ACMGenericCodecWrapper instead of ACMOpus. Most of the test functionality is preserved, except for the packet loss rate tests, which where already transferred to AudioEncoderOpusTest in r8244. R=kwiberg@webrtc.org, minyue@webrtc.org Review URL: https://webrtc-codereview.appspot.com/40029004 Cr-Commit-Position: refs/heads/master@{#8410} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8410 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
f68e186de3
commit
635838bd9b
@ -51,6 +51,7 @@ class AudioEncoderOpus final : public AudioEncoder {
|
|||||||
void SetTargetBitrate(int bits_per_second) override;
|
void SetTargetBitrate(int bits_per_second) override;
|
||||||
void SetProjectedPacketLossRate(double fraction) override;
|
void SetProjectedPacketLossRate(double fraction) override;
|
||||||
double packet_loss_rate() const { return packet_loss_rate_; }
|
double packet_loss_rate() const { return packet_loss_rate_; }
|
||||||
|
ApplicationMode application() const { return application_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool EncodeInternal(uint32_t rtp_timestamp,
|
virtual bool EncodeInternal(uint32_t rtp_timestamp,
|
||||||
|
@ -1715,6 +1715,11 @@ bool ACMGenericCodecWrapper::ExternalRedNeeded() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AudioEncoder* ACMGenericCodecWrapper::GetAudioEncoder() const {
|
||||||
|
WriteLockScoped wl(codec_wrapper_lock_);
|
||||||
|
return encoder_;
|
||||||
|
}
|
||||||
|
|
||||||
void ACMGenericCodecWrapper::DestructEncoderSafe() {
|
void ACMGenericCodecWrapper::DestructEncoderSafe() {
|
||||||
FATAL();
|
FATAL();
|
||||||
}
|
}
|
||||||
|
@ -1111,6 +1111,9 @@ class ACMGenericCodecWrapper : public ACMGenericCodec {
|
|||||||
|
|
||||||
bool ExternalRedNeeded() override;
|
bool ExternalRedNeeded() override;
|
||||||
|
|
||||||
|
// This method is only for testing.
|
||||||
|
const AudioEncoder* GetAudioEncoder() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DestructEncoderSafe() override
|
void DestructEncoderSafe() override
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
|
EXCLUSIVE_LOCKS_REQUIRED(codec_wrapper_lock_);
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 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 "testing/gtest/include/gtest/gtest.h"
|
||||||
|
#include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"
|
||||||
|
#include "webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace acm2 {
|
||||||
|
|
||||||
|
#ifdef WEBRTC_CODEC_OPUS
|
||||||
|
namespace {
|
||||||
|
const CodecInst kDefaultOpusCodecInst = {105, "opus", 48000, 960, 1, 32000};
|
||||||
|
const int kCngPt = 255; // Not using CNG in this test.
|
||||||
|
const int kRedPt = 255; // Not using RED in this test.
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class AcmGenericCodecOpusTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
AcmGenericCodecOpusTest() {
|
||||||
|
acm_codec_params_ = {kDefaultOpusCodecInst, false, false, VADNormal};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateCodec() {
|
||||||
|
codec_wrapper_.reset(new ACMGenericCodecWrapper(
|
||||||
|
acm_codec_params_.codec_inst, kCngPt, kCngPt, kCngPt, kCngPt,
|
||||||
|
false /* enable RED */, kRedPt));
|
||||||
|
ASSERT_TRUE(codec_wrapper_);
|
||||||
|
ASSERT_EQ(0, codec_wrapper_->InitEncoder(&acm_codec_params_, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
const AudioEncoderOpus* GetAudioEncoderOpus() {
|
||||||
|
const AudioEncoderOpus* ptr = static_cast<const AudioEncoderOpus*>(
|
||||||
|
codec_wrapper_->GetAudioEncoder());
|
||||||
|
EXPECT_NE(nullptr, ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
WebRtcACMCodecParams acm_codec_params_;
|
||||||
|
scoped_ptr<ACMGenericCodecWrapper> codec_wrapper_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AcmGenericCodecOpusTest, DefaultApplicationModeMono) {
|
||||||
|
acm_codec_params_.codec_inst.channels = 1;
|
||||||
|
CreateCodec();
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kVoip, GetAudioEncoderOpus()->application());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AcmGenericCodecOpusTest, DefaultApplicationModeStereo) {
|
||||||
|
acm_codec_params_.codec_inst.channels = 2;
|
||||||
|
CreateCodec();
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kAudio, GetAudioEncoderOpus()->application());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AcmGenericCodecOpusTest, ChangeApplicationMode) {
|
||||||
|
// Create a stereo encoder.
|
||||||
|
acm_codec_params_.codec_inst.channels = 2;
|
||||||
|
CreateCodec();
|
||||||
|
// Verify that the mode is kAudio.
|
||||||
|
const AudioEncoderOpus* opus_ptr = GetAudioEncoderOpus();
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kAudio, opus_ptr->application());
|
||||||
|
|
||||||
|
// Change mode.
|
||||||
|
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip));
|
||||||
|
// Verify that the AudioEncoder object was changed.
|
||||||
|
EXPECT_NE(opus_ptr, GetAudioEncoderOpus());
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kVoip, GetAudioEncoderOpus()->application());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AcmGenericCodecOpusTest, ResetWontChangeApplicationMode) {
|
||||||
|
// Create a stereo encoder.
|
||||||
|
acm_codec_params_.codec_inst.channels = 2;
|
||||||
|
CreateCodec();
|
||||||
|
const AudioEncoderOpus* opus_ptr = GetAudioEncoderOpus();
|
||||||
|
// Verify that the mode is kAudio.
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kAudio, opus_ptr->application());
|
||||||
|
|
||||||
|
// Trigger a reset.
|
||||||
|
ASSERT_EQ(0, codec_wrapper_->InitEncoder(&acm_codec_params_, false));
|
||||||
|
// Verify that the AudioEncoder object changed.
|
||||||
|
EXPECT_NE(opus_ptr, GetAudioEncoderOpus());
|
||||||
|
// Verify that the mode is still kAudio.
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kAudio, GetAudioEncoderOpus()->application());
|
||||||
|
|
||||||
|
// Now change to kVoip.
|
||||||
|
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip));
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kVoip, GetAudioEncoderOpus()->application());
|
||||||
|
|
||||||
|
opus_ptr = GetAudioEncoderOpus();
|
||||||
|
// Trigger a reset again.
|
||||||
|
ASSERT_EQ(0, codec_wrapper_->InitEncoder(&acm_codec_params_, false));
|
||||||
|
// Verify that the AudioEncoder object changed.
|
||||||
|
EXPECT_NE(opus_ptr, GetAudioEncoderOpus());
|
||||||
|
// Verify that the mode is still kVoip.
|
||||||
|
EXPECT_EQ(AudioEncoderOpus::kVoip, GetAudioEncoderOpus()->application());
|
||||||
|
}
|
||||||
|
#endif // WEBRTC_CODEC_OPUS
|
||||||
|
|
||||||
|
} // namespace acm2
|
||||||
|
} // namespace webrtc
|
@ -1,146 +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_opus.h"
|
|
||||||
|
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
|
||||||
#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
namespace acm2 {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
const CodecInst kOpusCodecInst = {105, "opus", 48000, 960, 1, 32000};
|
|
||||||
// These constants correspond to those used in ACMOpus::SetPacketLossRate().
|
|
||||||
const int kPacketLossRate20 = 20;
|
|
||||||
const int kPacketLossRate10 = 10;
|
|
||||||
const int kPacketLossRate5 = 5;
|
|
||||||
const int kPacketLossRate1 = 1;
|
|
||||||
const int kLossRate20Margin = 2;
|
|
||||||
const int kLossRate10Margin = 1;
|
|
||||||
const int kLossRate5Margin = 1;
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
class AcmOpusTest : public ACMOpus {
|
|
||||||
public:
|
|
||||||
explicit AcmOpusTest(int16_t codec_id) : ACMOpus(codec_id, false) {}
|
|
||||||
~AcmOpusTest() {}
|
|
||||||
int packet_loss_rate() { return packet_loss_rate_; }
|
|
||||||
OpusApplicationMode application() { return application_; }
|
|
||||||
bool encoder_initialized() {
|
|
||||||
ReadLockScoped cs(codec_wrapper_lock_);
|
|
||||||
return encoder_initialized_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestSetPacketLossRate(int from, int to, int expected_return);
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef WEBRTC_CODEC_OPUS
|
|
||||||
void AcmOpusTest::TestSetPacketLossRate(int from, int to, int expected_return) {
|
|
||||||
for (int loss = from; loss <= to; (to >= from) ? ++loss : --loss) {
|
|
||||||
EXPECT_EQ(0, SetPacketLossRate(loss));
|
|
||||||
EXPECT_EQ(expected_return, packet_loss_rate());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(AcmOpusTest, PacketLossRateOptimized) {
|
|
||||||
AcmOpusTest opus(ACMCodecDB::kOpus);
|
|
||||||
WebRtcACMCodecParams params;
|
|
||||||
memcpy(&(params.codec_inst), &kOpusCodecInst, sizeof(CodecInst));
|
|
||||||
EXPECT_EQ(0, opus.InitEncoder(¶ms, true));
|
|
||||||
EXPECT_EQ(0, opus.SetFEC(true));
|
|
||||||
|
|
||||||
// Note that the order of the following calls is critical.
|
|
||||||
opus.TestSetPacketLossRate(0, 0, 0);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate1,
|
|
||||||
kPacketLossRate5 + kLossRate5Margin - 1,
|
|
||||||
kPacketLossRate1);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate5 + kLossRate5Margin,
|
|
||||||
kPacketLossRate10 + kLossRate10Margin - 1,
|
|
||||||
kPacketLossRate5);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate10 + kLossRate10Margin,
|
|
||||||
kPacketLossRate20 + kLossRate20Margin - 1,
|
|
||||||
kPacketLossRate10);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate20 + kLossRate20Margin,
|
|
||||||
100,
|
|
||||||
kPacketLossRate20);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate20 + kLossRate20Margin,
|
|
||||||
kPacketLossRate20 - kLossRate20Margin,
|
|
||||||
kPacketLossRate20);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate20 - kLossRate20Margin - 1,
|
|
||||||
kPacketLossRate10 - kLossRate10Margin,
|
|
||||||
kPacketLossRate10);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate10 - kLossRate10Margin - 1,
|
|
||||||
kPacketLossRate5 - kLossRate5Margin,
|
|
||||||
kPacketLossRate5);
|
|
||||||
opus.TestSetPacketLossRate(kPacketLossRate5 - kLossRate5Margin - 1,
|
|
||||||
kPacketLossRate1,
|
|
||||||
kPacketLossRate1);
|
|
||||||
opus.TestSetPacketLossRate(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(AcmOpusTest, DefaultApplicationMode) {
|
|
||||||
AcmOpusTest opus(ACMCodecDB::kOpus);
|
|
||||||
WebRtcACMCodecParams params;
|
|
||||||
memcpy(&(params.codec_inst), &kOpusCodecInst, sizeof(CodecInst));
|
|
||||||
|
|
||||||
params.codec_inst.channels = 2;
|
|
||||||
// Codec is not initialized, and hence without force initialization (2nd
|
|
||||||
// argument being false), an initialization will take place.
|
|
||||||
EXPECT_FALSE(opus.encoder_initialized());
|
|
||||||
EXPECT_EQ(0, opus.InitEncoder(¶ms, false));
|
|
||||||
EXPECT_EQ(kAudio, opus.application());
|
|
||||||
|
|
||||||
params.codec_inst.channels = 1;
|
|
||||||
EXPECT_EQ(0, opus.InitEncoder(¶ms, true));
|
|
||||||
EXPECT_EQ(kVoip, opus.application());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(AcmOpusTest, ChangeApplicationMode) {
|
|
||||||
AcmOpusTest opus(ACMCodecDB::kOpus);
|
|
||||||
WebRtcACMCodecParams params;
|
|
||||||
memcpy(&(params.codec_inst), &kOpusCodecInst, sizeof(CodecInst));
|
|
||||||
|
|
||||||
params.codec_inst.channels = 2;
|
|
||||||
// Codec is not initialized, and hence without force initialization (2nd
|
|
||||||
// argument being false), an initialization will take place.
|
|
||||||
EXPECT_EQ(0, opus.InitEncoder(¶ms, false));
|
|
||||||
EXPECT_EQ(kAudio, opus.application());
|
|
||||||
|
|
||||||
opus.SetOpusApplication(kVoip);
|
|
||||||
EXPECT_EQ(kVoip, opus.application());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(AcmOpusTest, ResetWontChangeApplicationMode) {
|
|
||||||
AcmOpusTest opus(ACMCodecDB::kOpus);
|
|
||||||
WebRtcACMCodecParams params;
|
|
||||||
memcpy(&(params.codec_inst), &kOpusCodecInst, sizeof(CodecInst));
|
|
||||||
|
|
||||||
params.codec_inst.channels = 2;
|
|
||||||
// Codec is not initialized, and hence without force initialization (2nd
|
|
||||||
// argument being false), an initialization will take place.
|
|
||||||
EXPECT_EQ(0, opus.InitEncoder(¶ms, false));
|
|
||||||
EXPECT_EQ(kAudio, opus.application());
|
|
||||||
|
|
||||||
opus.ResetEncoder();
|
|
||||||
EXPECT_EQ(kAudio, opus.application());
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
void AcmOpusTest:TestSetPacketLossRate(int /* from */, int /* to */,
|
|
||||||
int /* expected_return */) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif // WEBRTC_CODEC_OPUS
|
|
||||||
|
|
||||||
} // namespace acm2
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
@ -91,7 +91,7 @@
|
|||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
|
'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
|
||||||
'audio_coding/main/acm2/acm_opus_unittest.cc',
|
'audio_coding/main/acm2/acm_generic_codec_opus_test.cc',
|
||||||
'audio_coding/main/acm2/acm_receiver_unittest.cc',
|
'audio_coding/main/acm2/acm_receiver_unittest.cc',
|
||||||
'audio_coding/main/acm2/acm_receiver_unittest_oldapi.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.cc',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user