mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
Bug 1266438 - Reset the AEC and other processing when audio devices change. r=jesup
MozReview-Commit-ID: Jrr9E9ZSukv
This commit is contained in:
parent
6edc6b4ddd
commit
b3adcea90b
@ -23,7 +23,7 @@ extern mozilla::LazyLogModule gMediaStreamGraphLog;
|
||||
|
||||
// We don't use NSPR log here because we want this interleaved with adb logcat
|
||||
// on Android/B2G
|
||||
// #define ENABLE_LIFECYCLE_LOG
|
||||
#define ENABLE_LIFECYCLE_LOG
|
||||
#ifdef ENABLE_LIFECYCLE_LOG
|
||||
#ifdef ANDROID
|
||||
#include "android/log.h"
|
||||
@ -660,12 +660,9 @@ AudioCallbackDriver::Init()
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef XP_MACOSX
|
||||
// Currently, only mac cares about this
|
||||
bool aec;
|
||||
Unused << mGraphImpl->AudioTrackPresent(aec);
|
||||
SetMicrophoneActive(aec);
|
||||
#endif
|
||||
|
||||
cubeb_stream_register_device_changed_callback(mAudioStream,
|
||||
AudioCallbackDriver::DeviceChangedCallback_s);
|
||||
@ -1070,34 +1067,14 @@ void AudioCallbackDriver::PanOutputIfNeeded(bool aMicrophoneActive)
|
||||
|
||||
void
|
||||
AudioCallbackDriver::DeviceChangedCallback() {
|
||||
#ifdef XP_MACOSX
|
||||
// Tell the audio engine the device has changed, it might want to reset some
|
||||
// state.
|
||||
MonitorAutoLock mon(mGraphImpl->GetMonitor());
|
||||
if (mAudioInput) {
|
||||
mAudioInput->DeviceChanged();
|
||||
}
|
||||
#ifdef XP_MACOSX
|
||||
PanOutputIfNeeded(mMicrophoneActive);
|
||||
// On OSX, changing the output device causes the audio thread to no call the
|
||||
// audio callback, so we're unable to process real-time input data, and this
|
||||
// results in latency building up.
|
||||
// We switch to a system driver until audio callbacks are called again, so we
|
||||
// still pull from the input stream, so that everything works apart from the
|
||||
// audio output.
|
||||
|
||||
// Don't bother doing the device switching dance if the graph is not RUNNING
|
||||
// (starting up, shutting down), because we haven't started pulling from the
|
||||
// SourceMediaStream.
|
||||
if (!GraphImpl()->Running()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSelfReference) {
|
||||
return;
|
||||
}
|
||||
STREAM_LOG(LogLevel::Error, ("Switching to SystemClockDriver during output switch"));
|
||||
mSelfReference.Take(this);
|
||||
mCallbackReceivedWhileSwitching = 0;
|
||||
SetNextDriver(new SystemClockDriver(GraphImpl()));
|
||||
RemoveCallback();
|
||||
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(mNextDriver);
|
||||
mNextDriver->Start();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -530,13 +530,14 @@ private:
|
||||
/* This is atomic and is set by the audio callback thread. It can be read by
|
||||
* any thread safely. */
|
||||
Atomic<bool> mInCallback;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
/**
|
||||
* True if microphone is being used by this process. This is synchronized by
|
||||
* the graph's monitor. */
|
||||
bool mMicrophoneActive;
|
||||
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
||||
/* Implements the workaround for the osx audio stack when changing output
|
||||
* devices. See comments in .cpp */
|
||||
bool OSXDeviceSwitchingWorkaround();
|
||||
|
@ -46,7 +46,7 @@ namespace mozilla {
|
||||
LazyLogModule gMediaStreamGraphLog("MediaStreamGraph");
|
||||
#define STREAM_LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
|
||||
|
||||
// #define ENABLE_LIFECYCLE_LOG
|
||||
#define ENABLE_LIFECYCLE_LOG
|
||||
|
||||
// We don't use NSPR log here because we want this interleaved with adb logcat
|
||||
// on Android/B2G
|
||||
@ -138,7 +138,7 @@ MediaStreamGraphImpl::RemoveStreamGraphThread(MediaStream* aStream)
|
||||
}
|
||||
|
||||
STREAM_LOG(LogLevel::Debug, ("Removed media stream %p from graph %p, count %lu",
|
||||
aStream, this, mStreams.Length()))
|
||||
aStream, this, mStreams.Length()));
|
||||
LIFECYCLE_LOG("Removed media stream %p from graph %p, count %lu",
|
||||
aStream, this, mStreams.Length());
|
||||
|
||||
|
@ -209,6 +209,11 @@ public:
|
||||
virtual void NotifyInputData(MediaStreamGraph* aGraph,
|
||||
const AudioDataValue* aBuffer, size_t aFrames,
|
||||
TrackRate aRate, uint32_t aChannels) = 0;
|
||||
|
||||
/**
|
||||
* Called when the underlying audio device has changed.
|
||||
*/
|
||||
virtual void DeviceChanged() = 0;
|
||||
};
|
||||
|
||||
class AudioDataListener : public AudioDataListenerInterface {
|
||||
|
@ -149,6 +149,8 @@ public:
|
||||
const AudioDataValue* aBuffer, size_t aFrames,
|
||||
TrackRate aRate, uint32_t aChannels) override
|
||||
{}
|
||||
void DeviceChanged() override
|
||||
{}
|
||||
bool IsFake() override {
|
||||
return true;
|
||||
}
|
||||
|
@ -103,6 +103,8 @@ public:
|
||||
AudioDataValue* aBuffer, size_t aFrames,
|
||||
TrackRate aRate, uint32_t aChannels) override
|
||||
{}
|
||||
void DeviceChanged() override
|
||||
{}
|
||||
void NotifyInputData(MediaStreamGraph* aGraph,
|
||||
const AudioDataValue* aBuffer, size_t aFrames,
|
||||
TrackRate aRate, uint32_t aChannels) override
|
||||
@ -391,6 +393,12 @@ public:
|
||||
mAudioSource->NotifyInputData(aGraph, aBuffer, aFrames, aRate, aChannels);
|
||||
}
|
||||
}
|
||||
virtual void DeviceChanged() override
|
||||
{
|
||||
if (mAudioSource) {
|
||||
mAudioSource->DeviceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
@ -471,6 +479,8 @@ public:
|
||||
const AudioDataValue* aBuffer, size_t aFrames,
|
||||
TrackRate aRate, uint32_t aChannels) override;
|
||||
|
||||
void DeviceChanged() override;
|
||||
|
||||
bool IsFake() override {
|
||||
return false;
|
||||
}
|
||||
|
@ -499,6 +499,46 @@ MediaEngineWebRTCMicrophoneSource::NotifyInputData(MediaStreamGraph* aGraph,
|
||||
}
|
||||
}
|
||||
|
||||
#define ResetProcessingIfNeeded(_processing) \
|
||||
do { \
|
||||
webrtc::_processing##Modes mode; \
|
||||
int rv = mVoEProcessing->Get##_processing##Status(enabled, mode); \
|
||||
if (rv) { \
|
||||
NS_WARNING("Could not get the status of the " \
|
||||
#_processing " on device change."); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (enabled) { \
|
||||
rv = mVoEProcessing->Set##_processing##Status(!enabled); \
|
||||
if (rv) { \
|
||||
NS_WARNING("Could not reset the status of the " \
|
||||
#_processing " on device change."); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
rv = mVoEProcessing->Set##_processing##Status(enabled); \
|
||||
if (rv) { \
|
||||
NS_WARNING("Could not reset the status of the " \
|
||||
#_processing " on device change."); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
MediaEngineWebRTCMicrophoneSource::DeviceChanged() {
|
||||
// Reset some processing
|
||||
bool enabled;
|
||||
ResetProcessingIfNeeded(Agc);
|
||||
ResetProcessingIfNeeded(Ec);
|
||||
ResetProcessingIfNeeded(Ns);
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineWebRTCMicrophoneSource::Init()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user