Bug 1481152 - Restrict to a single input stream per process on Linux, when using PulseAudio and audio remoting is enabled. r=pehrsons

Differential Revision: https://phabricator.services.mozilla.com/D5543

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Paul Adenot 2018-09-25 10:04:44 +00:00
Родитель e490a53de2
Коммит cc3d47676e
5 изменённых файлов: 48 добавлений и 2 удалений

Просмотреть файл

@ -38,6 +38,8 @@
#define PREF_CUBEB_OUTPUT_DEVICE "media.cubeb.output_device"
#define PREF_CUBEB_LATENCY_PLAYBACK "media.cubeb_latency_playback_ms"
#define PREF_CUBEB_LATENCY_MSG "media.cubeb_latency_msg_frames"
// This only works when audio remoting is active, and pulseaudio is the backend.
#define PREF_CUBEB_MAX_INPUT_STREAMS "media.cubeb_max_input_streams"
// Allows to get something non-default for the preferred sample-rate, to allow
// troubleshooting in the field and testing.
#define PREF_CUBEB_FORCE_SAMPLE_RATE "media.cubeb.force_sample_rate"
@ -127,6 +129,9 @@ cubeb* sCubebContext;
double sVolumeScale = 1.0;
uint32_t sCubebPlaybackLatencyInMilliseconds = 100;
uint32_t sCubebMSGLatencyInFrames = 512;
// Maximum number of audio input streams that can be open at once. This pref is
// only used when remoting is on, and we're using PulseAudio as a backend.
uint32_t sCubebMaxInputStreams = 1;
// If sCubebForcedSampleRate is zero, PreferredSampleRate will return the
// preferred sample-rate for the audio backend in use. Otherwise, it will be
// used as the preferred sample-rate.
@ -231,6 +236,9 @@ void PrefChanged(const char* aPref, void* aClosure)
// We don't want to limit the upper limit too much, so that people can
// experiment.
sCubebMSGLatencyInFrames = std::min<uint32_t>(std::max<uint32_t>(value, 128), 1e6);
} else if (strcmp(aPref, PREF_CUBEB_MAX_INPUT_STREAMS) == 0) {
StaticMutexAutoLock lock(sMutex);
sCubebMaxInputStreams = Preferences::GetUint(aPref);
} else if (strcmp(aPref, PREF_CUBEB_FORCE_SAMPLE_RATE) == 0) {
StaticMutexAutoLock lock(sMutex);
sCubebForcedSampleRate = Preferences::GetUint(aPref);
@ -551,12 +559,19 @@ uint32_t GetCubebMSGLatencyInFrames(cubeb_stream_params * params)
#endif
}
uint32_t GetMaxInputStreams()
{
StaticMutexAutoLock lock(sMutex);
return sCubebMaxInputStreams;
}
static const char* gInitCallbackPrefs[] = {
PREF_VOLUME_SCALE, PREF_CUBEB_OUTPUT_DEVICE,
PREF_CUBEB_LATENCY_PLAYBACK, PREF_CUBEB_LATENCY_MSG,
PREF_CUBEB_BACKEND, PREF_CUBEB_FORCE_NULL_CONTEXT,
PREF_CUBEB_SANDBOX, PREF_AUDIOIPC_POOL_SIZE,
PREF_AUDIOIPC_STACK_SIZE, nullptr,
PREF_CUBEB_MAX_INPUT_STREAMS, PREF_AUDIOIPC_STACK_SIZE,
nullptr,
};
static const char* gCallbackPrefs[] = {
PREF_CUBEB_FORCE_SAMPLE_RATE,

Просмотреть файл

@ -50,6 +50,7 @@ void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
Side aSide);
cubeb_stream_prefs GetDefaultStreamPrefs();
char* GetForcedOutputDevice();
uint32_t GetMaxInputStreams();
#ifdef MOZ_WIDGET_ANDROID
uint32_t AndroidGetAudioOutputSampleRate();

Просмотреть файл

@ -422,7 +422,8 @@ function setupEnvironment() {
['media.getusermedia.screensharing.enabled', true],
['media.getusermedia.window.focus_source.enabled', false],
['media.recorder.audio_node.enabled', true],
['media.webaudio.audiocontextoptions-samplerate.enabled', true]
['media.webaudio.audiocontextoptions-samplerate.enabled', true],
['media.cubeb_max_input_streams', 10000]
]
};

Просмотреть файл

@ -36,6 +36,10 @@ using namespace webrtc;
#define MAX_AEC_FIFO_DEPTH 200 // ms - multiple of 10
static_assert(!(MAX_AEC_FIFO_DEPTH % 10), "Invalid MAX_AEC_FIFO_DEPTH");
#ifdef MOZ_PULSEAUDIO
static uint32_t sInputStreamsOpen = 0;
#endif
namespace mozilla {
#ifdef LOG
@ -761,6 +765,22 @@ MediaEngineWebRTCMicrophoneSource::Start(const RefPtr<const AllocationHandle>& a
return NS_ERROR_FAILURE;
}
// On Linux with PulseAudio, we still only allow a certain number of audio
// input stream in each content process, because of issues related to audio
// remoting and PulseAudio.
#ifdef MOZ_PULSEAUDIO
// When remoting, cubeb reports it's using the "remote" backend instead of the
// backend on the other side of the IPC.
const char* backend = cubeb_get_backend_id(CubebUtils::GetCubebContext());
if (strstr(backend, "remote") &&
sInputStreamsOpen == CubebUtils::GetMaxInputStreams()) {
LOG(("%p Already capturing audio in this process, aborting", this));
return NS_ERROR_FAILURE;
}
sInputStreamsOpen++;
#endif
MOZ_ASSERT(!allocation.mEnabled, "Source already started");
{
// This spans setting both the enabled state and mState.
@ -820,6 +840,10 @@ MediaEngineWebRTCMicrophoneSource::Stop(const RefPtr<const AllocationHandle>& aH
Maybe<CubebUtils::AudioDeviceID> id = Some(deviceID);
allocation.mStream->CloseAudioInput(id, mListener);
mListener = nullptr;
#ifdef MOZ_PULSEAUDIO
MOZ_ASSERT(sInputStreamsOpen > 0);
sInputStreamsOpen--;
#endif
if (HasEnabledTrack()) {
// Another track is keeping us from stopping

Просмотреть файл

@ -622,6 +622,11 @@ pref("media.audioipc.stack_size", 262144);
pref("media.cubeb.sandbox", false);
#endif
#ifdef XP_LINUX
// Bug 1481152
pref("media.cubeb_max_input_streams", 1);
#endif
#ifdef MOZ_AV1
pref("media.av1.enabled", false);
#endif