Title: [236494] trunk/Source
Revision
236494
Author
[email protected]
Date
2018-09-25 19:33:02 -0700 (Tue, 25 Sep 2018)

Log Message

[MediaStream] Add Mac window capture source
https://bugs.webkit.org/show_bug.cgi?id=189958
<rdar://problem/44767616>

Reviewed by Youenn Fablet.

Source/WebCore:

* SourcesCocoa.txt: Add WindowDisplayCaptureSourceMac.
* WebCore.xcodeproj/project.pbxproj: Ditto.

* platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp:
(WebCore::DisplayCaptureManagerCocoa::captureDevices): Include window "devices".
(WebCore::DisplayCaptureManagerCocoa::updateWindowCaptureDevices): New.
(WebCore::DisplayCaptureManagerCocoa::windowCaptureDeviceWithPersistentID): New.
(WebCore::DisplayCaptureManagerCocoa::captureDeviceWithPersistentID): Include window devices.
* platform/mediastream/mac/DisplayCaptureManagerCocoa.h:

* platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp:
(WebCore::DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa):
(WebCore::DisplayCaptureSourceCocoa::settings): Use frameSize, report surface type and
logical surface.
(WebCore::DisplayCaptureSourceCocoa::settingsDidChange): Clear m_lastSampleBuffer when size changes.
(WebCore::DisplayCaptureSourceCocoa::frameSize const): New, return size() or intrinsic size.
(WebCore::DisplayCaptureSourceCocoa::setIntrinsicSize): New.
(WebCore::DisplayCaptureSourceCocoa::emitFrame): generateFrame now returns a CVPixelBuffer
so derived classes don't have to deal with resizing/transforming.
* platform/mediastream/mac/DisplayCaptureSourceCocoa.h:

* platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:

* platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h:
* platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
(WebCore::ScreenDisplayCaptureSourceMac::ScreenDisplayCaptureSourceMac): Add fixme.
(WebCore::ScreenDisplayCaptureSourceMac::createDisplayStream): Update intrinsic size when
width/height changes.
(WebCore::ScreenDisplayCaptureSourceMac::generateFrame): Return a CVPixelBuffer.

* platform/mediastream/mac/WindowDisplayCaptureSourceMac.h: Added.
* platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm: Added.
(WebCore::anyOfCGWindow):
(WebCore::windowDescription):
(WebCore::WindowDisplayCaptureSourceMac::create):
(WebCore::WindowDisplayCaptureSourceMac::WindowDisplayCaptureSourceMac):
(WebCore::WindowDisplayCaptureSourceMac::windowImage):
(WebCore::WindowDisplayCaptureSourceMac::generateFrame):
(WebCore::WindowDisplayCaptureSourceMac::pixelBufferFromCGImage):
(WebCore::WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID):
(WebCore::WindowDisplayCaptureSourceMac::windowCaptureDevices):

Source/WebKit:

* UIProcess/UserMediaPermissionRequestManagerProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::beginMonitoringCaptureDevices): Sync with webcore prefs before listening
to device changes so we listen on the correct devices.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (236493 => 236494)


--- trunk/Source/WebCore/ChangeLog	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/ChangeLog	2018-09-26 02:33:02 UTC (rev 236494)
@@ -1,3 +1,53 @@
+2018-09-25  Eric Carlson  <[email protected]>
+
+        [MediaStream] Add Mac window capture source
+        https://bugs.webkit.org/show_bug.cgi?id=189958
+        <rdar://problem/44767616>
+
+        Reviewed by Youenn Fablet.
+
+        * SourcesCocoa.txt: Add WindowDisplayCaptureSourceMac.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+
+        * platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp:
+        (WebCore::DisplayCaptureManagerCocoa::captureDevices): Include window "devices".
+        (WebCore::DisplayCaptureManagerCocoa::updateWindowCaptureDevices): New.
+        (WebCore::DisplayCaptureManagerCocoa::windowCaptureDeviceWithPersistentID): New.
+        (WebCore::DisplayCaptureManagerCocoa::captureDeviceWithPersistentID): Include window devices.
+        * platform/mediastream/mac/DisplayCaptureManagerCocoa.h:
+
+        * platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp:
+        (WebCore::DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa):
+        (WebCore::DisplayCaptureSourceCocoa::settings): Use frameSize, report surface type and 
+        logical surface.
+        (WebCore::DisplayCaptureSourceCocoa::settingsDidChange): Clear m_lastSampleBuffer when size changes.
+        (WebCore::DisplayCaptureSourceCocoa::frameSize const): New, return size() or intrinsic size.
+        (WebCore::DisplayCaptureSourceCocoa::setIntrinsicSize): New.
+        (WebCore::DisplayCaptureSourceCocoa::emitFrame): generateFrame now returns a CVPixelBuffer
+        so derived classes don't have to deal with resizing/transforming.
+        * platform/mediastream/mac/DisplayCaptureSourceCocoa.h:
+
+        * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+
+        * platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h:
+        * platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
+        (WebCore::ScreenDisplayCaptureSourceMac::ScreenDisplayCaptureSourceMac): Add fixme.
+        (WebCore::ScreenDisplayCaptureSourceMac::createDisplayStream): Update intrinsic size when
+        width/height changes.
+        (WebCore::ScreenDisplayCaptureSourceMac::generateFrame): Return a CVPixelBuffer.
+
+        * platform/mediastream/mac/WindowDisplayCaptureSourceMac.h: Added.
+        * platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm: Added.
+        (WebCore::anyOfCGWindow):
+        (WebCore::windowDescription):
+        (WebCore::WindowDisplayCaptureSourceMac::create):
+        (WebCore::WindowDisplayCaptureSourceMac::WindowDisplayCaptureSourceMac):
+        (WebCore::WindowDisplayCaptureSourceMac::windowImage):
+        (WebCore::WindowDisplayCaptureSourceMac::generateFrame):
+        (WebCore::WindowDisplayCaptureSourceMac::pixelBufferFromCGImage):
+        (WebCore::WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID):
+        (WebCore::WindowDisplayCaptureSourceMac::windowCaptureDevices):
+
 2018-09-25  Justin Fan  <[email protected]>
 
         WebGL 2 Conformance: primitive restart and draw_primitive_restart WebGL2 sample

