Title: [216463] trunk/Source
Revision
216463
Author
commit-qu...@webkit.org
Date
2017-05-08 16:31:56 -0700 (Mon, 08 May 2017)

Log Message

Add support for reading and writing settings from UIProcess audio capture
https://bugs.webkit.org/show_bug.cgi?id=171633

Patch by Youenn Fablet <you...@apple.com> on 2017-05-08
Reviewed by Eric Carlson.

Source/WebCore:

Covered by manual testing and existing test sets.

Moving success/failure callbacks for applyConstraints.
Making main RealtimeMediaSource::applyConstraints virtual so that WebProcess source proxies can implement it by
doing an IPC call directly. Doing so for UIProcess CoreAudioCaptureSource.

Adding support for volume to CoreAudioCaptureSource by applying gain post-capturing.
Adding support for toggling echo cancellation in CoreAudioCaptureSource.
Adding support to change echo cancellation and sample rate by scheduling a reconfiguration of the audio unit.
To do so, we stop producing data, delete the audio unit and restart producing data.
Removing CoreAudioCaptureSource::supportedConstraints as it is redundant with
RealtimeMediaSourceSettings::supportedConstraints.

Setting sample rate only to the following values: 8000, 16000, 32000, 44100, 48000.

* Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::applyConstraints):
* platform/mediastream/MediaStreamTrackPrivate.cpp:
(WebCore::MediaStreamTrackPrivate::applyConstraints):
* platform/mediastream/MediaStreamTrackPrivate.h:
* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::applyConstraints):
* platform/mediastream/RealtimeMediaSource.h:
* platform/mediastream/RealtimeMediaSourceSettings.h:
(WebCore::RealtimeMediaSourceSettings::supportedConstraints):
* platform/mediastream/mac/CoreAudioCaptureSource.cpp:
(WebCore::CoreAudioCaptureSource::~CoreAudioCaptureSource):
(WebCore::CoreAudioCaptureSource::processMicrophoneSamples):
(WebCore::CoreAudioCaptureSource::cleanupAudioUnit):
(WebCore::CoreAudioCaptureSource::createAudioUnit):
(WebCore::CoreAudioCaptureSource::configureAudioUnit):
(WebCore::CoreAudioCaptureSource::startProducingData):
(WebCore::CoreAudioCaptureSource::capabilities):
(WebCore::CoreAudioCaptureSource::settings):
(WebCore::CoreAudioCaptureSource::applySampleRate):
(WebCore::CoreAudioCaptureSource::applyEchoCancellation):
(WebCore::CoreAudioCaptureSource::scheduleReconfiguration):
(WebCore::CoreAudioCaptureSource::cleanupAudioUnits): Deleted.
(WebCore::CoreAudioCaptureSource::setupAudioUnits): Deleted.
* platform/mediastream/mac/CoreAudioCaptureSource.h:

Source/WebKit2:

* UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp:
(WebKit::UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints):
(WebKit::UserMediaCaptureManagerProxy::applyConstraints):
* UIProcess/Cocoa/UserMediaCaptureManagerProxy.h:
* UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in:
* WebProcess/cocoa/UserMediaCaptureManager.cpp:
(WebKit::UserMediaCaptureManager::Source::setSettings):
(WebKit::UserMediaCaptureManager::Source::applyConstraintsSucceeded):
(WebKit::UserMediaCaptureManager::Source::applyConstraintsFailed):
(WebKit::UserMediaCaptureManager::createCaptureSource):
(WebKit::UserMediaCaptureManager::sourceSettingsChanged):
(WebKit::UserMediaCaptureManager::applyConstraints):
(WebKit::UserMediaCaptureManager::applyConstraintsSucceeded):
(WebKit::UserMediaCaptureManager::applyConstraintsFailed):
(WebKit::UserMediaCaptureManager::Source::setMuted): Deleted.
(WebKit::UserMediaCaptureManager::Source::setEnabled): Deleted.
* WebProcess/cocoa/UserMediaCaptureManager.h:
* WebProcess/cocoa/UserMediaCaptureManager.messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (216462 => 216463)


