Title: [263844] trunk
Revision
263844
Author
you...@apple.com
Date
2020-07-02 07:05:28 -0700 (Thu, 02 Jul 2020)

Log Message

getUserMedia returns OverConstrained on Jitsi
https://bugs.webkit.org/show_bug.cgi?id=210932
<rdar://problem/64403675>

Reviewed by Philippe Normand.

Source/WebCore:

We compute the max width, max height and max frame rate across all presets.
In case a preset for the max resolution is different from the preset for the max frame rate,
we were selecting capture parameters that no preset can match.

To fix the issue, in case the frame rate constraint is not mandatory, and we do not find a preset
when starting to capture, we remove the frame rate constraint, pick the preset and choose the max frame rate from that preset.

Update mock sources to have a high resolution preset with low frame rate to enable writing a test.

Test: fast/mediastream/get-user-media-ideal-constraints.html

* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::supportsSizeAndFrameRate):
* platform/mediastream/RealtimeVideoCaptureSource.cpp:
(WebCore::RealtimeVideoCaptureSource::bestSupportedSizeAndFrameRate):
(WebCore::RealtimeVideoCaptureSource::setSizeAndFrameRate):
* platform/mediastream/VideoPreset.h:
(WebCore::VideoPreset::maxFrameRate const):
* platform/mock/MockRealtimeMediaSourceCenter.cpp:
(WebCore::defaultDevices):

LayoutTests:

We bumped the max width/height for mock sources and have to update existing tests according to that.

* 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/get-user-media-ideal-constraints-expected.txt: Added.
* fast/mediastream/get-user-media-ideal-constraints.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (263843 => 263844)


--- trunk/LayoutTests/ChangeLog	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/LayoutTests/ChangeLog	2020-07-02 14:05:28 UTC (rev 263844)
@@ -1,3 +1,21 @@
+2020-07-02  Youenn Fablet  <you...@apple.com>
+
+        getUserMedia returns OverConstrained on Jitsi
+        https://bugs.webkit.org/show_bug.cgi?id=210932
+        <rdar://problem/64403675>
+
+        Reviewed by Philippe Normand.
+
+        We bumped the max width/height for mock sources and have to update existing tests according to that.
+
+        * 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/get-user-media-ideal-constraints-expected.txt: Added.
+        * fast/mediastream/get-user-media-ideal-constraints.html: Added.
+
 2020-07-02  Karl Rackler  <rack...@apple.com>
 
         Remove expectation for fast/events/input-events-forecolor-data.html and fast/events/input-events-ime-composition.html and fast/events/input-events-selection-forecolor-data.html and fast/events/input-events-spell-checking-datatransfer.html and fast/events/offsetX-offsetY.html and fast/events/scale-and-scroll-iframe-body.html and fast/events/scale-and-scroll-iframe-window.html and fast/events/scroll-to-anchor-vertical-lr-writing-mode.html and fast/events/scroll-to-anchor-vertical-writing-mode.html and fast/forms/range/slider-transformed.html and fast/forms/range/slider-zoomed.html and fast/frames/content-opacity-1.html and fast/frames/content-opacity-2.html and fast/frames/iframe-text-contents.html and fast/frames/onlyCommentInIFrame.html and fast/frames/paint-iframe-background.html and fast/frames/sandboxed-iframe-close-top-noclose.html and fast/hidpi/image-srcset-invalid-descriptor.html and fast/hidpi/image-srcset-png-canvas.html and fast/html/listing
 .html as they are passing. 

Modified: trunk/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt (263843 => 263844)


--- trunk/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities-expected.txt	2020-07-02 14:05:28 UTC (rev 263844)
@@ -8,8 +8,8 @@
   capabilities.deviceId = <UUID>
   capabilities.facingMode = [ user ]
   capabilities.frameRate = { max: 30, min: 5 }
-  capabilities.height = { max: 720, min: 1 }
-  capabilities.width = { max: 1280, min: 1 }
+  capabilities.height = { max: 1440, min: 1 }
+  capabilities.width = { max: 2560, min: 1 }
 
 audio track capabilities:
   capabilities.deviceId = <UUID>

Modified: trunk/LayoutTests/fast/mediastream/apply-constraints-advanced-expected.txt (263843 => 263844)


--- trunk/LayoutTests/fast/mediastream/apply-constraints-advanced-expected.txt	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-advanced-expected.txt	2020-07-02 14:05:28 UTC (rev 263844)
@@ -12,7 +12,7 @@
 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 not supported, minimums are less than current, nothing is changed.
+** Constraint: {"width":{"min":320},"height":{"min":240},"advanced":[{"width":3000,"height":2000}]} - 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
 