Modified: trunk/Source/WebCore/SourcesCocoa.txt (236493 => 236494)


--- trunk/Source/WebCore/SourcesCocoa.txt	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/SourcesCocoa.txt	2018-09-26 02:33:02 UTC (rev 236494)
@@ -552,6 +552,7 @@
 platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp
 platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp
 platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm
+platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm
 
 platform/audio/mac/AudioSampleDataSource.mm
 

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (236493 => 236494)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-09-26 02:33:02 UTC (rev 236494)
@@ -204,6 +204,7 @@
 		07C1C0E21BFB600100BD2256 /* MediaTrackSupportedConstraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 07C1C0E01BFB600100BD2256 /* MediaTrackSupportedConstraints.h */; };
 		07C1C0E51BFB60ED00BD2256 /* RealtimeMediaSourceSupportedConstraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 07C1C0E41BFB60ED00BD2256 /* RealtimeMediaSourceSupportedConstraints.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		07CE77D516712A6A00C55A47 /* InbandTextTrackPrivateClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		07D60928214C5BFD00E7396C /* WindowDisplayCaptureSourceMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D60926214C5BFC00E7396C /* WindowDisplayCaptureSourceMac.h */; };
 		07D637401BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		07D6A4F41BED5F8800174146 /* MockRealtimeAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6A4F21BED5F8800174146 /* MockRealtimeAudioSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		07D6A4F81BF2307D00174146 /* AudioTrackPrivateMediaStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6A4F61BF2307D00174146 /* AudioTrackPrivateMediaStream.h */; };
@@ -5443,6 +5444,8 @@
 		07C8AD111D073D630087C5CE /* AVFoundationMIMETypeCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVFoundationMIMETypeCache.mm; sourceTree = "<group>"; };
 		07C8AD121D073D630087C5CE /* AVFoundationMIMETypeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AVFoundationMIMETypeCache.h; sourceTree = "<group>"; };
 		07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivateClient.h; sourceTree = "<group>"; };
+		07D60924214C5BFB00E7396C /* WindowDisplayCaptureSourceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowDisplayCaptureSourceMac.mm; sourceTree = "<group>"; };
+		07D60926214C5BFC00E7396C /* WindowDisplayCaptureSourceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowDisplayCaptureSourceMac.h; sourceTree = "<group>"; };
 		07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAudioSourceProviderAVFObjC.h; sourceTree = "<group>"; };
 		07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebAudioSourceProviderAVFObjC.mm; sourceTree = "<group>"; };
 		07D6A4F11BED5F8800174146 /* MockRealtimeAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockRealtimeAudioSource.cpp; sourceTree = "<group>"; };
@@ -15388,6 +15391,8 @@
 				070A9F601FFECC71003DF649 /* ScreenDisplayCaptureSourceMac.mm */,
 				07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */,
 				07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */,
+				07D60926214C5BFC00E7396C /* WindowDisplayCaptureSourceMac.h */,
+				07D60924214C5BFB00E7396C /* WindowDisplayCaptureSourceMac.mm */,
 			);
 			path = mac;
 			sourceTree = "<group>";
@@ -31115,6 +31120,7 @@
 				1411DCB1164C39A800D49BC1 /* WidthCache.h in Headers */,
 				939B02EF0EA2DBC400C54570 /* WidthIterator.h in Headers */,
 				0F15ED5C1B7EC7C500EDDFEB /* WillChangeData.h in Headers */,
+				07D60928214C5BFD00E7396C /* WindowDisplayCaptureSourceMac.h in Headers */,
 				BC8243E90D0CFD7500460C8F /* WindowFeatures.h in Headers */,
 				7E99AF530B13846468FB01A5 /* WindowFocusAllowedIndicator.h in Headers */,
 				463521AD2081092A00C28922 /* WindowProxy.h in Headers */,