--- trunk/Source/WebCore/ChangeLog	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/ChangeLog	2017-05-08 23:31:56 UTC (rev 216463)
@@ -1,3 +1,51 @@
+2017-05-08  Youenn Fablet  <you...@apple.com>
+
+        Add support for reading and writing settings from UIProcess audio capture
+        https://bugs.webkit.org/show_bug.cgi?id=171633
+
+        Reviewed by Eric Carlson.
+
+        Covered by manual testing and existing test sets.
+
+        Moving success/failure callbacks for applyConstraints.
+        Making main RealtimeMediaSource::applyConstraints virtual so that WebProcess source proxies can implement it by
+        doing an IPC call directly. Doing so for UIProcess CoreAudioCaptureSource.
+
+        Adding support for volume to CoreAudioCaptureSource by applying gain post-capturing.
+        Adding support for toggling echo cancellation in CoreAudioCaptureSource.
+        Adding support to change echo cancellation and sample rate by scheduling a reconfiguration of the audio unit.
+        To do so, we stop producing data, delete the audio unit and restart producing data.
+        Removing CoreAudioCaptureSource::supportedConstraints as it is redundant with
+        RealtimeMediaSourceSettings::supportedConstraints.
+
+        Setting sample rate only to the following values: 8000, 16000, 32000, 44100, 48000.
+
+        * Modules/mediastream/MediaStreamTrack.cpp:
+        (WebCore::MediaStreamTrack::applyConstraints):
+        * platform/mediastream/MediaStreamTrackPrivate.cpp:
+        (WebCore::MediaStreamTrackPrivate::applyConstraints):
+        * platform/mediastream/MediaStreamTrackPrivate.h:
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::applyConstraints):
+        * platform/mediastream/RealtimeMediaSource.h:
+        * platform/mediastream/RealtimeMediaSourceSettings.h:
+        (WebCore::RealtimeMediaSourceSettings::supportedConstraints):
+        * platform/mediastream/mac/CoreAudioCaptureSource.cpp:
+        (WebCore::CoreAudioCaptureSource::~CoreAudioCaptureSource):
+        (WebCore::CoreAudioCaptureSource::processMicrophoneSamples):
+        (WebCore::CoreAudioCaptureSource::cleanupAudioUnit):
+        (WebCore::CoreAudioCaptureSource::createAudioUnit):
+        (WebCore::CoreAudioCaptureSource::configureAudioUnit):
+        (WebCore::CoreAudioCaptureSource::startProducingData):
+        (WebCore::CoreAudioCaptureSource::capabilities):
+        (WebCore::CoreAudioCaptureSource::settings):
+        (WebCore::CoreAudioCaptureSource::applySampleRate):
+        (WebCore::CoreAudioCaptureSource::applyEchoCancellation):
+        (WebCore::CoreAudioCaptureSource::scheduleReconfiguration):
+        (WebCore::CoreAudioCaptureSource::cleanupAudioUnits): Deleted.
+        (WebCore::CoreAudioCaptureSource::setupAudioUnits): Deleted.
+        * platform/mediastream/mac/CoreAudioCaptureSource.h:
+
 2017-05-08  Chris Dumez  <cdu...@apple.com>
 
         Drop non-standard document.implementation.createCSSStyleSheet() API

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp (216462 => 216463)


--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2017-05-08 23:31:56 UTC (rev 216463)
@@ -269,7 +269,7 @@
         weakThis->m_promise->resolve();
         weakThis->m_constraints = constraints.value_or(MediaTrackConstraints { });
     };
-    m_private->applyConstraints(createMediaConstraintsImpl(constraints), successHandler, failureHandler);
+    m_private->applyConstraints(createMediaConstraintsImpl(constraints), WTFMove(successHandler), WTFMove(failureHandler));
 }
 
 void MediaStreamTrack::addObserver(Observer& observer)

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp (216462 => 216463)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp	2017-05-08 23:31:56 UTC (rev 216463)
@@ -141,9 +141,9 @@
     return m_source->capabilities();
 }
 
-void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::SuccessHandler successHandler, RealtimeMediaSource::FailureHandler failureHandler)
+void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::SuccessHandler&& successHandler, RealtimeMediaSource::FailureHandler&& failureHandler)
 {
-    m_source->applyConstraints(constraints, successHandler, failureHandler);
+    m_source->applyConstraints(constraints, WTFMove(successHandler), WTFMove(failureHandler));
 }
 
 AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider()

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h (216462 => 216463)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h	2017-05-08 23:31:56 UTC (rev 216463)
@@ -89,7 +89,7 @@
     const RealtimeMediaSourceSettings& settings() const;
     const RealtimeMediaSourceCapabilities& capabilities() const;
 
-    void applyConstraints(const MediaConstraints&, RealtimeMediaSource::SuccessHandler, RealtimeMediaSource::FailureHandler);
+    void applyConstraints(const MediaConstraints&, RealtimeMediaSource::SuccessHandler&&, RealtimeMediaSource::FailureHandler&&);
 
     AudioSourceProvider* audioSourceProvider();
 

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (216462 => 216463)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-05-08 23:31:56 UTC (rev 216463)
@@ -751,7 +751,7 @@
     return std::nullopt;
 }
 