Modified: trunk/LayoutTests/fast/mediastream/apply-constraints-advanced.html (263843 => 263844)


--- trunk/LayoutTests/fast/mediastream/apply-constraints-advanced.html	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-advanced.html	2020-07-02 14:05:28 UTC (rev 263844)
@@ -17,7 +17,7 @@
                                     width: { min: 320 },
                                     height: { min: 240 },
                                     advanced: [
-                                        { width: 1920, height: 1280 },
+                                        { width: 3000, height: 2000 },
                                     ]
                                 },
                     expected: { width: 640, height: 480 }, 

Modified: trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt (263843 => 263844)


--- trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt	2020-07-02 14:05:28 UTC (rev 263844)
@@ -18,7 +18,7 @@
 PASS settings['height'] is 240
 PASS settings['frameRate'] is 30
 
-** Constraint: {"width":{"exact":2000}} - the 'exact' constraint can't be satisfied, promise should reject and no settings should change.
+** Constraint: {"width":{"exact":3000}} - the 'exact' constraint can't be satisfied, promise should reject and no settings should change.
 PASS Promise was rejected
 PASS error.constraint is "width"
 PASS settings['width'] is 320
@@ -42,8 +42,8 @@
 PASS settings['height'] is 480
 
 ** 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 1280
-PASS settings['height'] is 720
+PASS settings['width'] is 2560
+PASS settings['height'] is 1440
 
 ** Constraint: {"width":{"min":320,"ideal":640},"height":{"min":480,"ideal":720}} - 'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen.
 PASS settings['width'] is 640
@@ -50,7 +50,7 @@
 PASS settings['height'] is 720
 
 ** Constraint: {"width":5000} - ideal width is greater than track capability, should be clamped to the maximum value.
-PASS settings['width'] is 1280
+PASS settings['width'] is 2560
 
 ** Constraint: {"width":100,"height":100,"frameRate":4} - frameRate value is less than track capabilities, should be clamped to the minimum values.
 PASS settings['width'] is 100

Modified: trunk/LayoutTests/fast/mediastream/apply-constraints-video.html (263843 => 263844)


--- trunk/LayoutTests/fast/mediastream/apply-constraints-video.html	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-video.html	2020-07-02 14:05:28 UTC (rev 263844)
@@ -18,7 +18,7 @@
                 },
                 {
                     message: "the 'exact' constraint can't be satisfied, promise should reject and no settings should change.",
-                    constraint: { width: { exact: 2000 } }, 
+                    constraint: { width: { exact: 3000 } },
                     expected: { width: 320, height: 240, frameRate: 30 },
                     error: "width",
                 },
@@ -42,7 +42,7 @@
                 {
                     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: 1280, height: 720 },
