Chromium Code Reviews| Index: webrtc/voice_engine/test/auto_test/voe_output_test.cc |
| diff --git a/webrtc/voice_engine/test/auto_test/voe_output_test.cc b/webrtc/voice_engine/test/auto_test/voe_output_test.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d1e47c7416396a548c7d2a57e2c5f563b64ab9ec |
| --- /dev/null |
| +++ b/webrtc/voice_engine/test/auto_test/voe_output_test.cc |
| @@ -0,0 +1,204 @@ |
| +/* |
| + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
|
the sun
2015/11/09 12:41:01
Why do we need to test at this level? Shouldn't th
minyue-webrtc
2015/11/09 15:13:00
I see. There are two reasons that I wanted to chec
the sun
2015/11/09 15:29:56
Ah, I see, sorry I didn't notice it was a fuzzer t
|
| + * |
| + * 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/base/scoped_ptr.h" |
| +#include "webrtc/base/timeutils.h" |
| +#include "webrtc/system_wrappers/include/sleep.h" |
| +#include "webrtc/test/channel_transport/include/channel_transport.h" |
| +#include "webrtc/test/random.h" |
| +#include "webrtc/test/testsupport/fileutils.h" |
| +#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h" |
| + |
| +namespace { |
| + |
| +const char kIp[] = "127.0.0.1"; |
| +const int kPort = 1234; |
| +const webrtc::CodecInst kCodecInst = {120, "opus", 48000, 960, 2, 64000}; |
| + |
| +} // namespace |
| + |
| +namespace voetest { |
| + |
| +using webrtc::test::Random; |
| +using webrtc::test::VoiceChannelTransport; |
| + |
| +// This test allows a check on the output signal in an end-to-end call. |
| +class OutputTest { |
| + public: |
| + OutputTest(); |
| + ~OutputTest(); |
| + |
| + void Start(); |
| + |
| + void EnableOutputCheck(); |
| + void DisableOutputCheck(); |
| + void SetOutputBound(int16_t lower_bound, int16_t upper_bound); |
|
the sun
2015/11/09 12:41:01
Make this settable in c-tor instead - the bounds d
minyue-webrtc
2015/11/09 15:13:00
ok. I just wanted to make this class a bit more ge
|
| + void Mute(); |
| + void Unmute(); |
| + void SetBitRate(int rate); |
| + |
| + private: |
| + // This class checks all output values and count the number of samples that |
| + // go out of a defined range. |
| + class VoEOutputCheckMediaProcess : public VoEMediaProcess { |
| + public: |
| + VoEOutputCheckMediaProcess(); |
| + void set_enabled(bool enabled) { enabled_ = enabled; } |
| + void set_lower_bound(int16_t lower_bound) { lower_bound_ = lower_bound; } |
|
the sun
2015/11/09 12:41:00
set in c-tor
minyue-webrtc
2015/11/09 15:13:00
Done.
|
| + void set_upper_bound(int16_t upper_bound) { upper_bound_ = upper_bound; } |
| + void Process(int channel, |
| + ProcessingTypes type, |
| + int16_t audio10ms[], |
| + size_t length, |
| + int samplingFreq, |
| + bool isStereo) override; |
| + |
| + private: |
| + bool enabled_; |
| + int16_t lower_bound_; |
| + int16_t upper_bound_; |
| + }; |
| + |
| + VoETestManager manager_; |
| + VoEOutputCheckMediaProcess output_checker_; |
| + |
| + int channel_; |
| +}; |
| + |
| +OutputTest::OutputTest() { |
| + EXPECT_TRUE(manager_.Init()); |
| + manager_.GetInterfaces(); |
| + |
| + VoEBase* base = manager_.BasePtr(); |
| + VoECodec* codec = manager_.CodecPtr(); |
| + VoENetwork* network = manager_.NetworkPtr(); |
| + |
| + EXPECT_EQ(0, base->Init()); |
| + |
| + channel_ = base->CreateChannel(); |
| + |
| + // |network| will take care of the life time of |transport|. |
| + VoiceChannelTransport* transport = |
| + new VoiceChannelTransport(network, channel_); |
| + |
| + EXPECT_EQ(0, transport->SetSendDestination(kIp, kPort)); |
| + EXPECT_EQ(0, transport->SetLocalReceiver(kPort)); |
| + |
| + EXPECT_EQ(0, codec->SetSendCodec(channel_, kCodecInst)); |
| + EXPECT_EQ(0, codec->SetOpusDtx(channel_, true)); |
| + |
| + EXPECT_EQ(0, manager_.VolumeControlPtr()->SetSpeakerVolume(255)); |
| + |
| + manager_.ExternalMediaPtr()->RegisterExternalMediaProcessing( |
| + channel_, ProcessingTypes::kPlaybackPerChannel, output_checker_); |
| +} |
| + |
| +OutputTest::~OutputTest() { |
| + EXPECT_EQ(0, manager_.NetworkPtr()->DeRegisterExternalTransport(channel_)); |
| + EXPECT_EQ(0, manager_.ReleaseInterfaces()); |
| +} |
| + |
| +void OutputTest::Start() { |
| + const std::string file_name = |
| + webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); |
| + const webrtc::FileFormats kInputFormat = webrtc::kFileFormatPcm32kHzFile; |
| + |
| + ASSERT_EQ(0, |
| + manager_.FilePtr()->StartPlayingFileAsMicrophone( |
| + channel_, file_name.c_str(), true, false, kInputFormat, 1.0)); |
|
the sun
2015/11/09 12:41:01
nit: formatting
minyue-webrtc
2015/11/09 15:13:00
Done.
|
| + |
| + VoEBase* base = manager_.BasePtr(); |
| + ASSERT_EQ(0, base->StartPlayout(channel_)); |
| + ASSERT_EQ(0, base->StartSend(channel_)); |
| +} |
| + |
| +void OutputTest::EnableOutputCheck() { |
| + output_checker_.set_enabled(true); |
| +} |
| + |
| +void OutputTest::DisableOutputCheck() { |
| + output_checker_.set_enabled(false); |
| +} |
| + |
| +void OutputTest::SetOutputBound(int16_t lower_bound, int16_t upper_bound) { |
| + output_checker_.set_lower_bound(lower_bound); |
| + output_checker_.set_upper_bound(upper_bound); |
| +} |
| + |
| +void OutputTest::Mute() { |
| + manager_.VolumeControlPtr()->SetInputMute(channel_, true); |
| +} |
| + |
| +void OutputTest::Unmute() { |
| + manager_.VolumeControlPtr()->SetInputMute(channel_, false); |
| +} |
| + |
| +void OutputTest::SetBitRate(int rate) { |
| + manager_.CodecPtr()->SetBitRate(channel_, rate); |
| +} |
| + |
| +OutputTest::VoEOutputCheckMediaProcess::VoEOutputCheckMediaProcess() |
| + : enabled_(false), |
| + lower_bound_(-32768), |
| + upper_bound_(32767) {} |
| + |
| +void OutputTest::VoEOutputCheckMediaProcess::Process(int channel, |
| + ProcessingTypes type, |
| + int16_t* audio10ms, |
| + size_t length, |
| + int samplingFreq, |
| + bool isStereo) { |
| + if (!enabled_) |
| + return; |
| + const int num_channels = isStereo ? 2 : 1; |
| + for (size_t i = 0; i < length; ++i) { |
| + for (int c = 0; c < num_channels; ++c) { |
| + ASSERT_GE(audio10ms[i * num_channels + c], lower_bound_); |
| + ASSERT_LE(audio10ms[i * num_channels + c], upper_bound_); |
| + } |
| + } |
| +} |
| + |
| +TEST(OutputTest, OpusDtxHasNoNoisePump) { |
| + const int kRuntimeMs = 20000; |
| + const uint32_t kUnmuteTimeMs = 1000; |
| + const int kCheckAfterMute = 2000; |
| + const uint32_t kCheckTimeMs = 2000; |
| + const int kMinOpusRate = 6000; |
| + const int kMaxOpusRate = 64000; |
| + |
| +#if defined(OPUS_FIXED_POINT) |
| + const int16_t kDtxBoundForSilence = 20; |
| +#else |
| + const int16_t kDtxBoundForSilence = 2; |
| +#endif |
| + |
| + OutputTest test; |
| + Random random(1234ull); |
| + |
| + uint32_t start_time = rtc::Time(); |
| + test.Start(); |
| + test.SetOutputBound(-kDtxBoundForSilence, kDtxBoundForSilence); |
| + while (rtc::TimeSince(start_time) < kRuntimeMs) { |
| + webrtc::SleepMs(random.Rand(kUnmuteTimeMs - kUnmuteTimeMs / 10, |
| + kUnmuteTimeMs + kUnmuteTimeMs / 10)); |
| + test.Mute(); |
| + webrtc::SleepMs(kCheckAfterMute); |
| + test.EnableOutputCheck(); |
| + webrtc::SleepMs(random.Rand(kCheckTimeMs - kCheckTimeMs / 10, |
| + kCheckTimeMs + kCheckTimeMs / 10)); |
| + test.DisableOutputCheck(); |
| + test.SetBitRate(random.Rand(kMinOpusRate, kMaxOpusRate)); |
| + test.Unmute(); |
| + } |
| +} |
| + |
| +} // namespace voetest |