-void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler successHandler, FailureHandler failureHandler)
+void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler&& successHandler, FailureHandler&& failureHandler)
 {
     auto result = applyConstraints(constraints);
     if (!result && successHandler)

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h (216462 => 216463)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h	2017-05-08 23:31:56 UTC (rev 216463)
@@ -123,7 +123,7 @@
 
     using SuccessHandler = std::function<void()>;
     using FailureHandler = std::function<void(const String& badConstraint, const String& errorString)>;
-    void applyConstraints(const MediaConstraints&, SuccessHandler, FailureHandler);
+    virtual void applyConstraints(const MediaConstraints&, SuccessHandler&&, FailureHandler&&);
     std::optional<std::pair<String, String>> applyConstraints(const MediaConstraints&);
 
     virtual bool supportsConstraints(const MediaConstraints&, String&);

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h (216462 => 216463)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h	2017-05-08 23:31:56 UTC (rev 216463)
@@ -93,6 +93,7 @@
     const AtomicString& groupId() const { return m_groupId; }
     void setGroupId(const AtomicString& groupId) { m_groupId = groupId; }
 
+    const RealtimeMediaSourceSupportedConstraints& supportedConstraints() const { return m_supportedConstraints; }
     void setSupportedConstraints(const RealtimeMediaSourceSupportedConstraints& supportedConstraints) { m_supportedConstraints = supportedConstraints; }
 
     template<class Encoder> void encode(Encoder&) const;

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


--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp	2017-05-08 23:31:56 UTC (rev 216463)
@@ -91,8 +91,9 @@
 
     OSStatus suspend();
 
-    OSStatus setupAudioUnits();
-    void cleanupAudioUnits();
+    OSStatus setupAudioUnit();
+    void cleanupAudioUnit();
+    OSStatus reconfigureAudioUnit();
 
     void addEchoCancellationSource(AudioSampleDataSource&);
     void removeEchoCancellationSource(AudioSampleDataSource&);
@@ -109,6 +110,8 @@
     void setSampleRate(int sampleRate) { m_sampleRate = sampleRate; }
     void setEnableEchoCancellation(bool enableEchoCancellation) { m_enableEchoCancellation = enableEchoCancellation; }
 
+    bool hasAudioUnit() const { return m_ioUnit; }
+
 private:
     OSStatus configureSpeakerProc();
     OSStatus configureMicrophoneProc();
@@ -121,7 +124,7 @@
     static OSStatus speakerCallback(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32, UInt32, AudioBufferList*);
     OSStatus provideSpeakerData(AudioUnitRenderActionFlags&, const AudioTimeStamp&, UInt32, UInt32, AudioBufferList*);
 
-    Vector<CoreAudioCaptureSource*> m_clients;
+    Vector<std::reference_wrapper<CoreAudioCaptureSource>> m_clients;
 
     AudioUnit m_ioUnit { nullptr };
 
@@ -152,7 +155,6 @@
     int32_t m_producingCount { 0 };
 
     mutable std::unique_ptr<RealtimeMediaSourceCapabilities> m_capabilities;
-    mutable RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
     mutable std::optional<RealtimeMediaSourceSettings> m_currentSettings;
 
 #if !LOG_DISABLED
@@ -181,12 +183,14 @@
 
 void CoreAudioSharedUnit::addClient(CoreAudioCaptureSource& client)
 {
-    m_clients.append(&client);
+    m_clients.append(client);
 }
 
 void CoreAudioSharedUnit::removeClient(CoreAudioCaptureSource& client)
 {
-    m_clients.removeAll(&client);
+    m_clients.removeAllMatching([&](const auto& item) {
+        return &client == &item.get();
+    });
 }
 
 void CoreAudioSharedUnit::addEchoCancellationSource(AudioSampleDataSource& source)
@@ -211,7 +215,7 @@
     return AudioSession::sharedSession().bufferSize();
 }
 
-OSStatus CoreAudioSharedUnit::setupAudioUnits()
+OSStatus CoreAudioSharedUnit::setupAudioUnit()
 {
     if (m_ioUnit)
         return 0;
@@ -226,7 +230,7 @@
     AudioComponent ioComponent = AudioComponentFindNext(nullptr, &ioUnitDescription);
     ASSERT(ioComponent);
     if (!ioComponent) {
-        LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to find vpio unit component", this);
+        LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) unable to find vpio unit component", this);
         return -1;
     }
 
@@ -236,13 +240,13 @@
     if (name) {
         m_ioUnitName = name;
         CFRelease(name);
-        LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) created \"%s\" component", this, m_ioUnitName.utf8().data());
+        LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) created \"%s\" component", this, m_ioUnitName.utf8().data());
     }
 #endif
 
     auto err = AudioComponentInstanceNew(ioComponent, &m_ioUnit);
     if (err) {
-        LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to open vpio unit, error %d (%.4s)", this, (int)err, (char*)&err);
+        LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) unable to open vpio unit, error %d (%.4s)", this, (int)err, (char*)&err);
         return err;
     }
 