+                    expected: { width: 2560, height: 1440 },
                 },
                 {
                     message: "'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen.",
@@ -52,7 +52,7 @@
                 {
                     message: "ideal width is greater than track capability, should be clamped to the maximum value.",
                     constraint: { width: 5000 },
-                    expected: { width: 1280},
+                    expected: { width: 2560},
                 },
                 {
                     message: "frameRate value is less than track capabilities, should be clamped to the minimum values.",

Added: trunk/LayoutTests/fast/mediastream/get-user-media-ideal-constraints-expected.txt (0 => 263844)


--- trunk/LayoutTests/fast/mediastream/get-user-media-ideal-constraints-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/get-user-media-ideal-constraints-expected.txt	2020-07-02 14:05:28 UTC (rev 263844)
@@ -0,0 +1,4 @@
+
+
+PASS Ideal constraints 
+

Added: trunk/LayoutTests/fast/mediastream/get-user-media-ideal-constraints.html (0 => 263844)


--- trunk/LayoutTests/fast/mediastream/get-user-media-ideal-constraints.html	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/get-user-media-ideal-constraints.html	2020-07-02 14:05:28 UTC (rev 263844)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Test passing constraints to getUserMedia</title>
+    <script src=""
+    <script src=""
+</head>
+<body>
+<video autoplay playsinline id="localVideo"></video>
+<script>
+promise_test(async (test) => {
+    localVideo.srcObject = await navigator.mediaDevices.getUserMedia({video: {width: 2000, height: 1200, frameRate: 30 }});
+
+    const settings = localVideo.srcObject.getVideoTracks()[0].getSettings();
+    assert_equals(settings.width, 2000, "settings width");
+    assert_equals(settings.height, 1200, "settings width");
+    assert_equals(settings.frameRate, 10, "settings frameRate");
+
+    await localVideo.play();
+
+    assert_equals(localVideo.videoWidth, 2000, "video width");
+    assert_equals(localVideo.videoHeight, 1200, "video height");
+}, "Ideal constraints");
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (263843 => 263844)


--- trunk/Source/WebCore/ChangeLog	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/Source/WebCore/ChangeLog	2020-07-02 14:05:28 UTC (rev 263844)
@@ -1,3 +1,32 @@
+2020-07-02  Youenn Fablet  <you...@apple.com>
+
+        getUserMedia returns OverConstrained on Jitsi
+        https://bugs.webkit.org/show_bug.cgi?id=210932
+        <rdar://problem/64403675>
+
+        Reviewed by Philippe Normand.
+
+        We compute the max width, max height and max frame rate across all presets.
+        In case a preset for the max resolution is different from the preset for the max frame rate,
+        we were selecting capture parameters that no preset can match.
+
+        To fix the issue, in case the frame rate constraint is not mandatory, and we do not find a preset
+        when starting to capture, we remove the frame rate constraint, pick the preset and choose the max frame rate from that preset.
+
+        Update mock sources to have a high resolution preset with low frame rate to enable writing a test.
+
+        Test: fast/mediastream/get-user-media-ideal-constraints.html
+
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::supportsSizeAndFrameRate):
+        * platform/mediastream/RealtimeVideoCaptureSource.cpp:
+        (WebCore::RealtimeVideoCaptureSource::bestSupportedSizeAndFrameRate):
+        (WebCore::RealtimeVideoCaptureSource::setSizeAndFrameRate):
+        * platform/mediastream/VideoPreset.h:
+        (WebCore::VideoPreset::maxFrameRate const):
+        * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+        (WebCore::defaultDevices):
+
 2020-07-02  Carlos Garcia Campos  <cgar...@igalia.com>
 
         Unreviewed. Fix GTK4 build

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (263843 => 263844)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2020-07-02 14:05:28 UTC (rev 263844)
@@ -360,6 +360,10 @@
 
     // Each of the non-null values is supported individually, see if they all can be applied at the same time.
     if (!supportsSizeAndFrameRate(WTFMove(width), WTFMove(height), WTFMove(frameRate))) {
+        // Let's try without frame rate constraint if not mandatory.
+        if (frameRateConstraint && !frameRateConstraint->isMandatory() && supportsSizeAndFrameRate(WTFMove(width), WTFMove(height), { }))
+            return true;
+
         if (widthConstraint)
             badConstraint = widthConstraint->name();
         else if (heightConstraint)

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp (263843 => 263844)


--- trunk/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp	2020-07-02 14:05:28 UTC (rev 263844)
@@ -234,6 +234,13 @@
     return candidate.size.width() <= current.size.width() && candidate.size.height() <= current.size.height() && prefersPreset(candidate);
 }
 
+static inline double frameRateFromPreset(const VideoPreset& preset, double currentFrameRate)
+{
+    auto minFrameRate = preset.minFrameRate();
+    auto maxFrameRate = preset.maxFrameRate();
+    return currentFrameRate >= minFrameRate && currentFrameRate <= maxFrameRate ? currentFrameRate : maxFrameRate;
+}
+
 Optional<RealtimeVideoCaptureSource::CaptureSizeAndFrameRate> RealtimeVideoCaptureSource::bestSupportedSizeAndFrameRate(Optional<int> requestedWidth, Optional<int> requestedHeight, Optional<double> requestedFrameRate)
 {
     if (!requestedWidth && !requestedHeight && !requestedFrameRate)
@@ -243,10 +250,7 @@
         requestedWidth = size().width();
         requestedHeight = size().height();
     }
-    if (!requestedFrameRate)
-        requestedFrameRate = frameRate();
 
-    CaptureSizeAndFrameRate result;
     RefPtr<VideoPreset> exactSizePreset;
     RefPtr<VideoPreset> aspectRatioPreset;
     IntSize aspectRatioMatchSize;
@@ -256,12 +260,12 @@
     for (const auto& preset : presets()) {
         const auto& presetSize = preset->size;
 
-        if (!presetSupportsFrameRate(&preset.get(), requestedFrameRate.value()))
+        if (requestedFrameRate && !presetSupportsFrameRate(&preset.get(), requestedFrameRate.value()))
             continue;
 
         if (!requestedWidth && !requestedHeight) {
-            result.requestedFrameRate = requestedFrameRate.value();
-            return result;
+            exactSizePreset = preset.ptr();
+            break;
         }
 
         // Don't look at presets smaller than the requested resolution because we never want to resize larger.
@@ -337,22 +341,19 @@
         return { };
     }
 
-    result.requestedFrameRate = requestedFrameRate.value();
     if (exactSizePreset) {
-        result.encodingPreset = exactSizePreset;
-        result.requestedSize = exactSizePreset->size;
-        return result;
+        auto size = exactSizePreset->size;
+        auto captureFrameRate = requestedFrameRate ? *requestedFrameRate : frameRateFromPreset(*exactSizePreset, frameRate());
+        return CaptureSizeAndFrameRate { WTFMove(exactSizePreset), size, captureFrameRate };
     }
 
     if (aspectRatioPreset) {
-        result.encodingPreset = aspectRatioPreset;
-        result.requestedSize = aspectRatioMatchSize;
-        return result;
+        auto captureFrameRate = requestedFrameRate ? *requestedFrameRate : frameRateFromPreset(*aspectRatioPreset, frameRate());
+        return CaptureSizeAndFrameRate { WTFMove(aspectRatioPreset), aspectRatioMatchSize, captureFrameRate };
     }
 
-    result.encodingPreset = resizePreset;
-    result.requestedSize = resizeSize;
-    return result;
+    auto captureFrameRate = requestedFrameRate ? *requestedFrameRate : frameRateFromPreset(*resizePreset, frameRate());
+    return CaptureSizeAndFrameRate { WTFMove(resizePreset), resizeSize, captureFrameRate };
 }
 
 void RealtimeVideoCaptureSource::setSizeAndFrameRate(Optional<int> width, Optional<int> height, Optional<double> frameRate)
