Adds support for real audio devices in video_quality_test.
The old test supported audio but only in combination with a fake ADM.
The new version allows the user to run real video and audio.
Now possible to do:
./out/Debug/video_loopback.exe --audio --use_real_adm
To run the test in loopback using real default audio devices.
By default:
./out/Debug/video_loopback.exe --audio
runs with fake audio devices as before.
Bug: webrtc:9265
Change-Id: Id89924ec0276f929487c71fc6321dcd9cb92693d
Reviewed-on: https://webrtc-review.googlesource.com/96161
Reviewed-by: Minyue Li <minyue@webrtc.org>
Commit-Queue: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24463}
diff --git a/api/test/video_quality_test_fixture.h b/api/test/video_quality_test_fixture.h
index deeb848..ed54076 100644
--- a/api/test/video_quality_test_fixture.h
+++ b/api/test/video_quality_test_fixture.h
@@ -63,6 +63,7 @@
bool enabled;
bool sync_video;
bool dtx;
+ bool use_real_adm;
} audio;
struct Screenshare {
bool enabled;
diff --git a/modules/audio_device/BUILD.gn b/modules/audio_device/BUILD.gn
index 6eb02a5..e0c0da8 100644
--- a/modules/audio_device/BUILD.gn
+++ b/modules/audio_device/BUILD.gn
@@ -167,8 +167,6 @@
# gradually phase out the old design.
# TODO(henrika): currently only supported on Windows.
rtc_source_set("audio_device_module_from_input_and_output") {
- visibility = [ ":*" ]
-
if (is_win && !build_with_chromium) {
sources = [
"include/audio_device_factory.cc",
diff --git a/video/BUILD.gn b/video/BUILD.gn
index a25b42d..02f117e 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -211,6 +211,9 @@
"../logging:rtc_event_log_impl_output",
"../media:rtc_audio_video",
"../media:rtc_internal_video_codecs",
+ "../modules/audio_device:audio_device_api",
+ "../modules/audio_device:audio_device_module_from_input_and_output",
+ "../modules/audio_device:windows_core_audio_utility",
"../modules/audio_mixer:audio_mixer_impl",
"../modules/rtp_rtcp",
"../modules/video_coding:video_coding",
diff --git a/video/DEPS b/video/DEPS
index 288ecfd..94a394b 100644
--- a/video/DEPS
+++ b/video/DEPS
@@ -4,6 +4,7 @@
"+logging/rtc_event_log",
"+media/base",
"+media/engine",
+ "+modules/audio_device",
"+modules/audio_mixer",
"+modules/bitrate_controller",
"+modules/congestion_controller",
diff --git a/video/video_loopback.cc b/video/video_loopback.cc
index 6f45cf3..52f0a65 100644
--- a/video/video_loopback.cc
+++ b/video/video_loopback.cc
@@ -243,6 +243,10 @@
DEFINE_bool(audio, false, "Add audio stream");
+DEFINE_bool(use_real_adm,
+ false,
+ "Use real ADM instead of fake (no effect if audio is false)");
+
DEFINE_bool(audio_video_sync,
false,
"Sync audio and video stream (no effect if"
@@ -307,7 +311,7 @@
flags::Clip(),
flags::GetCaptureDevice()};
params.audio = {flags::FLAG_audio, flags::FLAG_audio_video_sync,
- flags::FLAG_audio_dtx};
+ flags::FLAG_audio_dtx, flags::FLAG_use_real_adm};
params.logging = {flags::FLAG_rtc_event_log_name, flags::FLAG_rtp_dump_name,
flags::FLAG_encoded_frame_path};
params.screenshare[0].enabled = false;
diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc
index a2437d5..2233b31 100644
--- a/video/video_quality_test.cc
+++ b/video/video_quality_test.cc
@@ -20,9 +20,11 @@
#include "call/fake_network_pipe.h"
#include "call/simulated_network.h"
#include "logging/rtc_event_log/output/rtc_event_log_output_file.h"
+#include "media/engine/adm_helpers.h"
#include "media/engine/internalencoderfactory.h"
#include "media/engine/vp8_encoder_simulcast_proxy.h"
#include "media/engine/webrtcvideoengine.h"
+#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
#include "modules/video_coding/codecs/h264/include/h264.h"
#include "modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h"
@@ -32,6 +34,9 @@
#include "test/testsupport/fileutils.h"
#include "test/video_renderer.h"
#include "video/video_analyzer.h"
+#ifdef WEBRTC_WIN
+#include "modules/audio_device/include/audio_device_factory.h"
+#endif
namespace {
constexpr char kSyncGroup[] = "av_sync";
@@ -109,7 +114,7 @@
false, false, ""},
{false, 640, 480, 30, 50, 800, 800, false, "VP8", 1, -1, 0, false,
false, false, ""}},
- audio({false, false, false}),
+ audio({false, false, false, false}),
screenshare{{false, false, 10, 0}, {false, false, 10, 0}},
analyzer({"", 0.0, 0.0, 0, "", ""}),
pipe(),
@@ -871,7 +876,8 @@
task_queue_.SendTask([this, &send_call_config, &recv_call_config,
&send_transport, &recv_transport]() {
if (params_.audio.enabled)
- InitializeAudioDevice(&send_call_config, &recv_call_config);
+ InitializeAudioDevice(
+ &send_call_config, &recv_call_config, params_.audio.use_real_adm);
CreateCalls(send_call_config, recv_call_config);
send_transport = CreateSendTransport();
@@ -969,22 +975,59 @@
});
}
+rtc::scoped_refptr<AudioDeviceModule> VideoQualityTest::CreateAudioDevice() {
+#ifdef WEBRTC_WIN
+ RTC_LOG(INFO) << "Using latest version of ADM on Windows";
+ // We must initialize the COM library on a thread before we calling any of
+ // the library functions. All COM functions in the ADM will return
+ // CO_E_NOTINITIALIZED otherwise. The legacy ADM for Windows used internal
+ // COM initialization but the new ADM requires COM to be initialized
+ // externally.
+ com_initializer_ = absl::make_unique<webrtc_win::ScopedCOMInitializer>(
+ webrtc_win::ScopedCOMInitializer::kMTA);
+ RTC_CHECK(com_initializer_->Succeeded());
+ RTC_CHECK(webrtc_win::core_audio_utility::IsSupported());
+ RTC_CHECK(webrtc_win::core_audio_utility::IsMMCSSSupported());
+ return CreateWindowsCoreAudioAudioDeviceModule();
+#else
+ // Use legacy factory method on all platforms except Windows.
+ return AudioDeviceModule::Create(AudioDeviceModule::kPlatformDefaultAudio);
+#endif
+}
+
void VideoQualityTest::InitializeAudioDevice(Call::Config* send_call_config,
- Call::Config* recv_call_config) {
- rtc::scoped_refptr<TestAudioDeviceModule> fake_audio_device =
- TestAudioDeviceModule::CreateTestAudioDeviceModule(
- TestAudioDeviceModule::CreatePulsedNoiseCapturer(32000, 48000),
- TestAudioDeviceModule::CreateDiscardRenderer(48000), 1.f);
+ Call::Config* recv_call_config,
+ bool use_real_adm) {
+ rtc::scoped_refptr<AudioDeviceModule> audio_device;
+ if (use_real_adm) {
+ // Run test with real ADM (using default audio devices) if user has
+ // explicitly set the --audio and --use_real_adm command-line flags.
+ audio_device = CreateAudioDevice();
+ } else {
+ // By default, create a test ADM which fakes audio.
+ audio_device = TestAudioDeviceModule::CreateTestAudioDeviceModule(
+ TestAudioDeviceModule::CreatePulsedNoiseCapturer(32000, 48000),
+ TestAudioDeviceModule::CreateDiscardRenderer(48000), 1.f);
+ }
+ RTC_CHECK(audio_device);
AudioState::Config audio_state_config;
audio_state_config.audio_mixer = AudioMixerImpl::Create();
audio_state_config.audio_processing = AudioProcessingBuilder().Create();
- audio_state_config.audio_device_module = fake_audio_device;
+ audio_state_config.audio_device_module = audio_device;
send_call_config->audio_state = AudioState::Create(audio_state_config);
- RTC_CHECK(fake_audio_device->RegisterAudioCallback(
- send_call_config->audio_state->audio_transport()) == 0);
recv_call_config->audio_state = AudioState::Create(audio_state_config);
- fake_audio_device->Init();
+ if (use_real_adm) {
+ // The real ADM requires extra initialization: setting default devices,
+ // setting up number of channels etc. Helper class also calls
+ // AudioDeviceModule::Init().
+ webrtc::adm_helpers::Init(audio_device.get());
+ } else {
+ audio_device->Init();
+ }
+ // Always initialize the ADM before injecting a valid audio transport.
+ RTC_CHECK(audio_device->RegisterAudioCallback(
+ send_call_config->audio_state->audio_transport()) == 0);
}
void VideoQualityTest::SetupAudio(Transport* transport) {
@@ -1021,6 +1064,7 @@
}
void VideoQualityTest::RunWithRenderers(const Params& params) {
+ RTC_LOG(INFO) << __FUNCTION__;
num_video_streams_ = params.call.dual_video ? 2 : 1;
std::unique_ptr<test::LayerFilteringTransport> send_transport;
std::unique_ptr<test::DirectTransport> recv_transport;
@@ -1039,7 +1083,8 @@
Call::Config recv_call_config(&null_event_log);
if (params_.audio.enabled)
- InitializeAudioDevice(&send_call_config, &recv_call_config);
+ InitializeAudioDevice(
+ &send_call_config, &recv_call_config, params_.audio.use_real_adm);
CreateCalls(send_call_config, recv_call_config);
diff --git a/video/video_quality_test.h b/video/video_quality_test.h
index b25d7e1..1bc55ab 100644
--- a/video/video_quality_test.h
+++ b/video/video_quality_test.h
@@ -22,6 +22,9 @@
#include "test/call_test.h"
#include "test/frame_generator.h"
#include "test/layer_filtering_transport.h"
+#ifdef WEBRTC_WIN
+#include "modules/audio_device/win/core_audio_utility_win.h"
+#endif
namespace webrtc {
@@ -79,8 +82,11 @@
void StartThumbnails();
void StopThumbnails();
void DestroyThumbnailStreams();
+ // Helper method for creating a real ADM (using hardware) for all platforms.
+ rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice();
void InitializeAudioDevice(Call::Config* send_call_config,
- Call::Config* recv_call_config);
+ Call::Config* recv_call_config,
+ bool use_real_adm);
void SetupAudio(Transport* transport);
void StartEncodedFrameLogs(VideoSendStream* stream);
@@ -109,6 +115,12 @@
// separate send streams, the one in CallTest is the number of substreams for
// a single send stream.
size_t num_video_streams_;
+
+#ifdef WEBRTC_WIN
+ // Windows Core Audio based ADM needs to run on a COM initialized thread.
+ // Only referenced in combination with --audio --use_real_adm flags.
+ std::unique_ptr<webrtc_win::ScopedCOMInitializer> com_initializer_;
+#endif
};
} // namespace webrtc