@@ -250,13 +254,13 @@
         uint32_t param = 0;
         err = AudioUnitSetProperty(m_ioUnit, kAUVoiceIOProperty_VoiceProcessingEnableAGC, kAudioUnitScope_Global, inputBus, &param, sizeof(param));
         if (err) {
-            LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to set vpio automatic gain control, error %d (%.4s)", this, (int)err, (char*)&err);
+            LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) unable to set vpio automatic gain control, error %d (%.4s)", this, (int)err, (char*)&err);
             return err;
         }
         param = 1;
         err = AudioUnitSetProperty(m_ioUnit, kAUVoiceIOProperty_BypassVoiceProcessing, kAudioUnitScope_Global, inputBus, &param, sizeof(param));
         if (err) {
-            LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to set vpio unit echo cancellation, error %d (%.4s)", this, (int)err, (char*)&err);
+            LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) unable to set vpio unit echo cancellation, error %d (%.4s)", this, (int)err, (char*)&err);
             return err;
         }
     }
@@ -265,7 +269,7 @@
     uint32_t param = 1;
     err = AudioUnitSetProperty(m_ioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, inputBus, &param, sizeof(param));
     if (err) {
-        LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to enable vpio unit input, error %d (%.4s)", this, (int)err, (char*)&err);
+        LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) unable to enable vpio unit input, error %d (%.4s)", this, (int)err, (char*)&err);
         return err;
     }
 #else
@@ -277,7 +281,7 @@
 
     err = AudioUnitSetProperty(m_ioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, inputBus, &m_captureDeviceID, sizeof(m_captureDeviceID));
     if (err) {
-        LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to set vpio unit capture device ID, error %d (%.4s)", this, (int)err, (char*)&err);
+        LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) unable to set vpio unit capture device ID, error %d (%.4s)", this, (int)err, (char*)&err);
         return err;
     }
 #endif
@@ -286,17 +290,17 @@
     if (err)
         return err;
 
+    err = configureSpeakerProc();
+    if (err)
+        return err;
+
     err = AudioUnitInitialize(m_ioUnit);
     if (err) {
-        LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) AudioUnitInitialize() failed, error %d (%.4s)", this, (int)err, (char*)&err);
+        LOG(Media, "CoreAudioCaptureSource::setupAudioUnit(%p) AudioUnitInitialize() failed, error %d (%.4s)", this, (int)err, (char*)&err);
         return err;
     }
     m_ioUnitInitialized = true;
 
-    err = configureSpeakerProc();
-    if (err)
-        return err;
-
     return err;
 }
 
@@ -458,11 +462,10 @@
     if (m_volume != 1.0)
         m_microphoneSampleBuffer->applyGain(m_volume);
 
-    for (auto* client : m_clients) {
-        if (client->isProducingData())
-            client->audioSamplesAvailable(MediaTime(sampleTime, m_microphoneProcFormat.sampleRate()), m_microphoneSampleBuffer->bufferList(), m_microphoneProcFormat, inNumberFrames);
+    for (CoreAudioCaptureSource& client : m_clients) {
+        if (client.isProducingData())
+            client.audioSamplesAvailable(MediaTime(sampleTime, m_microphoneProcFormat.sampleRate()), m_microphoneSampleBuffer->bufferList(), m_microphoneProcFormat, inNumberFrames);
     }
-
     return noErr;
 }
 
@@ -474,14 +477,13 @@
     return dataSource->processMicrophoneSamples(*ioActionFlags, *inTimeStamp, inBusNumber, inNumberFrames, ioData);
 }
 
-void CoreAudioSharedUnit::cleanupAudioUnits()
+void CoreAudioSharedUnit::cleanupAudioUnit()
 {
-    ASSERT(m_clients.isEmpty());
     if (m_ioUnitInitialized) {
         ASSERT(m_ioUnit);
         auto err = AudioUnitUninitialize(m_ioUnit);
         if (err)
-            LOG(Media, "CoreAudioSharedUnit::cleanupAudioUnits(%p) AudioUnitUninitialize failed with error %d (%.4s)", this, (int)err, (char*)&err);
+            LOG(Media, "CoreAudioSharedUnit::cleanupAudioUnit(%p) AudioUnitUninitialize failed with error %d (%.4s)", this, (int)err, (char*)&err);
         m_ioUnitInitialized = false;
     }
 
@@ -497,6 +499,35 @@
 #endif
 }
 