@@ -365,10 +366,13 @@
         height = size.height();
     }
 
-    Optional<RealtimeVideoCaptureSource::CaptureSizeAndFrameRate> match = bestSupportedSizeAndFrameRate(width, height, frameRate);
-    ASSERT(match);
-    if (!match)
-        return;
+    auto match = bestSupportedSizeAndFrameRate(width, height, frameRate);
+    if (!match) {
+        match = bestSupportedSizeAndFrameRate(width, height, { });
+        ASSERT(match);
+        if (!match)
+            return;
+    }
 
     setFrameRateWithPreset(match->requestedFrameRate, match->encodingPreset);
 

Modified: trunk/Source/WebCore/platform/mediastream/VideoPreset.h (263843 => 263844)


--- trunk/Source/WebCore/platform/mediastream/VideoPreset.h	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/Source/WebCore/platform/mediastream/VideoPreset.h	2020-07-02 14:05:28 UTC (rev 263844)
@@ -114,6 +114,9 @@
     Vector<FrameRateRange> frameRateRanges;
     VideoPresetType type;
 
+    double maxFrameRate() const;
+    double minFrameRate() const;
+
     void log()const;
 
 protected:
@@ -132,6 +135,26 @@
         WTFLogAlways("VideoPreset frame rate range [%f, %f]", range.minimum, range.maximum);
 }
 
+inline double VideoPreset::minFrameRate() const
+{
+    double minFrameRate = std::numeric_limits<double>::max();
+    for (auto& range : frameRateRanges) {
+        if (minFrameRate > range.minimum)
+            minFrameRate = range.minimum;
+    }
+    return minFrameRate;
+}
+
+inline double VideoPreset::maxFrameRate() const
+{
+    double maxFrameRate = 0;
+    for (auto& range : frameRateRanges) {
+        if (maxFrameRate < range.maximum)
+            maxFrameRate = range.maximum;
+    }
+    return maxFrameRate;
+}
+
 } // namespace WebCore
 
 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::VideoPreset)

Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp (263843 => 263844)


--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp	2020-07-02 12:41:34 UTC (rev 263843)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp	2020-07-02 14:05:28 UTC (rev 263844)
@@ -59,6 +59,7 @@
             MockCameraProperties {
                 30,
                 RealtimeMediaSourceSettings::VideoFacingMode::User, {
+                    { { 2560, 1440 }, { { 10, 10 }, { 7.5, 7.5 }, { 5, 5 } } },
                     { { 1280, 720 }, { { 30, 30}, { 27.5, 27.5}, { 25, 25}, { 22.5, 22.5}, { 20, 20}, { 17.5, 17.5}, { 15, 15}, { 12.5, 12.5}, { 10, 10}, { 7.5, 7.5}, { 5, 5} } },
                     { { 640, 480 },  { { 30, 30}, { 27.5, 27.5}, { 25, 25}, { 22.5, 22.5}, { 20, 20}, { 17.5, 17.5}, { 15, 15}, { 12.5, 12.5}, { 10, 10}, { 7.5, 7.5}, { 5, 5} } },
                     { { 112, 112 },  { { 30, 30}, { 27.5, 27.5}, { 25, 25}, { 22.5, 22.5}, { 20, 20}, { 17.5, 17.5}, { 15, 15}, { 12.5, 12.5}, { 10, 10}, { 7.5, 7.5}, { 5, 5} } },
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to