<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[236494] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/236494">236494</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2018-09-25 19:33:02 -0700 (Tue, 25 Sep 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>[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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreSourcesCocoatxt">trunk/Source/WebCore/SourcesCocoa.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscvPixelBufferResizermm">trunk/Source/WebCore/platform/graphics/cv/PixelBufferResizer.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacDisplayCaptureManagerCocoacpp">trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacDisplayCaptureManagerCocoah">trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacDisplayCaptureSourceCocoacpp">trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacDisplayCaptureSourceCocoah">trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMaccpp">trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacScreenDisplayCaptureSourceMach">trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacScreenDisplayCaptureSourceMacmm">trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessUserMediaPermissionRequestManagerProxyh">trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxycpp">trunk/Source/WebKit/UIProcess/WebPageProxy.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformmediastreammacWindowDisplayCaptureSourceMach">trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacWindowDisplayCaptureSourceMacmm">trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,53 @@
</span><ins>+2018-09-25  Eric Carlson  <eric.carlson@apple.com>
+
+        [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):
+
</ins><span class="cx"> 2018-09-25  Justin Fan  <justin_fan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         WebGL 2 Conformance: primitive restart and draw_primitive_restart WebGL2 sample
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcesCocoatxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/SourcesCocoa.txt (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -552,6 +552,7 @@
</span><span class="cx"> platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp
</span><span class="cx"> platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp
</span><span class="cx"> platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm
</span><ins>+platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm
</ins><span class="cx"> 
</span><span class="cx"> platform/audio/mac/AudioSampleDataSource.mm
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -204,6 +204,7 @@
</span><span class="cx">          07C1C0E21BFB600100BD2256 /* MediaTrackSupportedConstraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 07C1C0E01BFB600100BD2256 /* MediaTrackSupportedConstraints.h */; };
</span><span class="cx">          07C1C0E51BFB60ED00BD2256 /* RealtimeMediaSourceSupportedConstraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 07C1C0E41BFB60ED00BD2256 /* RealtimeMediaSourceSupportedConstraints.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          07CE77D516712A6A00C55A47 /* InbandTextTrackPrivateClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+               07D60928214C5BFD00E7396C /* WindowDisplayCaptureSourceMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D60926214C5BFC00E7396C /* WindowDisplayCaptureSourceMac.h */; };
</ins><span class="cx">           07D637401BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          07D6A4F41BED5F8800174146 /* MockRealtimeAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6A4F21BED5F8800174146 /* MockRealtimeAudioSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          07D6A4F81BF2307D00174146 /* AudioTrackPrivateMediaStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6A4F61BF2307D00174146 /* AudioTrackPrivateMediaStream.h */; };
</span><span class="lines">@@ -5443,6 +5444,8 @@
</span><span class="cx">          07C8AD111D073D630087C5CE /* AVFoundationMIMETypeCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVFoundationMIMETypeCache.mm; sourceTree = "<group>"; };
</span><span class="cx">          07C8AD121D073D630087C5CE /* AVFoundationMIMETypeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AVFoundationMIMETypeCache.h; sourceTree = "<group>"; };
</span><span class="cx">          07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivateClient.h; sourceTree = "<group>"; };
</span><ins>+               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>"; };
</ins><span class="cx">           07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAudioSourceProviderAVFObjC.h; sourceTree = "<group>"; };
</span><span class="cx">          07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebAudioSourceProviderAVFObjC.mm; sourceTree = "<group>"; };
</span><span class="cx">          07D6A4F11BED5F8800174146 /* MockRealtimeAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockRealtimeAudioSource.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -15388,6 +15391,8 @@
</span><span class="cx">                          070A9F601FFECC71003DF649 /* ScreenDisplayCaptureSourceMac.mm */,
</span><span class="cx">                          07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */,
</span><span class="cx">                          07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */,
</span><ins>+                               07D60926214C5BFC00E7396C /* WindowDisplayCaptureSourceMac.h */,
+                               07D60924214C5BFB00E7396C /* WindowDisplayCaptureSourceMac.mm */,
</ins><span class="cx">                   );
</span><span class="cx">                  path = mac;
</span><span class="cx">                  sourceTree = "<group>";
</span><span class="lines">@@ -31115,6 +31120,7 @@
</span><span class="cx">                          1411DCB1164C39A800D49BC1 /* WidthCache.h in Headers */,
</span><span class="cx">                          939B02EF0EA2DBC400C54570 /* WidthIterator.h in Headers */,
</span><span class="cx">                          0F15ED5C1B7EC7C500EDDFEB /* WillChangeData.h in Headers */,
</span><ins>+                               07D60928214C5BFD00E7396C /* WindowDisplayCaptureSourceMac.h in Headers */,
</ins><span class="cx">                           BC8243E90D0CFD7500460C8F /* WindowFeatures.h in Headers */,
</span><span class="cx">                          7E99AF530B13846468FB01A5 /* WindowFocusAllowedIndicator.h in Headers */,
</span><span class="cx">                          463521AD2081092A00C28922 /* WindowProxy.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscvPixelBufferResizermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cv/PixelBufferResizer.mm (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -68,6 +68,10 @@
</span><span class="cx"> 
</span><span class="cx"> RetainPtr<CVPixelBufferRef> PixelBufferResizer::resize(CVPixelBufferRef inputBuffer)
</span><span class="cx"> {
</span><ins>+    ASSERT(m_bufferPool && !m_size.isEmpty());
+    if (!m_bufferPool || m_size.isEmpty())
+        return nullptr;
+
</ins><span class="cx">     RetainPtr<CVPixelBufferRef> result;
</span><span class="cx">     CVPixelBufferRef outputBuffer = nullptr;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacDisplayCaptureManagerCocoacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><del>-#include "CoreVideoSoftLink.h"
</del><span class="cx"> #include "Logging.h"
</span><span class="cx"> #include <wtf/Algorithms.h>
</span><span class="cx"> #include <wtf/NeverDestroyed.h>
</span><span class="lines">@@ -35,9 +34,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx"> #include "ScreenDisplayCaptureSourceMac.h"
</span><ins>+#include "WindowDisplayCaptureSourceMac.h"
</ins><span class="cx"> #include <CoreGraphics/CGDirectDisplay.h>
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#include "CoreVideoSoftLink.h"
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> DisplayCaptureManagerCocoa& DisplayCaptureManagerCocoa::singleton()
</span><span class="lines">@@ -50,6 +52,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_devices.clear();
</span><span class="cx"> 
</span><ins>+    updateWindowCaptureDevices();
</ins><span class="cx">     updateDisplayCaptureDevices();
</span><span class="cx"> 
</span><span class="cx">     return m_devices;
</span><span class="lines">@@ -62,6 +65,13 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void DisplayCaptureManagerCocoa::updateWindowCaptureDevices()
+{
+#if PLATFORM(MAC)
+    WindowDisplayCaptureSourceMac::windowCaptureDevices(m_devices);
+#endif
+}
+
</ins><span class="cx"> std::optional<CaptureDevice> DisplayCaptureManagerCocoa::screenCaptureDeviceWithPersistentID(const String& deviceID)
</span><span class="cx"> {
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="lines">@@ -72,6 +82,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+std::optional<CaptureDevice> DisplayCaptureManagerCocoa::windowCaptureDeviceWithPersistentID(const String& deviceID)
+{
+#if PLATFORM(MAC)
+    return WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID(deviceID);
+#else
+    UNUSED_PARAM(deviceID);
+    return std::nullopt;
+#endif
+}
+
</ins><span class="cx"> std::optional<CaptureDevice> DisplayCaptureManagerCocoa::captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id)
</span><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><span class="lines">@@ -78,9 +98,12 @@
</span><span class="cx">     case CaptureDevice::DeviceType::Screen:
</span><span class="cx">         return screenCaptureDeviceWithPersistentID(id);
</span><span class="cx">         break;
</span><del>-            
</del><ins>+
+    case CaptureDevice::DeviceType::Window:
+        return windowCaptureDeviceWithPersistentID(id);
+        break;
+
</ins><span class="cx">     case CaptureDevice::DeviceType::Application:
</span><del>-    case CaptureDevice::DeviceType::Window:
</del><span class="cx">     case CaptureDevice::DeviceType::Browser:
</span><span class="cx">         break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacDisplayCaptureManagerCocoah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.h (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -41,11 +41,13 @@
</span><span class="cx">     virtual ~DisplayCaptureManagerCocoa() = default;
</span><span class="cx"> 
</span><span class="cx">     void updateDisplayCaptureDevices();
</span><ins>+    void updateWindowCaptureDevices();
</ins><span class="cx"> 
</span><span class="cx">     const Vector<CaptureDevice>& captureDevices() final;
</span><span class="cx"> 
</span><span class="cx">     std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&) final;
</span><span class="cx">     std::optional<CaptureDevice> screenCaptureDeviceWithPersistentID(const String&);
</span><ins>+    std::optional<CaptureDevice> windowCaptureDeviceWithPersistentID(const String&);
</ins><span class="cx"> 
</span><span class="cx">     Vector<CaptureDevice> m_devices;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacDisplayCaptureSourceCocoacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -29,9 +29,13 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> 
</span><span class="cx"> #include "Logging.h"
</span><ins>+#include "MediaSampleAVFObjC.h"
+#include "PixelBufferConformerCV.h"
+#include "PixelBufferResizer.h"
</ins><span class="cx"> #include "RealtimeMediaSource.h"
</span><span class="cx"> #include "RealtimeMediaSourceCenter.h"
</span><span class="cx"> #include "RealtimeMediaSourceSettings.h"
</span><ins>+#include "RealtimeVideoUtilities.h"
</ins><span class="cx"> #include "Timer.h"
</span><span class="cx"> #include <CoreMedia/CMSync.h>
</span><span class="cx"> #include <mach/mach_time.h>
</span><span class="lines">@@ -47,8 +51,8 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> using namespace PAL;
</span><span class="cx"> 
</span><del>-DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(const String& name)
-    : RealtimeMediaSource("", Type::Video, name)
</del><ins>+DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(String&& name)
+    : RealtimeMediaSource("", Type::Video, WTFMove(name))
</ins><span class="cx">     , m_timer(RunLoop::current(), this, &DisplayCaptureSourceCocoa::emitFrame)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -80,17 +84,21 @@
</span><span class="cx">     if (!m_currentSettings) {
</span><span class="cx">         RealtimeMediaSourceSettings settings;
</span><span class="cx">         settings.setFrameRate(frameRate());
</span><del>-        auto size = this->size();
-        if (size.width() && size.height()) {
</del><ins>+        auto size = frameSize();
+        if (!size.isEmpty()) {
</ins><span class="cx">             settings.setWidth(size.width());
</span><span class="cx">             settings.setHeight(size.height());
</span><span class="cx">         }
</span><ins>+        settings.setDisplaySurface(surfaceType());
+        settings.setLogicalSurface(false);
</ins><span class="cx"> 
</span><span class="cx">         RealtimeMediaSourceSupportedConstraints supportedConstraints;
</span><span class="cx">         supportedConstraints.setSupportsFrameRate(true);
</span><span class="cx">         supportedConstraints.setSupportsWidth(true);
</span><span class="cx">         supportedConstraints.setSupportsHeight(true);
</span><del>-        supportedConstraints.setSupportsAspectRatio(true);
</del><ins>+        supportedConstraints.setSupportsDisplaySurface(true);
+        supportedConstraints.setSupportsLogicalSurface(true);
+
</ins><span class="cx">         settings.setSupportedConstraints(supportedConstraints);
</span><span class="cx"> 
</span><span class="cx">         m_currentSettings = WTFMove(settings);
</span><span class="lines">@@ -103,10 +111,12 @@
</span><span class="cx">     if (settings.contains(RealtimeMediaSourceSettings::Flag::FrameRate) && m_timer.isActive())
</span><span class="cx">         m_timer.startRepeating(1_s / frameRate());
</span><span class="cx"> 
</span><del>-    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height }))
</del><ins>+    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height })) {
</ins><span class="cx">         m_bufferAttributes = nullptr;
</span><ins>+        m_lastSampleBuffer = nullptr;
+    }
</ins><span class="cx"> 
</span><del>-    m_currentSettings = std::nullopt;
</del><ins>+    m_currentSettings = { };
</ins><span class="cx"> 
</span><span class="cx">     RealtimeMediaSource::settingsDidChange(settings);
</span><span class="cx"> }
</span><span class="lines">@@ -136,12 +146,76 @@
</span><span class="cx">     return m_elapsedTime + (MonotonicTime::now() - m_startTime);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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;
+}
+
</ins><span class="cx"> void DisplayCaptureSourceCocoa::emitFrame()
</span><span class="cx"> {
</span><span class="cx">     if (muted())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    generateFrame();
</del><ins>+    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()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RetainPtr<CMSampleBufferRef> DisplayCaptureSourceCocoa::sampleBufferFromPixelBuffer(CVPixelBufferRef pixelBuffer)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacDisplayCaptureSourceCocoah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -44,15 +44,19 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class CaptureDeviceInfo;
</span><ins>+class PixelBufferConformerCV;
+class PixelBufferResizer;
</ins><span class="cx"> 
</span><span class="cx"> class DisplayCaptureSourceCocoa : public RealtimeMediaSource {
</span><span class="cx"> public:
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    DisplayCaptureSourceCocoa(const String& name);
</del><ins>+    DisplayCaptureSourceCocoa(String&&);
</ins><span class="cx">     virtual ~DisplayCaptureSourceCocoa();
</span><span class="cx"> 
</span><del>-    virtual void generateFrame() = 0;
</del><ins>+    virtual RetainPtr<CVPixelBufferRef> generateFrame() = 0;
+    virtual RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const = 0;
+
</ins><span class="cx">     void startProducingData() override;
</span><span class="cx">     void stopProducingData() override;
</span><span class="cx"> 
</span><span class="lines">@@ -65,6 +69,10 @@
</span><span class="cx"> 
</span><span class="cx">     void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
</span><span class="cx"> 
</span><ins>+    const IntSize& intrinsicSize() const { return m_intrinsicSize; }
+    void setIntrinsicSize(const IntSize&);
+    IntSize frameSize() const;
+
</ins><span class="cx"> private:
</span><span class="cx"> 
</span><span class="cx">     bool isCaptureSource() const final { return true; }
</span><span class="lines">@@ -74,6 +82,7 @@
</span><span class="cx"> 
</span><span class="cx">     void emitFrame();
</span><span class="cx"> 
</span><ins>+    IntSize m_intrinsicSize;
</ins><span class="cx">     std::optional<RealtimeMediaSourceCapabilities> m_capabilities;
</span><span class="cx">     std::optional<RealtimeMediaSourceSettings> m_currentSettings;
</span><span class="cx">     RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
</span><span class="lines">@@ -83,6 +92,11 @@
</span><span class="cx"> 
</span><span class="cx">     RetainPtr<CFMutableDictionaryRef> m_bufferAttributes;
</span><span class="cx">     RunLoop::Timer<DisplayCaptureSourceCocoa> m_timer;
</span><ins>+
+    std::unique_ptr<PixelBufferResizer> m_pixelBufferResizer;
+    std::unique_ptr<PixelBufferConformerCV> m_pixelBufferConformer;
+    RetainPtr<CVPixelBufferRef> m_lastFullSizedPixelBuffer;
+    RetainPtr<CMSampleBufferRef> m_lastSampleBuffer;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMaccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -58,10 +58,12 @@
</span><span class="cx">         case CaptureDevice::DeviceType::Screen:
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">             return ScreenDisplayCaptureSourceMac::create(device.persistentId(), constraints);
</span><del>-            break;
</del><span class="cx"> #endif
</span><ins>+        case CaptureDevice::DeviceType::Window:
+#if PLATFORM(MAC)
+            return WindowDisplayCaptureSourceMac::create(device.persistentId(), constraints);
+#endif
</ins><span class="cx">         case CaptureDevice::DeviceType::Application:
</span><del>-        case CaptureDevice::DeviceType::Window:
</del><span class="cx">         case CaptureDevice::DeviceType::Browser:
</span><span class="cx">         case CaptureDevice::DeviceType::Microphone:
</span><span class="cx">         case CaptureDevice::DeviceType::Unknown:
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacScreenDisplayCaptureSourceMach"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -56,7 +56,9 @@
</span><span class="cx"> 
</span><span class="cx">     void frameAvailable(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisplayStreamUpdateRef);
</span><span class="cx"> 
</span><del>-    void generateFrame() final;
</del><ins>+    RetainPtr<CVPixelBufferRef> generateFrame() final;
+    RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Monitor; }
+
</ins><span class="cx">     void startProducingData() final;
</span><span class="cx">     void stopProducingData() final;
</span><span class="cx">     void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacScreenDisplayCaptureSourceMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ScreenDisplayCaptureSourceMac::ScreenDisplayCaptureSourceMac(uint32_t displayID)
</span><del>-    : DisplayCaptureSourceCocoa("Screen")
</del><ins>+    : DisplayCaptureSourceCocoa("Screen") // FIXME: figure out what to call this
</ins><span class="cx">     , m_displayID(displayID)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -126,17 +126,15 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!m_displayStream) {
</span><del>-        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));
</del><ins>+        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;
</ins><span class="cx">         }
</span><ins>+        setIntrinsicSize(IntSize(screenWidth, screenHeight));
</ins><span class="cx"> 
</span><span class="cx">         if (!m_captureQueue)
</span><span class="cx">             m_captureQueue = adoptOSObject(dispatch_queue_create("ScreenDisplayCaptureSourceMac Capture Queue", DISPATCH_QUEUE_SERIAL));
</span><span class="lines">@@ -167,7 +165,8 @@
</span><span class="cx">             weakThis->frameAvailable(status, displayTime, frameSurface, updateRef);
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-        m_displayStream = adoptCF(CGDisplayStreamCreateWithDispatchQueue(m_displayID, size().width(), size().height(), kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, streamOptions.get(), m_captureQueue.get(), m_frameAvailableBlock));
</del><ins>+        auto size = frameSize();
+        m_displayStream = adoptCF(CGDisplayStreamCreateWithDispatchQueue(m_displayID, size.width(), size.height(), kCVPixelFormatType_420YpCbCr8Planar, streamOptions.get(), m_captureQueue.get(), m_frameAvailableBlock));
</ins><span class="cx">         if (!m_displayStream) {
</span><span class="cx">             RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::createDisplayStream(%p), CGDisplayStreamCreate failed", this);
</span><span class="cx">             captureFailed();
</span><span class="lines">@@ -206,10 +205,10 @@
</span><span class="cx">     m_isRunning = false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScreenDisplayCaptureSourceMac::generateFrame()
</del><ins>+RetainPtr<CVPixelBufferRef> ScreenDisplayCaptureSourceMac::generateFrame()
</ins><span class="cx"> {
</span><span class="cx">     if (!m_currentFrame.ioSurface())
</span><del>-        return;
</del><ins>+        return nullptr;
</ins><span class="cx"> 
</span><span class="cx">     DisplaySurface currentFrame;
</span><span class="cx">     {
</span><span class="lines">@@ -217,15 +216,7 @@
</span><span class="cx">         currentFrame = m_currentFrame.ioSurface();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto pixelBuffer = pixelBufferFromIOSurface(currentFrame.ioSurface());
-    if (!pixelBuffer)
-        return;
-
-    auto sampleBuffer = sampleBufferFromPixelBuffer(pixelBuffer.get());
-    if (!sampleBuffer)
-        return;
-
-    videoSampleAvailable(MediaSampleAVFObjC::create(sampleBuffer.get()));
</del><ins>+    return pixelBufferFromIOSurface(currentFrame.ioSurface());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScreenDisplayCaptureSourceMac::startDisplayStream()
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacWindowDisplayCaptureSourceMach"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h (0 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+/*
+ * 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)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacWindowDisplayCaptureSourceMacmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm (0 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,247 @@
</span><ins>+/*
+ * 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 = CVPixelBufferGetBaseAddress(pixelBuffer);
+    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)
</ins></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2018-09-25  Eric Carlson  <eric.carlson@apple.com>
+
+        [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.
+
</ins><span class="cx"> 2018-09-25  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r236471 and r236480.
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessUserMediaPermissionRequestManagerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx">     void captureDevicesChanged();
</span><span class="cx"> 
</span><span class="cx">     void captureStateChanged(WebCore::MediaProducer::MediaStateFlags oldState, WebCore::MediaProducer::MediaStateFlags newState);
</span><ins>+    void syncWithWebCorePrefs() const;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     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&&);
</span><span class="lines">@@ -76,7 +77,6 @@
</span><span class="cx"> #endif
</span><span class="cx">     void getUserMediaPermissionInfo(uint64_t userMediaID, uint64_t frameID, UserMediaPermissionCheckProxy::CompletionHandler&&, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin);
</span><span class="cx"> 
</span><del>-    void syncWithWebCorePrefs() const;
</del><span class="cx">     void watchdogTimerFired();
</span><span class="cx"> 
</span><span class="cx">     HashMap<uint64_t, RefPtr<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests;
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (236493 => 236494)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -6448,6 +6448,7 @@
</span><span class="cx"> void WebPageProxy::beginMonitoringCaptureDevices()
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><ins>+    userMediaPermissionRequestManager().syncWithWebCorePrefs();
</ins><span class="cx">     UserMediaProcessManager::singleton().beginMonitoringCaptureDevices();
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>