Changeset 249715 in webkit


Ignore:
Timestamp:
Sep 10, 2019 8:27:41 AM (5 years ago)
Author:
youenn@apple.com
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):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r249714 r249715  
     12019-09-10  Youenn Fablet  <youenn@apple.com>
     2
     3        Audio sometimes fail to capture in WebRTC
     4        https://bugs.webkit.org/show_bug.cgi?id=180748
     5        <rdar://problem/36032346>
     6
     7        Reviewed by Eric Carlson.
     8
     9        In some cases, Safari is not receiving unsuspend notifications.
     10        In that case, the capture unit might stay in suspend state forever.
     11        To work around that, we force to unsuspend whenever there is a new capture happening.
     12        This will make it so that reloading the page will unsuspend the page.
     13
     14        Manually tested by triggering Siri, starting to use the microphone and quickly going back to a capturing page.
     15
     16        * platform/mediastream/mac/CoreAudioCaptureSource.cpp:
     17        (WebCore::CoreAudioSharedUnit::provideSpeakerData):
     18        When suspension happens, the buffer size might change.
     19        Since this is only an issue if there are some references data, we now do not fail the capture when there
     20        is no reference data.
     21        (WebCore::CoreAudioSharedUnit::resume):
     22        (WebCore::CoreAudioSharedUnit::prepareForNewCapture):
     23        Make sure to start with a clean slate by setting suspend state to false for the shared unit.
     24        And failing all previous sources in case we are going back from suspension.
     25        (WebCore::CoreAudioSharedUnit::startInternal):
     26        (WebCore::CoreAudioCaptureSourceFactory::audioCaptureDeviceManager):
     27        (WebCore::CoreAudioCaptureSource::CoreAudioCaptureSource):
     28
    1292019-09-10  Adrian Perez de Castro  <aperez@igalia.com>
    230
  • trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp

    r249154 r249715  
    108108    void devicesChanged(const Vector<CaptureDevice>&);
    109109
     110    void prepareForNewCapture();
     111
    110112private:
    111113    OSStatus configureSpeakerProc();
     
    451453
    452454    if (m_speakerSampleBuffer->sampleCapacity() < inNumberFrames) {
     455        if (m_activeSources.isEmpty())
     456            return 0;
    453457        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);
     458        // FIXME: This fails the capture, we should thus either reconfigure the audio unit or notify all clients that capture is failing.
    454459        return kAudio_ParamError;
    455460    }
     
    630635}
    631636
     637void CoreAudioSharedUnit::prepareForNewCapture()
     638{
     639    if (!m_suspended)
     640        return;
     641    m_suspended = false;
     642
     643    if (!m_producingCount)
     644        return;
     645
     646    RELEASE_LOG_ERROR(WebRTC, "CoreAudioSharedUnit::prepareForNewCapture, notifying suspended sources of capture failure");
     647    captureFailed();
     648}
     649
    632650OSStatus CoreAudioSharedUnit::startInternal()
    633651{
     
    648666    if (err) {
    649667        RELEASE_LOG_ERROR(WebRTC, "CoreAudioSharedUnit::start(%p) AudioOutputUnitStart failed with error %d (%.4s)", this, (int)err, (char*)&err);
     668        cleanupAudioUnit();
     669        ASSERT(!m_ioUnit);
    650670        return err;
    651671    }
     
    854874    , m_captureDeviceID(captureDeviceID)
    855875{
     876#if PLATFORM(IOS_FAMILY)
     877    // We ensure that we unsuspend ourselves on the constructor as a capture source
     878    // is created when getUserMedia grants access which only happens when the process is foregrounded.
     879    CoreAudioSharedUnit::singleton().prepareForNewCapture();
     880#endif
    856881}
    857882
     
    872897
    873898    unit.addClient(*this);
    874 
    875 #if PLATFORM(IOS_FAMILY)
    876     // We ensure that we unsuspend ourselves on the constructor as a capture source
    877     // is created when getUserMedia grants access which only happens when the process is foregrounded.
    878     if (unit.isSuspended())
    879         unit.reconfigureAudioUnit();
    880 #endif
    881899}
    882900
Note: See TracChangeset for help on using the changeset viewer.