From 255750bfb021ee2a228c40816ad4f23c0a17ec9e Mon Sep 17 00:00:00 2001 From: henrika Date: Mon, 27 Aug 2018 16:13:37 +0200 Subject: [PATCH] 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 Commit-Queue: Henrik Andreassson Cr-Commit-Position: refs/heads/master@{#24463} --- api/test/video_quality_test_fixture.h | 1 + modules/audio_device/BUILD.gn | 2 - video/BUILD.gn | 3 ++ video/DEPS | 1 + video/video_loopback.cc | 6 ++- video/video_quality_test.cc | 69 ++++++++++++++++++++++----- video/video_quality_test.h | 14 +++++- 7 files changed, 80 insertions(+), 16 deletions(-) diff --git a/api/test/video_quality_test_fixture.h b/api/test/video_quality_test_fixture.h index deeb848978..ed54076ca3 100644 --- a/api/test/video_quality_test_fixture.h +++ b/api/test/video_quality_test_fixture.h @@ -63,6 +63,7 @@ class VideoQualityTestFixtureInterface { 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 6eb02a500e..e0c0da8dd9 100644 --- a/modules/audio_device/BUILD.gn +++ b/modules/audio_device/BUILD.gn @@ -167,8 +167,6 @@ rtc_source_set("windows_core_audio_utility") { # 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 a25b42d85e..02f117ecac 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -211,6 +211,9 @@ if (rtc_include_tests) { "../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 288ecfdfe1..94a394b2dd 100644 --- a/video/DEPS +++ b/video/DEPS @@ -4,6 +4,7 @@ include_rules = [ "+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 6f45cf3538..52f0a65084 100644 --- a/video/video_loopback.cc +++ b/video/video_loopback.cc @@ -243,6 +243,10 @@ DEFINE_bool(use_flexfec, false, "Use FlexFEC forward error correction."); 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 @@ void Loopback() { 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 a2437d5360..2233b317cf 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 @@ VideoQualityTest::Params::Params() 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 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) { 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 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) { }); } +rtc::scoped_refptr 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::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 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 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::SetupAudio(Transport* transport) { } void VideoQualityTest::RunWithRenderers(const Params& params) { + RTC_LOG(INFO) << __FUNCTION__; num_video_streams_ = params.call.dual_video ? 2 : 1; std::unique_ptr send_transport; std::unique_ptr recv_transport; @@ -1039,7 +1083,8 @@ void VideoQualityTest::RunWithRenderers(const Params& params) { 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 b25d7e1345..1bc55ab177 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 @@ class VideoQualityTest : void StartThumbnails(); void StopThumbnails(); void DestroyThumbnailStreams(); + // Helper method for creating a real ADM (using hardware) for all platforms. + rtc::scoped_refptr 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 @@ class VideoQualityTest : // 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 com_initializer_; +#endif }; } // namespace webrtc