+OSStatus CoreAudioSharedUnit::reconfigureAudioUnit()
+{
+    OSStatus err;
+    if (!hasAudioUnit())
+        return 0;
+
+    if (m_ioUnitStarted) {
+        err = AudioOutputUnitStop(m_ioUnit);
+        if (err) {
+            LOG(Media, "CoreAudioSharedUnit::reconfigureAudioUnit(%p) AudioOutputUnitStop failed with error %d (%.4s)", this, (int)err, (char*)&err);
+            return err;
+        }
+    }
+
+    cleanupAudioUnit();
+    err = setupAudioUnit();
+    if (err)
+        return err;
+
+    if (m_ioUnitStarted) {
+        err = AudioOutputUnitStart(m_ioUnit);
+        if (err) {
+            LOG(Media, "CoreAudioSharedUnit::reconfigureAudioUnit(%p) AudioOutputUnitStart failed with error %d (%.4s)", this, (int)err, (char*)&err);
+            return err;
+        }
+    }
+    return err;
+}
+
 void CoreAudioSharedUnit::startProducingData()
 {
     ASSERT(isMainThread());
@@ -509,9 +540,9 @@
 
     OSStatus err;
     if (!m_ioUnit) {
-        err = setupAudioUnits();
+        err = setupAudioUnit();
         if (err) {
-            cleanupAudioUnits();
+            cleanupAudioUnit();
             ASSERT(!m_ioUnit);
             return;
         }
@@ -687,20 +718,15 @@
 
 const RealtimeMediaSourceCapabilities& CoreAudioCaptureSource::capabilities() const
 {
-    if (m_capabilities)
-        return *m_capabilities;
-
-    m_supportedConstraints.setSupportsDeviceId(true);
-    m_supportedConstraints.setSupportsEchoCancellation(true);
-    m_supportedConstraints.setSupportsVolume(true);
-
-    // FIXME: finish this.
-    m_capabilities = std::make_unique<RealtimeMediaSourceCapabilities>(m_supportedConstraints);
-    m_capabilities->setDeviceId(id());
-    m_capabilities->setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite);
-    m_capabilities->setVolume(CapabilityValueOrRange(0.0, 1.0));
-
-    return *m_capabilities;
+    if (!m_capabilities) {
+        RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints());
+        capabilities.setDeviceId(id());
+        capabilities.setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite);
+        capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0));
+        capabilities.setSampleRate(CapabilityValueOrRange(8000, 96000));
+        m_capabilities = WTFMove(capabilities);
+    }
+    return m_capabilities.value();
 }
 
 const RealtimeMediaSourceSettings& CoreAudioCaptureSource::settings() const
@@ -712,8 +738,14 @@
         settings.setDeviceId(id());
         settings.setEchoCancellation(echoCancellation());
 
+        RealtimeMediaSourceSupportedConstraints supportedConstraints;
+        supportedConstraints.setSupportsDeviceId(true);
+        supportedConstraints.setSupportsEchoCancellation(true);
+        supportedConstraints.setSupportsVolume(true);
+        supportedConstraints.setSupportsSampleRate(true);
+        settings.setSupportedConstraints(supportedConstraints);
+
         m_currentSettings = WTFMove(settings);
-
     }
     return m_currentSettings.value();
 }
@@ -752,7 +784,7 @@
 
     CoreAudioSharedUnit::singleton().setSampleRate(sampleRate);
 
-    // FIXME: do reconfiguration if audio unit is started.
+    scheduleReconfiguration();
     return true;
 }
 
@@ -760,10 +792,24 @@
 {
     CoreAudioSharedUnit::singleton().setEnableEchoCancellation(enableEchoCancellation);
 
-    // FIXME: do reconfiguration if audio unit is started.
+    scheduleReconfiguration();
     return true;
 }
 
+void CoreAudioCaptureSource::scheduleReconfiguration()
+{
+    ASSERT(isMainThread());
+    auto& unit = CoreAudioSharedUnit::singleton();
+    if (!unit.hasAudioUnit() || m_reconfigurationOngoing)
+        return;
+
+    m_reconfigurationOngoing = true;
+    scheduleDeferredTask([this, &unit] {
+        unit.reconfigureAudioUnit();
+        m_reconfigurationOngoing = false;
+    });
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)

Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h (216462 => 216463)


--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h	2017-05-08 23:31:56 UTC (rev 216463)
@@ -75,6 +75,8 @@
     friend class CoreAudioSharedUnit;
     friend class CoreAudioCaptureSourceFactory;
 
+    void scheduleReconfiguration();
+
     bool isCaptureSource() const final { return true; }
     void startProducingData() final;
     void stopProducingData() final;
@@ -94,11 +96,11 @@
     bool m_isProducingData { false };
     bool m_isSuspended { false };
 
-    mutable std::unique_ptr<RealtimeMediaSourceCapabilities> m_capabilities;
-    mutable RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
+    mutable std::optional<RealtimeMediaSourceCapabilities> m_capabilities;
     mutable std::optional<RealtimeMediaSourceSettings> m_currentSettings;
 
     RefPtr<WebAudioSourceProviderAVFObjC> m_audioSourceProvider;
