WebKit Bugzilla
Attachment 348418 Details for
Bug 189000
: Mock video devices should only support discrete sizes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-189000-20180829114259.patch (text/plain), 103.36 KB, created by
Eric Carlson
on 2018-08-29 11:43:01 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Eric Carlson
Created:
2018-08-29 11:43:01 PDT
Size:
103.36 KB
patch
obsolete
>Subversion Revision: 235468 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index d17dc740f5a79bf25e3711dbecc3d0e70b21f1ea..5262834263ac1e90d68b425a8a0272ad4ad69697 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,115 @@ >+2018-08-29 Eric Carlson <eric.carlson@apple.com> >+ >+ Mock video devices should only support discrete sizes >+ https://bugs.webkit.org/show_bug.cgi?id=189000 >+ <rdar://problem/43766551> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ While many/most video capture devices only support a finite number of discrete width/height >+ pairs, our mock video capture devices supported arbitrary width and height combinations which >+ made it difficult to write realistic tests using them. Change the mock devices to support >+ finite "presets" like those supported by AVFoundation. Create a RealtimeVideoSource base >+ class with support for these presets, so the same code will eventually be used by the mock >+ and real capture devices. >+ >+ No new tests, existing tests updated for these changes. >+ >+ * Sources.txt: Add RealtimeVideoSource.cpp, remove MockRealtimeMediaSource.cpp. >+ >+ * WebCore.xcodeproj/project.pbxproj: Ditto. >+ >+ * platform/mediastream/MediaConstraints.h: Deal with min constraint less than the supported minimum >+ and max larger than the supported maximum when there is no ideal. >+ >+ * platform/mediastream/RealtimeMediaSource.cpp: >+ (WebCore::RealtimeMediaSource::selectSettings): Use supportsSizeAndFrameRate for widths, >+ heights, and framerates in advanced constraints so a width and height that are supported but >+ in the same preset are filtered out. >+ (WebCore::RealtimeMediaSource::setSize): New. >+ * platform/mediastream/RealtimeMediaSource.h: >+ >+ * platform/mediastream/RealtimeMediaSourceSettings.h: Remove an unneeded include. >+ >+ * platform/mediastream/RealtimeVideoSource.cpp: Added. >+ (WebCore::RealtimeVideoSource::RealtimeVideoSource): >+ (WebCore::RealtimeVideoSource::~RealtimeVideoSource): >+ (WebCore::RealtimeVideoSource::startProducingData): >+ (WebCore::RealtimeVideoSource::setSupportedFrameRates): >+ (WebCore::RealtimeVideoSource::addSupportedCapabilities const): >+ (WebCore::RealtimeVideoSource::supportsSizeAndFrameRate): >+ (WebCore::RealtimeVideoSource::bestSupportedCaptureSizeForWidthAndHeight): >+ (WebCore::RealtimeVideoSource::applySize): >+ (WebCore::RealtimeVideoSource::applySizeAndFrameRate): >+ (WebCore::RealtimeVideoSource::videoSampleAvailable): >+ (WebCore::RealtimeVideoSource::applyFrameRate): >+ (WebCore::RealtimeVideoSource::supportsFrameRate): >+ >+ * platform/mediastream/RealtimeVideoSource.h: Copied from Source/WebCore/platform/mock/MockRealtimeAudioSource.h. >+ (WebCore::RealtimeVideoSource::setSupportedCaptureSizes): >+ (WebCore::RealtimeVideoSource::setDefaultSize): >+ (WebCore::RealtimeVideoSource::observedFrameRate const): >+ >+ * platform/mediastream/mac/AVMediaCaptureSource.mm: >+ (WebCore::AVMediaCaptureSource::initializeSettings): Don't set label, it isn't used. >+ >+ * platform/mediastream/mac/MockRealtimeVideoSourceMac.mm: >+ (WebCore::MockRealtimeVideoSourceMac::applySize): Call the base class. >+ >+ * platform/mock/MockMediaDevice.h: >+ (WebCore::MockCameraProperties::encode const): Add frame rates, sizes, and facing mode. >+ (WebCore::MockCameraProperties::decode): Ditto. >+ >+ * platform/mock/MockRealtimeAudioSource.cpp: >+ (WebCore::MockRealtimeAudioSource::MockRealtimeAudioSource): No more MockRealtimeMediaSource. >+ (WebCore::MockRealtimeAudioSource::settings const): Clean up. >+ (WebCore::MockRealtimeAudioSource::capabilities const): Ditto. >+ (WebCore::MockRealtimeAudioSource::settingsDidChange): Ditto. >+ (WebCore::MockRealtimeAudioSource::stopProducingData): m_elapsedTime isn't used, delete it. >+ (WebCore::MockRealtimeAudioSource::updateSettings): Deleted. >+ (WebCore::MockRealtimeAudioSource::initializeCapabilities): Deleted. >+ (WebCore::MockRealtimeAudioSource::initializeSupportedConstraints): Deleted. >+ (WebCore::MockRealtimeAudioSource::elapsedTime): Deleted. >+ * platform/mock/MockRealtimeAudioSource.h: >+ >+ * platform/mock/MockRealtimeMediaSourceCenter.cpp: Moved all of the mock device management >+ code from MockRealtimeMediaSource.cpp here. >+ (WebCore::defaultDevices): >+ (WebCore::devices): >+ (WebCore::deviceMap): >+ (WebCore::deviceListForDevice): >+ (WebCore::createCaptureDevice): >+ (WebCore::MockRealtimeMediaSourceCenter::resetDevices): >+ (WebCore::MockRealtimeMediaSourceCenter::setDevices): >+ (WebCore::MockRealtimeMediaSourceCenter::addDevice): >+ (WebCore::MockRealtimeMediaSourceCenter::removeDevice): >+ (WebCore::MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID): >+ (WebCore::MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID): >+ (WebCore::MockRealtimeMediaSourceCenter::audioDevices): >+ (WebCore::MockRealtimeMediaSourceCenter::videoDevices): >+ (WebCore::MockRealtimeMediaSourceCenter::displayDevices): >+ >+ * platform/mock/MockRealtimeVideoSource.cpp: >+ (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource): Use RealtimeVideoSource, no >+ more MockRealtimeMediaSource. >+ (WebCore::MockRealtimeVideoSource::capabilities const): Ditto, cleanup. >+ (WebCore::MockRealtimeVideoSource::settings const): Ditto. >+ (WebCore::MockRealtimeVideoSource::settingsDidChange): Ditto. >+ (WebCore::MockRealtimeVideoSource::startCaptureTimer): Ditto. >+ (WebCore::MockRealtimeVideoSource::startProducingData): Ditto. >+ (WebCore::MockRealtimeVideoSource::stopProducingData): Ditto. >+ (WebCore::MockRealtimeVideoSource::elapsedTime): Ditto. >+ (WebCore::MockRealtimeVideoSource::applySize): Ditto. >+ (WebCore::MockRealtimeVideoSource::drawText): Render the actual frame rate. >+ (WebCore::MockRealtimeVideoSource::generateFrame): Use m_fillColor. >+ (WebCore::MockRealtimeVideoSource::~MockRealtimeVideoSource): Deleted. >+ (WebCore::MockRealtimeVideoSource::updateSettings): Deleted. >+ (WebCore::MockRealtimeVideoSource::initializeCapabilities): Deleted. >+ (WebCore::MockRealtimeVideoSource::initializeSupportedConstraints): Deleted. >+ (WebCore::MockRealtimeVideoSource::applyFrameRate): Deleted. >+ * platform/mock/MockRealtimeVideoSource.h: >+ (WebCore::MockRealtimeVideoSource::updateSampleBuffer): Deleted. >+ > 2018-08-29 David Kilzer <ddkilzer@apple.com> > > Remove empty directories from from svn.webkit.org repository >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index bf2a8bae103d8cb01315ad1a7889a54e455e8a61..58b5d76add4492ea23a9efdf9549c76d15e3e271 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,16 @@ >+2018-08-29 Eric Carlson <eric.carlson@apple.com> >+ >+ Mock video devices should only support discrete sizes >+ https://bugs.webkit.org/show_bug.cgi?id=189000 >+ <rdar://problem/43766551> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * UIProcess/WebProcessPool.cpp: >+ (WebKit::WebProcessPool::resetMockMediaDevices): >+ * WebProcess/WebProcess.cpp: >+ (WebKit::WebProcess::resetMockMediaDevices): >+ > 2018-08-28 Don Olmstead <don.olmstead@sony.com> > > [CMake] Use CMake's FindFreetype >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index aa8ccf7143bf3e6264b5140673f7454416bbb4ae..af2315a9af4ec6bda20ad317a9904dec32aa2960 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -1745,6 +1745,7 @@ platform/mediastream/RealtimeMediaSourceCenter.cpp > platform/mediastream/RealtimeMediaSourceSettings.cpp > platform/mediastream/RealtimeOutgoingAudioSource.cpp > platform/mediastream/RealtimeOutgoingVideoSource.cpp >+platform/mediastream/RealtimeVideoSource.cpp > > platform/mediastream/libwebrtc/LibWebRTCProvider.cpp > >@@ -1753,7 +1754,6 @@ platform/mock/GeolocationClientMock.cpp > platform/mock/MediaEngineDecodingConfigurationMock.cpp > platform/mock/MediaEngineEncodingConfigurationMock.cpp > platform/mock/MockRealtimeAudioSource.cpp >-platform/mock/MockRealtimeMediaSource.cpp > platform/mock/MockRealtimeMediaSourceCenter.cpp > platform/mock/MockRealtimeVideoSource.cpp > platform/mock/RTCDataChannelHandlerMock.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 8c0323ce85235a2ecda3c8659b01585cb84a9a7e..c48a13af5762f8cf439668042ceb0dd06d137ab0 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -104,6 +104,7 @@ > 07277E5117D018CC0015534D /* JSMediaStreamEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 07277E4517D018CC0015534D /* JSMediaStreamEvent.h */; }; > 07277E5317D018CC0015534D /* JSMediaStreamTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 07277E4717D018CC0015534D /* JSMediaStreamTrack.h */; }; > 07277E5517D018CC0015534D /* JSMediaStreamTrackEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 07277E4917D018CC0015534D /* JSMediaStreamTrackEvent.h */; }; >+ 072880D12010F1F60071B255 /* RealtimeVideoSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 072880D02010EED70071B255 /* RealtimeVideoSource.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 072A70401D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */; }; > 072AE1E5183C0741000A5988 /* PluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1DF183C0741000A5988 /* PluginReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */; }; >@@ -208,7 +209,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, ); }; }; > 07D637401BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 07D6A4F01BECF2D200174146 /* MockRealtimeMediaSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6A4EE1BECF2D200174146 /* MockRealtimeMediaSource.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 */; }; > 07E3DFD11A9E786500764CA8 /* MediaPlaybackTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 07E3DFD01A9E786500764CA8 /* MediaPlaybackTarget.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -5288,6 +5288,8 @@ > 07277E4817D018CC0015534D /* JSMediaStreamTrackEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaStreamTrackEvent.cpp; sourceTree = "<group>"; }; > 07277E4917D018CC0015534D /* JSMediaStreamTrackEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaStreamTrackEvent.h; sourceTree = "<group>"; }; > 072847E216EBC5B00043CFA4 /* PlatformTextTrack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformTextTrack.h; sourceTree = "<group>"; }; >+ 072880CE2010EED60071B255 /* RealtimeVideoSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RealtimeVideoSource.cpp; sourceTree = "<group>"; }; >+ 072880D02010EED70071B255 /* RealtimeVideoSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RealtimeVideoSource.h; sourceTree = "<group>"; }; > 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OverconstrainedErrorEvent.h; sourceTree = "<group>"; }; > 072A703F1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OverconstrainedErrorEvent.idl; sourceTree = "<group>"; }; > 072AE1DF183C0741000A5988 /* PluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginReplacement.h; sourceTree = "<group>"; }; >@@ -5420,8 +5422,6 @@ > 07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivateClient.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>"; }; >- 07D6A4ED1BECF2D200174146 /* MockRealtimeMediaSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockRealtimeMediaSource.cpp; sourceTree = "<group>"; }; >- 07D6A4EE1BECF2D200174146 /* MockRealtimeMediaSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockRealtimeMediaSource.h; sourceTree = "<group>"; }; > 07D6A4F11BED5F8800174146 /* MockRealtimeAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockRealtimeAudioSource.cpp; sourceTree = "<group>"; }; > 07D6A4F21BED5F8800174146 /* MockRealtimeAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockRealtimeAudioSource.h; sourceTree = "<group>"; }; > 07D6A4F61BF2307D00174146 /* AudioTrackPrivateMediaStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioTrackPrivateMediaStream.h; path = platform/mediastream/AudioTrackPrivateMediaStream.h; sourceTree = SOURCE_ROOT; }; >@@ -15180,6 +15180,8 @@ > 41103AA81E39790A00769F03 /* RealtimeOutgoingAudioSource.h */, > 5CDD833B1E4324BB00621E92 /* RealtimeOutgoingVideoSource.cpp */, > 5CDD833C1E4324BB00621E92 /* RealtimeOutgoingVideoSource.h */, >+ 072880CE2010EED60071B255 /* RealtimeVideoSource.cpp */, >+ 072880D02010EED70071B255 /* RealtimeVideoSource.h */, > 3135910C1E7DDCB600F30630 /* RTCBundlePolicy.h */, > 07221BA217CF0AD400848E51 /* RTCDataChannelHandler.h */, > 07221BA317CF0AD400848E51 /* RTCDataChannelHandlerClient.h */, >@@ -18755,8 +18757,6 @@ > 413CCD4820DE013C0065A21A /* MockMediaDevice.h */, > 07D6A4F11BED5F8800174146 /* MockRealtimeAudioSource.cpp */, > 07D6A4F21BED5F8800174146 /* MockRealtimeAudioSource.h */, >- 07D6A4ED1BECF2D200174146 /* MockRealtimeMediaSource.cpp */, >- 07D6A4EE1BECF2D200174146 /* MockRealtimeMediaSource.h */, > 4A0FFA9B1AAF5E6C0062803B /* MockRealtimeMediaSourceCenter.cpp */, > 4A0FFA9C1AAF5E6C0062803B /* MockRealtimeMediaSourceCenter.h */, > 07EE76E91BE96DB000F89133 /* MockRealtimeVideoSource.cpp */, >@@ -29396,7 +29396,6 @@ > CDF2B0131820540600F2B424 /* MockMediaPlayerMediaSource.h in Headers */, > CDF2B0151820540600F2B424 /* MockMediaSourcePrivate.h in Headers */, > 07D6A4F41BED5F8800174146 /* MockRealtimeAudioSource.h in Headers */, >- 07D6A4F01BECF2D200174146 /* MockRealtimeMediaSource.h in Headers */, > 4A0FFA9E1AAF5E7E0062803B /* MockRealtimeMediaSourceCenter.h in Headers */, > 07EE76EC1BE96DB000F89133 /* MockRealtimeVideoSource.h in Headers */, > 07EE76EF1BEA619800F89133 /* MockRealtimeVideoSourceMac.h in Headers */, >@@ -29726,6 +29725,7 @@ > 07C1C0E51BFB60ED00BD2256 /* RealtimeMediaSourceSupportedConstraints.h in Headers */, > 41103AAC1E39791000769F03 /* RealtimeOutgoingAudioSource.h in Headers */, > 41103AAC1E39791000769F14 /* RealtimeOutgoingAudioSourceCocoa.h in Headers */, >+ 072880D12010F1F60071B255 /* RealtimeVideoSource.h in Headers */, > 91B952241F58A58F00931DC2 /* RecordingSwizzleTypes.h in Headers */, > BC4368E80C226E32005EFB5F /* Rect.h in Headers */, > FD45A958175D414C00C21EC8 /* RectangleShape.h in Headers */, >diff --git a/Source/WebCore/platform/mediastream/MediaConstraints.h b/Source/WebCore/platform/mediastream/MediaConstraints.h >index 056fc7ee5e9687f47de529237a92bce410dd4e63..65e96aca9db172dd2728b3c5f159167df33c2b6e 100644 >--- a/Source/WebCore/platform/mediastream/MediaConstraints.h >+++ b/Source/WebCore/platform/mediastream/MediaConstraints.h >@@ -254,6 +254,8 @@ public: > ASSERT(validForRange(value, capabilityMax)); > if (value > min) > min = value; >+ if (value < min) >+ value = min; > > // If there is no ideal, don't change if minimum is smaller than current. > if (!m_ideal && value < current) >@@ -265,6 +267,8 @@ public: > ASSERT(validForRange(capabilityMin, value)); > if (value < max) > max = value; >+ if (value > max) >+ value = max; > } > > if (m_ideal) >diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp >index cadaf75e2a946b1556ceddf2ee17e3436eea1164..2e9d965a199b5b321ad3fe30e18188f22e2b41df 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp >+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp >@@ -651,7 +651,19 @@ bool RealtimeMediaSource::selectSettings(const MediaConstraints& constraints, Fl > double constraintDistance = 0; > bool supported = false; > >+ if (advancedConstraint.width() || advancedConstraint.height() || advancedConstraint.frameRate()) { >+ String dummy; >+ if (!supportsSizeAndFrameRate(advancedConstraint.width(), advancedConstraint.height(), advancedConstraint.frameRate(), dummy, constraintDistance)) >+ continue; >+ >+ supported = true; >+ } >+ > advancedConstraint.forEach([&](const MediaConstraint& constraint) { >+ >+ if (constraint.constraintType() == MediaConstraintType::Width || constraint.constraintType() == MediaConstraintType::Height || constraint.constraintType() == MediaConstraintType::FrameRate) >+ return; >+ > distance = fitnessDistance(constraint); > constraintDistance += distance; > if (!std::isinf(distance)) >@@ -848,6 +860,18 @@ void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, > failureHandler(result.value().first, result.value().second); > } > >+void RealtimeMediaSource::setSize(const IntSize& size) >+{ >+ if (size == m_size) >+ return; >+ >+ if (!applySize(size)) >+ return; >+ >+ m_size = size; >+ settingsDidChange(); >+} >+ > void RealtimeMediaSource::setWidth(int width) > { > if (width == m_size.width()) >diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h >index c29ab19c16df3b1fd01a0040b92fa5a723b48b0a..2793fac08accf6256a3181364322923f66db20a0 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h >+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h >@@ -167,6 +167,7 @@ public: > > void setWidth(int); > void setHeight(int); >+ void setSize(const IntSize&); > const IntSize& size() const { return m_size; } > virtual bool applySize(const IntSize&) { return false; } > >@@ -247,7 +248,7 @@ protected: > void initializeSampleRate(int sampleRate) { m_sampleRate = sampleRate; } > void initializeEchoCancellation(bool echoCancellation) { m_echoCancellation = echoCancellation; } > >- void videoSampleAvailable(MediaSample&); >+ virtual void videoSampleAvailable(MediaSample&); > void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t); > > private: >diff --git a/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp b/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..87f5fe6cbc3e86e83847bb3d633ece4e5d7deaf7 >--- /dev/null >+++ b/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp >@@ -0,0 +1,197 @@ >+/* >+ * Copyright (C) 2013-2015 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 "RealtimeVideoSource.h" >+ >+#if ENABLE(MEDIA_STREAM) >+#include "CaptureDevice.h" >+#include "Logging.h" >+#include "RealtimeMediaSourceCenter.h" >+#include "RealtimeMediaSourceSettings.h" >+ >+namespace WebCore { >+ >+RealtimeVideoSource::RealtimeVideoSource(const String& id, const String& name) >+ : RealtimeMediaSource(id, Type::Video, name) >+{ >+} >+ >+RealtimeVideoSource::~RealtimeVideoSource() >+{ >+#if PLATFORM(IOS) >+ RealtimeMediaSourceCenter::singleton().videoFactory().unsetActiveSource(*this); >+#endif >+} >+ >+void RealtimeVideoSource::startProducingData() >+{ >+ ASSERT(frameRate()); >+ >+#if PLATFORM(IOS) >+ RealtimeMediaSourceCenter::singleton().videoFactory().setActiveSource(*this); >+#endif >+ >+ if (size().isEmpty() && !m_defaultSize.isEmpty()) >+ setSize(m_defaultSize); >+} >+ >+void RealtimeVideoSource::setSupportedFrameRates(const Vector<double>&& rates) >+{ >+ m_supportedFrameRates = rates; >+ std::sort(m_supportedFrameRates.begin(), m_supportedFrameRates.end()); >+} >+ >+void RealtimeVideoSource::addSupportedCapabilities(RealtimeMediaSourceCapabilities& capabilities) const >+{ >+ if (!m_supportedFrameRates.size()) >+ capabilities.setFrameRate({ 30, 15 }); >+ else >+ capabilities.setFrameRate({ m_supportedFrameRates[0], m_supportedFrameRates[m_supportedFrameRates.size() - 1] }); >+ >+ if (!m_supportedCaptureSizes.size()) { >+ capabilities.setWidth({ 640 }); >+ capabilities.setHeight({ 480 }); >+ capabilities.setAspectRatio({ 1.33 }); >+ >+ return; >+ } >+ >+ int minimumWidth = std::numeric_limits<int>::max(); >+ int maximumWidth = 0; >+ int minimumHeight = std::numeric_limits<int>::max(); >+ int maximumHeight = 0; >+ float minimumAspectRatio = std::numeric_limits<float>::max(); >+ float maximumAspectRatio = 0; >+ for (auto size : m_supportedCaptureSizes) { >+ minimumWidth = std::min(minimumWidth, size.width()); >+ maximumWidth = std::max(maximumWidth, size.width()); >+ >+ minimumHeight = std::min(minimumHeight, size.height()); >+ maximumHeight = std::max(maximumHeight, size.height()); >+ >+ minimumAspectRatio = std::min(minimumAspectRatio, size.aspectRatio()); >+ maximumAspectRatio = std::max(maximumAspectRatio, size.aspectRatio()); >+ } >+ >+ capabilities.setWidth({ minimumWidth, maximumWidth }); >+ capabilities.setHeight({ minimumHeight, maximumHeight }); >+ capabilities.setAspectRatio({ minimumAspectRatio, maximumAspectRatio }); >+} >+ >+bool RealtimeVideoSource::supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate) >+{ >+ if (!height && !width && !frameRate) >+ return true; >+ >+ if (height || width) { >+ if (!m_supportedCaptureSizes.size()) >+ return false; >+ >+ IntSize supportedSize = bestSupportedCaptureSizeForWidthAndHeight(width, height); >+ if (supportedSize.isEmpty()) >+ return false; >+ } >+ >+ if (!frameRate) >+ return true; >+ >+ return supportsFrameRate(frameRate.value()); >+} >+ >+IntSize RealtimeVideoSource::bestSupportedCaptureSizeForWidthAndHeight(std::optional<int> width, std::optional<int> height) >+{ >+ if (!width && !height) >+ return { }; >+ >+ for (auto size : m_supportedCaptureSizes) { >+ if ((!width || width.value() == size.width()) && (!height || height.value() == size.height())) >+ return size; >+ } >+ >+ return { }; >+} >+ >+bool RealtimeVideoSource::applySize(const IntSize& size) >+{ >+ IntSize supportedSize = bestSupportedCaptureSizeForWidthAndHeight(size.width(), size.height()); >+ if (supportedSize.isEmpty()) { >+ LOG(Media, "RealtimeVideoSource::applySize(%p), unable find or set preset for width: %i, height: %i", this, size.width(), size.height()); >+ return false; >+ } >+ >+ return true; >+} >+ >+void RealtimeVideoSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate) >+{ >+ if (width || height) { >+ IntSize supportedSize = bestSupportedCaptureSizeForWidthAndHeight(WTFMove(width), WTFMove(height)); >+ ASSERT(!supportedSize.isEmpty()); >+ if (!supportedSize.isEmpty()) >+ setSize(supportedSize); >+ } >+ >+ if (frameRate) >+ setFrameRate(frameRate.value()); >+} >+ >+void RealtimeVideoSource::dispatchMediaSampleToObservers(MediaSample& sample) >+{ >+ MediaTime sampleTime = sample.outputPresentationTime(); >+ if (!sampleTime || !sampleTime.isValid()) >+ sampleTime = sample.presentationTime(); >+ >+ auto frameTime = sampleTime.toDouble(); >+ m_observedFrameTimeStamps.append(frameTime); >+ m_observedFrameTimeStamps.removeAllMatching([&](auto time) { >+ return time <= frameTime - 2; >+ }); >+ >+ auto interval = m_observedFrameTimeStamps.last() - m_observedFrameTimeStamps.first(); >+ if (interval > 1) >+ m_observedFrameRate = (m_observedFrameTimeStamps.size() / interval); >+ >+ videoSampleAvailable(sample); >+} >+ >+bool RealtimeVideoSource::applyFrameRate(double rate) >+{ >+ return supportsFrameRate(rate); >+} >+ >+bool RealtimeVideoSource::supportsFrameRate(double frameRate) >+{ >+ double epsilon = 0.001; >+ for (auto rate : m_supportedFrameRates) { >+ if (frameRate + epsilon >= rate && frameRate - epsilon <= rate) >+ return true; >+ } >+ return false; >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(MEDIA_STREAM) >diff --git a/Source/WebCore/platform/mediastream/RealtimeVideoSource.h b/Source/WebCore/platform/mediastream/RealtimeVideoSource.h >new file mode 100644 >index 0000000000000000000000000000000000000000..854bc2529c79eaa788548346f5aefb1d086a59ed >--- /dev/null >+++ b/Source/WebCore/platform/mediastream/RealtimeVideoSource.h >@@ -0,0 +1,77 @@ >+/* >+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(MEDIA_STREAM) >+ >+#include "FontCascade.h" >+#include "ImageBuffer.h" >+#include "MediaSample.h" >+#include "RealtimeMediaSource.h" >+#include <wtf/Lock.h> >+#include <wtf/RunLoop.h> >+ >+namespace WebCore { >+ >+class RealtimeVideoSource : public RealtimeMediaSource { >+public: >+ virtual ~RealtimeVideoSource(); >+ >+protected: >+ RealtimeVideoSource(const String& id, const String& name); >+ >+ void startProducingData() override; >+ bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) override; >+ void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) override; >+ bool applySize(const IntSize&) override; >+ bool applyFrameRate(double) override; >+ >+ void setSupportedFrameRates(const Vector<double>&&); >+ void setSupportedCaptureSizes(const Vector<IntSize>&& sizes) { m_supportedCaptureSizes = sizes; } >+ IntSize bestSupportedCaptureSizeForWidthAndHeight(std::optional<int> width, std::optional<int> height); >+ >+ void addSupportedCapabilities(RealtimeMediaSourceCapabilities&) const; >+ >+ void setDefaultSize(const IntSize& size) { m_defaultSize = size; } >+ >+ double observedFrameRate() const { return m_observedFrameRate; } >+ >+ void dispatchMediaSampleToObservers(MediaSample&); >+ >+private: >+ bool supportsFrameRate(double); >+ >+ Vector<IntSize> m_supportedCaptureSizes; >+ Vector<double> m_supportedFrameRates; >+ Deque<double> m_observedFrameTimeStamps; >+ double m_observedFrameRate { 0 }; >+ IntSize m_defaultSize; >+}; >+ >+} // namespace WebCore >+ >+#endif // ENABLE(MEDIA_STREAM) >+ >diff --git a/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm b/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm >index 9824aa754b2139b545e787c3b5211bc3e0382b28..2c114eb9bedbfd2c118915b251add623ba4e1c45 100644 >--- a/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm >+++ b/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm >@@ -213,7 +213,6 @@ void AVMediaCaptureSource::initializeSettings() > m_currentSettings.setSupportedConstraints(supportedConstraints()); > > m_currentSettings.setDeviceId(id()); >- m_currentSettings.setLabel(name()); > updateSettings(m_currentSettings); > } > >diff --git a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm >index 7e7ca7d72e6e6bfaa95369d2f8591855f37bcde1..020ffa9ea2396aa93be6c439c7a64c0337bb0902 100644 >--- a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm >+++ b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm >@@ -151,15 +151,16 @@ void MockRealtimeVideoSourceMac::updateSampleBuffer() > auto sampleBuffer = CMSampleBufferFromPixelBuffer(pixelBuffer.get()); > > // We use m_deviceOrientation to emulate sensor orientation >- videoSampleAvailable(MediaSampleAVFObjC::create(sampleBuffer.get(), m_deviceOrientation)); >+ dispatchMediaSampleToObservers(MediaSampleAVFObjC::create(sampleBuffer.get(), m_deviceOrientation)); > } > > bool MockRealtimeVideoSourceMac::applySize(const IntSize& newSize) > { >- if (size() != newSize) >- m_bufferPool = nullptr; >+ if (!MockRealtimeVideoSource::applySize(newSize)) >+ return false; > >- return MockRealtimeVideoSource::applySize(newSize); >+ m_bufferPool = nullptr; >+ return true; > } > > void MockRealtimeVideoSourceMac::orientationChanged(int orientation) >diff --git a/Source/WebCore/platform/mock/MockMediaDevice.h b/Source/WebCore/platform/mock/MockMediaDevice.h >index 882dbaf10e7d6ada06656ce1871cd20ea5b84e4a..8e777cff2e2d6d0544a375dbbd186132f0f70bcf 100644 >--- a/Source/WebCore/platform/mock/MockMediaDevice.h >+++ b/Source/WebCore/platform/mock/MockMediaDevice.h >@@ -60,7 +60,9 @@ struct MockCameraProperties { > void encode(Encoder& encoder) const > { > encoder << defaultFrameRate; >- encoder << facingModeCapability; >+ encoder << facingMode; >+ encoder << frameRates; >+ encoder << frameSizes; > } > > template <class Decoder> >@@ -71,16 +73,28 @@ struct MockCameraProperties { > if (!defaultFrameRate) > return std::nullopt; > >- std::optional<RealtimeMediaSourceSettings::VideoFacingMode> facingModeCapability; >- decoder >> facingModeCapability; >- if (!facingModeCapability) >+ std::optional<RealtimeMediaSourceSettings::VideoFacingMode> facingMode; >+ decoder >> facingMode; >+ if (!facingMode) > return std::nullopt; > >- return MockCameraProperties { *defaultFrameRate, *facingModeCapability, Color::black }; >+ std::optional<Vector<double>> frameRates; >+ decoder >> frameRates; >+ if (!frameRates) >+ return std::nullopt; >+ >+ std::optional<Vector<IntSize>> frameSizes; >+ decoder >> frameSizes; >+ if (!frameSizes) >+ return std::nullopt; >+ >+ return MockCameraProperties { *defaultFrameRate, *facingMode, *frameRates, *frameSizes, Color::black }; > } > > double defaultFrameRate { 30 }; >- RealtimeMediaSourceSettings::VideoFacingMode facingModeCapability { RealtimeMediaSourceSettings::VideoFacingMode::User }; >+ RealtimeMediaSourceSettings::VideoFacingMode facingMode { RealtimeMediaSourceSettings::VideoFacingMode::User }; >+ Vector<double> frameRates { 30, 15 }; >+ Vector<IntSize> frameSizes { { 640, 480 }, { 352, 288 }, { 320, 240 } }; > Color fillColor { Color::black }; > }; > >diff --git a/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp b/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp >index 002caf31236ecb646bf82441182cb1508746c002..02011c2d8869c5453f9bcb4bb20ad3b231c621bd 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp >+++ b/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2015-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2015-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 >@@ -47,7 +47,7 @@ class MockRealtimeAudioSourceFactory : public RealtimeMediaSource::AudioCaptureF > public: > CaptureSourceOrError createAudioCaptureSource(const CaptureDevice& device, const MediaConstraints* constraints) final > { >- for (auto& mockDevice : MockRealtimeMediaSource::audioDevices()) { >+ for (auto& mockDevice : MockRealtimeMediaSourceCenter::audioDevices()) { > if (mockDevice.persistentId() == device.persistentId()) > return MockRealtimeAudioSource::create(mockDevice.persistentId(), mockDevice.label(), constraints); > } >@@ -78,9 +78,12 @@ RealtimeMediaSource::AudioCaptureFactory& MockRealtimeAudioSource::factory() > } > > MockRealtimeAudioSource::MockRealtimeAudioSource(const String& deviceID, const String& name) >- : MockRealtimeMediaSource(deviceID, RealtimeMediaSource::Type::Audio, name) >+ : RealtimeMediaSource(deviceID, RealtimeMediaSource::Type::Audio, name) > , m_timer(RunLoop::current(), this, &MockRealtimeAudioSource::tick) > { >+ auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); >+ ASSERT(device); >+ m_device = *device; > } > > MockRealtimeAudioSource::~MockRealtimeAudioSource() >@@ -90,25 +93,46 @@ MockRealtimeAudioSource::~MockRealtimeAudioSource() > #endif > } > >-void MockRealtimeAudioSource::updateSettings(RealtimeMediaSourceSettings& settings) >+const RealtimeMediaSourceSettings& MockRealtimeAudioSource::settings() const > { >- settings.setVolume(volume()); >- settings.setEchoCancellation(echoCancellation()); >- settings.setSampleRate(sampleRate()); >+ if (!m_currentSettings) { >+ RealtimeMediaSourceSettings settings; >+ settings.setDeviceId(id()); >+ settings.setVolume(volume()); >+ settings.setEchoCancellation(echoCancellation()); >+ settings.setSampleRate(sampleRate()); >+ >+ RealtimeMediaSourceSupportedConstraints supportedConstraints; >+ supportedConstraints.setSupportsDeviceId(true); >+ supportedConstraints.setSupportsVolume(true); >+ supportedConstraints.setSupportsEchoCancellation(true); >+ supportedConstraints.setSupportsSampleRate(true); >+ settings.setSupportedConstraints(supportedConstraints); >+ >+ m_currentSettings = WTFMove(settings); >+ } >+ return m_currentSettings.value(); > } > >-void MockRealtimeAudioSource::initializeCapabilities(RealtimeMediaSourceCapabilities& capabilities) >+const RealtimeMediaSourceCapabilities& MockRealtimeAudioSource::capabilities() const > { >- capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0)); >- capabilities.setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite); >- capabilities.setSampleRate(CapabilityValueOrRange(44100, 48000)); >+ if (!m_capabilities) { >+ RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints()); >+ >+ capabilities.setDeviceId(id()); >+ capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0)); >+ capabilities.setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite); >+ capabilities.setSampleRate(CapabilityValueOrRange(44100, 48000)); >+ >+ m_capabilities = WTFMove(capabilities); >+ } >+ return m_capabilities.value(); > } > >-void MockRealtimeAudioSource::initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints& supportedConstraints) >+void MockRealtimeAudioSource::settingsDidChange() > { >- supportedConstraints.setSupportsVolume(true); >- supportedConstraints.setSupportsEchoCancellation(true); >- supportedConstraints.setSupportsSampleRate(true); >+ m_currentSettings = std::nullopt; >+ RealtimeMediaSource::settingsDidChange(); > } > > void MockRealtimeAudioSource::startProducingData() >@@ -118,7 +142,7 @@ void MockRealtimeAudioSource::startProducingData() > #endif > > if (!sampleRate()) >- setSampleRate(WTF::get<MockMicrophoneProperties>(device().properties).defaultSampleRate); >+ setSampleRate(WTF::get<MockMicrophoneProperties>(m_device.properties).defaultSampleRate); > > m_startTime = MonotonicTime::now(); > m_timer.startRepeating(renderInterval()); >@@ -127,18 +151,9 @@ void MockRealtimeAudioSource::startProducingData() > void MockRealtimeAudioSource::stopProducingData() > { > m_timer.stop(); >- m_elapsedTime += MonotonicTime::now() - m_startTime; > m_startTime = MonotonicTime::nan(); > } > >-Seconds MockRealtimeAudioSource::elapsedTime() >-{ >- if (std::isnan(m_startTime)) >- return m_elapsedTime; >- >- return m_elapsedTime + (MonotonicTime::now() - m_startTime); >-} >- > void MockRealtimeAudioSource::tick() > { > if (std::isnan(m_lastRenderTime)) >diff --git a/Source/WebCore/platform/mock/MockRealtimeAudioSource.h b/Source/WebCore/platform/mock/MockRealtimeAudioSource.h >index 381a444cef604a9d3022ea0ef800e6fea463c8b0..443dd073f0b43bc562b4a7c1a039d32065156397 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeAudioSource.h >+++ b/Source/WebCore/platform/mock/MockRealtimeAudioSource.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2015-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2015-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 >@@ -33,12 +33,12 @@ > #if ENABLE(MEDIA_STREAM) > > #include "ImageBuffer.h" >-#include "MockRealtimeMediaSource.h" >+#include "MockMediaDevice.h" > #include <wtf/RunLoop.h> > > namespace WebCore { > >-class MockRealtimeAudioSource : public MockRealtimeMediaSource { >+class MockRealtimeAudioSource : public RealtimeMediaSource { > public: > > static CaptureSourceOrError create(const String& deviceID, const String& name, const MediaConstraints*); >@@ -55,19 +55,17 @@ protected: > > virtual void render(Seconds) { } > >- Seconds elapsedTime(); > static Seconds renderInterval() { return 60_ms; } > > private: >- > bool applyVolume(double) override { return true; } > bool applySampleRate(int) override { return true; } > bool applySampleSize(int) override { return true; } > bool applyEchoCancellation(bool) override { return true; } > >- void updateSettings(RealtimeMediaSourceSettings&) override; >- void initializeCapabilities(RealtimeMediaSourceCapabilities&) override; >- void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) override; >+ const RealtimeMediaSourceCapabilities& capabilities() const final; >+ const RealtimeMediaSourceSettings& settings() const final; >+ void settingsDidChange() final; > > void tick(); > >@@ -75,11 +73,16 @@ private: > > void delaySamples(Seconds) final; > >+ mutable std::optional<RealtimeMediaSourceCapabilities> m_capabilities; >+ mutable std::optional<RealtimeMediaSourceSettings> m_currentSettings; >+ RealtimeMediaSourceSupportedConstraints m_supportedConstraints; >+ > RunLoop::Timer<MockRealtimeAudioSource> m_timer; > MonotonicTime m_startTime { MonotonicTime::nan() }; > MonotonicTime m_lastRenderTime { MonotonicTime::nan() }; > Seconds m_elapsedTime { 0_s }; > MonotonicTime m_delayUntil; >+ MockMediaDevice m_device; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp b/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp >deleted file mode 100644 >index ec441efd75e9387676655bd025d937b5387737a3..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp >+++ /dev/null >@@ -1,255 +0,0 @@ >-/* >- * Copyright (C) 2015 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. >- * 3. Neither the name of Google Inc. nor the names of its contributors >- * may be used to endorse or promote products derived from this >- * software without specific prior written permission. >- * >- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >- * "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 THE COPYRIGHT >- * OWNER 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 "MockRealtimeMediaSource.h" >- >-#if ENABLE(MEDIA_STREAM) >- >-#include "CaptureDevice.h" >-#include "Logging.h" >-#include "MediaConstraints.h" >-#include "NotImplemented.h" >-#include "RealtimeMediaSourceSettings.h" >-#include <math.h> >-#include <wtf/NeverDestroyed.h> >-#include <wtf/text/StringView.h> >- >-namespace WebCore { >- >-static inline Vector<MockMediaDevice> defaultDevices() >-{ >- return Vector<MockMediaDevice> { >- MockMediaDevice { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 1"_s, MockMicrophoneProperties { 44100 } }, >- MockMediaDevice { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 2"_s, MockMicrophoneProperties { 48000 } }, >- >- MockMediaDevice { "239c24b2-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 1"_s, MockCameraProperties { 30, RealtimeMediaSourceSettings::VideoFacingMode::User, Color::black } }, >- MockMediaDevice { "239c24b3-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 2"_s, MockCameraProperties { 15, RealtimeMediaSourceSettings::VideoFacingMode::Environment, Color::darkGray } }, >- >- MockMediaDevice { "SCREEN-1"_s, "Mock screen device 1"_s, MockDisplayProperties { 30, Color::lightGray } }, >- MockMediaDevice { "SCREEN-2"_s, "Mock screen device 2"_s, MockDisplayProperties { 10, Color::yellow } } >- }; >-} >- >-static Vector<MockMediaDevice>& devices() >-{ >- static auto devices = makeNeverDestroyed([] { >- return defaultDevices(); >- }()); >- return devices; >-} >- >-static HashMap<String, MockMediaDevice>& deviceMap() >-{ >- static auto map = makeNeverDestroyed([] { >- HashMap<String, MockMediaDevice> map; >- for (auto& device : devices()) >- map.add(device.persistentId, device); >- >- return map; >- }()); >- return map; >-} >- >-static inline Vector<CaptureDevice>& deviceListForDevice(const MockMediaDevice& device) >-{ >- if (device.isMicrophone()) >- return MockRealtimeAudioSource::audioDevices(); >- if (device.isCamera()) >- return MockRealtimeAudioSource::videoDevices(); >- >- ASSERT(device.isDisplay()); >- return MockRealtimeAudioSource::displayDevices(); >-} >- >-void MockRealtimeMediaSource::createCaptureDevice(const MockMediaDevice& device) >-{ >- deviceListForDevice(device).append(captureDeviceWithPersistentID(device.type(), device.persistentId).value()); >-} >- >-void MockRealtimeMediaSource::resetDevices() >-{ >- setDevices(defaultDevices()); >- RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); >-} >- >-void MockRealtimeMediaSource::setDevices(Vector<MockMediaDevice>&& newMockDevices) >-{ >- audioDevices().clear(); >- videoDevices().clear(); >- displayDevices().clear(); >- >- auto& mockDevices = devices(); >- mockDevices = WTFMove(newMockDevices); >- >- auto& map = deviceMap(); >- map.clear(); >- >- for (const auto& device : mockDevices) { >- map.add(device.persistentId, device); >- createCaptureDevice(device); >- } >- RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); >-} >- >-void MockRealtimeMediaSource::addDevice(const MockMediaDevice& device) >-{ >- devices().append(device); >- deviceMap().set(device.persistentId, device); >- createCaptureDevice(device); >- RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); >-} >- >-void MockRealtimeMediaSource::removeDevice(const String& persistentId) >-{ >- auto& map = deviceMap(); >- auto iterator = map.find(persistentId); >- if (iterator == map.end()) >- return; >- >- devices().removeFirstMatching([&persistentId](const auto& device) { >- return device.persistentId == persistentId; >- }); >- >- deviceListForDevice(iterator->value).removeFirstMatching([&persistentId](const auto& device) { >- return device.persistentId() == persistentId; >- }); >- >- map.remove(iterator); >- RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); >-} >- >-std::optional<CaptureDevice> MockRealtimeMediaSource::captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) >-{ >- ASSERT(!id.isEmpty()); >- >- auto& map = deviceMap(); >- auto iterator = map.find(id); >- if (iterator == map.end() || iterator->value.type() != type) >- return std::nullopt; >- >- CaptureDevice device { iterator->value.persistentId, type, iterator->value.label }; >- device.setEnabled(true); >- return WTFMove(device); >-} >- >-Vector<CaptureDevice>& MockRealtimeMediaSource::audioDevices() >-{ >- static auto audioDevices = makeNeverDestroyed([] { >- Vector<CaptureDevice> audioDevices; >- for (const auto& device : devices()) { >- if (device.type() == CaptureDevice::DeviceType::Microphone) >- audioDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Microphone, device.persistentId).value()); >- } >- return audioDevices; >- }()); >- return audioDevices; >-} >- >-Vector<CaptureDevice>& MockRealtimeMediaSource::videoDevices() >-{ >- static auto videoDevices = makeNeverDestroyed([] { >- Vector<CaptureDevice> videoDevices; >- for (const auto& device : devices()) { >- if (device.type() == CaptureDevice::DeviceType::Camera) >- videoDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Camera, device.persistentId).value()); >- } >- return videoDevices; >- }()); >- return videoDevices; >-} >- >-Vector<CaptureDevice>& MockRealtimeMediaSource::displayDevices() >-{ >- static auto displayDevices = makeNeverDestroyed([] { >- Vector<CaptureDevice> displayDevices; >- for (const auto& device : devices()) { >- if (device.type() == CaptureDevice::DeviceType::Screen) >- displayDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Screen, device.persistentId).value()); >- } >- return displayDevices; >- }()); >- >- return displayDevices; >-} >- >-MockRealtimeMediaSource::MockRealtimeMediaSource(const String& id, RealtimeMediaSource::Type type, const String& name) >- : RealtimeMediaSource(id, type, name) >- , m_device(deviceMap().get(id)) >-{ >- ASSERT(type != RealtimeMediaSource::Type::None); >- setPersistentID(String(id)); >-} >- >-void MockRealtimeMediaSource::initializeCapabilities() >-{ >- m_capabilities = std::make_unique<RealtimeMediaSourceCapabilities>(supportedConstraints()); >- m_capabilities->setDeviceId(id()); >- initializeCapabilities(*m_capabilities.get()); >-} >- >-const RealtimeMediaSourceCapabilities& MockRealtimeMediaSource::capabilities() const >-{ >- if (!m_capabilities) >- const_cast<MockRealtimeMediaSource&>(*this).initializeCapabilities(); >- return *m_capabilities; >-} >- >-void MockRealtimeMediaSource::initializeSettings() >-{ >- if (m_currentSettings.deviceId().isEmpty()) { >- m_currentSettings.setSupportedConstraints(supportedConstraints()); >- m_currentSettings.setDeviceId(id()); >- m_currentSettings.setLabel(name()); >- } >- >- updateSettings(m_currentSettings); >-} >- >-const RealtimeMediaSourceSettings& MockRealtimeMediaSource::settings() const >-{ >- const_cast<MockRealtimeMediaSource&>(*this).initializeSettings(); >- return m_currentSettings; >-} >- >-RealtimeMediaSourceSupportedConstraints& MockRealtimeMediaSource::supportedConstraints() >-{ >- if (m_supportedConstraints.supportsDeviceId()) >- return m_supportedConstraints; >- >- m_supportedConstraints.setSupportsDeviceId(true); >- initializeSupportedConstraints(m_supportedConstraints); >- >- return m_supportedConstraints; >-} >- >-} // namespace WebCore >- >-#endif // ENABLE(MEDIA_STREAM) >diff --git a/Source/WebCore/platform/mock/MockRealtimeMediaSource.h b/Source/WebCore/platform/mock/MockRealtimeMediaSource.h >deleted file mode 100644 >index 3355da661ec60e9df1a251c000ab56971cf8cb1c..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/mock/MockRealtimeMediaSource.h >+++ /dev/null >@@ -1,84 +0,0 @@ >-/* >- * Copyright (C) 2015 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. >- * 3. Neither the name of Ericsson nor the names of its contributors >- * may be used to endorse or promote products derived from this >- * software without specific prior written permission. >- * >- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >- * "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 THE COPYRIGHT >- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, >- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT >- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#if ENABLE(MEDIA_STREAM) >- >-#include "CaptureDevice.h" >-#include "MockMediaDevice.h" >-#include "RealtimeMediaSource.h" >- >-namespace WebCore { >- >-class MockRealtimeMediaSource : public RealtimeMediaSource { >-public: >- virtual ~MockRealtimeMediaSource() = default; >- >- static void setDevices(Vector<MockMediaDevice>&&); >- static void addDevice(const MockMediaDevice&); >- static void removeDevice(const String& persistentId); >- WEBCORE_EXPORT static void resetDevices(); >- >- static Vector<CaptureDevice>& audioDevices(); >- static Vector<CaptureDevice>& videoDevices(); >- static Vector<CaptureDevice>& displayDevices(); >- >- static std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&); >- >-protected: >- MockRealtimeMediaSource(const String& id, Type, const String& name); >- >- static void createCaptureDevice(const MockMediaDevice&); >- >- virtual void updateSettings(RealtimeMediaSourceSettings&) = 0; >- virtual void initializeCapabilities(RealtimeMediaSourceCapabilities&) = 0; >- virtual void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) = 0; >- >- const RealtimeMediaSourceCapabilities& capabilities() const override; >- const RealtimeMediaSourceSettings& settings() const override; >- >- RealtimeMediaSourceSupportedConstraints& supportedConstraints(); >- >- const MockMediaDevice& device() const { return m_device; } >- MockMediaDevice m_device; >- >-private: >- void initializeCapabilities(); >- void initializeSettings(); >- >- RealtimeMediaSourceSettings m_currentSettings; >- RealtimeMediaSourceSupportedConstraints m_supportedConstraints; >- std::unique_ptr<RealtimeMediaSourceCapabilities> m_capabilities; >-}; >- >-} // namespace WebCore >- >-#endif // ENABLE(MEDIA_STREAM) >diff --git a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp >index db68821e31d2ce27d8be18dfd57e06fe3056a395..d9ab7331e26d675015011a888dde76752da9555a 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp >+++ b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp >@@ -30,13 +30,79 @@ > > #if ENABLE(MEDIA_STREAM) > >+#include "CaptureDevice.h" > #include "Logging.h" >+#include "MediaConstraints.h" > #include "MockRealtimeAudioSource.h" > #include "MockRealtimeVideoSource.h" >+#include "NotImplemented.h" >+#include "RealtimeMediaSourceSettings.h" >+#include <math.h> > #include <wtf/NeverDestroyed.h> >+#include <wtf/text/StringView.h> > > namespace WebCore { > >+static inline Vector<MockMediaDevice> defaultDevices() >+{ >+ return Vector<MockMediaDevice> { >+ MockMediaDevice { "239c24b0-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 1"_s, MockMicrophoneProperties { 44100 } }, >+ MockMediaDevice { "239c24b1-2b15-11e3-8224-0800200c9a66"_s, "Mock audio device 2"_s, MockMicrophoneProperties { 48000 } }, >+ >+ MockMediaDevice { "239c24b2-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 1"_s, >+ MockCameraProperties { >+ 30, >+ RealtimeMediaSourceSettings::VideoFacingMode::User, >+ { 30.00, 27.50, 25.00, 22.50, 20.00, 17.50, 15.00, 12.50, 10.00, 7.50, 5.00 }, >+ { { 3840, 2160 }, { 1920, 1080 }, { 1280, 720 }, { 960, 540 }, { 640, 480 }, { 352, 288 }, { 320, 240 } }, >+ Color::black, >+ } }, >+ >+ MockMediaDevice { "239c24b3-2b15-11e3-8224-0800200c9a66"_s, "Mock video device 2"_s, >+ MockCameraProperties { >+ 15, >+ RealtimeMediaSourceSettings::VideoFacingMode::Environment, >+ { 25.00, 22.50, 20.00, 17.50, 15.00, 12.50, 10.00, 7.50, 5.00 }, >+ { { 1280, 720 }, { 960, 540 }, { 640, 480 }, { 352, 288 }, { 320, 240 }, { 160, 120 } }, >+ Color::darkGray, >+ } }, >+ >+ MockMediaDevice { "SCREEN-1"_s, "Mock screen device 1"_s, MockDisplayProperties { 30, Color::lightGray } }, >+ MockMediaDevice { "SCREEN-2"_s, "Mock screen device 2"_s, MockDisplayProperties { 10, Color::yellow } } >+ }; >+} >+ >+static Vector<MockMediaDevice>& devices() >+{ >+ static auto devices = makeNeverDestroyed([] { >+ return defaultDevices(); >+ }()); >+ return devices; >+} >+ >+static HashMap<String, MockMediaDevice>& deviceMap() >+{ >+ static auto map = makeNeverDestroyed([] { >+ HashMap<String, MockMediaDevice> map; >+ for (auto& device : devices()) >+ map.add(device.persistentId, device); >+ >+ return map; >+ }()); >+ return map; >+} >+ >+static inline Vector<CaptureDevice>& deviceListForDevice(const MockMediaDevice& device) >+{ >+ if (device.isMicrophone()) >+ return MockRealtimeMediaSourceCenter::audioDevices(); >+ if (device.isCamera()) >+ return MockRealtimeMediaSourceCenter::videoDevices(); >+ >+ ASSERT(device.isDisplay()); >+ return MockRealtimeMediaSourceCenter::displayDevices(); >+} >+ > MockRealtimeMediaSourceCenter& MockRealtimeMediaSourceCenter::singleton() > { > static NeverDestroyed<MockRealtimeMediaSourceCenter> center; >@@ -52,19 +118,129 @@ void MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(bool > } > } > >+static void createCaptureDevice(const MockMediaDevice& device) >+{ >+ deviceListForDevice(device).append(MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(device.type(), device.persistentId).value()); >+} >+ >+void MockRealtimeMediaSourceCenter::resetDevices() >+{ >+ setDevices(defaultDevices()); >+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); >+} >+ > void MockRealtimeMediaSourceCenter::setDevices(Vector<MockMediaDevice>&& newMockDevices) > { >- MockRealtimeMediaSource::setDevices(WTFMove(newMockDevices)); >+ audioDevices().clear(); >+ videoDevices().clear(); >+ displayDevices().clear(); >+ >+ auto& mockDevices = devices(); >+ mockDevices = WTFMove(newMockDevices); >+ >+ auto& map = deviceMap(); >+ map.clear(); >+ >+ for (const auto& device : mockDevices) { >+ map.add(device.persistentId, device); >+ createCaptureDevice(device); >+ } >+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); > } > > void MockRealtimeMediaSourceCenter::addDevice(const MockMediaDevice& device) > { >- MockRealtimeMediaSource::addDevice(device); >+ devices().append(device); >+ deviceMap().set(device.persistentId, device); >+ createCaptureDevice(device); >+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); > } > > void MockRealtimeMediaSourceCenter::removeDevice(const String& persistentId) > { >- MockRealtimeMediaSource::removeDevice(persistentId); >+ auto& map = deviceMap(); >+ auto iterator = map.find(persistentId); >+ if (iterator == map.end()) >+ return; >+ >+ devices().removeFirstMatching([&persistentId](const auto& device) { >+ return device.persistentId == persistentId; >+ }); >+ >+ deviceListForDevice(iterator->value).removeFirstMatching([&persistentId](const auto& device) { >+ return device.persistentId() == persistentId; >+ }); >+ >+ map.remove(iterator); >+ RealtimeMediaSourceCenter::singleton().captureDevicesChanged(); >+} >+ >+std::optional<MockMediaDevice> MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(const String& id) >+{ >+ ASSERT(!id.isEmpty()); >+ >+ auto& map = deviceMap(); >+ auto iterator = map.find(id); >+ if (iterator == map.end()) >+ return std::nullopt; >+ >+ return iterator->value; >+} >+ >+std::optional<CaptureDevice> MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) >+{ >+ ASSERT(!id.isEmpty()); >+ >+ auto& map = deviceMap(); >+ auto iterator = map.find(id); >+ if (iterator == map.end() || iterator->value.type() != type) >+ return std::nullopt; >+ >+ CaptureDevice device { iterator->value.persistentId, type, iterator->value.label }; >+ device.setEnabled(true); >+ return WTFMove(device); >+} >+ >+Vector<CaptureDevice>& MockRealtimeMediaSourceCenter::audioDevices() >+{ >+ static auto audioDevices = makeNeverDestroyed([] { >+ Vector<CaptureDevice> audioDevices; >+ for (const auto& device : devices()) { >+ if (device.type() == CaptureDevice::DeviceType::Microphone) >+ audioDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Microphone, device.persistentId).value()); >+ } >+ return audioDevices; >+ }()); >+ >+ return audioDevices; >+} >+ >+Vector<CaptureDevice>& MockRealtimeMediaSourceCenter::videoDevices() >+{ >+ static auto videoDevices = makeNeverDestroyed([] { >+ Vector<CaptureDevice> videoDevices; >+ for (const auto& device : devices()) { >+ if (device.type() == CaptureDevice::DeviceType::Camera) >+ videoDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Camera, device.persistentId).value()); >+ } >+ return videoDevices; >+ }()); >+ >+ return videoDevices; >+} >+ >+Vector<CaptureDevice>& MockRealtimeMediaSourceCenter::displayDevices() >+{ >+ static auto displayDevices = makeNeverDestroyed([] { >+ Vector<CaptureDevice> displayDevices; >+ for (const auto& device : devices()) { >+ if (device.type() == CaptureDevice::DeviceType::Screen) >+ displayDevices.append(captureDeviceWithPersistentID(CaptureDevice::DeviceType::Screen, device.persistentId).value()); >+ } >+ return displayDevices; >+ }()); >+ >+ return displayDevices; > } > > } // namespace WebCore >diff --git a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h >index be47a0e3e46211d4effed02c1d716579a1c45752..50b73ff1ad49275c43d3038d0061c28ffe131123 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h >+++ b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.h >@@ -1,6 +1,6 @@ > /* > * Copyright (C) 2013 Google Inc. All rights reserved. >- * Copyright (C) 2013-2107 Apple Inc. All rights reserved. >+ * Copyright (C) 2013-2108 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -29,6 +29,7 @@ > #if ENABLE(MEDIA_STREAM) > > #include "CaptureDeviceManager.h" >+#include "MockMediaDevice.h" > #include "MockRealtimeAudioSource.h" > #include "MockRealtimeVideoSource.h" > #include "RealtimeMediaSourceCenter.h" >@@ -42,10 +43,18 @@ public: > WEBCORE_EXPORT static void setDevices(Vector<MockMediaDevice>&&); > WEBCORE_EXPORT static void addDevice(const MockMediaDevice&); > WEBCORE_EXPORT static void removeDevice(const String& persistentId); >+ WEBCORE_EXPORT static void resetDevices(); > > static RealtimeMediaSource::VideoCaptureFactory& videoCaptureSourceFactory() { return MockRealtimeVideoSource::factory(); } > static RealtimeMediaSource::AudioCaptureFactory& audioCaptureSourceFactory() { return MockRealtimeAudioSource::factory(); } > >+ static Vector<CaptureDevice>& audioDevices(); >+ static Vector<CaptureDevice>& videoDevices(); >+ static Vector<CaptureDevice>& displayDevices(); >+ >+ static std::optional<MockMediaDevice> mockDeviceWithPersistentID(const String&); >+ static std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&); >+ > private: > MockRealtimeMediaSourceCenter() = default; > friend NeverDestroyed<MockRealtimeMediaSourceCenter>; >@@ -59,22 +68,20 @@ private: > CaptureDeviceManager& videoCaptureDeviceManager() final { return m_videoCaptureDeviceManager; } > CaptureDeviceManager& displayCaptureDeviceManager() final { return m_displayCaptureDeviceManager; } > >- static std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&); >- > class MockAudioCaptureDeviceManager final : public CaptureDeviceManager { > private: >- const Vector<CaptureDevice>& captureDevices() final { return MockRealtimeMediaSource::audioDevices(); } >- std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) final { return MockRealtimeMediaSource::captureDeviceWithPersistentID(type, id); } >+ const Vector<CaptureDevice>& captureDevices() final { return MockRealtimeMediaSourceCenter::audioDevices(); } >+ std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) final { return MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(type, id); } > }; > class MockVideoCaptureDeviceManager final : public CaptureDeviceManager { > private: >- const Vector<CaptureDevice>& captureDevices() final { return MockRealtimeMediaSource::videoDevices(); } >- std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) final { return MockRealtimeMediaSource::captureDeviceWithPersistentID(type, id); } >+ const Vector<CaptureDevice>& captureDevices() final { return MockRealtimeMediaSourceCenter::videoDevices(); } >+ std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) final { return MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(type, id); } > }; > class MockDisplayCaptureDeviceManager final : public CaptureDeviceManager { > private: >- const Vector<CaptureDevice>& captureDevices() final { return MockRealtimeMediaSource::displayDevices(); } >- std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) final { return MockRealtimeMediaSource::captureDeviceWithPersistentID(type, id); } >+ const Vector<CaptureDevice>& captureDevices() final { return MockRealtimeMediaSourceCenter::displayDevices(); } >+ std::optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType type, const String& id) final { return MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(type, id); } > }; > > MockAudioCaptureDeviceManager m_audioCaptureDeviceManager; >diff --git a/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp b/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp >index 9c41e1c4727ee416643227ab0e4a53c9bcc9b200..8271143332d332b6c9141a5c24f87b56af33fd03 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp >+++ b/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2015-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2015-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 >@@ -53,7 +53,7 @@ class MockRealtimeVideoSourceFactory : public RealtimeMediaSource::VideoCaptureF > public: > CaptureSourceOrError createVideoCaptureSource(const CaptureDevice& device, const MediaConstraints* constraints) final > { >- ASSERT(MockRealtimeMediaSource::captureDeviceWithPersistentID(device.type(), device.persistentId())); >+ ASSERT(MockRealtimeMediaSourceCenter::captureDeviceWithPersistentID(device.type(), device.persistentId())); > > switch (device.type()) { > case CaptureDevice::DeviceType::Camera: >@@ -105,62 +105,59 @@ RealtimeMediaSource::VideoCaptureFactory& MockRealtimeVideoSource::factory() > } > > MockRealtimeVideoSource::MockRealtimeVideoSource(const String& deviceID, const String& name) >- : MockRealtimeMediaSource(deviceID, RealtimeMediaSource::Type::Video, name) >- , m_timer(RunLoop::current(), this, &MockRealtimeVideoSource::generateFrame) >+ : RealtimeVideoSource(deviceID, name) >+ , m_emitFrameTimer(RunLoop::current(), this, &MockRealtimeVideoSource::generateFrame) > { >+ auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); >+ ASSERT(device); >+ m_device = *device; >+ > m_dashWidths.reserveInitialCapacity(2); > m_dashWidths.uncheckedAppend(6); > m_dashWidths.uncheckedAppend(6); > > if (mockScreen()) { >- setFrameRate(WTF::get<MockDisplayProperties>(device().properties).defaultFrameRate); >+ auto& properties = WTF::get<MockDisplayProperties>(m_device.properties); >+ setFrameRate(properties.defaultFrameRate); >+ m_fillColor = properties.fillColor; > return; > } > >- auto& properties = WTF::get<MockCameraProperties>(device().properties); >- setFrameRate(properties.defaultFrameRate); >- setFacingMode(properties.facingModeCapability); >+ auto& properties = WTF::get<MockCameraProperties>(m_device.properties); >+ setFrameRate(properties.frameRates[0]); >+ setFacingMode(properties.facingMode); >+ setSupportedFrameRates(WTFMove(properties.frameRates)); >+ setSupportedCaptureSizes(WTFMove(properties.frameSizes)); >+ m_fillColor = properties.fillColor; > } > >-MockRealtimeVideoSource::~MockRealtimeVideoSource() >+const RealtimeMediaSourceCapabilities& MockRealtimeVideoSource::capabilities() const > { >-#if PLATFORM(IOS) >- MockRealtimeMediaSourceCenter::videoCaptureSourceFactory().unsetActiveSource(*this); >-#endif >-} >- >-void MockRealtimeVideoSource::startProducingData() >-{ >-#if PLATFORM(IOS) >- MockRealtimeMediaSourceCenter::videoCaptureSourceFactory().setActiveSource(*this); >-#endif >+ if (!m_capabilities) { >+ RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints()); >+ >+ capabilities.setDeviceId(id()); >+ if (mockCamera()) { >+ capabilities.addFacingMode(WTF::get<MockCameraProperties>(m_device.properties).facingMode); >+ addSupportedCapabilities(capabilities); >+ } else { >+ capabilities.setWidth(CapabilityValueOrRange(72, 2880)); >+ capabilities.setHeight(CapabilityValueOrRange(45, 1800)); >+ capabilities.setFrameRate(CapabilityValueOrRange(.01, 60.0)); >+ } > >- if (size().isEmpty()) { >- setWidth(640); >- setHeight(480); >+ m_capabilities = WTFMove(capabilities); > } >- >- m_startTime = MonotonicTime::now(); >- m_timer.startRepeating(1_ms * lround(1000 / frameRate())); >-} >- >-void MockRealtimeVideoSource::stopProducingData() >-{ >- m_timer.stop(); >- m_elapsedTime += MonotonicTime::now() - m_startTime; >- m_startTime = MonotonicTime::nan(); >+ return m_capabilities.value(); > } > >-Seconds MockRealtimeVideoSource::elapsedTime() >+const RealtimeMediaSourceSettings& MockRealtimeVideoSource::settings() const > { >- if (std::isnan(m_startTime)) >- return m_elapsedTime; >+ if (m_currentSettings) >+ return m_currentSettings.value(); > >- return m_elapsedTime + (MonotonicTime::now() - m_startTime); >-} > >-void MockRealtimeVideoSource::updateSettings(RealtimeMediaSourceSettings& settings) >-{ >+ RealtimeMediaSourceSettings settings; > if (mockCamera()) > settings.setFacingMode(facingMode()); > else { >@@ -173,49 +170,74 @@ void MockRealtimeVideoSource::updateSettings(RealtimeMediaSourceSettings& settin > settings.setHeight(size.height()); > if (aspectRatio()) > settings.setAspectRatio(aspectRatio()); >+ settings.setDeviceId(id()); >+ >+ RealtimeMediaSourceSupportedConstraints supportedConstraints; >+ supportedConstraints.setSupportsDeviceId(true); >+ supportedConstraints.setSupportsFrameRate(true); >+ supportedConstraints.setSupportsWidth(true); >+ supportedConstraints.setSupportsHeight(true); >+ supportedConstraints.setSupportsAspectRatio(true); >+ if (mockCamera()) >+ supportedConstraints.setSupportsFacingMode(true); >+ settings.setSupportedConstraints(supportedConstraints); >+ >+ m_currentSettings = WTFMove(settings); >+ >+ return m_currentSettings.value(); > } > >-void MockRealtimeVideoSource::initializeCapabilities(RealtimeMediaSourceCapabilities& capabilities) >+void MockRealtimeVideoSource::settingsDidChange() > { >- if (mockCamera()) { >- capabilities.addFacingMode(WTF::get<MockCameraProperties>(device().properties).facingModeCapability); >+ m_currentSettings = std::nullopt; >+ RealtimeVideoSource::settingsDidChange(); > >- capabilities.setWidth(CapabilityValueOrRange(320, 1920)); >- capabilities.setHeight(CapabilityValueOrRange(240, 1080)); >- capabilities.setFrameRate(CapabilityValueOrRange(15.0, 60.0)); >- capabilities.setAspectRatio(CapabilityValueOrRange(4 / 3.0, 16 / 9.0)); >- } else { >- capabilities.setWidth(CapabilityValueOrRange(72, 2880)); >- capabilities.setHeight(CapabilityValueOrRange(45, 1800)); >- capabilities.setFrameRate(CapabilityValueOrRange(.01, 60.0)); >+ if (m_haveProducedData) { >+ startCaptureTimer(); >+ generateFrame(); > } > } > >-void MockRealtimeVideoSource::initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints& supportedConstraints) >+void MockRealtimeVideoSource::startCaptureTimer() > { >- supportedConstraints.setSupportsWidth(true); >- supportedConstraints.setSupportsHeight(true); >- supportedConstraints.setSupportsAspectRatio(true); >- supportedConstraints.setSupportsFrameRate(true); >- if (mockCamera()) >- supportedConstraints.setSupportsFacingMode(true); >+ m_emitFrameTimer.startRepeating(1_ms * lround(1000 / frameRate())); > } > >-bool MockRealtimeVideoSource::applyFrameRate(double rate) >+void MockRealtimeVideoSource::startProducingData() > { >- if (m_timer.isActive()) >- m_timer.startRepeating(1_ms * lround(1000 / rate)); >+ RealtimeVideoSource::startProducingData(); > >- updateSampleBuffer(); >- return true; >+ startCaptureTimer(); >+ >+ m_startTime = MonotonicTime::now(); >+ m_haveProducedData = true; >+} >+ >+void MockRealtimeVideoSource::stopProducingData() >+{ >+ m_emitFrameTimer.stop(); >+ m_elapsedTime += MonotonicTime::now() - m_startTime; >+ m_startTime = MonotonicTime::nan(); >+} >+ >+Seconds MockRealtimeVideoSource::elapsedTime() >+{ >+ if (std::isnan(m_startTime)) >+ return m_elapsedTime; >+ >+ return m_elapsedTime + (MonotonicTime::now() - m_startTime); > } > > bool MockRealtimeVideoSource::applySize(const IntSize& size) > { >+ if (!RealtimeVideoSource::applySize(size)) >+ return false; >+ > m_baseFontSize = size.height() * .08; > m_bipBopFontSize = m_baseFontSize * 2.5; > m_statsFontSize = m_baseFontSize * .5; > m_imageBuffer = nullptr; >+ > return true; > } > >@@ -344,12 +366,16 @@ void MockRealtimeVideoSource::drawText(GraphicsContext& context) > timeLocation.move(0, m_baseFontSize); > context.drawText(timeFont, TextRun((StringView(string))), timeLocation); > >- FloatPoint statsLocation(size.width() * .65, size.height() * .75); >- string = String::format("Frame rate: %ffps", frameRate()); >+ FloatPoint statsLocation(size.width() * .45, size.height() * .75); >+ string = String::format("Requested frame rate: %.1f fps", frameRate()); > context.drawText(statsFont, TextRun((StringView(string))), statsLocation); > >- string = String::format("Size: %u x %u", size.width(), size.height()); > statsLocation.move(0, m_statsFontSize); >+ string = String::format("Observed frame rate: %.1f fps", observedFrameRate()); >+ context.drawText(statsFont, TextRun((StringView(string))), statsLocation); >+ >+ statsLocation.move(0, m_statsFontSize); >+ string = String::format("Size: %u x %u", size.width(), size.height()); > context.drawText(statsFont, TextRun((StringView(string))), statsLocation); > > if (mockCamera()) { >@@ -415,8 +441,7 @@ void MockRealtimeVideoSource::generateFrame() > auto& size = this->size(); > FloatRect frameRect(FloatPoint(), size); > >- auto fillColor = mockCamera() ? WTF::get<MockCameraProperties>(device().properties).fillColor : WTF::get<MockDisplayProperties>(device().properties).fillColor; >- context.fillRect(FloatRect(FloatPoint(), size), fillColor); >+ context.fillRect(FloatRect(FloatPoint(), size), m_fillColor); > > if (!muted()) { > drawText(context); >diff --git a/Source/WebCore/platform/mock/MockRealtimeVideoSource.h b/Source/WebCore/platform/mock/MockRealtimeVideoSource.h >index a6589b875487704e8b4887a452ee37d97710a60d..25e334691ce52320832fc67ddbb7b63a34ced45e 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeVideoSource.h >+++ b/Source/WebCore/platform/mock/MockRealtimeVideoSource.h >@@ -35,7 +35,8 @@ > > #include "FontCascade.h" > #include "ImageBuffer.h" >-#include "MockRealtimeMediaSource.h" >+#include "MockMediaDevice.h" >+#include "RealtimeVideoSource.h" > #include <wtf/RunLoop.h> > > namespace WebCore { >@@ -43,28 +44,28 @@ namespace WebCore { > class FloatRect; > class GraphicsContext; > >-class MockRealtimeVideoSource : public MockRealtimeMediaSource { >+class MockRealtimeVideoSource : public RealtimeVideoSource { > public: > > static CaptureSourceOrError create(const String& deviceID, const String& name, const MediaConstraints*); > > static VideoCaptureFactory& factory(); > >- virtual ~MockRealtimeVideoSource(); >- > protected: > MockRealtimeVideoSource(const String& deviceID, const String& name); >- virtual void updateSampleBuffer() { } > >+ virtual void updateSampleBuffer() = 0; >+ >+ void setCurrentFrame(MediaSample&); > ImageBuffer* imageBuffer() const; > > Seconds elapsedTime(); > bool applySize(const IntSize&) override; > > private: >- void updateSettings(RealtimeMediaSourceSettings&) override; >- void initializeCapabilities(RealtimeMediaSourceCapabilities&) override; >- void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) override; >+ const RealtimeMediaSourceCapabilities& capabilities() const final; >+ const RealtimeMediaSourceSettings& settings() const final; >+ void settingsDidChange() final; > > void startProducingData() final; > void stopProducingData() final; >@@ -73,18 +74,18 @@ private: > void drawText(GraphicsContext&); > void drawBoxes(GraphicsContext&); > >- bool applyFrameRate(double) override; > bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) override { return true; } > bool applyAspectRatio(double) override { return true; } > > bool isCaptureSource() const final { return true; } > > void generateFrame(); >+ void startCaptureTimer(); > > void delaySamples(Seconds) override; > >- bool mockCamera() const { return WTF::holds_alternative<MockCameraProperties>(device().properties); } >- bool mockScreen() const { return WTF::holds_alternative<MockDisplayProperties>(device().properties); } >+ bool mockCamera() const { return WTF::holds_alternative<MockCameraProperties>(m_device.properties); } >+ bool mockScreen() const { return WTF::holds_alternative<MockDisplayProperties>(m_device.properties); } > > float m_baseFontSize { 0 }; > float m_bipBopFontSize { 0 }; >@@ -100,8 +101,14 @@ private: > MonotonicTime m_delayUntil; > > unsigned m_frameNumber { 0 }; >- >- RunLoop::Timer<MockRealtimeVideoSource> m_timer; >+ RunLoop::Timer<MockRealtimeVideoSource> m_emitFrameTimer; >+ mutable std::optional<RealtimeMediaSourceCapabilities> m_capabilities; >+ mutable std::optional<RealtimeMediaSourceSettings> m_currentSettings; >+ RealtimeMediaSourceSupportedConstraints m_supportedConstraints; >+ Color m_fillColor { Color::black }; >+ MockMediaDevice m_device; >+ >+ bool m_haveProducedData { false }; > }; > > } // namespace WebCore >diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp >index 46b7680e064224fac84c91afaf5b7a237de02ef0..8274855e2498ba4a4c0b2d380b32ffd7bf1b4da4 100644 >--- a/Source/WebKit/UIProcess/WebProcessPool.cpp >+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp >@@ -2280,7 +2280,7 @@ void WebProcessPool::removeMockMediaDevice(const String& persistentId) > void WebProcessPool::resetMockMediaDevices() > { > #if ENABLE(MEDIA_STREAM) >- MockRealtimeMediaSource::resetDevices(); >+ MockRealtimeMediaSourceCenter::resetDevices(); > sendToAllProcesses(Messages::WebProcess::ResetMockMediaDevices { }); > #endif > } >diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp >index 0c1aeb6cd7eb0e9789d035bae307b8bb5e5c2fb2..88409422db13cc7679cbaa8cca65138e6d9e0080 100644 >--- a/Source/WebKit/WebProcess/WebProcess.cpp >+++ b/Source/WebKit/WebProcess/WebProcess.cpp >@@ -1745,7 +1745,7 @@ void WebProcess::removeMockMediaDevice(const String& persistentId) > > void WebProcess::resetMockMediaDevices() > { >- MockRealtimeMediaSource::resetDevices(); >+ MockRealtimeMediaSourceCenter::resetDevices(); > } > #endif > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 0ecc9a1f0d116abc6698624dd1f075c14ec7876f..ae8e1d715c44c6d4349b19db7cfb47f6bfaf2bb9 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,25 @@ >+2018-08-29 Eric Carlson <eric.carlson@apple.com> >+ >+ Mock video devices should only support discrete sizes >+ https://bugs.webkit.org/show_bug.cgi?id=189000 >+ <rdar://problem/43766551> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Updated tests and results now that we have better support for width and height constraints. >+ >+ * fast/mediastream/MediaDevices-getUserMedia.html: >+ * fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt: >+ * fast/mediastream/apply-constraints-advanced-expected.txt: >+ * fast/mediastream/apply-constraints-advanced.html: >+ * fast/mediastream/apply-constraints-video-expected.txt: >+ * fast/mediastream/apply-constraints-video.html: >+ * fast/mediastream/getUserMedia-default-expected.txt: >+ * fast/mediastream/getUserMedia-default.html: >+ * imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https-expected.txt: >+ * webrtc/video-interruption.html: >+ * webrtc/video.html: >+ > 2018-08-29 Truitt Savell <tsavell@apple.com> > > Layout Test svg/animations/animate-end-attribute-numeric-precision.html is flaky >diff --git a/LayoutTests/fast/mediastream/MediaDevices-getUserMedia.html b/LayoutTests/fast/mediastream/MediaDevices-getUserMedia.html >index 591a7d6e6deca8eb443aad86a588ec6c417c06ee..3c934d5c7b573d0b3562f1514cdaeec408e6fff4 100644 >--- a/LayoutTests/fast/mediastream/MediaDevices-getUserMedia.html >+++ b/LayoutTests/fast/mediastream/MediaDevices-getUserMedia.html >@@ -100,9 +100,8 @@ > > videoConstraints = { > width: { >- min: 400, >- exact: 400, >- max: 400, >+ min: 160, >+ max: 960, > ideal: 320 > }, > height: 240, >diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt >index 41da2be124fa4dc4eb06f341f7741ce5d0a41606..431f1f01a5aa31ef4a6cd80f961c05a51e2d3984 100644 >--- a/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt >+++ b/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt >@@ -4,12 +4,12 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE > > > video track capabilities: >- capabilities.aspectRatio = { max: 1.778, min: 1.333 } >+ capabilities.aspectRatio = { max: 1.778, min: 1.222 } > capabilities.deviceId = <UUID> > capabilities.facingMode = [ user ] >- capabilities.frameRate = { max: 60, min: 15 } >- capabilities.height = { max: 1080, min: 240 } >- capabilities.width = { max: 1920, min: 320 } >+ capabilities.frameRate = { max: 30, min: 5 } >+ capabilities.height = { max: 2160, min: 240 } >+ capabilities.width = { max: 3840, min: 320 } > > audio track capabilities: > capabilities.deviceId = <UUID> >diff --git a/LayoutTests/fast/mediastream/apply-constraints-advanced-expected.txt b/LayoutTests/fast/mediastream/apply-constraints-advanced-expected.txt >index d509a555c966cb13cf95c5ca24ba84e34c56aba6..75d0bdc6634a323c3284e802b2459bc5d8222e16 100644 >--- a/LayoutTests/fast/mediastream/apply-constraints-advanced-expected.txt >+++ b/LayoutTests/fast/mediastream/apply-constraints-advanced-expected.txt >@@ -12,19 +12,19 @@ PASS video.audioTracks.length is 0 > PASS settings['width'] is 640 > PASS settings['height'] is 480 > >-** Constraint: {"width":{"min":320},"height":{"min":240},"advanced":[{"width":1920,"height":1280}]} - advanced width and height are too big, minimums are less than current, nothing is changed. >+** Constraint: {"width":{"min":320},"height":{"min":240},"advanced":[{"width":1920,"height":1280}]} - advanced width and height are not supported, minimums are less than current, nothing is changed. > PASS settings['width'] is 640 > PASS settings['height'] is 480 > >-** Constraint: {"width":{"min":640},"height":{"min":480},"advanced":[{"width":1920,"height":1280},{"width":960,"height":720}]} - first width and height in advanced are too big, second is used. >-PASS settings['width'] is 960 >-PASS settings['height'] is 720 >+** Constraint: {"width":{"min":640},"height":{"min":480},"advanced":[{"width":6000,"height":6000},{"width":1920,"height":1080}]} - first width and height in advanced are too big, second is used. >+PASS settings['width'] is 1920 >+PASS settings['height'] is 1080 > > ** Constraint: {"width":320,"height":240} - reset width and height. > PASS settings['width'] is 320 > PASS settings['height'] is 240 > >-** Constraint: {"width":{"min":640},"height":{"min":480},"advanced":[{"width":1920,"height":1280}]} - advanced width and height are too big, fall back to required minimums. >+** Constraint: {"width":{"min":640},"height":{"min":480},"advanced":[{"width":7680,"height":4320}]} - advanced width and height are too big, fall back to required minimums. > PASS settings['width'] is 640 > PASS settings['height'] is 480 > >@@ -32,16 +32,9 @@ PASS settings['height'] is 480 > PASS settings['width'] is 320 > PASS settings['height'] is 240 > >-** Constraint: {"width":{"min":640},"height":{"min":480},"advanced":[{"width":1920,"height":1280},{"aspectRatio":1.777777}]} - advanced width and height are too big, aspectRatio is used. >-PASS settings['width'] is 640 >-PASS settings['height'] is 360 >- > ** Constraint: {"advanced":[{"facingMode":"left"},{"facingMode":"right"},{"facingMode":"environment"},{"facingMode":"user"}]} - no required constraints, advanced constraints are ignored. > PASS settings['facingMode'] is "user" > >-** Constraint: {"width":{"min":640},"advanced":[{"facingMode":"left"},{"facingMode":"right"},{"facingMode":"user"}]} - first two advanced facingModes are not supported, third is used. >-PASS settings['facingMode'] is "user" >- > PASS successfullyParsed is true > > TEST COMPLETE >diff --git a/LayoutTests/fast/mediastream/apply-constraints-advanced.html b/LayoutTests/fast/mediastream/apply-constraints-advanced.html >index ca65117cbfc997c900fe1677a25887deebee4943..922e1350ccf9a3f9ab2b834c55af81e6cca0db6b 100644 >--- a/LayoutTests/fast/mediastream/apply-constraints-advanced.html >+++ b/LayoutTests/fast/mediastream/apply-constraints-advanced.html >@@ -12,7 +12,7 @@ > expected: { width: 640, height: 480 }, > }, > { >- message: "advanced width and height are too big, minimums are less than current, nothing is changed.", >+ message: "advanced width and height are not supported, minimums are less than current, nothing is changed.", > constraint: { > width: { min: 320 }, > height: { min: 240 }, >@@ -28,11 +28,11 @@ > width: { min: 640 }, > height: { min: 480 }, > advanced: [ >- { width: 1920, height: 1280 }, >- { width: 960, height: 720 }, >+ { width: 6000, height: 6000 }, >+ { width: 1920, height: 1080 }, > ] > }, >- expected: { width: 960, height: 720 }, >+ expected: { width: 1920, height: 1080 }, > }, > { > message: "reset width and height.", >@@ -45,7 +45,7 @@ > width: { min: 640 }, > height: { min: 480 }, > advanced: [ >- { width: 1920, height: 1280 }, >+ { width: 7680, height: 4320 }, > ] > }, > expected: { width: 640, height: 480 }, >@@ -55,18 +55,6 @@ > constraint: { width: 320, height: 240 }, > expected: { width: 320, height: 240 }, > }, >- { >- message: "advanced width and height are too big, aspectRatio is used.", >- constraint: { >- width: { min: 640 }, >- height: { min: 480 }, >- advanced: [ >- { width: 1920, height: 1280 }, >- { aspectRatio: 1.777777 } >- ] >- }, >- expected: { width: 640, height: 360 }, >- }, > { > message: "no required constraints, advanced constraints are ignored.", > constraint: { >@@ -79,18 +67,6 @@ > }, > expected: { facingMode: "user" }, > }, >- { >- message: "first two advanced facingModes are not supported, third is used.", >- constraint: { >- width: { min: 640 }, >- advanced: [ >- { facingMode: "left" }, >- { facingMode: "right" }, >- { facingMode: "user" }, >- ] >- }, >- expected: { facingMode: "user" }, >- }, > ]; > > let tester = new ConstraintsTest({ video: true }, tests, "Tests applyConstraints on a video stream track.") >diff --git a/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt b/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt >index 3aa71af90f74c252d8a4fe1ccab0400f87879ab2..d890d367b6c784840d00c293b4eba5626bf6f3b4 100644 >--- a/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt >+++ b/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt >@@ -37,56 +37,40 @@ PASS Promise was rejected > PASS error.constraint is "frameRate" > PASS settings['frameRate'] is 30 > >-** Constraint: {"width":{"exact":400}} - the 'exact' constraint can be satisfied. >-PASS settings['width'] is 400 >-PASS settings['height'] is 240 >+** Constraint: {"width":{"exact":960}} - the 'exact' constraint can be satisfied. >+PASS settings['width'] is 960 >+PASS settings['height'] is 540 > >-** Constraint: {"width":{"min":300,"ideal":5000}} - the 'ideal' constraint can't be satisfied but the 'min' can, max should be chosen. >-PASS settings['width'] is 1920 >-PASS settings['height'] is 240 >+** Constraint: {"width":{"min":300,"ideal":5000}} - the 'ideal' constraint can't be satisfied but the 'min' can, maximum value should be chosen. >+PASS settings['width'] is 3840 >+PASS settings['height'] is 2160 > > ** Constraint: {"width":{"min":320,"ideal":1280},"height":{"min":480,"ideal":720}} - 'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen. > PASS settings['width'] is 1280 > PASS settings['height'] is 720 > >-** Constraint: {"width":3000} - ideal width is greater than track capability, should be clamped to the maximum value. >-PASS settings['width'] is 1920 >+** Constraint: {"width":5000} - ideal width is greater than track capability, should be clamped to the maximum value. >+PASS settings['width'] is 3840 > >-** Constraint: {"width":160,"height":120,"frameRate":10} - all values are less than track capabilities, should be clamped to the minimum values. >+** Constraint: {"width":160,"height":120,"frameRate":4} - all values are less than track capabilities, should be clamped to the minimum values. > PASS settings['width'] is 320 > PASS settings['height'] is 240 >-PASS settings['frameRate'] is 15 >+PASS settings['frameRate'] is 5 > > ** Constraint: {"frameRate":20} - set frame rate, width and height should remain unchanged > PASS settings['width'] is 320 > PASS settings['height'] is 240 > PASS settings['frameRate'] is 20 > >-** Constraint: {"facingMode":"environment","height":400} - illegal facing mode value should be ignored, height should change. >+** Constraint: {"facingMode":"xnvironment","height":720} - illegal facing mode value should be ignored, height should change. > PASS settings['facingMode'] is "user" >-PASS settings['width'] is 320 >-PASS settings['height'] is 400 >+PASS settings['width'] is 1280 >+PASS settings['height'] is 720 > > ** Constraint: {"WITDH":400,"frameRate":30} - unknown constraint should be ignored, frame rate should change. >-PASS settings['width'] is 320 >+PASS settings['width'] is 1280 > PASS settings['frameRate'] is 30 > >-** Constraint: {"aspectRatio":"1.3333"} - aspect ratio should change width and height. >-PASS settings['width'] is 320 >-PASS settings['height'] is 240 >- >-** Constraint: {"aspectRatio":"1.7778"} - new aspect ratio should again change width and height. >-PASS settings['width'] is 320 >-PASS settings['height'] is 180 >- >-** Constraint: {"width":1920} - when aspect ratio has been set, changing width should change height. >-PASS settings['width'] is 1920 >-PASS settings['height'] is 1080 >- >-** Constraint: {"height":576} - when aspect ratio has been set, changing height should change width. >-PASS settings['width'] is 1024 >-PASS settings['height'] is 576 >- > PASS successfullyParsed is true > > TEST COMPLETE >diff --git a/LayoutTests/fast/mediastream/apply-constraints-video.html b/LayoutTests/fast/mediastream/apply-constraints-video.html >index 3d6917a28a1cab52b3579471c519611bae8eba1d..7765c4810598c903e2178f6bcc245cfd1cce0c12 100644 >--- a/LayoutTests/fast/mediastream/apply-constraints-video.html >+++ b/LayoutTests/fast/mediastream/apply-constraints-video.html >@@ -36,13 +36,13 @@ > }, > { > message: "the 'exact' constraint can be satisfied.", >- constraint: { width: { exact: 400 } }, >- expected: { width: 400, height: 240 }, >+ constraint: { width: { exact: 960 } }, >+ expected: { width: 960, height: 540 }, > }, > { >- message: "the 'ideal' constraint can't be satisfied but the 'min' can, max should be chosen.", >+ message: "the 'ideal' constraint can't be satisfied but the 'min' can, maximum value should be chosen.", > constraint: { width: {min: 300, ideal: 5000} }, >- expected: { width: 1920, height: 240 }, >+ expected: { width: 3840, height: 2160 }, > }, > { > message: "'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen.", >@@ -51,13 +51,13 @@ > }, > { > message: "ideal width is greater than track capability, should be clamped to the maximum value.", >- constraint: { width: 3000 }, >- expected: { width: 1920}, >+ constraint: { width: 5000 }, >+ expected: { width: 3840}, > }, > { > message: "all values are less than track capabilities, should be clamped to the minimum values.", >- constraint: { width: 160, height: 120, frameRate: 10 }, >- expected: { width: 320, height: 240, frameRate: 15 }, >+ constraint: { width: 160, height: 120, frameRate: 4 }, >+ expected: { width: 320, height: 240, frameRate: 5 }, > }, > { > message: "set frame rate, width and height should remain unchanged", >@@ -66,33 +66,13 @@ > }, > { > message: "illegal facing mode value should be ignored, height should change.", >- constraint: { facingMode: "environment", height: 400 }, >- expected: { facingMode: "user", width: 320, height: 400 }, >+ constraint: { facingMode: "xnvironment", height: 720 }, >+ expected: { facingMode: "user", width: 1280, height: 720 }, > }, > { > message: "unknown constraint should be ignored, frame rate should change.", > constraint: { WITDH: 400, frameRate: 30 }, >- expected: { width: 320, frameRate: 30 }, >- }, >- { >- message: "aspect ratio should change width and height.", >- constraint: { aspectRatio: (4/3).toFixed(4) }, >- expected: { width: 320, height: 240 }, >- }, >- { >- message: "new aspect ratio should again change width and height.", >- constraint: { aspectRatio: (16/9).toFixed(4) }, >- expected: { width: 320, height: 180 }, >- }, >- { >- message: "when aspect ratio has been set, changing width should change height.", >- constraint: { width: 1920 }, >- expected: { width: 1920, height: 1080}, >- }, >- { >- message: "when aspect ratio has been set, changing height should change width.", >- constraint: { height: 576 }, >- expected: { width: 1024, height: 576}, >+ expected: { width: 1280, frameRate: 30 }, > }, > ]; > >diff --git a/LayoutTests/fast/mediastream/getUserMedia-default-expected.txt b/LayoutTests/fast/mediastream/getUserMedia-default-expected.txt >index ab4bc8f1129a10a42a20020e85ea0cf0e9b8ed1d..a020da14c673d882804c0feefd3f81a18e682016 100644 >--- a/LayoutTests/fast/mediastream/getUserMedia-default-expected.txt >+++ b/LayoutTests/fast/mediastream/getUserMedia-default-expected.txt >@@ -2,6 +2,6 @@ > PASS Checking default video tracks settings > PASS Checking only audio capture > PASS Checking default video tracks settings except width and height >-FAIL Checking default video tracks settings except height assert_equals: frame height expected 240 but got 480 >+PASS Checking default video tracks settings except height > PASS Checking default video tracks settings except frameRate > >diff --git a/LayoutTests/fast/mediastream/getUserMedia-default.html b/LayoutTests/fast/mediastream/getUserMedia-default.html >index 91883cc10d8aaebcdbec633180ca0125de391ac9..b1440960a92c35a98229d4e1f0518b500e995c4a 100644 >--- a/LayoutTests/fast/mediastream/getUserMedia-default.html >+++ b/LayoutTests/fast/mediastream/getUserMedia-default.html >@@ -46,7 +46,7 @@ promise_test((test) => { > promise_test((test) => { > return navigator.mediaDevices.getUserMedia({ audio: true, video: { frameRate: {ideal: 60 } } }).then((stream) => { > let settings = stream.getVideoTracks()[0].getSettings(); >- assert_equals(settings.frameRate, 60, "frame rate"); >+ assert_equals(settings.frameRate, 30, "frame rate"); > assert_equals(settings.width, settings.height == 640 ? 480 : 640, "frame width"); > assert_equals(settings.height, settings.width = 640 ? 480 : 640, "frame height"); > }); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https-expected.txt >index 390863706e98838c8b40c3ac74705457f642d2d4..fa05c3e62bc5c002843f859cc8bf4c04f56e1649 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https-expected.txt >@@ -2,5 +2,5 @@ When prompted, accept to share your video stream. > > > PASS A device can be opened twice and have the same device ID >-FAIL A device can be opened twice with different resolutions assert_equals: expected 640 but got 320 >+PASS A device can be opened twice with different resolutions > >diff --git a/LayoutTests/webrtc/video-interruption.html b/LayoutTests/webrtc/video-interruption.html >index d45a22459a1ad4da6823cd5f680a8d4c42257ea1..612f1dcfcdb9cf8aaab74e8de89ff2568b32300e 100644 >--- a/LayoutTests/webrtc/video-interruption.html >+++ b/LayoutTests/webrtc/video-interruption.html >@@ -45,7 +45,7 @@ promise_test((test) => { > testRunner.setUserMediaPermission(true); > > var stream; >- return navigator.mediaDevices.getUserMedia({video: {advanced: [{width:{min:1280}}, {height:{min:720} } ]}}).then((stream) => { >+ return navigator.mediaDevices.getUserMedia({video: {advanced: [{width:{min:640}}, {height:{min:480} } ]}}).then((stream) => { > return new Promise((resolve, reject) => { > createConnections((firstConnection) => { > var track = stream.getVideoTracks()[0]; >diff --git a/LayoutTests/webrtc/video.html b/LayoutTests/webrtc/video.html >index 387e7b4e65e037a8a898b99db1769d2de380b97c..4a7ca11b7957ba6c444e5ea8a2fedaac3bc317e1 100644 >--- a/LayoutTests/webrtc/video.html >+++ b/LayoutTests/webrtc/video.html >@@ -43,7 +43,7 @@ promise_test((test) => { > if (window.testRunner) > testRunner.setUserMediaPermission(true); > >- return navigator.mediaDevices.getUserMedia({video: {advanced: [{width:{min:1280}}, {height:{min:720} } ]}}).then((stream) => { >+ return navigator.mediaDevices.getUserMedia({video: {advanced: [{width:{min:640}}, {height:{min:480} } ]}}).then((stream) => { > if (window.internals) > assert_true(internals.pageMediaState().includes('HasActiveVideoCaptureDevice'), "Unexpected HasActiveVideoCaptureDevice"); > return new Promise((resolve, reject) => { >@@ -66,9 +66,9 @@ promise_test((test) => { > }).then((stream) => { > video.srcObject = stream; > return video.play(); >- }).then(() => { >+ }).then(test.step_func(() => { > testImage(); >- }); >+ })); > }, "Basic video exchange"); > </script> > </body>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189000
:
348195
|
348232
|
348260
|
348418
|
348420
|
348462
|
348517