Bug 1221587: add per-platform prefs to control full-duplex cubeb input r=jib
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -840,16 +840,17 @@ public:
}
RefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
RefPtr<AudioDevice> mAudioDevice; // so we can turn on AEC
RefPtr<VideoDevice> mVideoDevice;
bool mEchoOn;
bool mAgcOn;
bool mNoiseOn;
+ bool mFullDuplex;
uint32_t mEcho;
uint32_t mAgc;
uint32_t mNoise;
uint32_t mPlayoutDelay;
};
void
@@ -1510,26 +1511,28 @@ MediaManager::EnumerateRawDevices(uint64
MediaManager::MediaManager()
: mMediaThread(nullptr)
, mBackend(nullptr) {
mPrefs.mFreq = 1000; // 1KHz test tone
mPrefs.mWidth = 0; // adaptive default
mPrefs.mHeight = 0; // adaptive default
mPrefs.mFPS = MediaEngine::DEFAULT_VIDEO_FPS;
mPrefs.mMinFPS = MediaEngine::DEFAULT_VIDEO_MIN_FPS;
+ mPrefs.mFullDuplex = false;
nsresult rv;
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
if (branch) {
GetPrefs(branch, nullptr);
}
}
- LOG(("%s: default prefs: %dx%d @%dfps (min %d), %dHz test tones", __FUNCTION__,
- mPrefs.mWidth, mPrefs.mHeight, mPrefs.mFPS, mPrefs.mMinFPS, mPrefs.mFreq));
+ LOG(("%s: default prefs: %dx%d @%dfps (min %d), %dHz test tones, %sfull-duplex", __FUNCTION__,
+ mPrefs.mWidth, mPrefs.mHeight, mPrefs.mFPS, mPrefs.mMinFPS, mPrefs.mFreq,
+ mPrefs.mFullDuplex ? "" : "not "));
}
NS_IMPL_ISUPPORTS(MediaManager, nsIMediaManagerService, nsIObserver)
/* static */ StaticRefPtr<MediaManager> MediaManager::sSingleton;
#ifdef DEBUG
/* static */ bool
@@ -1581,16 +1584,18 @@ MediaManager::Get() {
}
// else MediaManager won't work properly and will leak (see bug 837874)
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs) {
prefs->AddObserver("media.navigator.video.default_width", sSingleton, false);
prefs->AddObserver("media.navigator.video.default_height", sSingleton, false);
prefs->AddObserver("media.navigator.video.default_fps", sSingleton, false);
prefs->AddObserver("media.navigator.video.default_minfps", sSingleton, false);
+ prefs->AddObserver("media.navigator.audio.fake_frequency", sSingleton, false);
+ prefs->AddObserver("media.navigator.audio.full_duplex", sSingleton, false);
}
// Prepare async shutdown
nsCOMPtr<nsIAsyncShutdownClient> shutdownPhase = GetShutdownPhase();
class Blocker : public media::ShutdownBlocker
{
@@ -2612,16 +2617,17 @@ MediaManager::GetPrefBool(nsIPrefBranch
void
MediaManager::GetPrefs(nsIPrefBranch *aBranch, const char *aData)
{
GetPref(aBranch, "media.navigator.video.default_width", aData, &mPrefs.mWidth);
GetPref(aBranch, "media.navigator.video.default_height", aData, &mPrefs.mHeight);
GetPref(aBranch, "media.navigator.video.default_fps", aData, &mPrefs.mFPS);
GetPref(aBranch, "media.navigator.video.default_minfps", aData, &mPrefs.mMinFPS);
GetPref(aBranch, "media.navigator.audio.fake_frequency", aData, &mPrefs.mFreq);
+ GetPrefBool(aBranch, "media.navigator.audio.full_duplex", aData, &mPrefs.mFullDuplex);
}
void
MediaManager::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
if (sInShutdown) {
return;
@@ -2638,16 +2644,17 @@ MediaManager::Shutdown()
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs) {
prefs->RemoveObserver("media.navigator.video.default_width", this);
prefs->RemoveObserver("media.navigator.video.default_height", this);
prefs->RemoveObserver("media.navigator.video.default_fps", this);
prefs->RemoveObserver("media.navigator.video.default_minfps", this);
prefs->RemoveObserver("media.navigator.audio.fake_frequency", this);
+ prefs->RemoveObserver("media.navigator.audio.full_duplex", this);
}
// Close off any remaining active windows.
GetActiveWindows()->Clear();
mActiveCallbacks.Clear();
mCallIds.Clear();
// Because mMediaThread is not an nsThread, we must dispatch to it so it can
@@ -3111,20 +3118,20 @@ MediaManager::IsActivelyCapturingOrHasAP
}
}
return audio == nsIPermissionManager::ALLOW_ACTION ||
video == nsIPermissionManager::ALLOW_ACTION;
}
void
GetUserMediaCallbackMediaStreamListener::AudioConfig(bool aEchoOn,
- uint32_t aEcho,
- bool aAgcOn, uint32_t aAGC,
- bool aNoiseOn, uint32_t aNoise,
- int32_t aPlayoutDelay)
+ uint32_t aEcho,
+ bool aAgcOn, uint32_t aAGC,
+ bool aNoiseOn, uint32_t aNoise,
+ int32_t aPlayoutDelay)
{
if (mAudioDevice) {
#ifdef MOZ_WEBRTC
MediaManager::PostTask(FROM_HERE,
NewRunnableMethod(mAudioDevice->GetSource(), &MediaEngineSource::Config,
aEchoOn, aEcho, aAgcOn, aAGC, aNoiseOn,
aNoise, aPlayoutDelay));
#endif
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -210,16 +210,17 @@ protected:
*/
class MediaEnginePrefs {
public:
int32_t mWidth;
int32_t mHeight;
int32_t mFPS;
int32_t mMinFPS;
int32_t mFreq; // for test tones (fake:true)
+ bool mFullDuplex;
// mWidth and/or mHeight may be zero (=adaptive default), so use functions.
int32_t GetWidth(bool aHD = false) const {
return mWidth? mWidth : (mHeight?
(mHeight * GetDefWidth(aHD)) / GetDefHeight(aHD) :
GetDefWidth(aHD));
}
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -46,17 +46,18 @@ namespace mozilla {
cubeb_device_collection* AudioInputCubeb::mDevices = nullptr;
bool AudioInputCubeb::mAnyInUse = false;
MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
: mMutex("mozilla::MediaEngineWebRTC"),
mVoiceEngine(nullptr),
mAudioInput(nullptr),
- mAudioEngineInit(false)
+ mAudioEngineInit(false),
+ mFullDuplex(aPrefs.mFullDuplex)
{
#ifndef MOZ_B2G_CAMERA
nsCOMPtr<nsIComponentRegistrar> compMgr;
NS_GetComponentRegistrar(getter_AddRefs(compMgr));
if (compMgr) {
compMgr->IsContractIDRegistered(NS_TABSOURCESERVICE_CONTRACTID, &mHasTabVideoSource);
}
#else
@@ -275,17 +276,18 @@ MediaEngineWebRTC::EnumerateAudioDevices
if (!mAudioEngineInit) {
if (ptrVoEBase->Init() < 0) {
return;
}
mAudioEngineInit = true;
}
if (!mAudioInput) {
- if (true /*platform_supports_full_duplex*/) {
+ if (mFullDuplex) {
+ // The platform_supports_full_duplex.
mAudioInput = new mozilla::AudioInputCubeb(mVoiceEngine);
} else {
mAudioInput = new mozilla::AudioInputWebRTC(mVoiceEngine);
}
}
int nDevices = 0;
mAudioInput->GetNumOfRecordingDevices(nDevices);
@@ -318,18 +320,20 @@ MediaEngineWebRTC::EnumerateAudioDevices
RefPtr<MediaEngineAudioSource> aSource;
NS_ConvertUTF8toUTF16 uuid(uniqueId);
if (mAudioSources.Get(uuid, getter_AddRefs(aSource))) {
// We've already seen this device, just append.
aASources->AppendElement(aSource.get());
} else {
AudioInput* audioinput = mAudioInput;
- if (true /*platform_supports_full_duplex*/) {
- // For cubeb, it has state (the selected ID
+ if (mFullDuplex) {
+ // The platform_supports_full_duplex.
+
+ // For cubeb, it has state (the selected ID)
// XXX just use the uniqueID for cubeb and support it everywhere, and get rid of this
// XXX Small window where the device list/index could change!
audioinput = new mozilla::AudioInputCubeb(mVoiceEngine);
}
aSource = new MediaEngineWebRTCMicrophoneSource(mThread, mVoiceEngine, audioinput,
i, deviceName, uniqueId);
mAudioSources.Put(uuid, aSource); // Hashtable takes ownership.
aASources->AppendElement(aSource);
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -523,17 +523,17 @@ private:
nsCOMPtr<nsIThread> mThread;
// gUM runnables can e.g. Enumerate from multiple threads
Mutex mMutex;
webrtc::VoiceEngine* mVoiceEngine;
RefPtr<mozilla::AudioInput> mAudioInput;
bool mAudioEngineInit;
-
+ bool mFullDuplex;
bool mHasTabVideoSource;
// Store devices we've already seen in a hashtable for quick return.
// Maps UUID to MediaEngineSource (one set for audio, one for video).
nsRefPtrHashtable<nsStringHashKey, MediaEngineVideoSource> mVideoSources;
nsRefPtrHashtable<nsStringHashKey, MediaEngineAudioSource> mAudioSources;
};
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -197,20 +197,21 @@ MediaEngineWebRTCMicrophoneSource::GetUU
}
nsresult
MediaEngineWebRTCMicrophoneSource::Config(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise,
int32_t aPlayoutDelay)
{
- LOG(("Audio config: aec: %d, agc: %d, noise: %d",
+ LOG(("Audio config: aec: %d, agc: %d, noise: %d, delay: %d",
aEchoOn ? aEcho : -1,
aAgcOn ? aAGC : -1,
- aNoiseOn ? aNoise : -1));
+ aNoiseOn ? aNoise : -1,
+ aPlayoutDelay));
bool update_echo = (mEchoOn != aEchoOn);
bool update_agc = (mAgcOn != aAgcOn);
bool update_noise = (mNoiseOn != aNoiseOn);
mEchoOn = aEchoOn;
mAgcOn = aAgcOn;
mNoiseOn = aNoiseOn;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -424,37 +424,43 @@ pref("media.getusermedia.noise_enabled",
pref("media.getusermedia.aec_enabled", true);
pref("media.getusermedia.noise_enabled", true);
#endif
pref("media.getusermedia.aec_extended_filter", true);
pref("media.getusermedia.aec_delay_agnostic", true);
pref("media.getusermedia.noise", 1);
pref("media.getusermedia.agc_enabled", false);
pref("media.getusermedia.agc", 1);
-// Adjustments for OS-specific input delay (lower bound)
-// Adjustments for OS-specific AudioStream+cubeb+output delay (lower bound)
+// capture_delay: Adjustments for OS-specific input delay (lower bound)
+// playout_delay: Adjustments for OS-specific AudioStream+cubeb+output delay (lower bound)
+// full_duplex: enable cubeb full-duplex capture/playback
#if defined(XP_MACOSX)
pref("media.peerconnection.capture_delay", 50);
pref("media.getusermedia.playout_delay", 10);
+pref("media.navigator.audio.full_duplex", false);
#elif defined(XP_WIN)
pref("media.peerconnection.capture_delay", 50);
pref("media.getusermedia.playout_delay", 40);
+pref("media.navigator.audio.full_duplex", false);
#elif defined(ANDROID)
pref("media.peerconnection.capture_delay", 100);
pref("media.getusermedia.playout_delay", 100);
+pref("media.navigator.audio.full_duplex", false);
// Whether to enable Webrtc Hardware acceleration support
pref("media.navigator.hardware.vp8_encode.acceleration_enabled", false);
pref("media.navigator.hardware.vp8_decode.acceleration_enabled", false);
#elif defined(XP_LINUX)
pref("media.peerconnection.capture_delay", 70);
pref("media.getusermedia.playout_delay", 50);
+pref("media.navigator.audio.full_duplex", false);
#else
// *BSD, others - merely a guess for now
pref("media.peerconnection.capture_delay", 50);
pref("media.getusermedia.playout_delay", 50);
+pref("media.navigator.audio.full_duplex", false);
#endif
#endif
#if !defined(ANDROID)
pref("media.getusermedia.screensharing.enabled", true);
#endif
#ifdef RELEASE_BUILD