+    bool m_reconfigurationOngoing { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit2/ChangeLog (216462 => 216463)


--- trunk/Source/WebKit2/ChangeLog	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebKit2/ChangeLog	2017-05-08 23:31:56 UTC (rev 216463)
@@ -1,3 +1,29 @@
+2017-05-08  Youenn Fablet  <you...@apple.com>
+
+        Add support for reading and writing settings from UIProcess audio capture
+        https://bugs.webkit.org/show_bug.cgi?id=171633
+
+        Reviewed by Eric Carlson.
+
+        * UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp:
+        (WebKit::UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints):
+        (WebKit::UserMediaCaptureManagerProxy::applyConstraints):
+        * UIProcess/Cocoa/UserMediaCaptureManagerProxy.h:
+        * UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in:
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+        (WebKit::UserMediaCaptureManager::Source::setSettings):
+        (WebKit::UserMediaCaptureManager::Source::applyConstraintsSucceeded):
+        (WebKit::UserMediaCaptureManager::Source::applyConstraintsFailed):
+        (WebKit::UserMediaCaptureManager::createCaptureSource):
+        (WebKit::UserMediaCaptureManager::sourceSettingsChanged):
+        (WebKit::UserMediaCaptureManager::applyConstraints):
+        (WebKit::UserMediaCaptureManager::applyConstraintsSucceeded):
+        (WebKit::UserMediaCaptureManager::applyConstraintsFailed):
+        (WebKit::UserMediaCaptureManager::Source::setMuted): Deleted.
+        (WebKit::UserMediaCaptureManager::Source::setEnabled): Deleted.
+        * WebProcess/cocoa/UserMediaCaptureManager.h:
+        * WebProcess/cocoa/UserMediaCaptureManager.messages.in:
+
 2017-05-08  Alex Christensen  <achristen...@webkit.org>
 
         Reduce PassRefPtr use

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp (216462 => 216463)


--- trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp	2017-05-08 23:31:56 UTC (rev 216463)
@@ -125,7 +125,7 @@
     m_process.removeMessageReceiver(Messages::UserMediaCaptureManagerProxy::messageReceiverName());
 }
 
-void UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints(uint64_t id, const String& deviceID, WebCore::RealtimeMediaSource::Type type, const MediaConstraintsData& constraintsData, bool& succeeded, String& invalidConstraints)
+void UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints(uint64_t id, const String& deviceID, WebCore::RealtimeMediaSource::Type type, const MediaConstraintsData& constraintsData, bool& succeeded, String& invalidConstraints, WebCore::RealtimeMediaSourceSettings& settings)
 {
     CaptureSourceOrError sourceOrError;
     auto constraints = MediaConstraintsImpl::create(MediaConstraintsData(constraintsData));
@@ -142,9 +142,11 @@
     }
 
     succeeded = !!sourceOrError;
-    if (sourceOrError)
-        m_proxies.set(id, std::make_unique<SourceProxy>(id, *this, sourceOrError.source()));
-    else
+    if (sourceOrError) {
+        auto source = sourceOrError.source();
+        settings = source->settings();
+        m_proxies.set(id, std::make_unique<SourceProxy>(id, *this, WTFMove(source)));
+    } else
         invalidConstraints = WTFMove(sourceOrError.errorMessage);
 }
 
@@ -183,6 +185,21 @@
         iter->value->source().setEnabled(enabled);
 }
 
+void UserMediaCaptureManagerProxy::applyConstraints(uint64_t id, const WebCore::MediaConstraintsData& constraintsData)
+{
+    auto constraints = MediaConstraintsImpl::create(MediaConstraintsData(constraintsData));
+    auto iter = m_proxies.find(id);
+    if (iter == m_proxies.end())
+        return;
+
+    auto& source = iter->value->source();
+    auto result = source.applyConstraints(constraints);
+    if (!result)
+        m_process.send(Messages::UserMediaCaptureManager::ApplyConstraintsSucceeded(id, source.settings()), 0);
+    else
+        m_process.send(Messages::UserMediaCaptureManager::ApplyConstraintsFailed(id, result.value().first, result.value().second), 0);
 }
 
+}
+
 #endif

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h (216462 => 216463)


--- trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h	2017-05-08 23:31:56 UTC (rev 216463)
@@ -49,12 +49,13 @@
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
     void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) final;
 
