Modified: trunk/Source/WebCore/ChangeLog (215545 => 215546)
--- trunk/Source/WebCore/ChangeLog 2017-04-20 00:43:59 UTC (rev 215545)
+++ trunk/Source/WebCore/ChangeLog 2017-04-20 00:53:37 UTC (rev 215546)
@@ -1,3 +1,24 @@
+2017-04-19 Eric Carlson <[email protected]>
+
+ Another deadlock in CoreAudioCaptureSource
+ https://bugs.webkit.org/show_bug.cgi?id=171001
+
+ Fix another regression introduced by r215201, plus make changes suggested
+ in the review of 170771.
+
+ Reviewed by Youenn Fablet.
+
+ * platform/mediastream/mac/CoreAudioCaptureSource.cpp:
+ (WebCore::CoreAudioCaptureSource::configureSpeakerProc): Assert if the lock is no held.
+ (WebCore::CoreAudioCaptureSource::provideSpeakerData): Don't reset the buffer.
+ (WebCore::CoreAudioCaptureSource::processMicrophoneSamples): Take the state lock. Don't
+ reset the buffer. No more microphone callbacks.
+ (WebCore::CoreAudioCaptureSource::stopProducingData): Return early if the io unit isn't
+ running. Drop the lock before calling setMuted to avoid another deadlock.
+ (WebCore::CoreAudioCaptureSource::addMicrophoneDataConsumer): Deleted.
+ (WebCore::CoreAudioCaptureSource::removeMicrophoneDataConsumer): Deleted.
+ * platform/mediastream/mac/CoreAudioCaptureSource.h:
+
2017-04-19 Anders Carlsson <[email protected]>
Stop using deprecated APIs, part 3
Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp (215545 => 215546)
--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp 2017-04-20 00:43:59 UTC (rev 215545)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp 2017-04-20 00:53:37 UTC (rev 215546)
@@ -170,6 +170,8 @@
OSStatus CoreAudioCaptureSource::configureSpeakerProc()
{
+ ASSERT(m_internalStateLock.isHeld());
+
AURenderCallbackStruct callback = { speakerCallback, this };
auto err = AudioUnitSetProperty(m_ioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, outputBus, &callback, sizeof(callback));
if (err) {
@@ -192,20 +194,6 @@
return err;
}
-uint64_t CoreAudioCaptureSource::addMicrophoneDataConsumer(MicrophoneDataCallback&& callback)
-{
- std::lock_guard<Lock> lock(m_pendingSourceQueueLock);
- m_microphoneDataCallbacks.add(++m_nextMicrophoneDataCallbackID, callback);
-
- return m_nextMicrophoneDataCallbackID;
-}
-
-void CoreAudioCaptureSource::removeMicrophoneDataConsumer(uint64_t callbackID)
-{
- std::lock_guard<Lock> lock(m_pendingSourceQueueLock);
- m_microphoneDataCallbacks.remove(callbackID);
-}
-
void CoreAudioCaptureSource::addEchoCancellationSource(AudioSampleDataSource& source)
{
if (!source.setOutputFormat(m_speakerProcFormat)) {
@@ -264,8 +252,6 @@
double adjustedHostTime = m_DTSConversionRatio * timeStamp.mHostTime;
uint64_t sampleTime = timeStamp.mSampleTime;
checkTimestamps(timeStamp, sampleTime, adjustedHostTime);
-
- m_speakerSampleBuffer->reset();
m_speakerSampleBuffer->setTimes(adjustedHostTime, sampleTime);
AudioBufferList& bufferList = m_speakerSampleBuffer->bufferList();
@@ -291,10 +277,11 @@
OSStatus CoreAudioCaptureSource::processMicrophoneSamples(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& timeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* /*ioData*/)
{
+ std::lock_guard<Lock> lock(m_internalStateLock);
+
++m_microphoneProcsCalled;
// Pull through the vpio unit to our mic buffer.
- m_microphoneSampleBuffer->reset();
AudioBufferList& bufferList = m_microphoneSampleBuffer->bufferList();
auto err = AudioUnitRender(m_ioUnit, &ioActionFlags, &timeStamp, inBusNumber, inNumberFrames, &bufferList);
if (err) {
@@ -306,17 +293,10 @@
uint64_t sampleTime = timeStamp.mSampleTime;
checkTimestamps(timeStamp, sampleTime, adjustedHostTime);
m_latestMicTimeStamp = sampleTime;
-
m_microphoneSampleBuffer->setTimes(adjustedHostTime, sampleTime);
audioSamplesAvailable(MediaTime(sampleTime, m_microphoneProcFormat.sampleRate()), m_microphoneSampleBuffer->bufferList(), m_microphoneProcFormat, inNumberFrames);
- if (m_microphoneDataCallbacks.isEmpty())
- return 0;
-
- for (auto& callback : m_microphoneDataCallbacks.values())
- callback(MediaTime(sampleTime, m_microphoneProcFormat.sampleRate()), m_microphoneSampleBuffer->bufferList(), m_microphoneProcFormat, inNumberFrames);
-
return noErr;
}
@@ -467,17 +447,20 @@
void CoreAudioCaptureSource::stopProducingData()
{
- std::lock_guard<Lock> lock(m_internalStateLock);
-
- if (!m_ioUnit)
+ if (!m_ioUnit || !m_ioUnitStarted)
return;
- auto err = AudioOutputUnitStop(m_ioUnit);
- if (err) {
- LOG(Media, "CoreAudioCaptureSource::stop(%p) AudioOutputUnitStop failed with error %d (%.4s)", this, (int)err, (char*)&err);
- return;
+ {
+ std::lock_guard<Lock> lock(m_internalStateLock);
+
+ auto err = AudioOutputUnitStop(m_ioUnit);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::stop(%p) AudioOutputUnitStop failed with error %d (%.4s)", this, (int)err, (char*)&err);
+ return;
+ }
+ m_ioUnitStarted = false;
}
- m_ioUnitStarted = false;
+
setMuted(true);
}
Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h (215545 => 215546)
--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h 2017-04-20 00:43:59 UTC (rev 215545)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h 2017-04-20 00:53:37 UTC (rev 215546)
@@ -115,9 +115,6 @@
uint64_t m_microphoneProcsCalled { 0 };
uint64_t m_latestMicTimeStamp { 0 };
- HashMap<uint64_t, MicrophoneDataCallback> m_microphoneDataCallbacks;
- uint64_t m_nextMicrophoneDataCallbackID { 0 };
-
CAAudioStreamDescription m_speakerProcFormat;
RefPtr<AudioSampleBufferList> m_speakerSampleBuffer;
uint64_t m_speakerProcsCalled { 0 };