Title: [249715] trunk/Source/WebCore
Revision
249715
Author
you...@apple.com
Date
2019-09-10 08:27:41 -0700 (Tue, 10 Sep 2019)

Log Message

Audio sometimes fail to capture in WebRTC
https://bugs.webkit.org/show_bug.cgi?id=180748
<rdar://problem/36032346>

Reviewed by Eric Carlson.

In some cases, Safari is not receiving unsuspend notifications.
In that case, the capture unit might stay in suspend state forever.
To work around that, we force to unsuspend whenever there is a new capture happening.
This will make it so that reloading the page will unsuspend the page.

Manually tested by triggering Siri, starting to use the microphone and quickly going back to a capturing page.

* platform/mediastream/mac/CoreAudioCaptureSource.cpp:
(WebCore::CoreAudioSharedUnit::provideSpeakerData):
When suspension happens, the buffer size might change.
Since this is only an issue if there are some references data, we now do not fail the capture when there
is no reference data.
(WebCore::CoreAudioSharedUnit::resume):
(WebCore::CoreAudioSharedUnit::prepareForNewCapture):
Make sure to start with a clean slate by setting suspend state to false for the shared unit.
And failing all previous sources in case we are going back from suspension.
(WebCore::CoreAudioSharedUnit::startInternal):
(WebCore::CoreAudioCaptureSourceFactory::audioCaptureDeviceManager):
(WebCore::CoreAudioCaptureSource::CoreAudioCaptureSource):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (249714 => 249715)


--- trunk/Source/WebCore/ChangeLog	2019-09-10 15:10:56 UTC (rev 249714)
+++ trunk/Source/WebCore/ChangeLog	2019-09-10 15:27:41 UTC (rev 249715)
@@ -1,3 +1,31 @@
+2019-09-10  Youenn Fablet  <you...@apple.com>
+
+        Audio sometimes fail to capture in WebRTC
+        https://bugs.webkit.org/show_bug.cgi?id=180748
+        <rdar://problem/36032346>
+
+        Reviewed by Eric Carlson.
+
+        In some cases, Safari is not receiving unsuspend notifications.
+        In that case, the capture unit might stay in suspend state forever.
+        To work around that, we force to unsuspend whenever there is a new capture happening.
+        This will make it so that reloading the page will unsuspend the page.
+
+        Manually tested by triggering Siri, starting to use the microphone and quickly going back to a capturing page.
+
+        * platform/mediastream/mac/CoreAudioCaptureSource.cpp:
+        (WebCore::CoreAudioSharedUnit::provideSpeakerData):
+        When suspension happens, the buffer size might change.
+        Since this is only an issue if there are some references data, we now do not fail the capture when there
+        is no reference data.
+        (WebCore::CoreAudioSharedUnit::resume):
+        (WebCore::CoreAudioSharedUnit::prepareForNewCapture):
+        Make sure to start with a clean slate by setting suspend state to false for the shared unit.
+        And failing all previous sources in case we are going back from suspension.
+        (WebCore::CoreAudioSharedUnit::startInternal):
+        (WebCore::CoreAudioCaptureSourceFactory::audioCaptureDeviceManager):
+        (WebCore::CoreAudioCaptureSource::CoreAudioCaptureSource):
+
 2019-09-10  Adrian Perez de Castro  <ape...@igalia.com>
 
         [GTK][WPE] Fixes for non-unified builds after r249022

Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp (249714 => 249715)


--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp	2019-09-10 15:10:56 UTC (rev 249714)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp	2019-09-10 15:27:41 UTC (rev 249715)
@@ -107,6 +107,8 @@
 
     void devicesChanged(const Vector<CaptureDevice>&);
 
+    void prepareForNewCapture();
+
 private:
     OSStatus configureSpeakerProc();
     OSStatus configureMicrophoneProc();
@@ -450,7 +452,10 @@
 #endif
 
     if (m_speakerSampleBuffer->sampleCapacity() < inNumberFrames) {
+        if (m_activeSources.isEmpty())
+            return 0;
         RELEASE_LOG_ERROR(WebRTC, "CoreAudioSharedUnit::provideSpeakerData: speaker sample buffer size (%d) too small for amount of sample data requested (%d)!", m_speakerSampleBuffer->sampleCapacity(), (int)inNumberFrames);
+        // FIXME: This fails the capture, we should thus either reconfigure the audio unit or notify all clients that capture is failing.
         return kAudio_ParamError;
     }
 
@@ -629,6 +634,19 @@
     return 0;
 }
 
+void CoreAudioSharedUnit::prepareForNewCapture()
+{
+    if (!m_suspended)
+        return;
+    m_suspended = false;
+
+    if (!m_producingCount)
+        return;
+
+    RELEASE_LOG_ERROR(WebRTC, "CoreAudioSharedUnit::prepareForNewCapture, notifying suspended sources of capture failure");
+    captureFailed();
+}
+
 OSStatus CoreAudioSharedUnit::startInternal()
 {
     OSStatus err;
@@ -647,6 +665,8 @@
     err = AudioOutputUnitStart(m_ioUnit);
     if (err) {
         RELEASE_LOG_ERROR(WebRTC, "CoreAudioSharedUnit::start(%p) AudioOutputUnitStart failed with error %d (%.4s)", this, (int)err, (char*)&err);
+        cleanupAudioUnit();
+        ASSERT(!m_ioUnit);
         return err;
     }
 
@@ -853,6 +873,11 @@
     : RealtimeMediaSource(RealtimeMediaSource::Type::Audio, WTFMove(label), WTFMove(deviceID), WTFMove(hashSalt))
     , m_captureDeviceID(captureDeviceID)
 {
+#if PLATFORM(IOS_FAMILY)
+    // We ensure that we unsuspend ourselves on the constructor as a capture source
+    // is created when getUserMedia grants access which only happens when the process is foregrounded.
+    CoreAudioSharedUnit::singleton().prepareForNewCapture();
+#endif
 }
 
 void CoreAudioCaptureSource::initializeToStartProducingData()
@@ -871,13 +896,6 @@
     initializeVolume(unit.volume());
 
     unit.addClient(*this);
-
-#if PLATFORM(IOS_FAMILY)
-    // We ensure that we unsuspend ourselves on the constructor as a capture source
-    // is created when getUserMedia grants access which only happens when the process is foregrounded.
-    if (unit.isSuspended())
-        unit.reconfigureAudioUnit();
-#endif
 }
 
 CoreAudioCaptureSource::~CoreAudioCaptureSource()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to