-    void createMediaSourceForCaptureDeviceWithConstraints(uint64_t id, const String& deviceID, WebCore::RealtimeMediaSource::Type, const WebCore::MediaConstraintsData&, bool& succeeded, String& invalidConstraints);
+    void createMediaSourceForCaptureDeviceWithConstraints(uint64_t id, const String& deviceID, WebCore::RealtimeMediaSource::Type, const WebCore::MediaConstraintsData&, bool& succeeded, String& invalidConstraints, WebCore::RealtimeMediaSourceSettings&);
     void startProducingData(uint64_t);
     void stopProducingData(uint64_t);
     void capabilities(uint64_t, WebCore::RealtimeMediaSourceCapabilities&);
     void setMuted(uint64_t, bool);
     void setEnabled(uint64_t, bool);
+    void applyConstraints(uint64_t, const WebCore::MediaConstraintsData&);
 
     class SourceProxy;
     friend class SourceProxy;

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in (216462 => 216463)


--- trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.messages.in	2017-05-08 23:31:56 UTC (rev 216463)
@@ -22,10 +22,11 @@
 # THE POSSIBILITY OF SUCH DAMAGE.
 
 messages -> UserMediaCaptureManagerProxy {
-    CreateMediaSourceForCaptureDeviceWithConstraints(uint64_t id, String deviceID, WebCore::RealtimeMediaSource::Type type, struct WebCore::MediaConstraintsData constraints) -> (bool success, String invalidConstraints)
+    CreateMediaSourceForCaptureDeviceWithConstraints(uint64_t id, String deviceID, WebCore::RealtimeMediaSource::Type type, struct WebCore::MediaConstraintsData constraints) -> (bool success, String invalidConstraints, WebCore::RealtimeMediaSourceSettings settings)
     StartProducingData(uint64_t id)
     StopProducingData(uint64_t id)
     Capabilities(uint64_t id) -> (WebCore::RealtimeMediaSourceCapabilities capabilities)
     SetMuted(uint64_t id, bool muted)
     SetEnabled(uint64_t id, bool enabled)
+    ApplyConstraints(uint64_t id, struct WebCore::MediaConstraintsData constraints)
 }

Modified: trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.cpp (216462 => 216463)


--- trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.cpp	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.cpp	2017-05-08 23:31:56 UTC (rev 216463)
@@ -73,9 +73,9 @@
     }
 
     const RealtimeMediaSourceSettings& settings() const final { return m_settings; }
-    void setSettings(const RealtimeMediaSourceSettings& settings)
+    void setSettings(RealtimeMediaSourceSettings&& settings)
     {
-        m_settings = settings;
+        m_settings = WTFMove(settings);
         settingsDidChange();
     }
 
@@ -114,8 +114,21 @@
             observer->audioSamplesAvailable(time, audioData, m_description, numberOfFrames);
     }
 
-    virtual void setMuted(bool muted)
+    void applyConstraintsSucceeded(const WebCore::RealtimeMediaSourceSettings& settings)
     {
+        auto callbacks = m_pendingApplyConstraintsCallbacks.takeFirst();
+        setSettings(WebCore::RealtimeMediaSourceSettings(settings));
+        callbacks.successHandler();
+    }
+
+    void applyConstraintsFailed(const String& failedConstraint, const String& errorMessage)
+    {
+        auto callbacks = m_pendingApplyConstraintsCallbacks.takeFirst();
+        callbacks.failureHandler(failedConstraint, errorMessage);
+    }
+
+    void setMuted(bool muted) final
+    {
         if (m_muted == muted)
             return;
 
@@ -123,7 +136,7 @@
         m_manager.setMuted(m_id, m_muted);
     }
 
-    virtual void setEnabled(bool enabled)
+    void setEnabled(bool enabled) final
     {
         if (m_enabled == enabled)
             return;
@@ -132,6 +145,7 @@
         m_manager.setEnabled(m_id, m_enabled);
     }
 
+private:
     void startProducingData() final { m_manager.startProducingData(m_id); }
     void stopProducingData() final { m_manager.stopProducingData(m_id); }
     bool isCaptureSource() const final { return true; }
@@ -145,11 +159,15 @@
         return m_audioSourceProvider.get();
     }
 
-private:
     // RealtimeMediaSource
     void beginConfiguration() final { }
     void commitConfiguration() final { }
 
+    void applyConstraints(const WebCore::MediaConstraints& constraints, SuccessHandler&& successHandler, FailureHandler&& failureHandler) final {
+        m_manager.applyConstraints(m_id, constraints);
+        m_pendingApplyConstraintsCallbacks.append({ WTFMove(successHandler), WTFMove(failureHandler)});
+    }
+
     uint64_t m_id;
     UserMediaCaptureManager& m_manager;
     mutable std::optional<RealtimeMediaSourceCapabilities> m_capabilities;
@@ -157,6 +175,12 @@
     CAAudioStreamDescription m_description;
     CARingBuffer m_ringBuffer;
     RefPtr<WebAudioSourceProviderAVFObjC> m_audioSourceProvider;
