From 0ddc112415d7d18de776d4868e1937ed12910b5b Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Tue, 20 Oct 2020 20:03:26 +0000 Subject: [PATCH] Bug 1670917 - Add a pref to allow using raw WASAPI streams. Make it default to input-only raw streams. r=kinetik Differential Revision: https://phabricator.services.mozilla.com/D93363 --- dom/media/AudioStream.cpp | 2 +- dom/media/CubebUtils.cpp | 15 ++++++++++----- dom/media/CubebUtils.h | 2 +- dom/media/GraphDriver.cpp | 4 ++-- modules/libpref/init/StaticPrefList.yaml | 13 +++++++++++++ 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/dom/media/AudioStream.cpp b/dom/media/AudioStream.cpp index d7809ae69286..a765837a5945 100644 --- a/dom/media/AudioStream.cpp +++ b/dom/media/AudioStream.cpp @@ -286,7 +286,7 @@ nsresult AudioStream::Init(uint32_t aNumChannels, params.channels = mOutChannels; params.layout = static_cast(aChannelMap); params.format = ToCubebFormat::value; - params.prefs = CubebUtils::GetDefaultStreamPrefs(); + params.prefs = CubebUtils::GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_OUTPUT); // This is noop if MOZ_DUMP_AUDIO is not set. mDumpFile.Open("AudioStream", mOutChannels, aRate); diff --git a/dom/media/CubebUtils.cpp b/dom/media/CubebUtils.cpp index dbccbc4be1ab..0bd78835812c 100644 --- a/dom/media/CubebUtils.cpp +++ b/dom/media/CubebUtils.cpp @@ -39,6 +39,7 @@ #include #include #include "AudioThreadRegistry.h" +#include "mozilla/StaticPrefs_media.h" #define AUDIOIPC_POOL_SIZE_DEFAULT 1 #define AUDIOIPC_STACK_SIZE_DEFAULT (64 * 4096) @@ -695,16 +696,20 @@ char* GetForcedOutputDevice() { return sCubebOutputDeviceName; } -cubeb_stream_prefs GetDefaultStreamPrefs() { +cubeb_stream_prefs GetDefaultStreamPrefs(cubeb_device_type aType) { + cubeb_stream_prefs prefs = CUBEB_STREAM_PREF_NONE; #ifdef XP_WIN // Investigation for bug 1427011 - if we're in E10S mode, rely on the // AudioNotification IPC to detect device changes. if (sCubebDisableDeviceSwitching && (XRE_IsE10sParentProcess() || XRE_IsContentProcess())) { - return CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING; + prefs |= CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING; + } + if (StaticPrefs::media_cubeb_wasapi_raw() & static_cast(aType)) { + prefs |= CUBEB_STREAM_PREF_RAW; } #endif - return CUBEB_STREAM_PREF_NONE; + return prefs; } bool RouteOutputAsVoice() { return sRouteOutputAsVoice; } @@ -735,7 +740,7 @@ bool EstimatedRoundTripLatencyDefaultDevices(double* aMean, double* aStdDev) { output_params.rate = rate; output_params.channels = 2; output_params.layout = CUBEB_LAYOUT_UNDEFINED; - output_params.prefs = GetDefaultStreamPrefs(); + output_params.prefs = GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_OUTPUT); latencyFrames = GetCubebMTGLatencyInFrames(&output_params); @@ -744,7 +749,7 @@ bool EstimatedRoundTripLatencyDefaultDevices(double* aMean, double* aStdDev) { input_params.rate = rate; input_params.channels = 1; input_params.layout = CUBEB_LAYOUT_UNDEFINED; - input_params.prefs = GetDefaultStreamPrefs(); + input_params.prefs = GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_INPUT); cubeb_stream* stm; rv = cubeb_stream_init(GetCubebContext(), &stm, diff --git a/dom/media/CubebUtils.h b/dom/media/CubebUtils.h index e9cb09aa6b01..7e024e3d92c5 100644 --- a/dom/media/CubebUtils.h +++ b/dom/media/CubebUtils.h @@ -54,7 +54,7 @@ uint32_t GetCubebPlaybackLatencyInMilliseconds(); uint32_t GetCubebMTGLatencyInFrames(cubeb_stream_params* params); bool CubebLatencyPrefSet(); void GetCurrentBackend(nsAString& aBackend); -cubeb_stream_prefs GetDefaultStreamPrefs(); +cubeb_stream_prefs GetDefaultStreamPrefs(cubeb_device_type aType); char* GetForcedOutputDevice(); // No-op on all platforms but Android, where it tells the device's AudioManager // to switch to "communication mode", which might change audio routing, diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp index 639b2bd1acf8..cbf15b75d00e 100644 --- a/dom/media/GraphDriver.cpp +++ b/dom/media/GraphDriver.cpp @@ -636,7 +636,7 @@ void AudioCallbackDriver::Init() { AudioConfig::ChannelLayout(mOutputChannelCount).Map(); output.layout = static_cast(channelMap); - output.prefs = CubebUtils::GetDefaultStreamPrefs(); + output.prefs = CubebUtils::GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_OUTPUT); if (mInputDevicePreference == CUBEB_DEVICE_PREF_VOICE && CubebUtils::RouteOutputAsVoice()) { output.prefs |= static_cast(CUBEB_STREAM_PREF_VOICE); @@ -666,7 +666,7 @@ void AudioCallbackDriver::Init() { input = output; input.channels = mInputChannelCount; input.layout = CUBEB_LAYOUT_UNDEFINED; - input.prefs = CubebUtils::GetDefaultStreamPrefs(); + input.prefs = CubebUtils::GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_INPUT); if (mInputDevicePreference == CUBEB_DEVICE_PREF_VOICE) { input.prefs |= static_cast(CUBEB_STREAM_PREF_VOICE); } diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index f5f096c8fa7c..ec2095e64bfb 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -6829,6 +6829,19 @@ value: false #endif +# Whether or not to pass AUDCLNT_STREAMOPTIONS_RAW when initializing audio +# streams when using WASAPI. +# 0 - don't use RAW streams +# 1 - use RAW streams for input streams only +# 2 - use RAW streams for output streams only +# 3 - use RAW streams for input and output streams +#if defined (XP_WIN) +- name: media.cubeb.wasapi-raw + type: RelaxedAtomicUint32 + mirror: always + value: 1 +#endif // XP_WIN + # ClockDrift desired buffering in milliseconds - name: media.clockdrift.buffering type: int32_t