Diff
Modified: trunk/LayoutTests/ChangeLog (260560 => 260561)
--- trunk/LayoutTests/ChangeLog 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/LayoutTests/ChangeLog 2020-04-23 08:59:31 UTC (rev 260561)
@@ -1,3 +1,25 @@
+2020-04-23 Youenn Fablet <[email protected]>
+
+ getDisplayMedia is not respecting aspect ratio with max constraints
+ https://bugs.webkit.org/show_bug.cgi?id=210858
+
+ Reviewed by Eric Carlson.
+
+ * fast/mediastream/getDisplayMedia-max-constraints-expected.txt: Added.
+ * fast/mediastream/getDisplayMedia-max-constraints.html: Added.
+ * fast/mediastream/getDisplayMedia-max-constraints1-expected.txt: Added.
+ * fast/mediastream/getDisplayMedia-max-constraints1.html: Added.
+ * fast/mediastream/getDisplayMedia-max-constraints2-expected.txt: Added.
+ * fast/mediastream/getDisplayMedia-max-constraints2.html: Added.
+ * fast/mediastream/getDisplayMedia-max-constraints3-expected.txt: Added.
+ * fast/mediastream/getDisplayMedia-max-constraints3.html: Added.
+ * fast/mediastream/resources/getDisplayMedia-utils.js: Added.
+ (async callGetDisplayMedia):
+ (async waitForHeight):
+ (async waitForWidth):
+ * platform/ios/TestExpectations:
+ Skip new tests as getDisplayMedia is not supported on iOS.
+
2020-04-23 Diego Pino Garcia <[email protected]>
[GTK][WPE] Gardening, update baselines and test expectations
Modified: trunk/LayoutTests/fast/mediastream/constraint-intrinsic-size.html (260560 => 260561)
--- trunk/LayoutTests/fast/mediastream/constraint-intrinsic-size.html 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/LayoutTests/fast/mediastream/constraint-intrinsic-size.html 2020-04-23 08:59:31 UTC (rev 260561)
@@ -5,22 +5,11 @@
<title>video track width and height should be set correctly when only one constraint is passed to getDisplayMedia</title>
<script src=""
<script src=""
+ <script src=""
</head>
<body>
<script>
- if (window.internals)
- window.internals.settings.setScreenCaptureEnabled(true);
-
- function callGetDisplayMedia(options)
- {
- let promise;
- window.internals.withUserGesture(() => {
- promise = navigator.mediaDevices.getDisplayMedia(options);
- });
- return promise;
- }
-
let defaultWidth;
let defaultHeight;
promise_test(async () => {
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints-expected.txt (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints-expected.txt 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,6 @@
+
+PASS setup
+PASS Maximize the width if max height is too big
+PASS Maximize the height if max width is too big
+PASS No effect of the max values if they are too big
+
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints.html (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints.html 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,93 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>getDisplayMedia track support of max constraints</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+
+ <script>
+ if (window.internals)
+ window.internals.settings.setScreenCaptureEnabled(true);
+
+ async function callGetDisplayMedia(options)
+ {
+ let promise;
+ window.internals.withUserGesture(() => {
+ promise = navigator.mediaDevices.getDisplayMedia(options);
+ });
+ const stream = await promise;
+ const track = stream.getVideoTracks()[0];
+
+ // getSettings is not computing the correct parameters right away. We should probably fix this.
+ while (true) {
+ const settings = track.getSettings();
+ if (settings.width && settings.height)
+ break;
+ await new Promise(resolve => setTimeout(resolve, 50));
+ }
+ return stream;
+ }
+
+ // getSettings is not computing the correct parameters right away. We should probably fix this.
+ async function waitForHeight(track, value) {
+ while (true) {
+ const settings = track.getSettings();
+ if (settings.height === value)
+ break;
+ await new Promise(resolve => setTimeout(resolve, 50));
+ }
+ }
+
+ // getSettings is not computing the correct parameters right away. We should probably fix this.
+ async function waitForWidth(track, value) {
+ while (true) {
+ const settings = track.getSettings();
+ if (settings.width === value)
+ break;
+ await new Promise(resolve => setTimeout(resolve, 50));
+ }
+ }
+
+ let defaultWidth;
+ let defaultHeight;
+ promise_test(async () => {
+ stream = await callGetDisplayMedia({ video: true });
+ let settings = stream.getVideoTracks()[0].getSettings();
+ defaultWidth = settings.width;
+ defaultHeight = settings.height;
+ }, "setup");
+
+ promise_test(async (test) => {
+ const stream = await callGetDisplayMedia({ video: { height: { max: 500 }, width : { max : 500 } } });
+
+ const expectedHeight =Math.floor(500 * (defaultHeight / defaultWidth))
+ await waitForHeight(stream.getVideoTracks()[0], expectedHeight);
+
+ const settings = stream.getVideoTracks()[0].getSettings()
+ assert_equals(settings.width, 500);
+ }, "Maximize the width if max height is too big");
+
+ promise_test(async (test) => {
+ const stream = await callGetDisplayMedia({ video: { height: { max: 100 }, width : { max : 500 } } });
+
+ const expectedWidth = Math.floor(100 * (defaultWidth / defaultHeight))
+ await waitForWidth(stream.getVideoTracks()[0], expectedWidth);
+
+ const settings = stream.getVideoTracks()[0].getSettings()
+ assert_equals(settings.height, 100);
+ }, "Maximize the height if max width is too big");
+
+ promise_test(async (test) => {
+ const stream = await callGetDisplayMedia({ video: { height: { max: 500000 }, width : { max : 500000 } } });
+
+ await waitForHeight(stream.getVideoTracks()[0], defaultHeight);
+
+ const settings = stream.getVideoTracks()[0].getSettings()
+ assert_equals(settings.width, defaultWidth);
+ }, "No effect of the max values if they are too big");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints1-expected.txt (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints1-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints1-expected.txt 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,4 @@
+
+PASS setup
+PASS Maximize the width if max height is too big
+
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints1.html (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints1.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints1.html 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>getDisplayMedia track support of max constraints</title>
+ <script src=""
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script>
+let defaultWidth;
+let defaultHeight;
+promise_test(async () => {
+ stream = await callGetDisplayMedia({ video: true });
+ let settings = stream.getVideoTracks()[0].getSettings();
+ defaultWidth = settings.width;
+ defaultHeight = settings.height;
+}, "setup");
+
+promise_test(async (test) => {
+ const stream = await callGetDisplayMedia({ video: { height: { max: 500 }, width : { max : 500 } } });
+
+ const expectedHeight =Math.floor(500 * (defaultHeight / defaultWidth))
+ await waitForHeight(stream.getVideoTracks()[0], expectedHeight);
+
+ const settings = stream.getVideoTracks()[0].getSettings()
+ assert_equals(settings.width, 500);
+}, "Maximize the width if max height is too big");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints2-expected.txt (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints2-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints2-expected.txt 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,4 @@
+
+PASS setup
+PASS Maximize the height if max width is too big
+
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints2.html (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints2.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints2.html 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>getDisplayMedia track support of max constraints</title>
+ <script src=""
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script>
+let defaultWidth;
+let defaultHeight;
+promise_test(async () => {
+ stream = await callGetDisplayMedia({ video: true });
+ let settings = stream.getVideoTracks()[0].getSettings();
+ defaultWidth = settings.width;
+ defaultHeight = settings.height;
+}, "setup");
+
+promise_test(async (test) => {
+ const stream = await callGetDisplayMedia({ video: { height: { max: 100 }, width : { max : 500 } } });
+
+ const expectedWidth = Math.floor(100 * (defaultWidth / defaultHeight))
+ await waitForWidth(stream.getVideoTracks()[0], expectedWidth);
+
+ const settings = stream.getVideoTracks()[0].getSettings()
+ assert_equals(settings.height, 100);
+}, "Maximize the height if max width is too big");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints3-expected.txt (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints3-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints3-expected.txt 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,4 @@
+
+PASS setup
+PASS No effect of the max values if they are too big
+
Added: trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints3.html (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints3.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getDisplayMedia-max-constraints3.html 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>getDisplayMedia track support of max constraints</title>
+ <script src=""
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script>
+let defaultWidth;
+let defaultHeight;
+promise_test(async () => {
+ stream = await callGetDisplayMedia({ video: true });
+ let settings = stream.getVideoTracks()[0].getSettings();
+ defaultWidth = settings.width;
+ defaultHeight = settings.height;
+}, "setup");
+
+promise_test(async (test) => {
+ const stream = await callGetDisplayMedia({ video: { height: { max: 500000 }, width : { max : 500000 } } });
+
+ await waitForHeight(stream.getVideoTracks()[0], defaultHeight);
+
+ const settings = stream.getVideoTracks()[0].getSettings()
+ assert_equals(settings.width, defaultWidth);
+}, "No effect of the max values if they are too big");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/fast/mediastream/resources/getDisplayMedia-utils.js (0 => 260561)
--- trunk/LayoutTests/fast/mediastream/resources/getDisplayMedia-utils.js (rev 0)
+++ trunk/LayoutTests/fast/mediastream/resources/getDisplayMedia-utils.js 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,39 @@
+if (window.internals)
+ window.internals.settings.setScreenCaptureEnabled(true);
+
+async function callGetDisplayMedia(options)
+{
+ let promise;
+ window.internals.withUserGesture(() => {
+ promise = navigator.mediaDevices.getDisplayMedia(options);
+ });
+ const stream = await promise;
+ const track = stream.getVideoTracks()[0];
+
+ // getSettings is not computing the correct parameters right away. We should probably fix this.
+ while (true) {
+ const settings = track.getSettings();
+ if (settings.width && settings.height)
+ break;
+ await new Promise(resolve => setTimeout(resolve, 50));
+ }
+ return stream;
+}
+
+async function waitForHeight(track, value) {
+ while (true) {
+ const settings = track.getSettings();
+ if (settings.height === value)
+ break;
+ await new Promise(resolve => setTimeout(resolve, 50));
+ }
+}
+
+async function waitForWidth(track, value) {
+ while (true) {
+ const settings = track.getSettings();
+ if (settings.width === value)
+ break;
+ await new Promise(resolve => setTimeout(resolve, 50));
+ }
+}
Modified: trunk/LayoutTests/platform/ios/TestExpectations (260560 => 260561)
--- trunk/LayoutTests/platform/ios/TestExpectations 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2020-04-23 08:59:31 UTC (rev 260561)
@@ -2895,6 +2895,9 @@
# screen capture not supported on iOS.
fast/mediastream/screencapture-user-gesture.html [ Skip ]
+fast/mediastream/getDisplayMedia-max-constraints1.html [ Skip ]
+fast/mediastream/getDisplayMedia-max-constraints2.html [ Skip ]
+fast/mediastream/getDisplayMedia-max-constraints3.html [ Skip ]
webkit.org/b/177401 webrtc/captureCanvas-webrtc.html [ Pass Timeout Failure ]
Modified: trunk/Source/WebCore/ChangeLog (260560 => 260561)
--- trunk/Source/WebCore/ChangeLog 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/ChangeLog 2020-04-23 08:59:31 UTC (rev 260561)
@@ -1,3 +1,75 @@
+2020-04-23 Youenn Fablet <[email protected]>
+
+ getDisplayMedia is not respecting aspect ratio with max constraints
+ https://bugs.webkit.org/show_bug.cgi?id=210858
+
+ Reviewed by Eric Carlson.
+
+ Add computation of exact frame size to respect aspect ratio in DisplayCaptureSourceCocoa::updateFrameSize.
+ Refactor code to have one source class DisplayCaptureSourceCocoa and specific capturer for screen and window.
+ This simplifies code and allows reusing DisplayCaptureSourceCocoa with a mock capturer.
+ Update mock code to use DisplayCaptureSourceCocoa.
+
+ Tests: fast/mediastream/getDisplayMedia-max-constraints.html
+ fast/mediastream/getDisplayMedia-max-constraints1.html
+ fast/mediastream/getDisplayMedia-max-constraints2.html
+ fast/mediastream/getDisplayMedia-max-constraints3.html
+
+ * SourcesCocoa.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp:
+ (WebCore::DisplayCaptureManagerCocoa::updateDisplayCaptureDevices):
+ (WebCore::DisplayCaptureManagerCocoa::updateWindowCaptureDevices):
+ (WebCore::DisplayCaptureManagerCocoa::screenCaptureDeviceWithPersistentID):
+ (WebCore::DisplayCaptureManagerCocoa::windowCaptureDeviceWithPersistentID):
+ * platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp:
+ (WebCore::DisplayCaptureSourceCocoa::create):
+ (WebCore::DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa):
+ (WebCore::DisplayCaptureSourceCocoa::~DisplayCaptureSourceCocoa):
+ (WebCore::DisplayCaptureSourceCocoa::capabilities):
+ (WebCore::DisplayCaptureSourceCocoa::settings):
+ (WebCore::DisplayCaptureSourceCocoa::startProducingData):
+ (WebCore::DisplayCaptureSourceCocoa::stopProducingData):
+ (WebCore::DisplayCaptureSourceCocoa::updateFrameSize):
+ (WebCore::DisplayCaptureSourceCocoa::emitFrame):
+ (WebCore::DisplayCaptureSourceCocoa::Capturer::setLogger):
+ (WebCore::DisplayCaptureSourceCocoa::Capturer::logChannel const):
+ * platform/mediastream/mac/DisplayCaptureSourceCocoa.h:
+ * platform/mediastream/mac/MockRealtimeVideoSourceMac.h:
+ * platform/mediastream/mac/MockRealtimeVideoSourceMac.mm:
+ (WebCore::MockRealtimeVideoSourceMac::createForMockDisplayCapturer):
+ * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+ * platform/mediastream/mac/ScreenDisplayCapturerMac.h: Added.
+ * platform/mediastream/mac/ScreenDisplayCapturerMac.mm: Added.
+ (WebCore::ScreenDisplayCapturerMac::create):
+ (WebCore::ScreenDisplayCapturerMac::ScreenDisplayCapturerMac):
+ (WebCore::ScreenDisplayCapturerMac::~ScreenDisplayCapturerMac):
+ (WebCore::ScreenDisplayCapturerMac::createDisplayStream):
+ (WebCore::ScreenDisplayCapturerMac::start):
+ (WebCore::ScreenDisplayCapturerMac::stop):
+ (WebCore::ScreenDisplayCapturerMac::generateFrame):
+ (WebCore::ScreenDisplayCapturerMac::startDisplayStream):
+ (WebCore::ScreenDisplayCapturerMac::commitConfiguration):
+ (WebCore::ScreenDisplayCapturerMac::displayWasReconfigured):
+ (WebCore::ScreenDisplayCapturerMac::displayReconfigurationCallBack):
+ (WebCore::ScreenDisplayCapturerMac::newFrame):
+ (WebCore::ScreenDisplayCapturerMac::screenCaptureDeviceWithPersistentID):
+ (WebCore::ScreenDisplayCapturerMac::screenCaptureDevices):
+ * platform/mediastream/mac/WindowDisplayCapturerMac.h: Added.
+ * platform/mediastream/mac/WindowDisplayCapturerMac.mm: ddedAdded.
+ (WebCore::WindowDisplayCapturerMac::create):
+ (WebCore::WindowDisplayCapturerMac::WindowDisplayCapturerMac):
+ (WebCore::WindowDisplayCapturerMac::windowImage):
+ (WebCore::WindowDisplayCapturerMac::generateFrame):
+ (WebCore::WindowDisplayCapturerMac::windowCaptureDeviceWithPersistentID):
+ (WebCore::WindowDisplayCapturerMac::windowCaptureDevices):
+ * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+ (WebCore::MockDisplayCapturer::MockDisplayCapturer):
+ (WebCore::MockDisplayCapturer::start):
+ (WebCore::MockDisplayCapturer::generateFrame):
+ * platform/mock/MockRealtimeVideoSource.h:
+ (isType):
+
2020-04-22 Simon Fraser <[email protected]>
Make it possible to eagerly apply scrolling tree state from the main thread
Modified: trunk/Source/WebCore/SourcesCocoa.txt (260560 => 260561)
--- trunk/Source/WebCore/SourcesCocoa.txt 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/SourcesCocoa.txt 2020-04-23 08:59:31 UTC (rev 260561)
@@ -570,8 +570,8 @@
platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp
platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp
platform/mediastream/mac/RealtimeVideoUtilities.mm
-platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm
-platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm
+platform/mediastream/mac/ScreenDisplayCapturerMac.mm
+platform/mediastream/mac/WindowDisplayCapturerMac.mm
platform/audio/mac/AudioSampleDataSource.mm
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (260560 => 260561)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-04-23 08:59:31 UTC (rev 260561)
@@ -215,7 +215,6 @@
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, ); }; };
07D12F5C23DE543F0080997D /* ISOVTTCue.h in Headers */ = {isa = PBXBuildFile; fileRef = CD871C651FB52B6700F0B965 /* ISOVTTCue.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 */; };
@@ -5454,8 +5453,6 @@
0709D7911AE5557E004E42F8 /* WebMediaSessionManagerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebMediaSessionManagerMac.h; sourceTree = "<group>"; };
0709D7941AE55A29004E42F8 /* WebMediaSessionManagerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebMediaSessionManagerClient.h; sourceTree = "<group>"; };
0709FC4D1025DEE30059CDBA /* AccessibilitySlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilitySlider.h; sourceTree = "<group>"; };
- 070A9F5E1FFECC70003DF649 /* ScreenDisplayCaptureSourceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenDisplayCaptureSourceMac.h; sourceTree = "<group>"; };
- 070A9F601FFECC71003DF649 /* ScreenDisplayCaptureSourceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScreenDisplayCaptureSourceMac.mm; sourceTree = "<group>"; };
070DD8F50F01868000727DEB /* mediaControls.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mediaControls.css; sourceTree = "<group>"; };
070E09181875ED93003A1D3C /* PlatformMediaSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformMediaSession.h; sourceTree = "<group>"; };
070E091A1875EF71003A1D3C /* PlatformMediaSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformMediaSession.cpp; sourceTree = "<group>"; };
@@ -5667,8 +5664,6 @@
07C8AD111D073D630087C5CE /* AVAssetMIMETypeCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVAssetMIMETypeCache.mm; sourceTree = "<group>"; };
07C8AD121D073D630087C5CE /* AVAssetMIMETypeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AVAssetMIMETypeCache.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>"; };
@@ -7449,6 +7444,10 @@
416D759F20C6441300D02D2C /* NetworkLoadInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkLoadInformation.h; sourceTree = "<group>"; };
416E0B37209BC3C2004A95D9 /* FetchIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchIdentifier.h; sourceTree = "<group>"; };
416E29A5102FA962007FC14E /* WorkerReportingProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerReportingProxy.h; sourceTree = "<group>"; };
+ 416F807924509F3200B68F02 /* WindowDisplayCapturerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowDisplayCapturerMac.h; sourceTree = "<group>"; };
+ 416F807A24509F3200B68F02 /* ScreenDisplayCapturerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScreenDisplayCapturerMac.mm; sourceTree = "<group>"; };
+ 416F807B24509F3300B68F02 /* WindowDisplayCapturerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowDisplayCapturerMac.mm; sourceTree = "<group>"; };
+ 416F807C24509F3300B68F02 /* ScreenDisplayCapturerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenDisplayCapturerMac.h; sourceTree = "<group>"; };
416FD25D240EE1AE006661D8 /* NowPlayingInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NowPlayingInfo.h; sourceTree = "<group>"; };
4170A2E91D8C0CC000318452 /* JSDOMWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMWrapper.cpp; sourceTree = "<group>"; };
417253A81354BBBC00360F2A /* MediaControlTextTrackContainerElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaControlTextTrackContainerElement.cpp; sourceTree = "<group>"; };
@@ -16539,12 +16538,12 @@
419242472127B7CC00634FCF /* RealtimeOutgoingVideoSourceCocoa.mm */,
41D1938F2152C561006F14CA /* RealtimeVideoUtilities.h */,
4158649F23BF7B9300A0A61E /* RealtimeVideoUtilities.mm */,
- 070A9F5E1FFECC70003DF649 /* ScreenDisplayCaptureSourceMac.h */,
- 070A9F601FFECC71003DF649 /* ScreenDisplayCaptureSourceMac.mm */,
+ 416F807C24509F3300B68F02 /* ScreenDisplayCapturerMac.h */,
+ 416F807A24509F3200B68F02 /* ScreenDisplayCapturerMac.mm */,
07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */,
07D6373F1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.mm */,
- 07D60926214C5BFC00E7396C /* WindowDisplayCaptureSourceMac.h */,
- 07D60924214C5BFB00E7396C /* WindowDisplayCaptureSourceMac.mm */,
+ 416F807924509F3200B68F02 /* WindowDisplayCapturerMac.h */,
+ 416F807B24509F3300B68F02 /* WindowDisplayCapturerMac.mm */,
);
path = mac;
sourceTree = "<group>";
@@ -33567,7 +33566,6 @@
1411DCB1164C39A800D49BC1 /* WidthCache.h in Headers */,
939B02EF0EA2DBC400C54570 /* WidthIterator.h in Headers */,
0F15ED5C1B7EC7C500EDDFEB /* WillChangeData.h in Headers */,
- 07D60928214C5BFD00E7396C /* WindowDisplayCaptureSourceMac.h in Headers */,
9B27FC60234D9ADB00394A46 /* WindowEventLoop.h in Headers */,
BC8243E90D0CFD7500460C8F /* WindowFeatures.h in Headers */,
7E99AF530B13846468FB01A5 /* WindowFocusAllowedIndicator.h in Headers */,
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -89,7 +89,11 @@
VideoCaptureFactory() = default;
};
-class DisplayCaptureFactory {
+class DisplayCaptureFactory
+#if PLATFORM(IOS_FAMILY)
+ : public SingleSourceFactory
+#endif
+{
public:
virtual ~DisplayCaptureFactory() = default;
virtual CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice&, const MediaConstraints*) = 0;
Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureManagerCocoa.cpp 2020-04-23 08:59:31 UTC (rev 260561)
@@ -33,8 +33,8 @@
#include <wtf/NeverDestroyed.h>
#if PLATFORM(MAC)
-#include "ScreenDisplayCaptureSourceMac.h"
-#include "WindowDisplayCaptureSourceMac.h"
+#include "ScreenDisplayCapturerMac.h"
+#include "WindowDisplayCapturerMac.h"
#include <CoreGraphics/CGDirectDisplay.h>
#endif
@@ -61,7 +61,7 @@
void DisplayCaptureManagerCocoa::updateDisplayCaptureDevices()
{
#if PLATFORM(MAC)
- ScreenDisplayCaptureSourceMac::screenCaptureDevices(m_devices);
+ ScreenDisplayCapturerMac::screenCaptureDevices(m_devices);
#endif
}
@@ -68,7 +68,7 @@
void DisplayCaptureManagerCocoa::updateWindowCaptureDevices()
{
#if PLATFORM(MAC)
- WindowDisplayCaptureSourceMac::windowCaptureDevices(m_devices);
+ WindowDisplayCapturerMac::windowCaptureDevices(m_devices);
#endif
}
@@ -75,7 +75,7 @@
Optional<CaptureDevice> DisplayCaptureManagerCocoa::screenCaptureDeviceWithPersistentID(const String& deviceID)
{
#if PLATFORM(MAC)
- return ScreenDisplayCaptureSourceMac::screenCaptureDeviceWithPersistentID(deviceID);
+ return ScreenDisplayCapturerMac::screenCaptureDeviceWithPersistentID(deviceID);
#else
UNUSED_PARAM(deviceID);
return WTF::nullopt;
@@ -85,7 +85,7 @@
Optional<CaptureDevice> DisplayCaptureManagerCocoa::windowCaptureDeviceWithPersistentID(const String& deviceID)
{
#if PLATFORM(MAC)
- return WindowDisplayCaptureSourceMac::windowCaptureDeviceWithPersistentID(deviceID);
+ return WindowDisplayCapturerMac::windowCaptureDeviceWithPersistentID(deviceID);
#else
UNUSED_PARAM(deviceID);
return WTF::nullopt;
Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp 2020-04-23 08:59:31 UTC (rev 260561)
@@ -53,8 +53,45 @@
namespace WebCore {
using namespace PAL;
-DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(String&& name)
+CaptureSourceOrError DisplayCaptureSourceCocoa::create(const CaptureDevice& device, const MediaConstraints* constraints)
+{
+#if PLATFORM(MAC)
+ switch (device.type()) {
+ case CaptureDevice::DeviceType::Screen:
+ return create(ScreenDisplayCapturerMac::create(device.persistentId()), device, constraints);
+ case CaptureDevice::DeviceType::Window:
+ return create(WindowDisplayCapturerMac::create(device.persistentId()), device, constraints);
+ case CaptureDevice::DeviceType::Microphone:
+ case CaptureDevice::DeviceType::Camera:
+ case CaptureDevice::DeviceType::Unknown:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+#else
+ UNUSED_PARAM(device);
+ UNUSED_PARAM(constraints);
+#endif
+ return { };
+}
+
+CaptureSourceOrError DisplayCaptureSourceCocoa::create(Expected<UniqueRef<Capturer>, String>&& capturer, const CaptureDevice& device, const MediaConstraints* constraints)
+{
+ if (!capturer.has_value())
+ return CaptureSourceOrError { WTFMove(capturer.error()) };
+
+ auto source = adoptRef(*new DisplayCaptureSourceCocoa(WTFMove(capturer.value()), String { device.label() }));
+ if (constraints) {
+ auto result = source->applyConstraints(*constraints);
+ if (result)
+ return WTFMove(result.value().badConstraint);
+ }
+
+ return CaptureSourceOrError(WTFMove(source));
+}
+
+DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(UniqueRef<Capturer>&& capturer, String&& name)
: RealtimeMediaSource(Type::Video, WTFMove(name))
+ , m_capturer(WTFMove(capturer))
, m_timer(RunLoop::current(), this, &DisplayCaptureSourceCocoa::emitFrame)
{
}
@@ -62,7 +99,7 @@
DisplayCaptureSourceCocoa::~DisplayCaptureSourceCocoa()
{
#if PLATFORM(IOS_FAMILY)
- RealtimeMediaSourceCenter::singleton().videoCaptureFactory().unsetActiveSource(*this);
+ RealtimeMediaSourceCenter::singleton().displayCaptureFactory().unsetActiveSource(*this);
#endif
}
@@ -72,8 +109,8 @@
RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints());
// FIXME: what should these be?
- capabilities.setWidth(CapabilityValueOrRange(72, 2880));
- capabilities.setHeight(CapabilityValueOrRange(45, 1800));
+ capabilities.setWidth(CapabilityValueOrRange(1, 3840));
+ capabilities.setHeight(CapabilityValueOrRange(1, 2160));
capabilities.setFrameRate(CapabilityValueOrRange(.01, 30.0));
m_capabilities = WTFMove(capabilities);
@@ -91,7 +128,7 @@
settings.setWidth(size.width());
settings.setHeight(size.height());
- settings.setDisplaySurface(surfaceType());
+ settings.setDisplaySurface(m_capturer->surfaceType());
settings.setLogicalSurface(false);
RealtimeMediaSourceSupportedConstraints supportedConstraints;
@@ -122,11 +159,14 @@
void DisplayCaptureSourceCocoa::startProducingData()
{
#if PLATFORM(IOS_FAMILY)
- RealtimeMediaSourceCenter::singleton().videoCaptureFactory().setActiveSource(*this);
+ RealtimeMediaSourceCenter::singleton().displayCaptureFactory().setActiveSource(*this);
#endif
m_startTime = MonotonicTime::now();
m_timer.startRepeating(1_s / frameRate());
+
+ if (!m_capturer->start(frameRate()))
+ captureFailed();
}
void DisplayCaptureSourceCocoa::stopProducingData()
@@ -134,6 +174,8 @@
m_timer.stop();
m_elapsedTime += MonotonicTime::now() - m_startTime;
m_startTime = MonotonicTime::nan();
+
+ m_capturer->stop();
}
Seconds DisplayCaptureSourceCocoa::elapsedTime()
@@ -144,13 +186,32 @@
return m_elapsedTime + (MonotonicTime::now() - m_startTime);
}
-IntSize DisplayCaptureSourceCocoa::frameSize() const
+// We keep the aspect ratio of the intrinsic size for the frame size as getDisplayMedia allows max constraints only.
+void DisplayCaptureSourceCocoa::updateFrameSize()
{
- IntSize frameSize = size();
- if (frameSize.isEmpty())
- return intrinsicSize();
+ auto intrinsicSize = this->intrinsicSize();
- return frameSize;
+ auto frameSize = size();
+ if (!frameSize.height())
+ frameSize.setHeight(intrinsicSize.height());
+ if (!frameSize.width())
+ frameSize.setWidth(intrinsicSize.width());
+
+ auto maxHeight = std::min(frameSize.height(), intrinsicSize.height());
+ auto maxWidth = std::min(frameSize.width(), intrinsicSize.width());
+
+ auto heightForMaxWidth = maxWidth * intrinsicSize.height() / intrinsicSize.width();
+ auto widthForMaxHeight = maxHeight * intrinsicSize.width() / intrinsicSize.height();
+
+ if (heightForMaxWidth <= maxHeight) {
+ setSize({ maxWidth, heightForMaxWidth });
+ return;
+ }
+ if (widthForMaxHeight <= maxWidth) {
+ setSize({ widthForMaxHeight, maxHeight });
+ return;
+ }
+ setSize(intrinsicSize);
}
void DisplayCaptureSourceCocoa::emitFrame()
@@ -164,7 +225,7 @@
auto sampleTime = MediaTime::createWithDouble((elapsedTime() + 100_ms).seconds());
- auto frame = generateFrame();
+ auto frame = m_capturer->generateFrame();
auto imageSize = WTF::switchOn(frame,
[](RetainPtr<IOSurfaceRef> surface) -> IntSize {
if (!surface)
@@ -184,22 +245,23 @@
if (imageSize.isEmpty())
return;
- setIntrinsicSize(imageSize);
+ if (intrinsicSize() != imageSize) {
+ setIntrinsicSize(imageSize);
+ updateFrameSize();
+ }
- auto mediaSampleSize = frameSize();
-
- RefPtr<MediaSample> sample = WTF::switchOn(frame,
- [this, sampleTime, mediaSampleSize](RetainPtr<IOSurfaceRef> surface) -> RefPtr<MediaSample> {
+ auto sample = WTF::switchOn(frame,
+ [this, sampleTime](RetainPtr<IOSurfaceRef> surface) -> RefPtr<MediaSample> {
if (!surface)
return nullptr;
- return m_imageTransferSession->createMediaSample(surface.get(), sampleTime, mediaSampleSize);
+ return m_imageTransferSession->createMediaSample(surface.get(), sampleTime, size());
},
- [this, sampleTime, mediaSampleSize](RetainPtr<CGImageRef> image) -> RefPtr<MediaSample> {
+ [this, sampleTime](RetainPtr<CGImageRef> image) -> RefPtr<MediaSample> {
if (!image)
return nullptr;
- return m_imageTransferSession->createMediaSample(image.get(), sampleTime, mediaSampleSize);
+ return m_imageTransferSession->createMediaSample(image.get(), sampleTime, size());
}
);
@@ -212,6 +274,19 @@
#endif
}
+#if !RELEASE_LOG_DISABLED
+void DisplayCaptureSourceCocoa::Capturer::setLogger(const Logger& newLogger, const void* newLogIdentifier)
+{
+ m_logger = &newLogger;
+ m_logIdentifier = newLogIdentifier;
+}
+
+WTFLogChannel& DisplayCaptureSourceCocoa::Capturer::logChannel() const
+{
+ return LogWebRTC;
+}
+#endif
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -33,6 +33,7 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/RunLoop.h>
+#include <wtf/UniqueRef.h>
#include <wtf/text/WTFString.h>
typedef struct CGImage *CGImageRef;
@@ -49,36 +50,66 @@
class ImageTransferSessionVT;
class PixelBufferConformerCV;
-class DisplayCaptureSourceCocoa : public RealtimeMediaSource {
+class DisplayCaptureSourceCocoa final : public RealtimeMediaSource {
public:
+ using DisplayFrameType = WTF::Variant<RetainPtr<CGImageRef>, RetainPtr<IOSurfaceRef>>;
+ class Capturer
+#if !RELEASE_LOG_DISABLED
+ : public LoggerHelper
+#endif
+ {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
+ virtual ~Capturer() = default;
-protected:
- DisplayCaptureSourceCocoa(String&& name);
- virtual ~DisplayCaptureSourceCocoa();
+ virtual bool start(float frameRate) = 0;
+ virtual void stop() = 0;
+ virtual DisplayFrameType generateFrame() = 0;
+ virtual CaptureDevice::DeviceType deviceType() const = 0;
+ virtual RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const = 0;
+ virtual void commitConfiguration(float frameRate) = 0;
- using DisplayFrameType = WTF::Variant<RetainPtr<CGImageRef>, RetainPtr<IOSurfaceRef>>;
- virtual DisplayFrameType generateFrame() = 0;
+#if !RELEASE_LOG_DISABLED
+ virtual void setLogger(const Logger&, const void*);
+ const Logger* loggerPtr() const { return m_logger.get(); }
+ const Logger& logger() const final { ASSERT(m_logger); return *m_logger.get(); }
+ const void* logIdentifier() const final { return m_logIdentifier; }
+ WTFLogChannel& logChannel() const final;
+#endif
- virtual RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const = 0;
+ private:
+#if !RELEASE_LOG_DISABLED
+ RefPtr<const Logger> m_logger;
+ const void* m_logIdentifier;
+#endif
+ };
- void startProducingData() override;
- void stopProducingData() override;
+ static CaptureSourceOrError create(const CaptureDevice&, const MediaConstraints*);
+ static CaptureSourceOrError create(Expected<UniqueRef<Capturer>, String>&&, const CaptureDevice&, const MediaConstraints*);
Seconds elapsedTime();
+ void updateFrameSize();
- void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
-
- IntSize frameSize() const;
-
private:
+ DisplayCaptureSourceCocoa(UniqueRef<Capturer>&&, String&& name);
+ ~DisplayCaptureSourceCocoa();
+ void startProducingData() final;
+ void stopProducingData() final;
+ void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
bool isCaptureSource() const final { return true; }
-
const RealtimeMediaSourceCapabilities& capabilities() final;
const RealtimeMediaSourceSettings& settings() final;
+ CaptureDevice::DeviceType deviceType() const { return m_capturer->deviceType(); }
+ void commitConfiguration() final { return m_capturer->commitConfiguration(frameRate()); }
+#if !RELEASE_LOG_DISABLED
+ const char* logClassName() const final { return "DisplayCaptureSourceCocoa"; }
+#endif
+
void emitFrame();
+ UniqueRef<Capturer> m_capturer;
Optional<RealtimeMediaSourceCapabilities> m_capabilities;
Optional<RealtimeMediaSourceSettings> m_currentSettings;
RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
Modified: trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -46,8 +46,10 @@
class MockRealtimeVideoSourceMac final : public MockRealtimeVideoSource {
public:
- virtual ~MockRealtimeVideoSourceMac() = default;
+ static Ref<MockRealtimeVideoSource> createForMockDisplayCapturer(String&& deviceID, String&& name, String&& hashSalt);
+ ~MockRealtimeVideoSourceMac() = default;
+
private:
friend class MockRealtimeVideoSource;
MockRealtimeVideoSourceMac(String&& deviceID, String&& name, String&& hashSalt);
Modified: trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm 2020-04-23 08:59:31 UTC (rev 260561)
@@ -71,6 +71,11 @@
return CaptureSourceOrError(RealtimeVideoSource::create(WTFMove(source)));
}
+Ref<MockRealtimeVideoSource> MockRealtimeVideoSourceMac::createForMockDisplayCapturer(String&& deviceID, String&& name, String&& hashSalt)
+{
+ return adoptRef(*new MockRealtimeVideoSourceMac(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt)));
+}
+
MockRealtimeVideoSourceMac::MockRealtimeVideoSourceMac(String&& deviceID, String&& name, String&& hashSalt)
: MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))
{
Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp 2020-04-23 08:59:31 UTC (rev 260561)
@@ -38,8 +38,8 @@
#include "DisplayCaptureManagerCocoa.h"
#include "Logging.h"
#include "MediaStreamPrivate.h"
-#include "ScreenDisplayCaptureSourceMac.h"
-#include "WindowDisplayCaptureSourceMac.h"
+#include "ScreenDisplayCapturerMac.h"
+#include "WindowDisplayCapturerMac.h"
#include <wtf/MainThread.h>
namespace WebCore {
@@ -72,23 +72,11 @@
UNUSED_PARAM(device);
UNUSED_PARAM(constraints);
#endif
- switch (device.type()) {
- case CaptureDevice::DeviceType::Screen:
#if PLATFORM(MAC)
- return ScreenDisplayCaptureSourceMac::create(String { device.persistentId() }, constraints);
+ return DisplayCaptureSourceCocoa::create(device, constraints);
+#else
+ return { };
#endif
- case CaptureDevice::DeviceType::Window:
-#if PLATFORM(MAC)
- return WindowDisplayCaptureSourceMac::create(String { device.persistentId() }, constraints);
-#endif
- case CaptureDevice::DeviceType::Microphone:
- case CaptureDevice::DeviceType::Camera:
- case CaptureDevice::DeviceType::Unknown:
- ASSERT_NOT_REACHED();
- break;
- }
-
- return { };
}
private:
CaptureDeviceManager& displayCaptureDeviceManager() { return DisplayCaptureManagerCocoa::singleton(); }
Deleted: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017-2019 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"
-#include "IOSurface.h"
-#include <CoreGraphics/CGDisplayConfiguration.h>
-#include <CoreGraphics/CGDisplayStream.h>
-#include <wtf/Lock.h>
-#include <wtf/OSObjectPtr.h>
-
-typedef struct __CVBuffer *CVPixelBufferRef;
-typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
-
-namespace WebCore {
-
-class ScreenDisplayCaptureSourceMac : public DisplayCaptureSourceCocoa {
-public:
- static CaptureSourceOrError create(String&&, const MediaConstraints*);
-
- static Optional<CaptureDevice> screenCaptureDeviceWithPersistentID(const String&);
- static void screenCaptureDevices(Vector<CaptureDevice>&);
-
-private:
- ScreenDisplayCaptureSourceMac(uint32_t, String&&);
- virtual ~ScreenDisplayCaptureSourceMac();
-
- static void displayReconfigurationCallBack(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void*);
-
- void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags);
-
- DisplayCaptureSourceCocoa::DisplayFrameType generateFrame() final;
- RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Monitor; }
-
- void startProducingData() final;
- void stopProducingData() final;
- void commitConfiguration() final;
- CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Screen; }
-
- bool createDisplayStream();
- void startDisplayStream();
-
-#if !RELEASE_LOG_DISABLED
- const char* logClassName() const override { return "ScreenDisplayCaptureSourceMac"; }
-#endif
-
- class DisplaySurface {
- public:
- DisplaySurface() = default;
- explicit DisplaySurface(IOSurfaceRef surface)
- : m_surface(surface)
- {
- if (m_surface)
- IOSurfaceIncrementUseCount(m_surface.get());
- }
-
- ~DisplaySurface()
- {
- if (m_surface)
- IOSurfaceDecrementUseCount(m_surface.get());
- }
-
- DisplaySurface& operator=(IOSurfaceRef surface)
- {
- if (m_surface)
- IOSurfaceDecrementUseCount(m_surface.get());
- if (surface)
- IOSurfaceIncrementUseCount(surface);
- m_surface = surface;
- return *this;
- }
-
- IOSurfaceRef ioSurface() const { return m_surface.get(); }
-
- private:
- RetainPtr<IOSurfaceRef> m_surface;
- };
-
- void newFrame(CGDisplayStreamFrameStatus, DisplaySurface&&);
-
- DisplaySurface m_currentFrame;
- RetainPtr<CGDisplayStreamRef> m_displayStream;
- OSObjectPtr<dispatch_queue_t> m_captureQueue;
-
- uint32_t m_displayID { 0 };
- bool m_isRunning { false };
- bool m_observingDisplayChanges { false };
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM) && PLATFORM(MAC)
Deleted: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm 2020-04-23 08:59:31 UTC (rev 260561)
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2017-2019 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 "ScreenDisplayCaptureSourceMac.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 "PlatformLayer.h"
-#import "PlatformScreen.h"
-#import "RealtimeMediaSourceSettings.h"
-#import "RealtimeVideoUtilities.h"
-
-#import "CoreVideoSoftLink.h"
-
-extern "C" {
-size_t CGDisplayModeGetPixelsWide(CGDisplayModeRef);
-size_t CGDisplayModeGetPixelsHigh(CGDisplayModeRef);
-}
-
-namespace WebCore {
-
-static Optional<CGDirectDisplayID> updateDisplayID(CGDirectDisplayID displayID)
-{
- 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", static_cast<int>(err));
- return WTF::nullopt;
- }
-
- if (!displayCount) {
- RELEASE_LOG(Media, "CGGetActiveDisplayList() returned a display count of 0");
- return WTF::nullopt;
- }
-
- Vector<CGDirectDisplayID> activeDisplays(displayCount);
- err = CGGetActiveDisplayList(displayCount, activeDisplays.data(), &displayCount);
- if (err) {
- RELEASE_LOG(Media, "CGGetActiveDisplayList() returned error %d when trying to get the active display list", static_cast<int>(err));
- return WTF::nullopt;
- }
-
- auto displayMask = CGDisplayIDToOpenGLDisplayMask(displayID);
- for (auto display : activeDisplays) {
- if (displayMask == CGDisplayIDToOpenGLDisplayMask(display))
- return display;
- }
-
- return WTF::nullopt;
-}
-
-CaptureSourceOrError ScreenDisplayCaptureSourceMac::create(String&& deviceID, const MediaConstraints* constraints)
-{
- bool ok;
- auto displayID = deviceID.toUIntStrict(&ok);
- if (!ok) {
- RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::create: Display ID does not convert to 32-bit integer");
- return { };
- }
-
- auto actualDisplayID = updateDisplayID(displayID);
- if (!actualDisplayID)
- return { };
-
- auto source = adoptRef(*new ScreenDisplayCaptureSourceMac(actualDisplayID.value(), "Screen"_s)); // FIXME: figure out what title to use
- if (constraints && source->applyConstraints(*constraints))
- return { };
-
- return CaptureSourceOrError(WTFMove(source));
-}
-
-ScreenDisplayCaptureSourceMac::ScreenDisplayCaptureSourceMac(uint32_t displayID, String&& title)
- : DisplayCaptureSourceCocoa(WTFMove(title))
- , m_displayID(displayID)
-{
-}
-
-ScreenDisplayCaptureSourceMac::~ScreenDisplayCaptureSourceMac()
-{
- if (m_observingDisplayChanges)
- CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallBack, this);
-
- m_currentFrame = nullptr;
-}
-
-bool ScreenDisplayCaptureSourceMac::createDisplayStream()
-{
- static const int screenQueueMaximumLength = 6;
-
- ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER);
-
- auto actualDisplayID = updateDisplayID(m_displayID);
- if (!actualDisplayID) {
- ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "invalid display ID: ", m_displayID);
- captureFailed();
- return false;
- }
-
- if (m_displayID != actualDisplayID.value()) {
- m_displayID = actualDisplayID.value();
- ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER, "display ID changed to ", static_cast<int>(m_displayID));
- m_displayStream = nullptr;
- }
-
- if (!m_displayStream) {
- auto displayMode = adoptCF(CGDisplayCopyDisplayMode(m_displayID));
- auto screenWidth = CGDisplayModeGetPixelsWide(displayMode.get());
- auto screenHeight = CGDisplayModeGetPixelsHigh(displayMode.get());
- if (!screenWidth || !screenHeight) {
- ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "unable to get screen width/height");
- captureFailed();
- return false;
- }
- setIntrinsicSize(IntSize(screenWidth, screenHeight));
-
- if (!m_captureQueue)
- m_captureQueue = adoptOSObject(dispatch_queue_create("ScreenDisplayCaptureSourceMac Capture Queue", DISPATCH_QUEUE_SERIAL));
-
- NSDictionary* streamOptions = @{
- (__bridge NSString *)kCGDisplayStreamMinimumFrameTime : @(1 / frameRate()),
- (__bridge NSString *)kCGDisplayStreamQueueDepth : @(screenQueueMaximumLength),
- (__bridge NSString *)kCGDisplayStreamColorSpace : (__bridge id)sRGBColorSpaceRef(),
- (__bridge NSString *)kCGDisplayStreamShowCursor : @YES,
- };
-
- auto weakThis = makeWeakPtr(*this);
- auto frameAvailableBlock = ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) {
-
- if (!frameSurface || !displayTime)
- return;
-
- size_t count;
- auto* rects = CGDisplayStreamUpdateGetRects(updateRef, kCGDisplayStreamUpdateDirtyRects, &count);
- if (!rects || !count)
- return;
-
- RunLoop::main().dispatch([weakThis, status, frame = DisplaySurface { frameSurface }]() mutable {
- if (!weakThis)
- return;
- weakThis->newFrame(status, WTFMove(frame));
- });
- };
-
- m_displayStream = adoptCF(CGDisplayStreamCreateWithDispatchQueue(m_displayID, screenWidth, screenHeight, preferedPixelBufferFormat(), (__bridge CFDictionaryRef)streamOptions, m_captureQueue.get(), frameAvailableBlock));
- if (!m_displayStream) {
- ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "CGDisplayStreamCreate failed");
- captureFailed();
- return false;
- }
- }
-
- if (!m_observingDisplayChanges) {
- CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, this);
- m_observingDisplayChanges = true;
- }
-
- return true;
-}
-
-void ScreenDisplayCaptureSourceMac::startProducingData()
-{
- ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER);
- DisplayCaptureSourceCocoa::startProducingData();
-
- if (m_isRunning)
- return;
-
- startDisplayStream();
-}
-
-void ScreenDisplayCaptureSourceMac::stopProducingData()
-{
- ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER);
- DisplayCaptureSourceCocoa::stopProducingData();
-
- if (!m_isRunning)
- return;
-
- if (m_displayStream)
- CGDisplayStreamStop(m_displayStream.get());
-
- m_isRunning = false;
-}
-
-DisplayCaptureSourceCocoa::DisplayFrameType ScreenDisplayCaptureSourceMac::generateFrame()
-{
- return DisplayCaptureSourceCocoa::DisplayFrameType { RetainPtr<IOSurfaceRef> { m_currentFrame.ioSurface() } };
-}
-
-void ScreenDisplayCaptureSourceMac::startDisplayStream()
-{
- auto actualDisplayID = updateDisplayID(m_displayID);
- if (!actualDisplayID)
- return;
-
- if (m_displayID != actualDisplayID.value()) {
- m_displayID = actualDisplayID.value();
- ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER, "display ID changed to ", static_cast<int>(m_displayID));
- }
-
- if (!m_displayStream && !createDisplayStream())
- return;
-
- auto err = CGDisplayStreamStart(m_displayStream.get());
- if (err) {
- ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "CGDisplayStreamStart failed with error ", static_cast<int>(err));
- captureFailed();
- return;
- }
-
- m_isRunning = true;
-}
-
-void ScreenDisplayCaptureSourceMac::commitConfiguration()
-{
- if (m_isRunning && !m_displayStream)
- startDisplayStream();
-}
-
-void ScreenDisplayCaptureSourceMac::displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags)
-{
- // FIXME: implement!
-}
-
-void ScreenDisplayCaptureSourceMac::displayReconfigurationCallBack(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *userInfo)
-{
- if (userInfo)
- reinterpret_cast<ScreenDisplayCaptureSourceMac *>(userInfo)->displayWasReconfigured(display, flags);
-}
-
-void ScreenDisplayCaptureSourceMac::newFrame(CGDisplayStreamFrameStatus status, DisplaySurface&& newFrame)
-{
- switch (status) {
- case kCGDisplayStreamFrameStatusFrameComplete:
- break;
-
- case kCGDisplayStreamFrameStatusFrameIdle:
- break;
-
- case kCGDisplayStreamFrameStatusFrameBlank:
- RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::frameAvailable: kCGDisplayStreamFrameStatusFrameBlank");
- break;
-
- case kCGDisplayStreamFrameStatusStopped:
- RELEASE_LOG(Media, "ScreenDisplayCaptureSourceMac::frameAvailable: kCGDisplayStreamFrameStatusStopped");
- break;
- }
-
- m_currentFrame = WTFMove(newFrame);
-}
-
-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 WTF::nullopt;
- }
-
- auto actualDisplayID = updateDisplayID(displayID);
- if (!actualDisplayID)
- return WTF::nullopt;
-
- auto device = CaptureDevice(String::number(actualDisplayID.value()), CaptureDevice::DeviceType::Screen, "ScreenCaptureDevice"_s);
- device.setEnabled(true);
-
- return device;
-}
-
-void ScreenDisplayCaptureSourceMac::screenCaptureDevices(Vector<CaptureDevice>& displays)
-{
- auto screenID = displayID([NSScreen mainScreen]);
- if (CGDisplayIDToOpenGLDisplayMask(screenID)) {
- CaptureDevice displayDevice(String::number(screenID), CaptureDevice::DeviceType::Screen, makeString("Screen 0"));
- displayDevice.setEnabled(true);
- displays.append(WTFMove(displayDevice));
- return;
- }
-
- 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;
- }
-
- Vector<CGDirectDisplayID> activeDisplays(displayCount);
- err = CGGetActiveDisplayList(displayCount, activeDisplays.data(), &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)
Copied: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCapturerMac.h (from rev 260560, trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h) (0 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCapturerMac.h (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCapturerMac.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017-2019 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"
+#include "IOSurface.h"
+#include <CoreGraphics/CGDisplayConfiguration.h>
+#include <CoreGraphics/CGDisplayStream.h>
+#include <wtf/Lock.h>
+#include <wtf/OSObjectPtr.h>
+
+typedef struct __CVBuffer *CVPixelBufferRef;
+typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
+
+namespace WebCore {
+
+class ScreenDisplayCapturerMac final : public DisplayCaptureSourceCocoa::Capturer, public CanMakeWeakPtr<ScreenDisplayCapturerMac> {
+public:
+ static Expected<UniqueRef<DisplayCaptureSourceCocoa::Capturer>, String> create(const String&);
+
+ explicit ScreenDisplayCapturerMac(uint32_t);
+ ~ScreenDisplayCapturerMac();
+
+ static Optional<CaptureDevice> screenCaptureDeviceWithPersistentID(const String&);
+ static void screenCaptureDevices(Vector<CaptureDevice>&);
+
+private:
+ static void displayReconfigurationCallBack(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void*);
+
+ // DisplayCaptureSourceCocoa::Capturer
+ bool start(float frameRate) final;
+ void stop() final;
+ DisplayCaptureSourceCocoa::DisplayFrameType generateFrame() final;
+ RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Monitor; }
+ void commitConfiguration(float frameRate) final;
+ CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Screen; }
+#if !RELEASE_LOG_DISABLED
+ const char* logClassName() const final { return "ScreenDisplayCapturerMac"; }
+#endif
+
+ void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags);
+ bool createDisplayStream(float frameRate);
+ bool startDisplayStream(float frameRate);
+
+ class DisplaySurface {
+ public:
+ DisplaySurface() = default;
+ explicit DisplaySurface(IOSurfaceRef surface)
+ : m_surface(surface)
+ {
+ if (m_surface)
+ IOSurfaceIncrementUseCount(m_surface.get());
+ }
+
+ ~DisplaySurface()
+ {
+ if (m_surface)
+ IOSurfaceDecrementUseCount(m_surface.get());
+ }
+
+ DisplaySurface& operator=(IOSurfaceRef surface)
+ {
+ if (m_surface)
+ IOSurfaceDecrementUseCount(m_surface.get());
+ if (surface)
+ IOSurfaceIncrementUseCount(surface);
+ m_surface = surface;
+ return *this;
+ }
+
+ IOSurfaceRef ioSurface() const { return m_surface.get(); }
+
+ private:
+ RetainPtr<IOSurfaceRef> m_surface;
+ };
+
+ void newFrame(CGDisplayStreamFrameStatus, DisplaySurface&&);
+
+ DisplaySurface m_currentFrame;
+ RetainPtr<CGDisplayStreamRef> m_displayStream;
+ OSObjectPtr<dispatch_queue_t> m_captureQueue;
+
+ uint32_t m_displayID { 0 };
+ bool m_isRunning { false };
+ bool m_observingDisplayChanges { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && PLATFORM(MAC)
Copied: trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCapturerMac.mm (from rev 260560, trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm) (0 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCapturerMac.mm (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/ScreenDisplayCapturerMac.mm 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScreenDisplayCapturerMac.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 "PlatformLayer.h"
+#import "PlatformScreen.h"
+#import "RealtimeMediaSourceSettings.h"
+#import "RealtimeVideoUtilities.h"
+
+#import "CoreVideoSoftLink.h"
+
+extern "C" {
+size_t CGDisplayModeGetPixelsWide(CGDisplayModeRef);
+size_t CGDisplayModeGetPixelsHigh(CGDisplayModeRef);
+}
+
+namespace WebCore {
+
+static Optional<CGDirectDisplayID> updateDisplayID(CGDirectDisplayID displayID)
+{
+ uint32_t displayCount = 0;
+ auto err = CGGetActiveDisplayList(0, nullptr, &displayCount);
+ if (err) {
+ RELEASE_LOG(WebRTC, "CGGetActiveDisplayList() returned error %d when trying to get display count", static_cast<int>(err));
+ return WTF::nullopt;
+ }
+
+ if (!displayCount) {
+ RELEASE_LOG(WebRTC, "CGGetActiveDisplayList() returned a display count of 0");
+ return WTF::nullopt;
+ }
+
+ Vector<CGDirectDisplayID> activeDisplays(displayCount);
+ err = CGGetActiveDisplayList(displayCount, activeDisplays.data(), &displayCount);
+ if (err) {
+ RELEASE_LOG(WebRTC, "CGGetActiveDisplayList() returned error %d when trying to get the active display list", static_cast<int>(err));
+ return WTF::nullopt;
+ }
+
+ auto displayMask = CGDisplayIDToOpenGLDisplayMask(displayID);
+ for (auto display : activeDisplays) {
+ if (displayMask == CGDisplayIDToOpenGLDisplayMask(display))
+ return display;
+ }
+
+ return WTF::nullopt;
+}
+
+Expected<UniqueRef<DisplayCaptureSourceCocoa::Capturer>, String> ScreenDisplayCapturerMac::create(const String& deviceID)
+{
+ bool ok;
+ auto displayID = deviceID.toUIntStrict(&ok);
+ if (!ok)
+ return makeUnexpected("Invalid display device ID"_s);
+
+ auto actualDisplayID = updateDisplayID(displayID);
+ if (!actualDisplayID)
+ return makeUnexpected("Invalid display ID"_s);
+
+ return UniqueRef<DisplayCaptureSourceCocoa::Capturer>(makeUniqueRef<ScreenDisplayCapturerMac>(actualDisplayID.value()));
+}
+
+ScreenDisplayCapturerMac::ScreenDisplayCapturerMac(uint32_t displayID)
+ : m_displayID(displayID)
+{
+}
+
+ScreenDisplayCapturerMac::~ScreenDisplayCapturerMac()
+{
+ if (m_observingDisplayChanges)
+ CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallBack, this);
+
+ m_currentFrame = nullptr;
+}
+
+bool ScreenDisplayCapturerMac::createDisplayStream(float frameRate)
+{
+ static const int screenQueueMaximumLength = 6;
+
+ ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER);
+
+ auto actualDisplayID = updateDisplayID(m_displayID);
+ if (!actualDisplayID) {
+ ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "invalid display ID: ", m_displayID);
+ return false;
+ }
+
+ if (m_displayID != actualDisplayID.value()) {
+ m_displayID = actualDisplayID.value();
+ ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER, "display ID changed to ", static_cast<int>(m_displayID));
+ m_displayStream = nullptr;
+ }
+
+ if (!m_displayStream) {
+ auto displayMode = adoptCF(CGDisplayCopyDisplayMode(m_displayID));
+ auto screenWidth = CGDisplayModeGetPixelsWide(displayMode.get());
+ auto screenHeight = CGDisplayModeGetPixelsHigh(displayMode.get());
+ if (!screenWidth || !screenHeight) {
+ ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "unable to get screen width/height");
+ return false;
+ }
+
+ if (!m_captureQueue)
+ m_captureQueue = adoptOSObject(dispatch_queue_create("ScreenDisplayCapturerMac Capture Queue", DISPATCH_QUEUE_SERIAL));
+
+ NSDictionary* streamOptions = @{
+ (__bridge NSString *)kCGDisplayStreamMinimumFrameTime : @(1 / frameRate),
+ (__bridge NSString *)kCGDisplayStreamQueueDepth : @(screenQueueMaximumLength),
+ (__bridge NSString *)kCGDisplayStreamColorSpace : (__bridge id)sRGBColorSpaceRef(),
+ (__bridge NSString *)kCGDisplayStreamShowCursor : @YES,
+ };
+
+ auto weakThis = makeWeakPtr(*this);
+ auto frameAvailableBlock = ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) {
+
+ if (!frameSurface || !displayTime)
+ return;
+
+ size_t count;
+ auto* rects = CGDisplayStreamUpdateGetRects(updateRef, kCGDisplayStreamUpdateDirtyRects, &count);
+ if (!rects || !count)
+ return;
+
+ RunLoop::main().dispatch([weakThis, status, frame = DisplaySurface { frameSurface }]() mutable {
+ if (!weakThis)
+ return;
+ weakThis->newFrame(status, WTFMove(frame));
+ });
+ };
+
+ m_displayStream = adoptCF(CGDisplayStreamCreateWithDispatchQueue(m_displayID, screenWidth, screenHeight, preferedPixelBufferFormat(), (__bridge CFDictionaryRef)streamOptions, m_captureQueue.get(), frameAvailableBlock));
+ if (!m_displayStream) {
+ ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "CGDisplayStreamCreate failed");
+ return false;
+ }
+ }
+
+ if (!m_observingDisplayChanges) {
+ CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, this);
+ m_observingDisplayChanges = true;
+ }
+
+ return true;
+}
+
+bool ScreenDisplayCapturerMac::start(float frameRate)
+{
+ ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER);
+
+ if (m_isRunning)
+ return true;
+
+ return startDisplayStream(frameRate);
+}
+
+void ScreenDisplayCapturerMac::stop()
+{
+ ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER);
+
+ if (!m_isRunning)
+ return;
+
+ if (m_displayStream)
+ CGDisplayStreamStop(m_displayStream.get());
+
+ m_isRunning = false;
+}
+
+DisplayCaptureSourceCocoa::DisplayFrameType ScreenDisplayCapturerMac::generateFrame()
+{
+ return DisplayCaptureSourceCocoa::DisplayFrameType { RetainPtr<IOSurfaceRef> { m_currentFrame.ioSurface() } };
+}
+
+bool ScreenDisplayCapturerMac::startDisplayStream(float frameRate)
+{
+ auto actualDisplayID = updateDisplayID(m_displayID);
+ if (!actualDisplayID)
+ return false;
+
+ if (m_displayID != actualDisplayID.value()) {
+ m_displayID = actualDisplayID.value();
+ ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER, "display ID changed to ", static_cast<int>(m_displayID));
+ }
+
+ if (!m_displayStream && !createDisplayStream(frameRate))
+ return false;
+
+ auto err = CGDisplayStreamStart(m_displayStream.get());
+ if (err) {
+ ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "CGDisplayStreamStart failed with error ", static_cast<int>(err));
+ return false;
+ }
+
+ m_isRunning = true;
+ return true;
+}
+
+void ScreenDisplayCapturerMac::commitConfiguration(float frameRate)
+{
+ if (m_isRunning && !m_displayStream)
+ startDisplayStream(frameRate);
+}
+
+void ScreenDisplayCapturerMac::displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags)
+{
+ // FIXME: implement!
+}
+
+void ScreenDisplayCapturerMac::displayReconfigurationCallBack(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *userInfo)
+{
+ if (userInfo)
+ reinterpret_cast<ScreenDisplayCapturerMac *>(userInfo)->displayWasReconfigured(display, flags);
+}
+
+void ScreenDisplayCapturerMac::newFrame(CGDisplayStreamFrameStatus status, DisplaySurface&& newFrame)
+{
+ switch (status) {
+ case kCGDisplayStreamFrameStatusFrameComplete:
+ break;
+
+ case kCGDisplayStreamFrameStatusFrameIdle:
+ break;
+
+ case kCGDisplayStreamFrameStatusFrameBlank:
+ RELEASE_LOG(WebRTC, "ScreenDisplayCapturerMac::frameAvailable: kCGDisplayStreamFrameStatusFrameBlank");
+ break;
+
+ case kCGDisplayStreamFrameStatusStopped:
+ RELEASE_LOG(WebRTC, "ScreenDisplayCapturerMac::frameAvailable: kCGDisplayStreamFrameStatusStopped");
+ break;
+ }
+
+ m_currentFrame = WTFMove(newFrame);
+}
+
+Optional<CaptureDevice> ScreenDisplayCapturerMac::screenCaptureDeviceWithPersistentID(const String& deviceID)
+{
+ bool ok;
+ auto displayID = deviceID.toUIntStrict(&ok);
+ if (!ok) {
+ RELEASE_LOG(WebRTC, "ScreenDisplayCapturerMac::screenCaptureDeviceWithPersistentID: display ID does not convert to 32-bit integer");
+ return WTF::nullopt;
+ }
+
+ auto actualDisplayID = updateDisplayID(displayID);
+ if (!actualDisplayID)
+ return WTF::nullopt;
+
+ auto device = CaptureDevice(String::number(actualDisplayID.value()), CaptureDevice::DeviceType::Screen, "ScreenCaptureDevice"_s);
+ device.setEnabled(true);
+
+ return device;
+}
+
+void ScreenDisplayCapturerMac::screenCaptureDevices(Vector<CaptureDevice>& displays)
+{
+ auto screenID = displayID([NSScreen mainScreen]);
+ if (CGDisplayIDToOpenGLDisplayMask(screenID)) {
+ CaptureDevice displayDevice(String::number(screenID), CaptureDevice::DeviceType::Screen, makeString("Screen 0"));
+ displayDevice.setEnabled(true);
+ displays.append(WTFMove(displayDevice));
+ return;
+ }
+
+ uint32_t displayCount = 0;
+ auto err = CGGetActiveDisplayList(0, nullptr, &displayCount);
+ if (err) {
+ RELEASE_LOG(WebRTC, "CGGetActiveDisplayList() returned error %d when trying to get display count", (int)err);
+ return;
+ }
+
+ if (!displayCount) {
+ RELEASE_LOG(WebRTC, "CGGetActiveDisplayList() returned a display count of 0");
+ return;
+ }
+
+ Vector<CGDirectDisplayID> activeDisplays(displayCount);
+ err = CGGetActiveDisplayList(displayCount, activeDisplays.data(), &displayCount);
+ if (err) {
+ RELEASE_LOG(WebRTC, "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)
Deleted: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -1,68 +0,0 @@
-/*
- * 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(String&&, const MediaConstraints*);
-
- static Optional<CaptureDevice> windowCaptureDeviceWithPersistentID(const String&);
- static void windowCaptureDevices(Vector<CaptureDevice>&);
-
-private:
- WindowDisplayCaptureSourceMac(uint32_t, String&&);
- virtual ~WindowDisplayCaptureSourceMac() = default;
-
- DisplayCaptureSourceCocoa::DisplayFrameType generateFrame() final;
- RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Window; }
- CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Window; }
-
- RetainPtr<CGImageRef> windowImage();
-
- 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)
Deleted: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm (260560 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm 2020-04-23 08:59:31 UTC (rev 260561)
@@ -1,187 +0,0 @@
-/*
- * 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(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;
-}
-
-DisplayCaptureSourceCocoa::DisplayFrameType WindowDisplayCaptureSourceMac::generateFrame()
-{
- return DisplayCaptureSourceCocoa::DisplayFrameType { RetainPtr<CGImageRef> { windowImage() } };
-}
-
-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 WTF::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 WTF::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)
Copied: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCapturerMac.h (from rev 260560, trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.h) (0 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCapturerMac.h (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCapturerMac.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,75 @@
+/*
+ * 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 WindowDisplayCapturerMac final : public DisplayCaptureSourceCocoa::Capturer {
+public:
+ static Expected<UniqueRef<DisplayCaptureSourceCocoa::Capturer>, String> create(const String&);
+
+ explicit WindowDisplayCapturerMac(uint32_t);
+ virtual ~WindowDisplayCapturerMac() = default;
+
+ static Optional<CaptureDevice> windowCaptureDeviceWithPersistentID(const String&);
+ static void windowCaptureDevices(Vector<CaptureDevice>&);
+
+private:
+ // DisplayCaptureSourceCocoa::Capturer
+ bool start(float) final { return true; }
+ void stop() final { }
+ DisplayCaptureSourceCocoa::DisplayFrameType generateFrame() final;
+ RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Window; }
+ CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Window; }
+ void commitConfiguration(float) final { }
+#if !RELEASE_LOG_DISABLED
+ const char* logClassName() const final { return "WindowDisplayCapturerMac"; }
+#endif
+
+ RetainPtr<CGImageRef> windowImage();
+
+ 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)
Copied: trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCapturerMac.mm (from rev 260560, trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCaptureSourceMac.mm) (0 => 260561)
--- trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCapturerMac.mm (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/WindowDisplayCapturerMac.mm 2020-04-23 08:59:31 UTC (rev 260561)
@@ -0,0 +1,178 @@
+/*
+ * 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 "WindowDisplayCapturerMac.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/spi/cg/CoreGraphicsSPI.h>
+#import <wtf/cf/TypeCastsCF.h>
+
+#import <pal/cf/CoreMediaSoftLink.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(WebRTC, "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));
+}
+
+Expected<UniqueRef<DisplayCaptureSourceCocoa::Capturer>, String> WindowDisplayCapturerMac::create(const String& deviceID)
+{
+ bool ok;
+ auto displayID = deviceID.toUIntStrict(&ok);
+ if (!ok)
+ return makeUnexpected("Invalid window device ID"_s);
+
+ auto windowInfo = windowDescription(displayID);
+ if (!windowInfo)
+ return makeUnexpected("Invalid window ID"_s);
+
+ return UniqueRef<DisplayCaptureSourceCocoa::Capturer>(makeUniqueRef<WindowDisplayCapturerMac>(displayID));
+}
+
+WindowDisplayCapturerMac::WindowDisplayCapturerMac(uint32_t windowID)
+ : m_windowID(windowID)
+{
+}
+
+RetainPtr<CGImageRef> WindowDisplayCapturerMac::windowImage()
+{
+ auto image = adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, m_windowID, kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque));
+ if (!image)
+ RELEASE_LOG(WebRTC, "WindowDisplayCapturerMac::windowImage: failed to capture window image");
+
+ return image;
+}
+
+DisplayCaptureSourceCocoa::DisplayFrameType WindowDisplayCapturerMac::generateFrame()
+{
+ return DisplayCaptureSourceCocoa::DisplayFrameType { RetainPtr<CGImageRef> { windowImage() } };
+}
+
+Optional<CaptureDevice> WindowDisplayCapturerMac::windowCaptureDeviceWithPersistentID(const String& idString)
+{
+ bool ok;
+ auto windowID = idString.toUIntStrict(&ok);
+ if (!ok) {
+ RELEASE_LOG(WebRTC, "WindowDisplayCapturerMac::windowCaptureDeviceWithPersistentID: window ID does not convert to 32-bit integer");
+ return WTF::nullopt;
+ }
+
+ String windowTitle;
+ if (!anyOfCGWindow([&windowTitle, windowID] (CFDictionaryRef, CGWindowID id, const String& title) {
+ if (windowID != id)
+ return false;
+
+ windowTitle = title;
+ return true;
+
+ })) {
+ RELEASE_LOG(WebRTC, "WindowDisplayCapturerMac::windowCaptureDeviceWithPersistentID: window ID is not valid");
+ return WTF::nullopt;
+ }
+
+ auto device = CaptureDevice(String::number(windowID), CaptureDevice::DeviceType::Window, windowTitle);
+ device.setEnabled(true);
+
+ return device;
+}
+
+void WindowDisplayCapturerMac::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/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp (260560 => 260561)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp 2020-04-23 08:59:31 UTC (rev 260561)
@@ -43,6 +43,8 @@
#if PLATFORM(COCOA)
#include "CoreAudioCaptureSource.h"
+#include "DisplayCaptureSourceCocoa.h"
+#include "MockRealtimeVideoSourceMac.h"
#endif
namespace WebCore {
@@ -110,17 +112,59 @@
CaptureDeviceManager& videoCaptureDeviceManager() final { return MockRealtimeMediaSourceCenter::singleton().videoCaptureDeviceManager(); }
};
+#if PLATFORM(MAC)
+class MockDisplayCapturer final : public DisplayCaptureSourceCocoa::Capturer {
+public:
+ explicit MockDisplayCapturer(const CaptureDevice&);
+
+private:
+ bool start(float) final;
+ void stop() final { m_source->stop(); }
+ DisplayCaptureSourceCocoa::DisplayFrameType generateFrame() final;
+ RealtimeMediaSourceSettings::DisplaySurfaceType surfaceType() const final { return RealtimeMediaSourceSettings::DisplaySurfaceType::Monitor; }
+ void commitConfiguration(float) final { }
+ CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Screen; }
+#if !RELEASE_LOG_DISABLED
+ const char* logClassName() const final { return "MockDisplayCapturer"; }
+#endif
+
+ Ref<MockRealtimeVideoSource> m_source;
+};
+
+MockDisplayCapturer::MockDisplayCapturer(const CaptureDevice& device)
+ : m_source(MockRealtimeVideoSourceMac::createForMockDisplayCapturer(String { device.persistentId() }, String { device.label() }, String { }))
+{
+}
+
+bool MockDisplayCapturer::start(float)
+{
+ m_source->start();
+ return true;
+}
+
+DisplayCaptureSourceCocoa::DisplayFrameType MockDisplayCapturer::generateFrame()
+{
+ if (auto* imageBuffer = m_source->imageBuffer())
+ return imageBuffer->copyNativeImage();
+ return { };
+}
+#endif
+
class MockRealtimeDisplaySourceFactory : public DisplayCaptureFactory {
public:
CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, const MediaConstraints* constraints) final
{
if (!MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(device.type(), device.persistentId()))
- return { "Unable to find mock display device with given persistentID"_s };
+ return { "Unable to find mock display device with given persistentID"_s };
switch (device.type()) {
case CaptureDevice::DeviceType::Screen:
case CaptureDevice::DeviceType::Window:
+#if PLATFORM(MAC)
+ return DisplayCaptureSourceCocoa::create(UniqueRef<DisplayCaptureSourceCocoa::Capturer>(makeUniqueRef<MockDisplayCapturer>(device)), device, constraints);
+#else
return MockRealtimeVideoSource::create(String { device.persistentId() }, String { device.label() }, String { }, constraints);
+#endif
break;
case CaptureDevice::DeviceType::Microphone:
case CaptureDevice::DeviceType::Camera:
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h (260560 => 260561)
--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h 2020-04-23 08:47:37 UTC (rev 260560)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h 2020-04-23 08:59:31 UTC (rev 260561)
@@ -48,9 +48,10 @@
class MockRealtimeVideoSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer {
public:
-
static CaptureSourceOrError create(String&& deviceID, String&& name, String&& hashSalt, const MediaConstraints*);
+ ImageBuffer* imageBuffer() const;
+
protected:
MockRealtimeVideoSource(String&& deviceID, String&& name, String&& hashSalt);
@@ -57,7 +58,6 @@
virtual void updateSampleBuffer() = 0;
void setCurrentFrame(MediaSample&);
- ImageBuffer* imageBuffer() const;
Seconds elapsedTime();
void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
@@ -125,6 +125,10 @@
} // namespace WebCore
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MockRealtimeVideoSource)
+ static bool isType(const WebCore::RealtimeMediaSource& source) { return source.isCaptureSource() && source.isMockSource() && (source.deviceType() == WebCore::CaptureDevice::DeviceType::Camera || source.deviceType() == WebCore::CaptureDevice::DeviceType::Screen || source.deviceType() == WebCore::CaptureDevice::DeviceType::Window); }
+SPECIALIZE_TYPE_TRAITS_END()
+
#endif // ENABLE(MEDIA_STREAM)
#endif // MockRealtimeVideoSource_h