Diff
Modified: trunk/Source/WebCore/ChangeLog (215200 => 215201)
--- trunk/Source/WebCore/ChangeLog 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebCore/ChangeLog 2017-04-10 21:24:13 UTC (rev 215201)
@@ -1,3 +1,57 @@
+2017-04-10 Jeremy Jones <jere...@apple.com>
+
+ Add CoreAudioCaptureSource.
+ https://bugs.webkit.org/show_bug.cgi?id=170112
+ rdar://problem/30293338
+
+ Reviewed by Eric Carlson.
+
+ No new tests because this provides the same funcitonality as AVAudioCaptureSource.
+ Funcionality is covered by existing test cases.
+
+ Add CoreAudioCaptureSource for audio capture. And use it by default in AVCaptureDeviceManager.
+ Add UseAVFoundationAudioCapture setting to switch back to AVFoundation for audio capture.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/Settings.cpp:
+ (WebCore::Settings::useAVFoundationAudioCapture):
+ (WebCore::Settings::setUseAVFoundationAudioCapture):
+ * page/Settings.h:
+ * platform/mediastream/mac/AVCaptureDeviceManager.h:
+ * platform/mediastream/mac/AVCaptureDeviceManager.mm:
+ (WebCore::AVCaptureDeviceManager::setUseAVFoundationAudioCapture):
+ * platform/mediastream/mac/CoreAudioCaptureSource.cpp: Added.
+ (WebCore::CoreAudioCaptureSource::create):
+ (WebCore::CoreAudioCaptureSource::factory):
+ (WebCore::CoreAudioCaptureSource::CoreAudioCaptureSource):
+ (WebCore::CoreAudioCaptureSource::~CoreAudioCaptureSource):
+ (WebCore::CoreAudioCaptureSource::preferredSampleRate):
+ (WebCore::CoreAudioCaptureSource::preferredIOBufferDuration):
+ (WebCore::CoreAudioCaptureSource::configureMicrophoneProc):
+ (WebCore::CoreAudioCaptureSource::configureSpeakerProc):
+ (WebCore::CoreAudioCaptureSource::addMicrophoneDataConsumer):
+ (WebCore::CoreAudioCaptureSource::removeMicrophoneDataConsumer):
+ (WebCore::CoreAudioCaptureSource::addEchoCancellationSource):
+ (WebCore::CoreAudioCaptureSource::removeEchoCancellationSource):
+ (WebCore::CoreAudioCaptureSource::checkTimestamps):
+ (WebCore::CoreAudioCaptureSource::provideSpeakerData):
+ (WebCore::CoreAudioCaptureSource::speakerCallback):
+ (WebCore::CoreAudioCaptureSource::processMicrophoneSamples):
+ (WebCore::CoreAudioCaptureSource::microphoneCallback):
+ (WebCore::CoreAudioCaptureSource::defaultOutputDevice):
+ (WebCore::CoreAudioCaptureSource::defaultInputDevice):
+ (WebCore::CoreAudioCaptureSource::setupAudioUnits):
+ (WebCore::CoreAudioCaptureSource::startProducingData):
+ (WebCore::CoreAudioCaptureSource::stopProducingData):
+ (WebCore::CoreAudioCaptureSource::suspend):
+ (WebCore::CoreAudioCaptureSource::resume):
+ (WebCore::CoreAudioCaptureSource::capabilities):
+ (WebCore::CoreAudioCaptureSource::settings):
+ * platform/mediastream/mac/CoreAudioCaptureSource.h: Added.
+ * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+ (WebCore::RealtimeMediaSourceCenterMac::RealtimeMediaSourceCenterMac):
+ (WebCore::RealtimeMediaSourceCenterMac::defaultAudioFactory):
+
2017-04-10 Youenn Fablet <you...@apple.com>
Wrap legacy MediaStream API in runtime flag
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (215200 => 215201)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-10 21:24:13 UTC (rev 215201)
@@ -73,7 +73,7 @@
070334E9145A1F36008D8D45 /* JSTrackCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 070334E8145A1F35008D8D45 /* JSTrackCustom.cpp */; };
070363E0181A1CDC00C074A5 /* AVAudioCaptureSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 070363D8181A1CDC00C074A5 /* AVAudioCaptureSource.h */; };
070363E1181A1CDC00C074A5 /* AVAudioCaptureSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 070363D9181A1CDC00C074A5 /* AVAudioCaptureSource.mm */; };
- 070363E2181A1CDC00C074A5 /* AVCaptureDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 070363DA181A1CDC00C074A5 /* AVCaptureDeviceManager.h */; };
+ 070363E2181A1CDC00C074A5 /* AVCaptureDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 070363DA181A1CDC00C074A5 /* AVCaptureDeviceManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
070363E3181A1CDC00C074A5 /* AVCaptureDeviceManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 070363DB181A1CDC00C074A5 /* AVCaptureDeviceManager.mm */; };
070363E4181A1CDC00C074A5 /* AVMediaCaptureSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 070363DC181A1CDC00C074A5 /* AVMediaCaptureSource.h */; };
070363E5181A1CDC00C074A5 /* AVMediaCaptureSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 070363DD181A1CDC00C074A5 /* AVMediaCaptureSource.mm */; };
@@ -274,7 +274,7 @@
07B5A30D14687D7100A81ECE /* JSTextTrackListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07B5A30C14687D7100A81ECE /* JSTextTrackListCustom.cpp */; };
07B7116D1D899E63009F0FFB /* CaptureDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B7116A1D899E63009F0FFB /* CaptureDevice.h */; settings = {ATTRIBUTES = (Private, ); }; };
07B7116E1D899E63009F0FFB /* CaptureDeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07B7116B1D899E63009F0FFB /* CaptureDeviceManager.cpp */; };
- 07B7116F1D899E63009F0FFB /* CaptureDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B7116C1D899E63009F0FFB /* CaptureDeviceManager.h */; };
+ 07B7116F1D899E63009F0FFB /* CaptureDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B7116C1D899E63009F0FFB /* CaptureDeviceManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
07C046C31E42508B007201E7 /* CAAudioStreamDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 073B87571E40DCFD0071C0EC /* CAAudioStreamDescription.cpp */; };
07C046C41E42508B007201E7 /* CAAudioStreamDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 073B87581E40DCFD0071C0EC /* CAAudioStreamDescription.h */; settings = {ATTRIBUTES = (Private, ); }; };
07C046C81E425155007201E7 /* AudioTrackPrivateMediaStreamCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 07C046C61E42512F007201E7 /* AudioTrackPrivateMediaStreamCocoa.h */; };
@@ -1673,6 +1673,7 @@
3F42B31E1881191B00278AAC /* WebVideoFullscreenControllerAVKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3F42B31C1881191B00278AAC /* WebVideoFullscreenControllerAVKit.mm */; };
3FBC4AF3189881560046EE38 /* WebVideoFullscreenInterfaceAVKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3FBC4AF1189881560046EE38 /* WebVideoFullscreenInterfaceAVKit.mm */; };
3FBC4AF4189881560046EE38 /* WebVideoFullscreenInterfaceAVKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FBC4AF2189881560046EE38 /* WebVideoFullscreenInterfaceAVKit.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 3FF1FA661E7350FD00C1002F /* CoreAudioCaptureSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F3BB5821E709EE400C701F2 /* CoreAudioCaptureSource.cpp */; };
3FF813A71DBA8640009BF001 /* PointerLockController.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CFC434F192406A900A0D3B5 /* PointerLockController.h */; settings = {ATTRIBUTES = (Private, ); }; };
3FFFF9A8159D9A550020BBD5 /* WebKitCSSViewportRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FFFF9A6159D9A550020BBD5 /* WebKitCSSViewportRule.cpp */; };
3FFFF9A9159D9A550020BBD5 /* WebKitCSSViewportRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FFFF9A7159D9A550020BBD5 /* WebKitCSSViewportRule.h */; };
@@ -9257,6 +9258,8 @@
3F2B33E3165ABD3500E3987C /* WebKitCSSViewportRule.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebKitCSSViewportRule.idl; sourceTree = "<group>"; };
3F2B33E9165AF15500E3987C /* JSWebKitCSSViewportRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebKitCSSViewportRule.cpp; sourceTree = "<group>"; };
3F2B33EA165AF15500E3987C /* JSWebKitCSSViewportRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebKitCSSViewportRule.h; sourceTree = "<group>"; };
+ 3F3BB5821E709EE400C701F2 /* CoreAudioCaptureSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoreAudioCaptureSource.cpp; sourceTree = "<group>"; };
+ 3F3BB5831E709EE400C701F2 /* CoreAudioCaptureSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudioCaptureSource.h; sourceTree = "<group>"; };
3F42B31B1881191B00278AAC /* WebVideoFullscreenControllerAVKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVideoFullscreenControllerAVKit.h; sourceTree = "<group>"; };
3F42B31C1881191B00278AAC /* WebVideoFullscreenControllerAVKit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebVideoFullscreenControllerAVKit.mm; sourceTree = "<group>"; };
3FBC4AF1189881560046EE38 /* WebVideoFullscreenInterfaceAVKit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebVideoFullscreenInterfaceAVKit.mm; sourceTree = "<group>"; };
@@ -16117,6 +16120,8 @@
070363DD181A1CDC00C074A5 /* AVMediaCaptureSource.mm */,
070363DE181A1CDC00C074A5 /* AVVideoCaptureSource.h */,
070363DF181A1CDC00C074A5 /* AVVideoCaptureSource.mm */,
+ 3F3BB5821E709EE400C701F2 /* CoreAudioCaptureSource.cpp */,
+ 3F3BB5831E709EE400C701F2 /* CoreAudioCaptureSource.h */,
0744ECEB1E0C4AE5000D0944 /* MockRealtimeAudioSourceMac.h */,
0744ECEC1E0C4AE5000D0944 /* MockRealtimeAudioSourceMac.mm */,
07EE76ED1BEA619800F89133 /* MockRealtimeVideoSourceMac.h */,
@@ -30618,6 +30623,7 @@
E13F01F11270E19000DFBA71 /* CookieStorageMac.mm in Sources */,
9746AF2114F4DDE6003E7A72 /* Coordinates.cpp in Sources */,
443817FF1A91B2F8006E04F2 /* CoreMediaSoftLink.cpp in Sources */,
+ 3FF1FA661E7350FD00C1002F /* CoreAudioCaptureSource.cpp in Sources */,
CD7D33471C7A16BF00041293 /* CoreVideoSoftLink.cpp in Sources */,
BC5EB9500E82056B00B25965 /* CounterDirectives.cpp in Sources */,
9392F1500AD1862300691BD4 /* CounterNode.cpp in Sources */,
Modified: trunk/Source/WebCore/page/Settings.cpp (215200 => 215201)
--- trunk/Source/WebCore/page/Settings.cpp 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebCore/page/Settings.cpp 2017-04-10 21:24:13 UTC (rev 215201)
@@ -48,6 +48,10 @@
#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
+#if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
+#include "AVCaptureDeviceManager.h"
+#endif
+
#if ENABLE(MEDIA_STREAM)
#include "MockRealtimeMediaSourceCenter.h"
#endif
@@ -94,6 +98,7 @@
#if ENABLE(MEDIA_STREAM)
bool Settings::gMockCaptureDevicesEnabled = false;
bool Settings::gMediaCaptureRequiresSecureConnection = true;
+bool Settings::gUseAVFoundationAudioCapture = false;
#endif
#if PLATFORM(WIN)
@@ -615,7 +620,20 @@
{
gMediaCaptureRequiresSecureConnection = mediaCaptureRequiresSecureConnection;
}
+
+bool Settings::useAVFoundationAudioCapture()
+{
+ return gUseAVFoundationAudioCapture;
+}
+
+void Settings::setUseAVFoundationAudioCapture(bool useAVFoundationAudioCapture)
+{
+ gUseAVFoundationAudioCapture = useAVFoundationAudioCapture;
+#if USE(AVFOUNDATION)
+ AVCaptureDeviceManager::setUseAVFoundationAudioCapture(useAVFoundationAudioCapture);
#endif
+}
+#endif
void Settings::setScrollingPerformanceLoggingEnabled(bool enabled)
{
Modified: trunk/Source/WebCore/page/Settings.h (215200 => 215201)
--- trunk/Source/WebCore/page/Settings.h 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebCore/page/Settings.h 2017-04-10 21:24:13 UTC (rev 215201)
@@ -310,6 +310,9 @@
bool mediaCaptureRequiresSecureConnection() const;
WEBCORE_EXPORT static void setMediaCaptureRequiresSecureConnection(bool);
+
+ static bool useAVFoundationAudioCapture();
+ WEBCORE_EXPORT static void setUseAVFoundationAudioCapture(bool);
#endif
#if ENABLE(APPLE_PAY)
@@ -415,6 +418,7 @@
String m_mediaDeviceIdentifierStorageDirectory;
static bool gMockCaptureDevicesEnabled;
static bool gMediaCaptureRequiresSecureConnection;
+ static bool gUseAVFoundationAudioCapture;
#endif
#if ENABLE(APPLE_PAY)
Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h (215200 => 215201)
--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h 2017-04-10 21:24:13 UTC (rev 215201)
@@ -45,6 +45,8 @@
class AVCaptureDeviceManager final : public CaptureDeviceManager {
friend class NeverDestroyed<AVCaptureDeviceManager>;
public:
+ WEBCORE_EXPORT static void setUseAVFoundationAudioCapture(bool);
+
Vector<CaptureDevice>& captureDevices() final;
static AVCaptureDeviceManager& singleton();
Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm (215200 => 215201)
--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm 2017-04-10 21:24:13 UTC (rev 215201)
@@ -32,6 +32,7 @@
#import "AVMediaCaptureSource.h"
#import "AVVideoCaptureSource.h"
#import "AudioSourceProvider.h"
+#import "CoreAudioCaptureSource.h"
#import "Logging.h"
#import "MediaConstraints.h"
#import "RealtimeMediaSource.h"
@@ -92,6 +93,19 @@
namespace WebCore {
+void AVCaptureDeviceManager::setUseAVFoundationAudioCapture(bool enabled)
+{
+ static bool active = false;
+ if (active == enabled)
+ return;
+
+ active = enabled;
+ if (active)
+ RealtimeMediaSourceCenter::singleton().setAudioFactory(AVAudioCaptureSource::factory());
+ else
+ RealtimeMediaSourceCenter::singleton().setAudioFactory(CoreAudioCaptureSource::factory());
+}
+
Vector<CaptureDevice>& AVCaptureDeviceManager::captureDevices()
{
if (!isAvailable())
Added: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp (0 => 215201)
--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp 2017-04-10 21:24:13 UTC (rev 215201)
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CoreAudioCaptureSource.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioSampleBufferList.h"
+#include "AudioSampleDataSource.h"
+#include "Logging.h"
+#include "MediaTimeAVFoundation.h"
+#include <AudioToolbox/AudioConverter.h>
+#include <AudioUnit/AudioUnit.h>
+#include <CoreMedia/CMSync.h>
+#include <mach/mach_time.h>
+#include <sys/time.h>
+#include <wtf/NeverDestroyed.h>
+#include "CoreMediaSoftLink.h"
+
+namespace WebCore {
+
+class CoreAudioCaptureSourceFactory : public RealtimeMediaSource::CaptureFactory {
+public:
+ RefPtr<RealtimeMediaSource> createMediaSourceForCaptureDeviceWithConstraints(const CaptureDevice& captureDevice, const MediaConstraints* constraints, String& invalidConstraint) final {
+ return CoreAudioCaptureSource::create(captureDevice, constraints, invalidConstraint);
+ }
+};
+
+const UInt32 outputBus = 0;
+const UInt32 inputBus = 1;
+
+RefPtr<CoreAudioCaptureSource> CoreAudioCaptureSource::create(const CaptureDevice& deviceInfo, const MediaConstraints* constraints, String& invalidConstraint)
+{
+ auto source = adoptRef(new CoreAudioCaptureSource(deviceInfo));
+ if (constraints) {
+ auto result = source->applyConstraints(*constraints);
+ if (result) {
+ invalidConstraint = result.value().first;
+ return nullptr;
+ }
+ }
+
+ return source;
+}
+
+
+RealtimeMediaSource::CaptureFactory& CoreAudioCaptureSource::factory()
+{
+ static NeverDestroyed<CoreAudioCaptureSourceFactory> factory;
+ return factory.get();
+}
+
+
+CoreAudioCaptureSource::CoreAudioCaptureSource(const CaptureDevice& deviceInfo)
+ : RealtimeMediaSource(emptyString(), RealtimeMediaSource::Type::Audio, deviceInfo.label())
+ , m_captureDeviceID(0)
+{
+ // FIXME: use deviceInfo to set the m_captureDeviceID
+
+ setPersistentID(deviceInfo.persistentId());
+ setMuted(true);
+
+ m_currentSettings.setVolume(1.0);
+ m_currentSettings.setSampleRate(preferredSampleRate());
+ m_currentSettings.setDeviceId(id());
+ m_currentSettings.setEchoCancellation(true);
+
+ mach_timebase_info_data_t timebaseInfo;
+ mach_timebase_info(&timebaseInfo);
+ m_DTSConversionRatio = 1e-9 * static_cast<double>(timebaseInfo.numer) / static_cast<double>(timebaseInfo.denom);
+}
+
+CoreAudioCaptureSource::~CoreAudioCaptureSource()
+{
+ suspend();
+
+ std::lock_guard<Lock> lock(m_internalStateLock);
+
+ if (m_ioUnit)
+ AudioComponentInstanceDispose(m_ioUnit);
+
+ m_ioUnitName = emptyString();
+
+ m_microphoneSampleBuffer = nullptr;
+ m_speakerSampleBuffer = nullptr;
+
+ m_speakerProcsCalled = 0;
+ m_microphoneProcsCalled = 0;
+ m_latestMicTimeStamp = 0;
+
+ m_activeSources.clear();
+ m_pendingSources.clear();
+
+ m_speakerSampleBuffer = nullptr;
+
+ m_ioUnitInitialized = false;
+ m_ioUnitStarted = false;
+}
+
+double CoreAudioCaptureSource::preferredSampleRate()
+{
+ // FIXME: Get the preferred rate dynamically, kAUVoiceIOProperty_PreferredHWSampleRate/ [[AVAudioSession sharedInstance] preferredSampleRate]
+ static const float preferredRate = 24000.;
+ return preferredRate;
+}
+
+double CoreAudioCaptureSource::preferredIOBufferDuration()
+{
+ // FIXME: Get the preferred duration dynamically - kAUVoiceIOProperty_PreferredHWBlockSizeInSeconds / [[AVAudioSession sharedInstance] preferredIOBufferDuration]
+ static const float preferredDuration = 0.02;
+ return preferredDuration;
+}
+
+OSStatus CoreAudioCaptureSource::configureMicrophoneProc()
+{
+ AURenderCallbackStruct callback = { microphoneCallback, this };
+ auto err = AudioUnitSetProperty(m_ioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, inputBus, &callback, sizeof(callback));
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::configureMicrophoneProc(%p) unable to set vpio unit mic proc, error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+
+ AudioStreamBasicDescription microphoneProcFormat = { };
+
+ UInt32 size = sizeof(microphoneProcFormat);
+ err = AudioUnitGetProperty(m_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, inputBus, µphoneProcFormat, &size);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::configureMicrophoneProc(%p) unable to get output stream format, error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+
+ m_microphoneSampleBuffer = AudioSampleBufferList::create(microphoneProcFormat, preferredIOBufferDuration() * microphoneProcFormat.mSampleRate * 2);
+ m_microphoneProcFormat = microphoneProcFormat;
+
+ return err;
+}
+
+OSStatus CoreAudioCaptureSource::configureSpeakerProc()
+{
+ AURenderCallbackStruct callback = { speakerCallback, this };
+ auto err = AudioUnitSetProperty(m_ioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, outputBus, &callback, sizeof(callback));
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::configureSpeakerProc(%p) unable to set vpio unit speaker proc, error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+
+ AudioStreamBasicDescription speakerProcFormat = { };
+
+ UInt32 size = sizeof(speakerProcFormat);
+ err = AudioUnitGetProperty(m_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, outputBus, &speakerProcFormat, &size);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::configureSpeakerProc(%p) unable to get input stream format, error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+
+ m_speakerSampleBuffer = AudioSampleBufferList::create(speakerProcFormat, preferredIOBufferDuration() * speakerProcFormat.mSampleRate * 2);
+ m_speakerProcFormat = speakerProcFormat;
+
+ 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)) {
+ LOG(Media, "CoreAudioCaptureSource::addEchoCancellationSource: source %p configureOutput failed", &source);
+ return;
+ }
+
+ std::lock_guard<Lock> lock(m_pendingSourceQueueLock);
+ m_pendingSources.append({ QueueAction::Add, source });
+}
+
+void CoreAudioCaptureSource::removeEchoCancellationSource(AudioSampleDataSource& source)
+{
+ std::lock_guard<Lock> lock(m_pendingSourceQueueLock);
+ m_pendingSources.append({ QueueAction::Remove, source });
+}
+
+void CoreAudioCaptureSource::checkTimestamps(const AudioTimeStamp& timeStamp, uint64_t sampleTime, double hostTime)
+{
+ if (!timeStamp.mSampleTime || sampleTime == m_latestMicTimeStamp || !hostTime)
+ LOG(Media, "CoreAudioCaptureSource::checkTimestamps: unusual timestamps, sample time = %lld, previous sample time = %lld, hostTime %f", sampleTime, m_latestMicTimeStamp, hostTime);
+}
+
+OSStatus CoreAudioCaptureSource::provideSpeakerData(AudioUnitRenderActionFlags& /*ioActionFlags*/, const AudioTimeStamp& timeStamp, UInt32 /*inBusNumber*/, UInt32 inNumberFrames, AudioBufferList* ioData)
+{
+ // Called when the audio unit needs data to play through the speakers.
+ ++m_speakerProcsCalled;
+
+ if (m_speakerSampleBuffer->sampleCapacity() < inNumberFrames) {
+ LOG(Media, "CoreAudioCaptureSource::provideSpeakerData: speaker sample buffer size (%d) too small for amount of sample data requested (%d)!", m_speakerSampleBuffer->sampleCapacity(), (int)inNumberFrames);
+ return kAudio_ParamError;
+ }
+
+ // Add/remove sources from the queue, but only if we get the lock immediately. Otherwise try
+ // again on the next callback.
+ {
+ std::unique_lock<Lock> lock(m_pendingSourceQueueLock, std::try_to_lock);
+ if (lock.owns_lock()) {
+ for (auto& pair : m_pendingSources) {
+ if (pair.first == QueueAction::Add)
+ m_activeSources.append(pair.second.copyRef());
+ else {
+ auto removeSource = pair.second.copyRef();
+ m_activeSources.removeFirstMatching([&removeSource](auto& source) {
+ return source.ptr() == removeSource.ptr();
+ });
+ }
+ }
+ m_pendingSources.clear();
+ }
+ }
+
+ if (m_activeSources.isEmpty())
+ return 0;
+
+ 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();
+ for (uint32_t i = 0; i < bufferList.mNumberBuffers; ++i)
+ bufferList.mBuffers[i] = ioData->mBuffers[i];
+
+ bool firstSource = true;
+ for (auto& source : m_activeSources) {
+ source->pullSamples(*m_speakerSampleBuffer.get(), inNumberFrames, adjustedHostTime, sampleTime, firstSource ? AudioSampleDataSource::Copy : AudioSampleDataSource::Mix);
+ firstSource = false;
+ }
+
+ return noErr;
+}
+
+OSStatus CoreAudioCaptureSource::speakerCallback(void *inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData)
+{
+ ASSERT(ioActionFlags);
+ ASSERT(inTimeStamp);
+ auto dataSource = static_cast<CoreAudioCaptureSource*>(inRefCon);
+ return dataSource->provideSpeakerData(*ioActionFlags, *inTimeStamp, inBusNumber, inNumberFrames, ioData);
+}
+
+OSStatus CoreAudioCaptureSource::processMicrophoneSamples(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& timeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* /*ioData*/)
+{
+ ++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) {
+ LOG(Media, "CoreAudioCaptureSource::processMicrophoneSamples(%p) AudioUnitRender failed with error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+
+ double adjustedHostTime = m_DTSConversionRatio * timeStamp.mHostTime;
+ 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;
+}
+
+OSStatus CoreAudioCaptureSource::microphoneCallback(void *inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData)
+{
+ ASSERT(ioActionFlags);
+ ASSERT(inTimeStamp);
+ CoreAudioCaptureSource* dataSource = static_cast<CoreAudioCaptureSource*>(inRefCon);
+ return dataSource->processMicrophoneSamples(*ioActionFlags, *inTimeStamp, inBusNumber, inNumberFrames, ioData);
+}
+
+OSStatus CoreAudioCaptureSource::defaultInputDevice(uint32_t* deviceID)
+{
+ ASSERT(m_ioUnit);
+
+ UInt32 propertySize = sizeof(*deviceID);
+ auto err = AudioUnitGetProperty(m_ioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, inputBus, deviceID, &propertySize);
+ if (err)
+ LOG(Media, "CoreAudioCaptureSource::defaultInputDevice(%p) unable to get default input device ID, error %d (%.4s)", this, (int)err, (char*)&err);
+
+ return err;
+}
+
+OSStatus CoreAudioCaptureSource::setupAudioUnits()
+{
+ ASSERT(m_internalStateLock.isHeld());
+
+ if (m_ioUnit)
+ return 0;
+
+ AudioComponentDescription ioUnitDescription = { kAudioUnitType_Output, kAudioUnitSubType_VoiceProcessingIO, kAudioUnitManufacturer_Apple, 0, 0 };
+ AudioComponent ioComponent = AudioComponentFindNext(nullptr, &ioUnitDescription);
+ ASSERT(ioComponent);
+ if (!ioComponent) {
+ LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to find vpio unit component", this);
+ return -1;
+ }
+
+ CFStringRef name = nullptr;
+ AudioComponentCopyName(ioComponent, &name);
+ if (name) {
+ m_ioUnitName = name;
+ CFRelease(name);
+ LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) created \"%s\" component", this, m_ioUnitName.utf8().data());
+ }
+
+ 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);
+ return err;
+ }
+
+#if PLATFORM(IOS)
+ uint32_t param = 1;
+ err = AudioUnitSetProperty(m_ioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, inputBus, ¶m, sizeof(param));
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to enable vpio unit input, error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+
+ param = 1;
+ err = AudioUnitSetProperty(m_ioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, outputBus, ¶m, sizeof(param));
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to enable vpio unit output, error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+#endif
+
+ if (!m_captureDeviceID) {
+ err = defaultInputDevice(&m_captureDeviceID);
+ if (err)
+ return err;
+ }
+
+ UInt32 propertySize = sizeof(m_captureDeviceID);
+ err = AudioUnitSetProperty(m_ioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, inputBus, &m_captureDeviceID, propertySize);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::setupAudioUnits(%p) unable to set vpio unit capture device ID, error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+
+ err = configureMicrophoneProc();
+ 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);
+ return err;
+ }
+ m_ioUnitInitialized = true;
+
+ err = configureSpeakerProc();
+ if (err)
+ return err;
+
+ return err;
+}
+
+void CoreAudioCaptureSource::startProducingData()
+{
+ std::lock_guard<Lock> lock(m_internalStateLock);
+ if (m_ioUnitStarted)
+ return;
+
+ OSStatus err;
+ if (!m_ioUnit) {
+ err = setupAudioUnits();
+ if (err)
+ return;
+ }
+
+ err = AudioOutputUnitStart(m_ioUnit);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::start(%p) AudioOutputUnitStart failed with error %d (%.4s)", this, (int)err, (char*)&err);
+ return;
+ }
+
+ m_ioUnitStarted = true;
+ setMuted(false);
+}
+
+void CoreAudioCaptureSource::stopProducingData()
+{
+ std::lock_guard<Lock> lock(m_internalStateLock);
+
+ ASSERT(m_ioUnit);
+
+ 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;
+ setMuted(true);
+}
+
+OSStatus CoreAudioCaptureSource::suspend()
+{
+ std::lock_guard<Lock> lock(m_internalStateLock);
+
+ ASSERT(m_ioUnit);
+
+ if (m_ioUnitStarted) {
+ auto err = AudioOutputUnitStop(m_ioUnit);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::resume(%p) AudioOutputUnitStop failed with error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+ m_ioUnitStarted = false;
+ }
+
+ if (m_ioUnitInitialized) {
+ auto err = AudioUnitUninitialize(m_ioUnit);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::resume(%p) AudioUnitUninitialize failed with error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+ m_ioUnitInitialized = false;
+ }
+
+ return 0;
+}
+
+OSStatus CoreAudioCaptureSource::resume()
+{
+ std::lock_guard<Lock> lock(m_internalStateLock);
+
+ ASSERT(m_ioUnit);
+ ASSERT(!m_ioUnitStarted);
+
+ auto err = AudioOutputUnitStart(m_ioUnit);
+ if (err) {
+ LOG(Media, "CoreAudioCaptureSource::resume(%p) AudioOutputUnitStart failed with error %d (%.4s)", this, (int)err, (char*)&err);
+ return err;
+ }
+ m_ioUnitStarted = false;
+
+ return err;
+}
+
+RefPtr<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 = RealtimeMediaSourceCapabilities::create(m_supportedConstraints);
+ m_capabilities->setDeviceId(id());
+ m_capabilities->setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite);
+ m_capabilities->setVolume(CapabilityValueOrRange(0.0, 1.0));
+
+ return m_capabilities;
+}
+
+const RealtimeMediaSourceSettings& CoreAudioCaptureSource::settings() const
+{
+ return m_currentSettings;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
Added: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h (0 => 215201)
--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h 2017-04-10 21:24:13 UTC (rev 215201)
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "CAAudioStreamDescription.h"
+#include "CaptureDevice.h"
+#include "RealtimeMediaSource.h"
+#include <AudioToolbox/AudioToolbox.h>
+#include <CoreAudio/CoreAudioTypes.h>
+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
+
+typedef struct OpaqueCMClock* CMClockRef;
+
+namespace WTF {
+class MediaTime;
+}
+
+namespace WebCore {
+
+class AudioSampleBufferList;
+class AudioSampleDataSource;
+class CaptureDeviceInfo;
+
+class CoreAudioCaptureSource : public RealtimeMediaSource {
+public:
+
+ static RefPtr<CoreAudioCaptureSource> create(const CaptureDevice&, const MediaConstraints*, String&);
+
+ WEBCORE_EXPORT static CaptureFactory& factory();
+
+ void addEchoCancellationSource(AudioSampleDataSource&);
+ void removeEchoCancellationSource(AudioSampleDataSource&);
+
+ using MicrophoneDataCallback = std::function<void(const MediaTime& sampleTime, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t sampleCount)>;
+
+ uint64_t addMicrophoneDataConsumer(MicrophoneDataCallback&&);
+ void removeMicrophoneDataConsumer(uint64_t);
+
+ CMClockRef timebaseClock();
+
+private:
+ CoreAudioCaptureSource(const CaptureDevice&);
+ virtual ~CoreAudioCaptureSource();
+
+ void startProducingData() final;
+ void stopProducingData() final;
+ bool isProducingData() const final { return m_ioUnitStarted; }
+
+ OSStatus suspend();
+ OSStatus resume();
+
+ RefPtr<RealtimeMediaSourceCapabilities> capabilities() const final;
+ const RealtimeMediaSourceSettings& settings() const final;
+
+ OSStatus setupAudioUnits();
+ OSStatus configureSpeakerProc();
+ OSStatus configureMicrophoneProc();
+ OSStatus defaultOutputDevice(uint32_t*);
+ OSStatus defaultInputDevice(uint32_t*);
+
+ void checkTimestamps(const AudioTimeStamp&, uint64_t, double);
+
+ static OSStatus microphoneCallback(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32, UInt32, AudioBufferList*);
+ OSStatus processMicrophoneSamples(AudioUnitRenderActionFlags&, const AudioTimeStamp&, UInt32, UInt32, AudioBufferList*);
+
+ static OSStatus speakerCallback(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32, UInt32, AudioBufferList*);
+ OSStatus provideSpeakerData(AudioUnitRenderActionFlags&, const AudioTimeStamp&, UInt32, UInt32, AudioBufferList*);
+
+ static double preferredSampleRate();
+ static double preferredIOBufferDuration();
+
+ AudioUnit m_ioUnit { nullptr };
+ String m_ioUnitName;
+
+ // Only read/modified from the IO thread.
+ Vector<Ref<AudioSampleDataSource>> m_activeSources;
+
+ enum QueueAction { Add, Remove };
+ Vector<std::pair<QueueAction, Ref<AudioSampleDataSource>>> m_pendingSources;
+
+ uint32_t m_captureDeviceID { 0 };
+
+ CAAudioStreamDescription m_microphoneProcFormat;
+ RefPtr<AudioSampleBufferList> m_microphoneSampleBuffer;
+ 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 };
+
+ double m_DTSConversionRatio { 0 };
+
+ bool m_ioUnitInitialized { false };
+ bool m_ioUnitStarted { false };
+
+ Lock m_pendingSourceQueueLock;
+ Lock m_internalStateLock;
+
+ mutable RefPtr<RealtimeMediaSourceCapabilities> m_capabilities;
+ mutable RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
+ RealtimeMediaSourceSettings m_currentSettings;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (215200 => 215201)
--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp 2017-04-10 21:24:13 UTC (rev 215201)
@@ -33,9 +33,9 @@
#if ENABLE(MEDIA_STREAM)
#include "RealtimeMediaSourceCenterMac.h"
-#include "AVAudioCaptureSource.h"
#include "AVCaptureDeviceManager.h"
#include "AVVideoCaptureSource.h"
+#include "CoreAudioCaptureSource.h"
#include "Logging.h"
#include "MediaStreamPrivate.h"
#include <wtf/MainThread.h>
@@ -63,7 +63,7 @@
m_supportedConstraints.setSupportsDeviceId(true);
m_supportedConstraints.setSupportsGroupId(true);
- m_audioFactory = &AVAudioCaptureSource::factory();
+ m_audioFactory = &CoreAudioCaptureSource::factory();
m_videoFactory = &AVVideoCaptureSource::factory();
}
@@ -174,7 +174,7 @@
RealtimeMediaSource::CaptureFactory* RealtimeMediaSourceCenterMac::defaultAudioFactory()
{
- return &AVAudioCaptureSource::factory();
+ return &CoreAudioCaptureSource::factory();
}
RealtimeMediaSource::CaptureFactory* RealtimeMediaSourceCenterMac::defaultVideoFactory()
Modified: trunk/Source/WebKit/mac/ChangeLog (215200 => 215201)
--- trunk/Source/WebKit/mac/ChangeLog 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit/mac/ChangeLog 2017-04-10 21:24:13 UTC (rev 215201)
@@ -1,3 +1,22 @@
+2017-04-10 Jeremy Jones <jere...@apple.com>
+
+ Add CoreAudioCaptureSource.
+ https://bugs.webkit.org/show_bug.cgi?id=170112
+ rdar://problem/30293338
+
+ Reviewed by Eric Carlson.
+
+ Add UseAVFoundationAudioCapture preference to switch back from the new default of CoreAudio.
+
+ * WebView/WebPreferenceKeysPrivate.h:
+ * WebView/WebPreferences.mm:
+ (+[WebPreferences initialize]):
+ (-[WebPreferences useAVFoundationAudioCapture]):
+ (-[WebPreferences setUseAVFoundationAudioCapture:]):
+ * WebView/WebPreferencesPrivate.h:
+ * WebView/WebView.mm:
+ (-[WebView _preferencesChanged:]):
+
2017-04-10 Chris Dumez <cdu...@apple.com>
Drop Timer::startOneShot() overload taking a double
Modified: trunk/Source/WebKit/mac/WebView/WebPreferenceKeysPrivate.h (215200 => 215201)
--- trunk/Source/WebKit/mac/WebView/WebPreferenceKeysPrivate.h 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit/mac/WebView/WebPreferenceKeysPrivate.h 2017-04-10 21:24:13 UTC (rev 215201)
@@ -224,6 +224,7 @@
#define WebKitEnableInheritURIQueryComponentPreferenceKey @"WebKitEnableInheritURIQueryComponent"
#define WebKitMediaDataLoadsAutomaticallyPreferenceKey @"WebKitMediaDataLoadsAutomatically"
#define WebKitMockCaptureDevicesEnabledPreferenceKey @"WebKitMockCaptureDevicesEnabled"
+#define WebKitUseAVFoundationAudioCapturePreferenceKey @"WebKitUseAVFoundationAudioCaptureEnabled"
#define WebKitEnumeratingAllNetworkInterfacesEnabledPreferenceKey @"WebKitEnumeratingAllNetworkInterfacesEnabled"
#define WebKitICECandidateFilteringEnabledPreferenceKey @"WebKitICECandidateFilteringEnabled"
#define WebKitMediaCaptureRequiresSecureConnectionPreferenceKey @"WebKitMediaCaptureRequiresSecureConnection"
Modified: trunk/Source/WebKit/mac/WebView/WebPreferences.mm (215200 => 215201)
--- trunk/Source/WebKit/mac/WebView/WebPreferences.mm 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit/mac/WebView/WebPreferences.mm 2017-04-10 21:24:13 UTC (rev 215201)
@@ -619,6 +619,7 @@
#if ENABLE(MEDIA_STREAM)
[NSNumber numberWithBool:NO], WebKitMockCaptureDevicesEnabledPreferenceKey,
[NSNumber numberWithBool:YES], WebKitMediaCaptureRequiresSecureConnectionPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitUseAVFoundationAudioCapturePreferenceKey,
#endif
[NSNumber numberWithBool:YES], WebKitShadowDOMEnabledPreferenceKey,
[NSNumber numberWithBool:YES], WebKitCustomElementsEnabledPreferenceKey,
@@ -2866,6 +2867,16 @@
[self _setBoolValue:flag forKey:WebKitMockCaptureDevicesEnabledPreferenceKey];
}
+- (BOOL)useAVFoundationAudioCapture
+{
+ return [self _boolValueForKey:WebKitUseAVFoundationAudioCapturePreferenceKey];
+}
+
+- (void)setUseAVFoundationAudioCapture:(BOOL)flag
+{
+ [self _setBoolValue:flag forKey:WebKitUseAVFoundationAudioCapturePreferenceKey];
+}
+
- (BOOL)enumeratingAllNetworkInterfacesEnabled
{
return [self _boolValueForKey:WebKitEnumeratingAllNetworkInterfacesEnabledPreferenceKey];
Modified: trunk/Source/WebKit/mac/WebView/WebPreferencesPrivate.h (215200 => 215201)
--- trunk/Source/WebKit/mac/WebView/WebPreferencesPrivate.h 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit/mac/WebView/WebPreferencesPrivate.h 2017-04-10 21:24:13 UTC (rev 215201)
@@ -511,6 +511,9 @@
- (void)setMediaCaptureRequiresSecureConnection:(BOOL)flag;
- (BOOL)mediaCaptureRequiresSecureConnection;
+- (void)setUseAVFoundationAudioCapture:(BOOL)flag;
+- (BOOL)useAVFoundationAudioCapture;
+
- (void)setShadowDOMEnabled:(BOOL)flag;
- (BOOL)shadowDOMEnabled;
Modified: trunk/Source/WebKit/mac/WebView/WebView.mm (215200 => 215201)
--- trunk/Source/WebKit/mac/WebView/WebView.mm 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit/mac/WebView/WebView.mm 2017-04-10 21:24:13 UTC (rev 215201)
@@ -2964,6 +2964,7 @@
settings.setMockCaptureDevicesEnabled([preferences mockCaptureDevicesEnabled]);
settings.setMediaCaptureRequiresSecureConnection([preferences mediaCaptureRequiresSecureConnection]);
RuntimeEnabledFeatures::sharedFeatures().setMediaStreamEnabled([preferences mediaStreamEnabled]);
+ settings.setUseAVFoundationAudioCapture([preferences useAVFoundationAudioCapture]);
#endif
#if ENABLE(WEB_RTC)
Modified: trunk/Source/WebKit2/ChangeLog (215200 => 215201)
--- trunk/Source/WebKit2/ChangeLog 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit2/ChangeLog 2017-04-10 21:24:13 UTC (rev 215201)
@@ -1,3 +1,25 @@
+2017-04-10 Jeremy Jones <jere...@apple.com>
+
+ Add CoreAudioCaptureSource.
+ https://bugs.webkit.org/show_bug.cgi?id=170112
+ rdar://problem/30293338
+
+ Reviewed by Tim Horton.
+
+ Add UseAVFoundationAudioCapture preference to switch back from the new default of CoreAudio.
+
+ * Shared/WebPreferencesDefinitions.h:
+ * UIProcess/API/C/WKPreferences.cpp:
+ (WKPreferencesSetUseAVFoundationAudioCapture):
+ (WKPreferencesGetUseAVFoundationAudioCapture):
+ * UIProcess/API/C/WKPreferencesRefPrivate.h:
+ * UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp:
+ (WebKit::UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints):
+ * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+ (WebKit::UserMediaPermissionRequestManagerProxy::syncWithWebCorePrefs):
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::updatePreferences):
+
2017-04-10 Brent Fulgham <bfulg...@apple.com>
[WK2][macOS] Block access to Apple Events before launch.
Modified: trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h (215200 => 215201)
--- trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h 2017-04-10 21:24:13 UTC (rev 215201)
@@ -241,6 +241,7 @@
macro(HTTPEquivEnabled, httpEquivEnabled, Bool, bool, true, "", "") \
macro(MockCaptureDevicesEnabled, mockCaptureDevicesEnabled, Bool, bool, false, "", "") \
macro(MediaCaptureRequiresSecureConnection, mediaCaptureRequiresSecureConnection, Bool, bool, true, "", "") \
+ macro(UseAVFoundationAudioCapture, useAVFoundationAudioCapture, Bool, bool, false, "", "") \
macro(EnumeratingAllNetworkInterfacesEnabled, enumeratingAllNetworkInterfacesEnabled, Bool, bool, false, "", "") \
macro(WebRTCLegacyAPIEnabled, webRTCLegacyAPIEnabled, Bool, bool, true, "", "") \
macro(ICECandidateFilteringEnabled, iceCandidateFilteringEnabled, Bool, bool, true, "", "") \
Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp (215200 => 215201)
--- trunk/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp 2017-04-10 21:24:13 UTC (rev 215201)
@@ -1601,6 +1601,16 @@
return toImpl(preferencesRef)->mediaCaptureRequiresSecureConnection();
}
+void WKPreferencesSetUseAVFoundationAudioCapture(WKPreferencesRef preferencesRef, bool enabled)
+{
+ toImpl(preferencesRef)->setUseAVFoundationAudioCapture(enabled);
+}
+
+bool WKPreferencesGetUseAVFoundationAudioCapture(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->useAVFoundationAudioCapture();
+}
+
void WKPreferencesSetFetchAPIEnabled(WKPreferencesRef preferencesRef, bool flag)
{
toImpl(preferencesRef)->setFetchAPIEnabled(flag);
Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h (215200 => 215201)
--- trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h 2017-04-10 21:24:13 UTC (rev 215201)
@@ -433,6 +433,10 @@
WK_EXPORT void WKPreferencesSetMediaCaptureRequiresSecureConnection(WKPreferencesRef, bool);
WK_EXPORT bool WKPreferencesGetMediaCaptureRequiresSecureConnection(WKPreferencesRef);
+// Defaults to false.
+WK_EXPORT void WKPreferencesSetUseAVFoundationAudioCapture(WKPreferencesRef, bool);
+WK_EXPORT bool WKPreferencesGetUseAVFoundationAudioCapture(WKPreferencesRef);
+
// Defaults to false
WK_EXPORT void WKPreferencesSetFetchAPIEnabled(WKPreferencesRef, bool flag);
WK_EXPORT bool WKPreferencesGetFetchAPIEnabled(WKPreferencesRef);
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp (215200 => 215201)
--- trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp 2017-04-10 21:24:13 UTC (rev 215201)
@@ -128,7 +128,7 @@
void UserMediaCaptureManagerProxy::createMediaSourceForCaptureDeviceWithConstraints(uint64_t id, const CaptureDevice& device, const MediaConstraintsData& constraintsData, bool& succeeded, String& invalidConstraints)
{
auto constraints = MediaConstraintsImpl::create(constraintsData);
- RefPtr<RealtimeMediaSource> source = RealtimeMediaSourceCenter::singleton().defaultAudioFactory()->createMediaSourceForCaptureDeviceWithConstraints(device, constraints.ptr(), invalidConstraints);
+ auto source = RealtimeMediaSourceCenter::singleton().audioFactory()->createMediaSourceForCaptureDeviceWithConstraints(device, constraints.ptr(), invalidConstraints);
succeeded = !!source;
if (source)
Modified: trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (215200 => 215201)
--- trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2017-04-10 21:24:13 UTC (rev 215201)
@@ -31,6 +31,10 @@
#include <WebCore/RealtimeMediaSource.h>
#include <WebCore/SecurityOriginData.h>
+#if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
+#include <WebCore/AVCaptureDeviceManager.h>
+#endif
+
using namespace WebCore;
namespace WebKit {
@@ -329,7 +333,12 @@
// this is a noop if the preference hasn't changed since the last time this was called.
bool mockDevicesEnabled = m_page.preferences().mockCaptureDevicesEnabled();
WebCore::MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(mockDevicesEnabled);
+
+#if USE(AVFOUNDATION)
+ bool useAVFoundationAudioCapture = m_page.preferences().useAVFoundationAudioCapture();
+ WebCore::AVCaptureDeviceManager::setUseAVFoundationAudioCapture(useAVFoundationAudioCapture);
#endif
+#endif
}
void UserMediaPermissionRequestManagerProxy::stopCapture()
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (215200 => 215201)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2017-04-10 21:02:16 UTC (rev 215200)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2017-04-10 21:24:13 UTC (rev 215201)
@@ -3240,6 +3240,7 @@
#if ENABLE(MEDIA_STREAM)
settings.setMockCaptureDevicesEnabled(store.getBoolValueForKey(WebPreferencesKey::mockCaptureDevicesEnabledKey()));
settings.setMediaCaptureRequiresSecureConnection(store.getBoolValueForKey(WebPreferencesKey::mediaCaptureRequiresSecureConnectionKey()));
+ settings.setUseAVFoundationAudioCapture(store.getBoolValueForKey(WebPreferencesKey::useAVFoundationAudioCaptureKey()));
#endif
settings.setShouldConvertPositionStyleOnCopy(store.getBoolValueForKey(WebPreferencesKey::shouldConvertPositionStyleOnCopyKey()));