Modified: trunk/Source/WebCore/platform/graphics/cv/PixelBufferResizer.mm (236493 => 236494)


--- trunk/Source/WebCore/platform/graphics/cv/PixelBufferResizer.mm	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/graphics/cv/PixelBufferResizer.mm	2018-09-26 02:33:02 UTC (rev 236494)
@@ -68,6 +68,10 @@
 
 RetainPtr<CVPixelBufferRef> PixelBufferResizer::resize(CVPixelBufferRef inputBuffer)
 {
+    ASSERT(m_bufferPool && !m_size.isEmpty());
+    if (!m_bufferPool || m_size.isEmpty())
+        return nullptr;
+
     RetainPtr<CVPixelBufferRef> result;
     CVPixelBufferRef outputBuffer = nullptr;
 

Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp (236493 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp	2018-09-26 02:33:02 UTC (rev 236494)
@@ -28,7 +28,6 @@
 
 #if ENABLE(MEDIA_STREAM)
 
-#include "CoreVideoSoftLink.h"
 #include "Logging.h"
 #include <wtf/Algorithms.h>
 #include <wtf/NeverDestroyed.h>
@@ -35,9 +34,12 @@
 
 #if PLATFORM(MAC)
 #include "ScreenDisplayCaptureSourceMac.h"
+#include "WindowDisplayCaptureSourceMac.h"
 #include <CoreGraphics/CGDirectDisplay.h>
 #endif
 
+#include "CoreVideoSoftLink.h"
+
 namespace WebCore {
 
 DisplayCaptureManagerCocoa& DisplayCaptureManagerCocoa::singleton()
@@ -50,6 +52,7 @@
 {
     m_devices.clear();
 
+    updateWindowCaptureDevices();
     updateDisplayCaptureDevices();
 
     return m_devices;
@@ -62,6 +65,13 @@
 #endif
 }
 
+void DisplayCaptureManagerCocoa::updateWindowCaptureDevices()
+{
+#if PLATFORM(MAC)
+    WindowDisplayCaptureSourceMac::windowCaptureDevices(m_devices);
+#endif
+}
+
 std::optional<CaptureDevice> DisplayCaptureManagerCocoa::screenCaptureDeviceWithPersistentID(const String& deviceID)
 {
 #if PLATFORM(MAC)
@@ -72,6 +82,16 @@
 #endif
 }
 
+std::optional<CaptureDevice> DisplayCaptureManagerCocoa::windowCaptureDeviceWithPersistentID(const String& deviceID)
+{
+#if PLATFORM(MAC)
+    return WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID(deviceID);
+#else
+    UNUSED_PARAM(deviceID);
+    return std::nullopt;
+#endif
+}
+
 std::optional<CaptureDevice> DisplayCaptureManagerCocoa::captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id)
 {
     switch (type) {
@@ -78,9 +98,12 @@
     case CaptureDevice::DeviceType::Screen:
         return screenCaptureDeviceWithPersistentID(id);
         break;
-            
+
+    case CaptureDevice::DeviceType::Window:
+        return windowCaptureDeviceWithPersistentID(id);
+        break;
+
     case CaptureDevice::DeviceType::Application:
-    case CaptureDevice::DeviceType::Window:
     case CaptureDevice::DeviceType::Browser:
         break;
 

Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.h (236493 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.h	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.h	2018-09-26 02:33:02 UTC (rev 236494)
@@ -41,11 +41,13 @@
     virtual ~DisplayCaptureManagerCocoa() = default;
 
     void updateDisplayCaptureDevices();
+    void updateWindowCaptureDevices();
 
     const Vector<CaptureDevice>& captureDevices() final;
 
     std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&) final;
     std::optional<CaptureDevice> screenCaptureDeviceWithPersistentID(const String&);
+    std::optional<CaptureDevice> windowCaptureDeviceWithPersistentID(const String&);
 
     Vector<CaptureDevice> m_devices;
 };

Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp (236493 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp	2018-09-26 02:33:02 UTC (rev 236494)
@@ -29,9 +29,13 @@
 #if ENABLE(MEDIA_STREAM)
 
 #include "Logging.h"
+#include "MediaSampleAVFObjC.h"
+#include "PixelBufferConformerCV.h"
+#include "PixelBufferResizer.h"
 #include "RealtimeMediaSource.h"
 #include "RealtimeMediaSourceCenter.h"
 #include "RealtimeMediaSourceSettings.h"
+#include "RealtimeVideoUtilities.h"
 #include "Timer.h"
 #include <CoreMedia/CMSync.h>
 #include <mach/mach_time.h>
@@ -47,8 +51,8 @@
 namespace WebCore {
 using namespace PAL;
 
-DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(const String& name)
-    : RealtimeMediaSource("", Type::Video, name)
+DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(String&& name)
+    : RealtimeMediaSource("", Type::Video, WTFMove(name))
     , m_timer(RunLoop::current(), this, &DisplayCaptureSourceCocoa::emitFrame)
 {
 }
@@ -80,17 +84,21 @@
     if (!m_currentSettings) {
         RealtimeMediaSourceSettings settings;
         settings.setFrameRate(frameRate());
-        auto size = this->size();
-        if (size.width() && size.height()) {
+        auto size = frameSize();
+        if (!size.isEmpty()) {
             settings.setWidth(size.width());
             settings.setHeight(size.height());
         }
+        settings.setDisplaySurface(surfaceType());
+        settings.setLogicalSurface(false);
 
         RealtimeMediaSourceSupportedConstraints supportedConstraints;
         supportedConstraints.setSupportsFrameRate(true);
         supportedConstraints.setSupportsWidth(true);
         supportedConstraints.setSupportsHeight(true);
-        supportedConstraints.setSupportsAspectRatio(true);
+        supportedConstraints.setSupportsDisplaySurface(true);
+        supportedConstraints.setSupportsLogicalSurface(true);
+
         settings.setSupportedConstraints(supportedConstraints);
 
         m_currentSettings = WTFMove(settings);
@@ -103,10 +111,12 @@
     if (settings.contains(RealtimeMediaSourceSettings::Flag::FrameRate) && m_timer.isActive())
         m_timer.startRepeating(1_s / frameRate());
 
-    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height }))
+    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height })) {
         m_bufferAttributes = nullptr;
+        m_lastSampleBuffer = nullptr;
+    }
 
-    m_currentSettings = std::nullopt;
+    m_currentSettings = { };
 
     RealtimeMediaSource::settingsDidChange(settings);
 }
