[MediaStream] Restructure getDisplayMedia classes
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jul 2018 15:04:43 +0000 (15:04 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jul 2018 15:04:43 +0000 (15:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187905

Reviewed by Dean Jackson.

No new tests, no functional changes.

* platform/mediastream/CaptureDeviceManager.h:
(WebCore::CaptureDeviceManager::refreshCaptureDevices): Deleted, no need for it to be a
virtual method.
* platform/mediastream/mac/AVCaptureDeviceManager.h:

* platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h: refreshCaptureDevices is
no longer virtual.

* platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp:
(WebCore::DisplayCaptureManagerCocoa::captureDevices):
(WebCore::DisplayCaptureManagerCocoa::updateDisplayCaptureDevices): Moved functionality
to ScreenDisplayCaptureSourceMac.
(WebCore::DisplayCaptureManagerCocoa::screenCaptureDeviceWithPersistentID): Ditto.
(WebCore::displayReconfigurationCallBack): Deleted, moved to ScreenDisplayCaptureSourceMac.
(WebCore::DisplayCaptureManagerCocoa::~DisplayCaptureManagerCocoa): Deleted.
(WebCore::DisplayCaptureManagerCocoa::refreshCaptureDevices): Deleted.
* platform/mediastream/mac/DisplayCaptureManagerCocoa.h:

* platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp:
(WebCore::roundUpToMacroblockMultiple): Moved from ScreenDisplayCaptureSourceMac.
(WebCore::DisplayCaptureSourceCocoa::applySize): Ditto.
(WebCore::DisplayCaptureSourceCocoa::sampleBufferFromPixelBuffer): Ditto.
(WebCore::DisplayCaptureSourceCocoa::pixelBufferFromIOSurface): Ditto.
* platform/mediastream/mac/DisplayCaptureSourceCocoa.h:

* platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h:
* platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
(WebCore::updateDisplayID):
(WebCore::ScreenDisplayCaptureSourceMac::createDisplayStream): Fix log message.
(WebCore::ScreenDisplayCaptureSourceMac::startDisplayStream): Ditto.
(WebCore::ScreenDisplayCaptureSourceMac::applySize): Update for base class changes.
(WebCore::ScreenDisplayCaptureSourceMac::applyFrameRate): Ditto.
(WebCore::ScreenDisplayCaptureSourceMac::frameAvailable): Ditto.
(WebCore::ScreenDisplayCaptureSourceMac::screenCaptureDeviceWithPersistentID): Moved from
DisplayCaptureManagerCocoa.
(WebCore::ScreenDisplayCaptureSourceMac::screenCaptureDevices): Ditto.
(WebCore::roundUpToMacroblockMultiple): Moved to DisplayCaptureSourceCocoa.
(WebCore::ScreenDisplayCaptureSourceMac::updateDisplayID): Ditto.
(WebCore::ScreenDisplayCaptureSourceMac::sampleBufferFromPixelBuffer): Ditto.
(WebCore::ScreenDisplayCaptureSourceMac::pixelBufferFromIOSurface): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234146 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/CaptureDeviceManager.h
Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h
Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h
Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp
Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.h
Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp
Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h
Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h
Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm

index bdc3dd1..f5172bb 100644 (file)
@@ -1,3 +1,53 @@
+2018-07-24  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Restructure getDisplayMedia classes
+        https://bugs.webkit.org/show_bug.cgi?id=187905
+
+        Reviewed by Dean Jackson.
+
+        No new tests, no functional changes.
+
+        * platform/mediastream/CaptureDeviceManager.h:
+        (WebCore::CaptureDeviceManager::refreshCaptureDevices): Deleted, no need for it to be a 
+        virtual method.
+        * platform/mediastream/mac/AVCaptureDeviceManager.h:
+
+        * platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h: refreshCaptureDevices is
+        no longer virtual.
+
+        * platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp:
+        (WebCore::DisplayCaptureManagerCocoa::captureDevices):
+        (WebCore::DisplayCaptureManagerCocoa::updateDisplayCaptureDevices): Moved functionality 
+        to ScreenDisplayCaptureSourceMac.
+        (WebCore::DisplayCaptureManagerCocoa::screenCaptureDeviceWithPersistentID): Ditto.
+        (WebCore::displayReconfigurationCallBack): Deleted, moved to ScreenDisplayCaptureSourceMac.
+        (WebCore::DisplayCaptureManagerCocoa::~DisplayCaptureManagerCocoa): Deleted.
+        (WebCore::DisplayCaptureManagerCocoa::refreshCaptureDevices): Deleted.
+        * platform/mediastream/mac/DisplayCaptureManagerCocoa.h:
+
+        * platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp:
+        (WebCore::roundUpToMacroblockMultiple): Moved from ScreenDisplayCaptureSourceMac.
+        (WebCore::DisplayCaptureSourceCocoa::applySize): Ditto.
+        (WebCore::DisplayCaptureSourceCocoa::sampleBufferFromPixelBuffer): Ditto.
+        (WebCore::DisplayCaptureSourceCocoa::pixelBufferFromIOSurface): Ditto.
+        * platform/mediastream/mac/DisplayCaptureSourceCocoa.h:
+
+        * platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h:
+        * platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
+        (WebCore::updateDisplayID):
+        (WebCore::ScreenDisplayCaptureSourceMac::createDisplayStream): Fix log message.
+        (WebCore::ScreenDisplayCaptureSourceMac::startDisplayStream): Ditto.
+        (WebCore::ScreenDisplayCaptureSourceMac::applySize): Update for base class changes.
+        (WebCore::ScreenDisplayCaptureSourceMac::applyFrameRate): Ditto.
+        (WebCore::ScreenDisplayCaptureSourceMac::frameAvailable): Ditto.
+        (WebCore::ScreenDisplayCaptureSourceMac::screenCaptureDeviceWithPersistentID): Moved from
+        DisplayCaptureManagerCocoa.
+        (WebCore::ScreenDisplayCaptureSourceMac::screenCaptureDevices): Ditto.
+        (WebCore::roundUpToMacroblockMultiple): Moved to DisplayCaptureSourceCocoa.
+        (WebCore::ScreenDisplayCaptureSourceMac::updateDisplayID): Ditto.
+        (WebCore::ScreenDisplayCaptureSourceMac::sampleBufferFromPixelBuffer): Ditto.
+        (WebCore::ScreenDisplayCaptureSourceMac::pixelBufferFromIOSurface): Ditto.
+
 2018-07-24  Zalan Bujtas  <zalan@apple.com>
 
         [LFC] Move geometry data structures to a dedicated file
index 5e6bf9f..45edb30 100644 (file)
@@ -42,8 +42,6 @@ public:
     virtual const Vector<CaptureDevice>& captureDevices() = 0;
     virtual std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&) { return std::nullopt; }
 
-    virtual void refreshCaptureDevices() { }
-
 protected:
     virtual ~CaptureDeviceManager();
     CaptureDevice captureDeviceFromPersistentID(const String& captureDeviceID);
index 8639241..b1fd782 100644 (file)
@@ -33,12 +33,12 @@ class GStreamerCaptureDeviceManager : public CaptureDeviceManager {
 public:
     std::optional<GStreamerCaptureDevice> gstreamerDeviceWithUID(const String&);
 
-    void refreshCaptureDevices() final;
     const Vector<CaptureDevice>& captureDevices() final;
     virtual CaptureDevice::DeviceType deviceType() = 0;
 
 private:
     void deviceAdded(GRefPtr<GstDevice>&&);
+    void refreshCaptureDevices();
 
     GRefPtr<GstDeviceMonitor> m_deviceMonitor;
     Vector<GStreamerCaptureDevice> m_gstreamerDevices;
index 7f07df3..b21ca9b 100644 (file)
@@ -58,7 +58,7 @@ protected:
     AVCaptureDeviceManager();
     ~AVCaptureDeviceManager() final;
 
-    void refreshCaptureDevices() final;
+    void refreshCaptureDevices();
     void registerForDeviceNotifications();
     void refreshAVCaptureDevicesOfType(CaptureDevice::DeviceType);
     Vector<CaptureDevice>& captureDevicesInternal();
index ab5fb04..5c2a9d2 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(MEDIA_STREAM)
 
 #include "Logging.h"
+#include <wtf/Algorithms.h>
 #include <wtf/NeverDestroyed.h>
 
 #if PLATFORM(MAC)
 
 namespace WebCore {
 
-#if PLATFORM(MAC)
-static void displayReconfigurationCallBack(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void* userInfo)
-{
-    if (userInfo)
-        reinterpret_cast<DisplayCaptureManagerCocoa*>(userInfo)->refreshCaptureDevices();
-}
-#endif
-
 DisplayCaptureManagerCocoa& DisplayCaptureManagerCocoa::singleton()
 {
     static NeverDestroyed<DisplayCaptureManagerCocoa> manager;
     return manager.get();
 }
 
-DisplayCaptureManagerCocoa::~DisplayCaptureManagerCocoa()
-{
-#if PLATFORM(MAC)
-    if (m_observingDisplayChanges)
-        CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallBack, this);
-#endif
-}
-
 const Vector<CaptureDevice>& DisplayCaptureManagerCocoa::captureDevices()
 {
-    static bool initialized;
-    if (!initialized) {
-        refreshCaptureDevices();
+    m_devices.clear();
 
-#if PLATFORM(MAC)
-        CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, this);
-#endif
+    updateDisplayCaptureDevices();
 
-        m_observingDisplayChanges = true;
-        initialized = true;
-    };
-    
-    return m_displays;
+    return m_devices;
 }
 
-void DisplayCaptureManagerCocoa::refreshCaptureDevices()
+void DisplayCaptureManagerCocoa::updateDisplayCaptureDevices()
 {
 #if PLATFORM(MAC)
-    uint32_t displayCount = 0;
-    auto err = CGGetActiveDisplayList(0, nullptr, &displayCount);
-    if (err) {
-        RELEASE_LOG(Media, "CGGetActiveDisplayList() returned error %d when trying to get display count", (int)err);
-        return;
-    }
-
-    if (!displayCount) {
-        RELEASE_LOG(Media, "CGGetActiveDisplayList() returned a display count of 0");
-        return;
-    }
-
-    CGDirectDisplayID activeDisplays[displayCount];
-    err = CGGetActiveDisplayList(displayCount, &(activeDisplays[0]), &displayCount);
-    if (err) {
-        RELEASE_LOG(Media, "CGGetActiveDisplayList() returned error %d when trying to get the active display list", (int)err);
-        return;
-    }
-
-    bool haveDeviceChanges = false;
-    for (auto displayID : activeDisplays) {
-        if (std::any_of(m_displaysInternal.begin(), m_displaysInternal.end(), [displayID](auto& device) { return device.cgDirectDisplayID == displayID; }))
-            continue;
-        haveDeviceChanges = true;
-        m_displaysInternal.append({ displayID, CGDisplayIDToOpenGLDisplayMask(displayID) });
-    }
-
-    for (auto& display : m_displaysInternal) {
-        auto displayMask = CGDisplayIDToOpenGLDisplayMask(display.cgDirectDisplayID);
-        if (display.cgOpenGLDisplayMask != displayMask) {
-            display.cgOpenGLDisplayMask = displayMask;
-            haveDeviceChanges = true;
-        }
-    }
-
-    if (!haveDeviceChanges)
-        return;
-
-    int count = 0;
-    m_displays = Vector<CaptureDevice>();
-    for (auto& device : m_displaysInternal) {
-        CaptureDevice displayDevice(String::number(device.cgDirectDisplayID), CaptureDevice::DeviceType::Screen, makeString("Screen ", String::number(count++)));
-        displayDevice.setEnabled(device.cgOpenGLDisplayMask);
-        m_displays.append(WTFMove(displayDevice));
-    }
+    ScreenDisplayCaptureSourceMac::screenCaptureDevices(m_devices);
 #endif
 }
 
 std::optional<CaptureDevice> DisplayCaptureManagerCocoa::screenCaptureDeviceWithPersistentID(const String& deviceID)
 {
 #if PLATFORM(MAC)
-    bool ok;
-    auto displayID = deviceID.toUIntStrict(&ok);
-    if (!ok) {
-        RELEASE_LOG(Media, "Display ID does not convert to 32-bit integer");
-        return std::nullopt;
-    }
-
-    auto actualDisplayID = ScreenDisplayCaptureSourceMac::updateDisplayID(displayID);
-    if (!actualDisplayID)
-        return std::nullopt;
-
-    auto device = CaptureDevice(String::number(actualDisplayID.value()), CaptureDevice::DeviceType::Screen, "ScreenCaptureDevice"_s);
-    device.setEnabled(true);
-
-    return device;
+    return ScreenDisplayCaptureSourceMac::screenCaptureDeviceWithPersistentID(deviceID);
 #else
     UNUSED_PARAM(deviceID);
     return std::nullopt;
index d762864..68cee60 100644 (file)
@@ -34,24 +34,20 @@ namespace WebCore {
 class DisplayCaptureManagerCocoa final : public CaptureDeviceManager {
 public:
     static DisplayCaptureManagerCocoa& singleton();
-    DisplayCaptureManagerCocoa() = default;
 
-    void refreshCaptureDevices() final;
+    DisplayCaptureManagerCocoa() = default;
 
 private:
-    virtual ~DisplayCaptureManagerCocoa();
+    virtual ~DisplayCaptureManagerCocoa() = default;
+
+    void updateDisplayCaptureDevices();
 
     const Vector<CaptureDevice>& captureDevices() final;
+
     std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&) final;
     std::optional<CaptureDevice> screenCaptureDeviceWithPersistentID(const String&);
 
-    struct CGDisplayCaptureDevice {
-        uint32_t cgDirectDisplayID;
-        uint32_t cgOpenGLDisplayMask;
-    };
-    Vector<CGDisplayCaptureDevice> m_displaysInternal;
-    Vector<CaptureDevice> m_displays;
-    bool m_observingDisplayChanges { false };
+    Vector<CaptureDevice> m_devices;
 };
 
 } // namespace WebCore
index c6360a5..5f033f3 100644 (file)
@@ -127,6 +127,15 @@ Seconds DisplayCaptureSourceCocoa::elapsedTime()
     return m_elapsedTime + (MonotonicTime::now() - m_startTime);
 }
 