+
+    struct ApplyConstraintsCallback {
+        SuccessHandler successHandler;
+        FailureHandler failureHandler;
+    };
+    Deque<ApplyConstraintsCallback> m_pendingApplyConstraintsCallbacks;
 };
 
 UserMediaCaptureManager::UserMediaCaptureManager(WebProcess* process)
@@ -194,11 +218,13 @@
     constraintsData.isValid = constraints->isValid();
     bool succeeded;
 
+    RealtimeMediaSourceSettings settings;
     String errorMessage;
-    if (!m_process.sendSync(Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints(id, deviceID, sourceType, constraintsData), Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints::Reply(succeeded, errorMessage), 0))
+    if (!m_process.sendSync(Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints(id, deviceID, sourceType, constraintsData), Messages::UserMediaCaptureManagerProxy::CreateMediaSourceForCaptureDeviceWithConstraints::Reply(succeeded, errorMessage, settings), 0))
         return WTFMove(errorMessage);
 
     auto source = adoptRef(*new Source(String::number(id), sourceType, emptyString(), id, *this));
+    source->setSettings(WTFMove(settings));
     m_sources.set(id, source.copyRef());
     return WebCore::CaptureSourceOrError(WTFMove(source));
 }
@@ -224,7 +250,7 @@
 void UserMediaCaptureManager::sourceSettingsChanged(uint64_t id, const RealtimeMediaSourceSettings& settings)
 {
     ASSERT(m_sources.contains(id));
-    m_sources.get(id)->setSettings(settings);
+    m_sources.get(id)->setSettings(RealtimeMediaSourceSettings(settings));
 }
 
 void UserMediaCaptureManager::storageChanged(uint64_t id, const SharedMemory::Handle& handle, const WebCore::CAAudioStreamDescription& description, uint64_t numberOfFrames)
@@ -274,6 +300,30 @@
     m_process.send(Messages::UserMediaCaptureManagerProxy::SetEnabled(id, enabled), 0);
 }
 
+void UserMediaCaptureManager::applyConstraints(uint64_t id, const WebCore::MediaConstraints& constraints)
+{
+    MediaConstraintsData constraintsData;
+    constraintsData.mandatoryConstraints = constraints.mandatoryConstraints();
+    constraintsData.advancedConstraints = constraints.advancedConstraints();
+    constraintsData.isValid = constraints.isValid();
+
+    m_process.send(Messages::UserMediaCaptureManagerProxy::ApplyConstraints(id, constraintsData), 0);
 }
 
+void UserMediaCaptureManager::applyConstraintsSucceeded(uint64_t id, const WebCore::RealtimeMediaSourceSettings& settings)
+{
+    ASSERT(m_sources.contains(id));
+    auto& source = *m_sources.get(id);
+    source.applyConstraintsSucceeded(settings);
+}
+
+void UserMediaCaptureManager::applyConstraintsFailed(uint64_t id, const String& failedConstraint, const String& message)
+{
+    ASSERT(m_sources.contains(id));
+    auto& source = *m_sources.get(id);
+    source.applyConstraintsFailed(failedConstraint, message);
+}
+
+}
+
 #endif

Modified: trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.h (216462 => 216463)


--- trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.h	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.h	2017-05-08 23:31:56 UTC (rev 216463)
@@ -75,6 +75,9 @@
     WebCore::RealtimeMediaSourceCapabilities capabilities(uint64_t);
     void setMuted(uint64_t, bool);
     void setEnabled(uint64_t, bool);
+    void applyConstraints(uint64_t, const WebCore::MediaConstraints&);
+    void applyConstraintsSucceeded(uint64_t, const WebCore::RealtimeMediaSourceSettings&);
+    void applyConstraintsFailed(uint64_t, const String&, const String&);
 
     class Source;
     friend class Source;

Modified: trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.messages.in (216462 => 216463)


--- trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.messages.in	2017-05-08 23:15:00 UTC (rev 216462)
+++ trunk/Source/WebKit2/WebProcess/cocoa/UserMediaCaptureManager.messages.in	2017-05-08 23:31:56 UTC (rev 216463)
@@ -28,4 +28,6 @@
     SourceSettingsChanged(uint64_t id, WebCore::RealtimeMediaSourceSettings settings)
     StorageChanged(uint64_t id, WebKit::SharedMemory::Handle storageHandle, WebCore::CAAudioStreamDescription description, uint64_t numberOfFrames)
     AudioSamplesAvailable(uint64_t id, MediaTime time, uint64_t numberOfFrames, uint64_t startFrame, uint64_t endFrame)
+    ApplyConstraintsSucceeded(uint64_t id, WebCore::RealtimeMediaSourceSettings settings)
+    ApplyConstraintsFailed(uint64_t id, String failedConstraint, String message)
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to