@@ -136,12 +146,76 @@
     return m_elapsedTime + (MonotonicTime::now() - m_startTime);
 }
 
+IntSize DisplayCaptureSourceCocoa::frameSize() const
+{
+    IntSize frameSize = size();
+    if (frameSize.isEmpty())
+        frameSize = m_intrinsicSize;
+
+    return frameSize;
+}
+
+void DisplayCaptureSourceCocoa::setIntrinsicSize(const IntSize& size)
+{
+    if (m_intrinsicSize == size)
+        return;
+
+    m_intrinsicSize = size;
+    m_lastSampleBuffer = nullptr;
+}
+
 void DisplayCaptureSourceCocoa::emitFrame()
 {
     if (muted())
         return;
 
-    generateFrame();
+    auto pixelBuffer = generateFrame();
+    if (!pixelBuffer)
+        return;
+
+    if (m_lastSampleBuffer && m_lastFullSizedPixelBuffer && CFEqual(m_lastFullSizedPixelBuffer.get(), pixelBuffer.get())) {
+        videoSampleAvailable(MediaSampleAVFObjC::create(m_lastSampleBuffer.get()));
+        return;
+    }
+
+    m_lastFullSizedPixelBuffer = pixelBuffer;
+
+    int width = WTF::safeCast<int>(CVPixelBufferGetWidth(pixelBuffer.get()));
+    int height = WTF::safeCast<int>(CVPixelBufferGetHeight(pixelBuffer.get()));
+    auto requestedSize = frameSize();
+    if (width != requestedSize.width() || height != requestedSize.height()) {
+        if (m_pixelBufferResizer && !m_pixelBufferResizer->canResizeTo(requestedSize))
+            m_pixelBufferResizer = nullptr;
+
+        if (!m_pixelBufferResizer)
+            m_pixelBufferResizer = std::make_unique<PixelBufferResizer>(requestedSize, preferedPixelBufferFormat());
+
+        pixelBuffer = m_pixelBufferResizer->resize(pixelBuffer.get());
+    } else {
+        m_pixelBufferResizer = nullptr;
+
+        auto pixelFormatType = CVPixelBufferGetPixelFormatType(pixelBuffer.get());
+        if (pixelFormatType != preferedPixelBufferFormat()) {
+            if (!m_pixelBufferConformer) {
+                auto preferredFromat = preferedPixelBufferFormat();
+                auto conformerAttributes = adoptCF(CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+                auto videoType = adoptCF(CFNumberCreate(nullptr,  kCFNumberSInt32Type,  &preferredFromat));
+                CFDictionarySetValue(conformerAttributes.get(), kCVPixelBufferPixelFormatTypeKey, videoType.get());
+
+                m_pixelBufferConformer = std::make_unique<PixelBufferConformerCV>(conformerAttributes.get());
+            }
+
+            pixelBuffer = m_pixelBufferConformer->convert(pixelBuffer.get());
+        }
+    }
+    if (!pixelBuffer)
+        return;
+
+    m_lastSampleBuffer = sampleBufferFromPixelBuffer(pixelBuffer.get());
+    if (!m_lastSampleBuffer)
+        return;
+
+    videoSampleAvailable(MediaSampleAVFObjC::create(m_lastSampleBuffer.get()));
 }
 
 RetainPtr<CMSampleBufferRef> DisplayCaptureSourceCocoa::sampleBufferFromPixelBuffer(CVPixelBufferRef pixelBuffer)

Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h (236493 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h	2018-09-26 02:33:02 UTC (rev 236494)
@@ -44,15 +44,19 @@
 namespace WebCore {
 
 class CaptureDeviceInfo;
+class PixelBufferConformerCV;
+class PixelBufferResizer;
 
 class DisplayCaptureSourceCocoa : public RealtimeMediaSource {
 public:
 
 protected:
-    DisplayCaptureSourceCocoa(const String& name);
+    DisplayCaptureSourceCocoa(String&&);
     virtual ~DisplayCaptureSourceCocoa();
 
-    virtual void generateFrame() = 0;
+    virtual RetainPtr<CVPixelBufferRef> generateFrame() = 0;
+    virtual RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const = 0;
+
     void startProducingData() override;
     void stopProducingData() override;
 
@@ -65,6 +69,10 @@
 
     void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
 
+    const IntSize& intrinsicSize() const { return m_intrinsicSize; }
+    void setIntrinsicSize(const IntSize&);
+    IntSize frameSize() const;
+
 private:
 
     bool isCaptureSource() const final { return true; }
@@ -74,6 +82,7 @@
 
     void emitFrame();
 
+    IntSize m_intrinsicSize;
     std::optional<RealtimeMediaSourceCapabilities> m_capabilities;
     std::optional<RealtimeMediaSourceSettings> m_currentSettings;
     RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
@@ -83,6 +92,11 @@
 
     RetainPtr<CFMutableDictionaryRef> m_bufferAttributes;
     RunLoop::Timer<DisplayCaptureSourceCocoa> m_timer;
+
+    std::unique_ptr<PixelBufferResizer> m_pixelBufferResizer;
+    std::unique_ptr<PixelBufferConformerCV> m_pixelBufferConformer;
+    RetainPtr<CVPixelBufferRef> m_lastFullSizedPixelBuffer;
+    RetainPtr<CMSampleBufferRef> m_lastSampleBuffer;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (236493 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp	2018-09-26 02:33:02 UTC (rev 236494)
@@ -58,10 +58,12 @@
         case CaptureDevice::DeviceType::Screen:
 #if PLATFORM(MAC)
             return ScreenDisplayCaptureSourceMac::create(device.persistentId(), constraints);
-            break;
 #endif
+        case CaptureDevice::DeviceType::Window:
+#if PLATFORM(MAC)
+            return WindowDisplayCaptureSourceMac::create(device.persistentId(), constraints);
+#endif
         case CaptureDevice::DeviceType::Application:
-        case CaptureDevice::DeviceType::Window:
         case CaptureDevice::DeviceType::Browser:
         case CaptureDevice::DeviceType::Microphone:
         case CaptureDevice::DeviceType::Unknown:

Modified: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h (236493 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h	2018-09-26 02:33:02 UTC (rev 236494)
@@ -56,7 +56,9 @@
 
     void frameAvailable(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisplayStreamUpdateRef);
 
-    void generateFrame() final;
+    RetainPtr<CVPixelBufferRef> generateFrame() final;
+    RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Monitor; }
+
     void startProducingData() final;
     void stopProducingData() final;
     void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;

Modified: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm (236493 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm	2018-09-26 02:33:02 UTC (rev 236494)
@@ -97,7 +97,7 @@
 }
 
 ScreenDisplayCaptureSourceMac::ScreenDisplayCaptureSourceMac(uint32_t displayID)
-    : DisplayCaptureSourceCocoa("Screen")
+    : DisplayCaptureSourceCocoa("Screen") // FIXME: figure out what to call this
     , m_displayID(displayID)
 {
 }
@@ -126,17 +126,15 @@
     }
 
     if (!m_displayStream) {
-        if (size().isEmpty()) {
-            RetainPtr<CGDisplayModeRef> displayMode = adoptCF(CGDisplayCopyDisplayMode(m_displayID));
-            auto screenWidth = CGDisplayModeGetPixelsWide(displayMode.get());
-            auto screenHeight = CGDisplayModeGetPixelsHigh(displayMode.get());
-            if (!screenWidth || !screenHeight) {
-                RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::createDisplayStream(%p), unable to get screen width/height", this);
-                captureFailed();
-                return false;
-            }
-            setSize(IntSize(screenWidth, screenHeight));
+        auto displayMode = adoptCF(CGDisplayCopyDisplayMode(m_displayID));
+        auto screenWidth = CGDisplayModeGetPixelsWide(displayMode.get());
+        auto screenHeight = CGDisplayModeGetPixelsHigh(displayMode.get());
+        if (!screenWidth || !screenHeight) {
+            RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::createDisplayStream(%p), unable to get screen width/height", this);
+            captureFailed();
+            return false;
         }
+        setIntrinsicSize(IntSize(screenWidth, screenHeight));
 
         if (!m_captureQueue)
             m_captureQueue = adoptOSObject(dispatch_queue_create("ScreenDisplayCaptureSourceMac Capture Queue", DISPATCH_QUEUE_SERIAL));
@@ -167,7 +165,8 @@
             weakThis->frameAvailable(status, displayTime, frameSurface, updateRef);
         });
 
-        m_displayStream = adoptCF(CGDisplayStreamCreateWithDispatchQueue(m_displayID, size().width(), size().height(), kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, streamOptions.get(), m_captureQueue.get(), m_frameAvailableBlock));
+        auto size = frameSize();
+        m_displayStream = adoptCF(CGDisplayStreamCreateWithDispatchQueue(m_displayID, size.width(), size.height(), kCVPixelFormatType_420YpCbCr8Planar, streamOptions.get(), m_captureQueue.get(), m_frameAvailableBlock));
         if (!m_displayStream) {
             RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::createDisplayStream(%p), CGDisplayStreamCreate failed", this);
             captureFailed();
@@ -206,10 +205,10 @@
     m_isRunning = false;
 }
 
-void ScreenDisplayCaptureSourceMac::generateFrame()
+RetainPtr<CVPixelBufferRef> ScreenDisplayCaptureSourceMac::generateFrame()
 {
     if (!m_currentFrame.ioSurface())
-        return;
+        return nullptr;
 
     DisplaySurface currentFrame;
     {
@@ -217,15 +216,7 @@
         currentFrame = m_currentFrame.ioSurface();
     }
 
-    auto pixelBuffer = pixelBufferFromIOSurface(currentFrame.ioSurface());
-    if (!pixelBuffer)
-        return;
-
-    auto sampleBuffer = sampleBufferFromPixelBuffer(pixelBuffer.get());
-    if (!sampleBuffer)
-        return;
-
-    videoSampleAvailable(MediaSampleAVFObjC::create(sampleBuffer.get()));
+    return pixelBufferFromIOSurface(currentFrame.ioSurface());
 }
 
 void ScreenDisplayCaptureSourceMac::startDisplayStream()

Added: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h (0 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h	2018-09-26 02:33:02 UTC (rev 236494)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 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) && PLATFORM(MAC)
+
+#include "DisplayCaptureSourceCocoa.h"
+
+typedef struct __CVBuffer *CVBufferRef;
+typedef CVBufferRef CVImageBufferRef;
+typedef CVImageBufferRef CVPixelBufferRef;
+typedef struct __CVPixelBufferPool *CVPixelBufferPoolRef;
+
+namespace WebCore {
+
+class PixelBufferConformerCV;
+
+class WindowDisplayCaptureSourceMac : public DisplayCaptureSourceCocoa {
+public:
+    static CaptureSourceOrError create(const String&, const MediaConstraints*);
+
+    static std::optional<CaptureDevice> windowCaptureDeviceWithPersistentID(const String&);
+    static void windowCaptureDevices(Vector<CaptureDevice>&);
+
+private:
+    WindowDisplayCaptureSourceMac(uint32_t windowID, String&&);
+    virtual ~WindowDisplayCaptureSourceMac() = default;
+
+    RetainPtr<CVPixelBufferRef> generateFrame() final;
+    RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Window; }
+
+    RetainPtr<CGImageRef> windowImage();
+    RetainPtr<CVPixelBufferRef> pixelBufferFromCGImage(CGImageRef);
+
+    IntSize m_windowSize;
+    CGWindowID m_windowID { 0 };
+    RetainPtr<CVPixelBufferPoolRef> m_bufferPool;
+    std::unique_ptr<PixelBufferConformerCV> m_pixelBufferConformer;
+    RetainPtr<CGImageRef> m_lastImage;
+    RetainPtr<CVPixelBufferRef> m_lastPixelBuffer;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && PLATFORM(MAC)

Added: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm (0 => 236494)


--- trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm	                        (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm	2018-09-26 02:33:02 UTC (rev 236494)
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#import "config.h"
+#import "WindowDisplayCaptureSourceMac.h"
+
+#if ENABLE(MEDIA_STREAM) && PLATFORM(MAC)
+
+#import "GraphicsContextCG.h"
+#import "ImageBuffer.h"
+#import "Logging.h"
+#import "MediaConstraints.h"
+#import "MediaSampleAVFObjC.h"
+#import "NotImplemented.h"
+#import "PixelBufferConformerCV.h"
+#import "PlatformLayer.h"
+#import "RealtimeMediaSourceSettings.h"
+#import <pal/cf/CoreMediaSoftLink.h>
+#import <pal/spi/cg/CoreGraphicsSPI.h>
+#import <wtf/cf/TypeCastsCF.h>
+
+#import "CoreVideoSoftLink.h"
+
+WTF_DECLARE_CF_TYPE_TRAIT(CGImage);
+
+namespace WebCore {
+using namespace PAL;
+
+static bool anyOfCGWindow(const Function<bool(CFDictionaryRef info, unsigned id, const String& title)>& predicate)
+{
+    auto windows = adoptCF(CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID));
+    if (!windows) {
+        RELEASE_LOG(Media, "CGWindowListCopyWindowInfo returned NULL");
+        return false;
+    }
+
+    auto windowCount = CFArrayGetCount(windows.get());
+    for (auto i = 0; i < windowCount; i++) {
+        auto windowInfo = checked_cf_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(windows.get(), i));
+        if (!windowInfo)
+            continue;
+
+        // Menus, the dock, etc have layers greater than 0, skip them.
+        auto windowLayerRef = checked_cf_cast<CFNumberRef>(CFDictionaryGetValue(windowInfo, kCGWindowLayer));
+        if (!windowLayerRef)
+            continue;
+        unsigned windowLayer;
+        CFNumberGetValue(windowLayerRef, kCFNumberIntType, &windowLayer);
+        if (windowLayer)
+            continue;
+
+        auto _onScreen_ = checked_cf_cast<CFBooleanRef>(CFDictionaryGetValue(windowInfo, kCGWindowIsOnscreen));
+        if (!CFBooleanGetValue(onScreen))
+            continue;
+
+        auto windowIDRef = checked_cf_cast<CFNumberRef>(CFDictionaryGetValue(windowInfo, kCGWindowNumber));
+        if (!windowIDRef)
+            continue;
+        unsigned windowID;
+        CFNumberGetValue(windowIDRef, kCFNumberIntType, &windowID);
+        if (!windowID)
+            continue;
+
+        auto windowTitle = checked_cf_cast<CFStringRef>(CFDictionaryGetValue(windowInfo, kCGWindowName));
+
+        if (predicate(windowInfo, windowID, windowTitle))
+            return true;
+    }
+
+    return false;
+}
+
+static RetainPtr<CFDictionaryRef> windowDescription(CGWindowID id)
+{
+    auto ids = adoptCF(CFArrayCreate(nullptr, reinterpret_cast<const void**>(&id), 1, nullptr));
+    auto windows = adoptCF(CGWindowListCreateDescriptionFromArray(ids.get()));
+    if (!windows)
+        return nullptr;
+
+    return checked_cf_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(windows.get(), 0));
+}
+
+CaptureSourceOrError WindowDisplayCaptureSourceMac::create(const String& windowID, const MediaConstraints* constraints)
+{
+    bool ok;
+    auto actualID = windowID.toUIntStrict(&ok);
+    if (!ok) {
+        RELEASE_LOG(Media, "WindowDisplayCaptureSourceMac::create: window ID does not convert to 32-bit integer");
+        return { };
+    }
+
+    auto windowInfo = windowDescription(actualID);
+    if (!windowInfo) {
+        RELEASE_LOG(Media, "WindowDisplayCaptureSourceMac::create: invalid window ID");
+        return { };
+    }
+
+    auto source = adoptRef(*new WindowDisplayCaptureSourceMac(actualID, checked_cf_cast<CFStringRef>(CFDictionaryGetValue(windowInfo.get(), kCGWindowName))));
+    if (constraints && source->applyConstraints(*constraints))
+        return { };
+
+    return CaptureSourceOrError(WTFMove(source));
+}
+
+WindowDisplayCaptureSourceMac::WindowDisplayCaptureSourceMac(uint32_t windowID, String&& title)
+    : DisplayCaptureSourceCocoa(WTFMove(title))
+    , m_windowID(windowID)
+{
+}
+
+RetainPtr<CGImageRef> WindowDisplayCaptureSourceMac::windowImage()
+{
+    auto image = adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, m_windowID, kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque));
+    if (!image)
+        RELEASE_LOG(Media, "WindowDisplayCaptureSourceMac::windowImage: failed to capture window image");
+
+    return image;
+}
+
+RetainPtr<CVPixelBufferRef> WindowDisplayCaptureSourceMac::generateFrame()
+{
+    auto image = windowImage();
+    if (!image)
+        return nullptr;
+
+    if (m_lastImage && m_lastPixelBuffer && CFEqual(m_lastImage.get(), image.get()))
+        return m_lastPixelBuffer.get();
+
+    m_lastImage = WTFMove(image);
+    return pixelBufferFromCGImage(m_lastImage.get());
+}
+
+RetainPtr<CVPixelBufferRef> WindowDisplayCaptureSourceMac::pixelBufferFromCGImage(CGImageRef image)
+{
+    static CGColorSpaceRef sRGBColorSpace = sRGBColorSpaceRef();
+
+    auto imageSize = IntSize(CGImageGetWidth(image), CGImageGetHeight(image));
+    if (imageSize != intrinsicSize()) {
+        m_bufferPool = nullptr;
+        m_lastImage = nullptr;
+        m_lastPixelBuffer = nullptr;
+    }
+
+    if (!m_bufferPool) {
+        CVPixelBufferPoolRef bufferPool;
+        CFDictionaryRef sourcePixelBufferOptions = (__bridge CFDictionaryRef) @{
+        (__bridge NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32ARGB),
+        (__bridge NSString *)kCVPixelBufferWidthKey : @(imageSize.width()),
+        (__bridge NSString *)kCVPixelBufferHeightKey : @(imageSize.height()),
+#if PLATFORM(IOS)
+        (__bridge NSString *)kCVPixelFormatOpenGLESCompatibility : @(YES),
+#else
+        (__bridge NSString *)kCVPixelBufferOpenGLCompatibilityKey : @(YES),
+#endif
+        (__bridge NSString *)kCVPixelBufferIOSurfacePropertiesKey : @{ /*empty dictionary*/ }
+    };
+
+        CFDictionaryRef pixelBufferPoolOptions = (__bridge CFDictionaryRef) @{
+            (__bridge NSString *)kCVPixelBufferPoolMinimumBufferCountKey : @(3)
+        };
+
+        CVReturn status = CVPixelBufferPoolCreate(kCFAllocatorDefault, pixelBufferPoolOptions, sourcePixelBufferOptions, &bufferPool);
+        if (status != kCVReturnSuccess)
+            return nullptr;
+
+        m_bufferPool = adoptCF(bufferPool);
+        setIntrinsicSize(imageSize);
+    }
+
+    CVPixelBufferRef pixelBuffer;
+    CVReturn status = CVPixelBufferPoolCreatePixelBuffer(nullptr, m_bufferPool.get(), &pixelBuffer);
+    if (status != kCVReturnSuccess)
+        return nullptr;
+
+    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
+    void* data = ""
+    auto context = adoptCF(CGBitmapContextCreate(data, imageSize.width(), imageSize.height(), 8, CVPixelBufferGetBytesPerRow(pixelBuffer), sRGBColorSpace, (CGBitmapInfo) kCGImageAlphaNoneSkipFirst));
+    CGContextDrawImage(context.get(), CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
+    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
+
+    m_lastPixelBuffer = adoptCF(pixelBuffer);
+    return m_lastPixelBuffer;
+}
+
+std::optional<CaptureDevice> WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID(const String& idString)
+{
+    bool ok;
+    auto windowID = idString.toUIntStrict(&ok);
+    if (!ok) {
+        RELEASE_LOG(Media, "WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID: window ID does not convert to 32-bit integer");
+        return std::nullopt;
+    }
+
+    String windowTitle;
+    if (!anyOfCGWindow([&windowTitle, windowID] (CFDictionaryRef, CGWindowID id, const String& title) {
+        if (windowID != id)
+            return false;
+
+        windowTitle = title;
+        return true;
+
+    })) {
+        RELEASE_LOG(Media, "WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID: window ID is not valid");
+        return std::nullopt;
+    }
+
+    auto device = CaptureDevice(String::number(windowID), CaptureDevice::DeviceType::Window, windowTitle);
+    device.setEnabled(true);
+
+    return device;
+}
+
+void WindowDisplayCaptureSourceMac::windowCaptureDevices(Vector<CaptureDevice>& windows)
+{
+    anyOfCGWindow([&] (CFDictionaryRef, int id, const String& title) mutable {
+        CaptureDevice device(String::number(id), CaptureDevice::DeviceType::Window, title);
+        device.setEnabled(true);
+        windows.append(WTFMove(device));
+        return false;
+    });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && PLATFORM(MAC)

Modified: trunk/Source/WebKit/ChangeLog (236493 => 236494)


--- trunk/Source/WebKit/ChangeLog	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebKit/ChangeLog	2018-09-26 02:33:02 UTC (rev 236494)
@@ -1,3 +1,16 @@
+2018-09-25  Eric Carlson  <[email protected]>
+
+        [MediaStream] Add Mac window capture source
+        https://bugs.webkit.org/show_bug.cgi?id=189958
+        <rdar://problem/44767616>
+
+        Reviewed by Youenn Fablet.
+
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::beginMonitoringCaptureDevices): Sync with webcore prefs before listening
+        to device changes so we listen on the correct devices.
+
 2018-09-25  Chris Dumez  <[email protected]>
 
         Unreviewed, rolling out r236471 and r236480.

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h (236493 => 236494)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h	2018-09-26 02:33:02 UTC (rev 236494)
@@ -64,6 +64,7 @@
     void captureDevicesChanged();
 
     void captureStateChanged(WebCore::MediaProducer::MediaStateFlags oldState, WebCore::MediaProducer::MediaStateFlags newState);
+    void syncWithWebCorePrefs() const;
 
 private:
     Ref<UserMediaPermissionRequestProxy> createPermissionRequest(uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, String&&, WebCore::MediaStreamRequest&&);
@@ -76,7 +77,6 @@
 #endif
     void getUserMediaPermissionInfo(uint64_t userMediaID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&&, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin);
 
-    void syncWithWebCorePrefs() const;
     void watchdogTimerFired();
 
     HashMap<uint64_t, RefPtr<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests;

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (236493 => 236494)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-09-26 02:03:00 UTC (rev 236493)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-09-26 02:33:02 UTC (rev 236494)
@@ -6448,6 +6448,7 @@
 void WebPageProxy::beginMonitoringCaptureDevices()
 {
 #if ENABLE(MEDIA_STREAM)
+    userMediaPermissionRequestManager().syncWithWebCorePrefs();
     UserMediaProcessManager::singleton().beginMonitoringCaptureDevices();
 #endif
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to