+bool DisplayCaptureSourceCocoa::applySize(const IntSize& newSize)
+{
+    if (size() == newSize)
+        return true;
+
+    m_bufferAttributes = nullptr;
+    return true;
+}
+
 bool DisplayCaptureSourceCocoa::applyFrameRate(double rate)
 {
     if (m_timer.isActive())
@@ -143,6 +152,76 @@ void DisplayCaptureSourceCocoa::emitFrame()
     generateFrame();
 }
 
+RetainPtr<CMSampleBufferRef> DisplayCaptureSourceCocoa::sampleBufferFromPixelBuffer(CVPixelBufferRef pixelBuffer)
+{
+    if (!pixelBuffer)
+        return nullptr;
+
+    CMTime sampleTime = CMTimeMake(((elapsedTime() + 100_ms) * 100).seconds(), 100);
+    CMSampleTimingInfo timingInfo = { kCMTimeInvalid, sampleTime, sampleTime };
+
+    CMVideoFormatDescriptionRef formatDescription = nullptr;
+    auto status = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, (CVImageBufferRef)pixelBuffer, &formatDescription);
+    if (status) {
+        RELEASE_LOG(Media, "Failed to initialize CMVideoFormatDescription with error code: %d", static_cast<int>(status));
+        return nullptr;
+    }
+
+    CMSampleBufferRef sampleBuffer;
+    status = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, (CVImageBufferRef)pixelBuffer, formatDescription, &timingInfo, &sampleBuffer);
+    CFRelease(formatDescription);
+    if (status) {
+        RELEASE_LOG(Media, "Failed to initialize CMSampleBuffer with error code: %d", static_cast<int>(status));
+        return nullptr;
+    }
+
+    return adoptCF(sampleBuffer);
+}
+
+#if HAVE(IOSURFACE)
+static int32_t roundUpToMacroblockMultiple(int32_t size)
+{
+    return (size + 15) & ~15;
+}
+
+RetainPtr<CVPixelBufferRef> DisplayCaptureSourceCocoa::pixelBufferFromIOSurface(IOSurfaceRef surface)
+{
+    if (!m_bufferAttributes) {
+        m_bufferAttributes = adoptCF(CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+        auto format = IOSurfaceGetPixelFormat(surface);
+        if (format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange || format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
+
+            // If the width x height isn't a multiple of 16 x 16 and the surface has extra memory in the planes, set pixel buffer attributes to reflect it.
+            auto width = IOSurfaceGetWidth(surface);
+            auto height = IOSurfaceGetHeight(surface);
+            int32_t extendedRight = roundUpToMacroblockMultiple(width) - width;
+            int32_t extendedBottom = roundUpToMacroblockMultiple(height) - height;
+
+            if ((IOSurfaceGetBytesPerRowOfPlane(surface, 0) >= width + extendedRight)
+                && (IOSurfaceGetBytesPerRowOfPlane(surface, 1) >= width + extendedRight)
+                && (IOSurfaceGetAllocSize(surface) >= (height + extendedBottom) * IOSurfaceGetBytesPerRowOfPlane(surface, 0) * 3 / 2)) {
+                auto cfInt = adoptCF(CFNumberCreate(nullptr,  kCFNumberIntType,  &extendedRight));
+                CFDictionarySetValue(m_bufferAttributes.get(), kCVPixelBufferExtendedPixelsRightKey, cfInt.get());
+                cfInt = adoptCF(CFNumberCreate(nullptr,  kCFNumberIntType,  &extendedBottom));
+                CFDictionarySetValue(m_bufferAttributes.get(), kCVPixelBufferExtendedPixelsBottomKey, cfInt.get());
+            }
+        }
+
+        CFDictionarySetValue(m_bufferAttributes.get(), kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue);
+    }
+
+    CVPixelBufferRef pixelBuffer;
+    auto status = CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface, m_bufferAttributes.get(), &pixelBuffer);
+    if (status) {
+        RELEASE_LOG(Media, "CVPixelBufferCreateWithIOSurface failed with error code: %d", static_cast<int>(status));
+        return nullptr;
+    }
+
+    return adoptCF(pixelBuffer);
+}
+#endif
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)
index 8b2bcef..7877e0b 100644 (file)
@@ -55,6 +55,12 @@ protected:
 
     Seconds elapsedTime();
     bool applyFrameRate(double) override;
+    bool applySize(const IntSize&) override;
+
+    RetainPtr<CMSampleBufferRef> sampleBufferFromPixelBuffer(CVPixelBufferRef);
+#if HAVE(IOSURFACE)
+    RetainPtr<CVPixelBufferRef> pixelBufferFromIOSurface(IOSurfaceRef);
+#endif
 
 private:
 
@@ -73,6 +79,7 @@ private:
     MonotonicTime m_startTime { MonotonicTime::nan() };
     Seconds m_elapsedTime { 0_s };
 
+    RetainPtr<CFMutableDictionaryRef> m_bufferAttributes;
     RunLoop::Timer<DisplayCaptureSourceCocoa> m_timer;
 };
 
index 3db270f..d26a294 100644 (file)
@@ -33,7 +33,6 @@
 #include <CoreGraphics/CGDisplayStream.h>
 #include <wtf/Lock.h>
 #include <wtf/OSObjectPtr.h>
-#include <wtf/WeakPtr.h>
 
 typedef struct __CVBuffer *CVPixelBufferRef;
 typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
@@ -44,9 +43,8 @@ class ScreenDisplayCaptureSourceMac : public DisplayCaptureSourceCocoa {
 public:
     static CaptureSourceOrError create(const String&, const MediaConstraints*);
 
-    WEBCORE_EXPORT static VideoCaptureFactory& factory();
-
-    WEBCORE_EXPORT static std::optional<CGDirectDisplayID> updateDisplayID(CGDirectDisplayID);
+    static std::optional<CaptureDevice> screenCaptureDeviceWithPersistentID(const String&);
+    static void screenCaptureDevices(Vector<CaptureDevice>&);
 
 private:
     ScreenDisplayCaptureSourceMac(uint32_t);
@@ -65,8 +63,6 @@ private:
     bool applyFrameRate(double) final;
     void commitConfiguration() final;
 
-    RetainPtr<CMSampleBufferRef> sampleBufferFromPixelBuffer(CVPixelBufferRef);
-    RetainPtr<CVPixelBufferRef> pixelBufferFromIOSurface(IOSurfaceRef);
     bool createDisplayStream();
     void startDisplayStream();
     
@@ -98,14 +94,10 @@ private:
     mutable Lock m_currentFrameMutex;
     DisplaySurface m_currentFrame;
     RetainPtr<CGDisplayStreamRef> m_displayStream;
-    RetainPtr<CFMutableDictionaryRef> m_bufferAttributes;
     CGDisplayStreamFrameAvailableHandler m_frameAvailableBlock;
-    MediaTime m_presentationTimeStamp;
-    MediaTime m_frameDuration;
 
     OSObjectPtr<dispatch_queue_t> m_captureQueue;
 
-    MonotonicTime m_lastFrameTime { MonotonicTime::nan() };
     uint32_t m_displayID { 0 };
     bool m_isRunning { false };
     bool m_observingDisplayChanges { false };
index 36d1e84..b17e7c2 100644 (file)
@@ -46,12 +46,7 @@ size_t CGDisplayModeGetPixelsHigh(CGDisplayModeRef);
 
 namespace WebCore {
 
-static int32_t roundUpToMacroblockMultiple(int32_t size)
-{
-    return (size + 15) & ~15;
-}
-
-std::optional<CGDirectDisplayID> ScreenDisplayCaptureSourceMac::updateDisplayID(CGDirectDisplayID displayID)
+static std::optional<CGDirectDisplayID> updateDisplayID(CGDirectDisplayID displayID)
 {
     uint32_t displayCount = 0;
     auto err = CGGetActiveDisplayList(0, nullptr, &displayCount);
@@ -127,11 +122,10 @@ bool ScreenDisplayCaptureSourceMac::createDisplayStream()
 
     if (m_displayID != actualDisplayID.value()) {
         m_displayID = actualDisplayID.value();
-        RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::create(%p), display ID changed to %d", this, static_cast<int>(m_displayID));
+        RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::createDisplayStream(%p), display ID changed to %d", this, static_cast<int>(m_displayID));
     }
 
     if (!m_displayStream) {
-
         if (size().isEmpty()) {
             RetainPtr<CGDisplayModeRef> displayMode = adoptCF(CGDisplayCopyDisplayMode(m_displayID));
             auto screenWidth = CGDisplayModeGetPixelsWide(displayMode.get());
@@ -213,69 +207,6 @@ void ScreenDisplayCaptureSourceMac::stopProducingData()
     m_isRunning = false;
 }
 
-RetainPtr<CMSampleBufferRef> ScreenDisplayCaptureSourceMac::sampleBufferFromPixelBuffer(CVPixelBufferRef pixelBuffer)
-{
-    if (!pixelBuffer)
-        return nullptr;
-
-    CMTime sampleTime = CMTimeMake(((elapsedTime() + 100_ms) * 100).seconds(), 100);
-    CMSampleTimingInfo timingInfo = { kCMTimeInvalid, sampleTime, sampleTime };
-
-    CMVideoFormatDescriptionRef formatDescription = nullptr;
-    auto status = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, (CVImageBufferRef)pixelBuffer, &formatDescription);
-    if (status) {
-        RELEASE_LOG(Media, "Failed to initialize CMVideoFormatDescription with error code: %d", static_cast<int>(status));
-        return nullptr;
-    }
-
-    CMSampleBufferRef sampleBuffer;
-    status = CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, (CVImageBufferRef)pixelBuffer, formatDescription, &timingInfo, &sampleBuffer);
-    CFRelease(formatDescription);
-    if (status) {
-        RELEASE_LOG(Media, "Failed to initialize CMSampleBuffer with error code: %d", static_cast<int>(status));
-        return nullptr;
-    }
-
-    return adoptCF(sampleBuffer);
-}
-
-RetainPtr<CVPixelBufferRef> ScreenDisplayCaptureSourceMac::pixelBufferFromIOSurface(IOSurfaceRef surface)
-{
-    if (!m_bufferAttributes) {
-        m_bufferAttributes = adoptCF(CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-
-        auto format = IOSurfaceGetPixelFormat(surface);
-        if (format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange || format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
-
-            // If the width x height isn't a multiple of 16 x 16 and the surface has extra memory in the planes, set pixel buffer attributes to reflect it.
-            auto width = IOSurfaceGetWidth(surface);
-            auto height = IOSurfaceGetHeight(surface);
-            int32_t extendedRight = roundUpToMacroblockMultiple(width) - width;
-            int32_t extendedBottom = roundUpToMacroblockMultiple(height) - height;
-
-            if ((IOSurfaceGetBytesPerRowOfPlane(surface, 0) >= width + extendedRight)
-                && (IOSurfaceGetBytesPerRowOfPlane(surface, 1) >= width + extendedRight)
-                && (IOSurfaceGetAllocSize(surface) >= (height + extendedBottom) * IOSurfaceGetBytesPerRowOfPlane(surface, 0) * 3 / 2)) {
-                    auto cfInt = adoptCF(CFNumberCreate(nullptr,  kCFNumberIntType,  &extendedRight));
-                    CFDictionarySetValue(m_bufferAttributes.get(), kCVPixelBufferExtendedPixelsRightKey, cfInt.get());
-                    cfInt = adoptCF(CFNumberCreate(nullptr,  kCFNumberIntType,  &extendedBottom));
-                    CFDictionarySetValue(m_bufferAttributes.get(), kCVPixelBufferExtendedPixelsBottomKey, cfInt.get());
-            }
-        }
-
-        CFDictionarySetValue(m_bufferAttributes.get(), kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue);
-    }
-
-    CVPixelBufferRef pixelBuffer;
-    auto status = CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface, m_bufferAttributes.get(), &pixelBuffer);
-    if (status) {
-        RELEASE_LOG(Media, "Failed to initialize CMVideoFormatDescription with error code: %d", static_cast<int>(status));
-        return nullptr;
-    }
-
-    return adoptCF(pixelBuffer);
-}
-
 void ScreenDisplayCaptureSourceMac::generateFrame()
 {
     if (!m_currentFrame.ioSurface())
@@ -306,7 +237,7 @@ void ScreenDisplayCaptureSourceMac::startDisplayStream()
 
     if (m_displayID != actualDisplayID.value()) {
         m_displayID = actualDisplayID.value();
-        RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::create(%p), display ID changed to %d", this, static_cast<int>(m_displayID));
+        RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::startDisplayStream(%p), display ID changed to %d", this, static_cast<int>(m_displayID));
     }
 
     if (!m_displayStream && !createDisplayStream())
@@ -314,7 +245,7 @@ void ScreenDisplayCaptureSourceMac::startDisplayStream()
 
     auto err = CGDisplayStreamStart(m_displayStream.get());
     if (err) {
-        RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::startProducingData(%p), CGDisplayStreamStart failed with error %d", this, static_cast<int>(err));
+        RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::startDisplayStream(%p), CGDisplayStreamStart failed with error %d", this, static_cast<int>(err));
         captureFailed();
         return;
     }
@@ -324,20 +255,17 @@ void ScreenDisplayCaptureSourceMac::startDisplayStream()
 
 bool ScreenDisplayCaptureSourceMac::applySize(const IntSize& newSize)
 {
-    if (size() == newSize)
-        return true;
+    if (!DisplayCaptureSourceCocoa::applySize(newSize))
+        return false;
 
-    m_bufferAttributes = nullptr;
     m_displayStream = nullptr;
     return true;
 }
 
 bool ScreenDisplayCaptureSourceMac::applyFrameRate(double rate)
 {
-    if (frameRate() != rate) {
-        m_bufferAttributes = nullptr;
+    if (frameRate() != rate)
         m_displayStream = nullptr;
-    }
 
     return DisplayCaptureSourceCocoa::applyFrameRate(rate);
 }
@@ -386,10 +314,57 @@ void ScreenDisplayCaptureSourceMac::frameAvailable(CGDisplayStreamFrameStatus st
         return;
 
     LockHolder lock(m_currentFrameMutex);
-    m_lastFrameTime = MonotonicTime::now();
     m_currentFrame = frameSurface;
 }
 
+std::optional<CaptureDevice> ScreenDisplayCaptureSourceMac::screenCaptureDeviceWithPersistentID(const String& deviceID)
+{
+    bool ok;
+    auto displayID = deviceID.toUIntStrict(&ok);
+    if (!ok) {
+        RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::screenCaptureDeviceWithPersistentID: display ID does not convert to 32-bit integer");
+        return std::nullopt;
+    }
+
+    auto actualDisplayID = updateDisplayID(displayID);
+    if (!actualDisplayID)
+        return std::nullopt;
+
+    auto device = CaptureDevice(String::number(actualDisplayID.value()), CaptureDevice::DeviceType::Screen, "ScreenCaptureDevice"_s);
+    device.setEnabled(true);
+
+    return device;
+}
+
+void ScreenDisplayCaptureSourceMac::screenCaptureDevices(Vector<CaptureDevice>& displays)
+{
+    uint32_t displayCount = 0;
+    auto err = CGGetActiveDisplayList(0, nullptr, &displayCount);
+    if (err) {
+        RELEASE_LOG(Media, "CGGetActiveDisplayList() returned error %d when trying to get display count", (int)err);
+        return;
+    }
+
+    if (!displayCount) {
+        RELEASE_LOG(Media, "CGGetActiveDisplayList() returned a display count of 0");
+        return;
+    }
+
+    CGDirectDisplayID activeDisplays[displayCount];
+    err = CGGetActiveDisplayList(displayCount, &(activeDisplays[0]), &displayCount);
+    if (err) {
+        RELEASE_LOG(Media, "CGGetActiveDisplayList() returned error %d when trying to get the active display list", (int)err);
+        return;
+    }
+
+    int count = 0;
+    for (auto displayID : activeDisplays) {
+        CaptureDevice displayDevice(String::number(displayID), CaptureDevice::DeviceType::Screen, makeString("Screen ", String::number(count++)));
+        displayDevice.setEnabled(CGDisplayIDToOpenGLDisplayMask(displayID));
+        displays.append(WTFMove(displayDevice));
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM) && PLATFORM(MAC)