[MediaStream] Include supported frame rates in video capture presets
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Sep 2018 22:10:16 +0000 (22:10 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Sep 2018 22:10:16 +0000 (22:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189351
<rdar://problem/44188917>

Reviewed by Youenn Fablet.

No new tests, no functionality changed.

Include frame rates as well as width/height in video capture presets, so the mock video
capture devices model real camera devices more closely.

* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::setSizeAndFrameRate): Renamed from applySizeAndFrameRate. Use
setSize instead of setWidth and setHeight.
(WebCore::RealtimeMediaSource::applyConstraints): applySizeAndFrameRate -> setSizeAndFrameRate.
(WebCore::RealtimeMediaSource::applySizeAndFrameRate): Deleted.
(WebCore::RealtimeMediaSource::setWidth): Deleted.
(WebCore::RealtimeMediaSource::setHeight): Deleted.
* platform/mediastream/RealtimeMediaSource.h:

* platform/mediastream/RealtimeVideoSource.cpp:
(WebCore::RealtimeVideoSource::setSupportedPresets): New.
(WebCore::updateMinMax):
(WebCore::RealtimeVideoSource::addSupportedCapabilities const): Calculate capabilities from
presets.
(WebCore::RealtimeVideoSource::supportsSizeAndFrameRate): Use bestSupportedSizeAndFrameRate.
(WebCore::RealtimeVideoSource::bestSupportedSizeAndFrameRate):
(WebCore::RealtimeVideoSource::setSizeAndFrameRate):
(WebCore::RealtimeVideoSource::setSupportedFrameRates): Deleted.
(WebCore::RealtimeVideoSource::bestSupportedCaptureSizeForWidthAndHeight): Deleted.
(WebCore::RealtimeVideoSource::applySizeAndFrameRate): Deleted.
(WebCore::RealtimeVideoSource::supportsFrameRate): Deleted.
* platform/mediastream/RealtimeVideoSource.h:
(WebCore::RealtimeVideoSource::setSupportedCaptureSizes): Deleted.
* platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp:
(WebCore::GStreamerVideoCaptureSource::stopProducingData):
* platform/mediastream/mac/AVVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::setSizeAndFrameRate):
(WebCore::AVVideoCaptureSource::applySizeAndFrameRate): Deleted.
* platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
(WebCore::ScreenDisplayCaptureSourceMac::createDisplayStream):
* platform/mock/MockMediaDevice.h:
(WebCore::MockCameraProperties::encode const):
(WebCore::MockCameraProperties::decode):
(WebCore::MockDisplayProperties::encode const):
(WebCore::MockDisplayProperties::decode):
* platform/mock/MockRealtimeMediaSourceCenter.cpp:
(WebCore::defaultDevices):
* platform/mock/MockRealtimeVideoSource.cpp:
(WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
(WebCore::MockRealtimeVideoSource::capabilities const):
(WebCore::MockRealtimeVideoSource::settings const):

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

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSource.h
Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp
Source/WebCore/platform/mediastream/RealtimeVideoSource.h
Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm
Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm
Source/WebCore/platform/mock/MockMediaDevice.h
Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp
Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp

index c3a379f..fad9190 100644 (file)
@@ -1,3 +1,59 @@
+2018-09-06  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Include supported frame rates in video capture presets
+        https://bugs.webkit.org/show_bug.cgi?id=189351
+        <rdar://problem/44188917>
+
+        Reviewed by Youenn Fablet.
+
+        No new tests, no functionality changed.
+
+        Include frame rates as well as width/height in video capture presets, so the mock video
+        capture devices model real camera devices more closely.
+
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::setSizeAndFrameRate): Renamed from applySizeAndFrameRate. Use
+        setSize instead of setWidth and setHeight.
+        (WebCore::RealtimeMediaSource::applyConstraints): applySizeAndFrameRate -> setSizeAndFrameRate.
+        (WebCore::RealtimeMediaSource::applySizeAndFrameRate): Deleted.
+        (WebCore::RealtimeMediaSource::setWidth): Deleted.
+        (WebCore::RealtimeMediaSource::setHeight): Deleted.
+        * platform/mediastream/RealtimeMediaSource.h:
+
+        * platform/mediastream/RealtimeVideoSource.cpp:
+        (WebCore::RealtimeVideoSource::setSupportedPresets): New.
+        (WebCore::updateMinMax):
+        (WebCore::RealtimeVideoSource::addSupportedCapabilities const): Calculate capabilities from
+        presets.
+        (WebCore::RealtimeVideoSource::supportsSizeAndFrameRate): Use bestSupportedSizeAndFrameRate.
+        (WebCore::RealtimeVideoSource::bestSupportedSizeAndFrameRate): 
+        (WebCore::RealtimeVideoSource::setSizeAndFrameRate):
+        (WebCore::RealtimeVideoSource::setSupportedFrameRates): Deleted.
+        (WebCore::RealtimeVideoSource::bestSupportedCaptureSizeForWidthAndHeight): Deleted.
+        (WebCore::RealtimeVideoSource::applySizeAndFrameRate): Deleted.
+        (WebCore::RealtimeVideoSource::supportsFrameRate): Deleted.
+        * platform/mediastream/RealtimeVideoSource.h:
+        (WebCore::RealtimeVideoSource::setSupportedCaptureSizes): Deleted.
+        * platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp:
+        (WebCore::GStreamerVideoCaptureSource::stopProducingData):
+        * platform/mediastream/mac/AVVideoCaptureSource.h:
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSource::setSizeAndFrameRate):
+        (WebCore::AVVideoCaptureSource::applySizeAndFrameRate): Deleted.
+        * platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
+        (WebCore::ScreenDisplayCaptureSourceMac::createDisplayStream):
+        * platform/mock/MockMediaDevice.h:
+        (WebCore::MockCameraProperties::encode const):
+        (WebCore::MockCameraProperties::decode):
+        (WebCore::MockDisplayProperties::encode const):
+        (WebCore::MockDisplayProperties::decode):
+        * platform/mock/MockRealtimeMediaSourceCenter.cpp:
+        (WebCore::defaultDevices):
+        * platform/mock/MockRealtimeVideoSource.cpp:
+        (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource):
+        (WebCore::MockRealtimeVideoSource::capabilities const):
+        (WebCore::MockRealtimeVideoSource::settings const):
+
 2018-09-06  Antti Koivisto  <antti@apple.com>
 
         Actively prewarm processes created for prewarm pool
index 07113fe..f2793f3 100644 (file)
@@ -438,12 +438,14 @@ static void applyNumericConstraint(const NumericConstraint<ValueType>& constrain
         (source.*applier)(value);
 }
 
-void RealtimeMediaSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
+void RealtimeMediaSource::setSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
 {
+    IntSize size = this->size();
     if (width)
-        setWidth(width.value());
+        size.setWidth(width.value());
     if (height)
-        setHeight(height.value());
+        size.setHeight(height.value());
+    setSize(size);
     if (frameRate)
         setFrameRate(frameRate.value());
 }
@@ -816,7 +818,7 @@ void RealtimeMediaSource::applyConstraints(const FlattenedConstraint& constraint
     }
 
     if (width || height || frameRate)
-        applySizeAndFrameRate(WTFMove(width), WTFMove(height), WTFMove(frameRate));
+        setSizeAndFrameRate(WTFMove(width), WTFMove(height), WTFMove(frameRate));
 
     for (auto& variant : constraints) {
         if (variant.constraintType() == MediaConstraintType::Width || variant.constraintType() == MediaConstraintType::Height || variant.constraintType() == MediaConstraintType::FrameRate)
@@ -865,30 +867,6 @@ void RealtimeMediaSource::setSize(const IntSize& size)
     settingsDidChange(changed);
 }
 
-void RealtimeMediaSource::setWidth(int width)
-{
-    if (width == m_size.width())
-        return;
-
-    m_size.setWidth(width);
-    if (m_aspectRatio)
-        m_size.setHeight(width / m_aspectRatio);
-
-    settingsDidChange({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height });
-}
-
-void RealtimeMediaSource::setHeight(int height)
-{
-    if (height == m_size.height())
-        return;
-
-    if (m_aspectRatio)
-        m_size.setWidth(height * m_aspectRatio);
-    m_size.setHeight(height);
-
-    settingsDidChange({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height });
-}
-
 void RealtimeMediaSource::setFrameRate(double rate)
 {
     if (m_frameRate == rate)
index e08e656..1e1bb82 100644 (file)
@@ -165,8 +165,6 @@ public:
     WEBCORE_EXPORT void addObserver(Observer&);
     WEBCORE_EXPORT void removeObserver(Observer&);
 
-    void setWidth(int);
-    void setHeight(int);
     void setSize(const IntSize&);
     const IntSize& size() const { return m_size; }
 
@@ -233,7 +231,7 @@ protected:
     bool supportsSizeAndFrameRate(std::optional<IntConstraint> width, std::optional<IntConstraint> height, std::optional<DoubleConstraint>, String&, double& fitnessDistance);
 
     virtual bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
-    virtual void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
+    virtual void setSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
 
     void notifyMutedObservers() const;
     void notifyMutedChange(bool muted);
index f3fc4ea..b3ad6cb 100644 (file)
@@ -58,84 +58,116 @@ void RealtimeVideoSource::prepareToProduceData()
         setSize(m_defaultSize);
 }
 
-void RealtimeVideoSource::setSupportedFrameRates(Vector<double>&& rates)
+void RealtimeVideoSource::setSupportedPresets(RealtimeVideoSource::VideoPresets&& presets)
 {
-    m_supportedFrameRates = WTFMove(rates);
-    std::sort(m_supportedFrameRates.begin(), m_supportedFrameRates.end());
+    m_presets = WTFMove(presets);
+    std::sort(m_presets.begin(), m_presets.end(),
+        [&] (const auto& a, const auto& b) -> bool {
+            return (a.size.width() * a.size.height()) < (b.size.width() * b.size.height());
+    });
+    
+    for (auto& preset : m_presets) {
+        std::sort(preset.frameRateRanges.begin(), preset.frameRateRanges.end(),
+            [&] (const auto& a, const auto& b) -> bool {
+                return a.minimum < b.minimum;
+        });
+    }
 }
 
-void RealtimeVideoSource::addSupportedCapabilities(RealtimeMediaSourceCapabilities& capabilities) const
+template <typename ValueType>
+static void updateMinMax(ValueType& min, ValueType& max, ValueType value)
 {
-    ASSERT(!m_supportedCaptureSizes.isEmpty());
-    ASSERT(!m_supportedFrameRates.isEmpty());
+    min = std::min<ValueType>(min, value);
+    max = std::max<ValueType>(max, value);
+}
 
-    capabilities.setFrameRate({ m_supportedFrameRates[0], m_supportedFrameRates[m_supportedFrameRates.size() - 1] });
+void RealtimeVideoSource::addSupportedCapabilities(RealtimeMediaSourceCapabilities& capabilities) const
+{
+    ASSERT(!m_presets.isEmpty());
 
     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 (const 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());
+    double minimumAspectRatio = std::numeric_limits<double>::max();
+    double maximumAspectRatio = 0;
+    double minimumFrameRate = std::numeric_limits<double>::max();
+    double maximumFrameRate = 0;
+    for (const auto& preset : m_presets) {
+        const auto& size = preset.size;
+        updateMinMax(minimumWidth, maximumWidth, size.width());
+        updateMinMax(minimumHeight, maximumHeight, size.height());
+
+        updateMinMax(minimumAspectRatio, maximumAspectRatio, static_cast<double>(size.width()) / size.height());
+
+        for (const auto& rate : preset.frameRateRanges) {
+            updateMinMax(minimumFrameRate, maximumFrameRate, rate.minimum);
+            updateMinMax(minimumFrameRate, maximumFrameRate, rate.maximum);
+        }
     }
-
     capabilities.setWidth({ minimumWidth, maximumWidth });
     capabilities.setHeight({ minimumHeight, maximumHeight });
     capabilities.setAspectRatio({ minimumAspectRatio, maximumAspectRatio });
+    capabilities.setFrameRate({ minimumFrameRate, maximumFrameRate });
 }
 
 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.isEmpty())
-            return false;
-
-        if (bestSupportedCaptureSizeForWidthAndHeight(width, height).isEmpty())
-            return false;
-    }
-
-    if (!frameRate)
+    if (!width && !height && !frameRate)
         return true;
 
-    return supportsFrameRate(frameRate.value());
+    return !!bestSupportedSizeAndFrameRate(width, height, frameRate);
 }
 
-IntSize RealtimeVideoSource::bestSupportedCaptureSizeForWidthAndHeight(std::optional<int> width, std::optional<int> height)
+std::optional<RealtimeVideoSource::CaptureSizeAndFrameRate> RealtimeVideoSource::bestSupportedSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
 {
-    if (!width && !height)
+    if (!width && !height && !frameRate)
         return { };
 
-    for (auto size : m_supportedCaptureSizes) {
-        if ((!width || width.value() == size.width()) && (!height || height.value() == size.height()))
-            return size;
+    CaptureSizeAndFrameRate match;
+    for (const auto& preset : m_presets) {
+        const auto& size = preset.size;
+        if ((width && width.value() != size.width()) || (height && height.value() != size.height()))
+            continue;
+
+        match.size = size;
+        if (!frameRate) {
+            match.frameRate = preset.frameRateRanges[preset.frameRateRanges.size() - 1].maximum;
+            return match;
+        }
+
+        const double epsilon = 0.001;
+        for (const auto& rate : preset.frameRateRanges) {
+            if (frameRate.value() + epsilon >= rate.minimum && frameRate.value() - epsilon <= rate.maximum) {
+                match.frameRate = frameRate.value();
+                return match;
+            }
+        }
+
+        break;
     }
 
     return { };
 }
 
-void RealtimeVideoSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
+void RealtimeVideoSource::setSizeAndFrameRate(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);
-    }
+    std::optional<RealtimeVideoSource::CaptureSizeAndFrameRate> match;
+
+    // If only the framerate is changing, first see if it is supported with the current width and height.
+    auto size = this->size();
+    if (!width && !height && !size.isEmpty())
+        match = bestSupportedSizeAndFrameRate(size.width(), size.height(), frameRate);
+
+    if (!match)
+        match = bestSupportedSizeAndFrameRate(width, height, frameRate);
 
-    if (frameRate)
-        setFrameRate(frameRate.value());
+    ASSERT(match);
+    if (!match)
+        return;
+
+    setSize(match->size);
+    setFrameRate(match->frameRate);
 }
 
 void RealtimeVideoSource::dispatchMediaSampleToObservers(MediaSample& sample)
@@ -157,16 +189,6 @@ void RealtimeVideoSource::dispatchMediaSampleToObservers(MediaSample& sample)
     videoSampleAvailable(sample);
 }
 
-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)
index 6a2d4a1..1fb0334 100644 (file)
@@ -36,6 +36,9 @@
 
 namespace WebCore {
 
+struct FrameRateRange;
+struct VideoPreset;
+
 class RealtimeVideoSource : public RealtimeMediaSource {
 public:
     virtual ~RealtimeVideoSource();
@@ -45,11 +48,16 @@ protected:
 
     void prepareToProduceData();
     bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
-    void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
+    void setSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
+
+    using VideoPresets = Vector<VideoPreset>;
+    void setSupportedPresets(VideoPresets&&);
 
-    void setSupportedFrameRates(Vector<double>&&);
-    void setSupportedCaptureSizes(const Vector<IntSize>&& sizes) { m_supportedCaptureSizes = sizes; }
-    IntSize bestSupportedCaptureSizeForWidthAndHeight(std::optional<int> width, std::optional<int> height);
+    struct CaptureSizeAndFrameRate {
+        IntSize size;
+        double frameRate;
+    };
+    std::optional<CaptureSizeAndFrameRate> bestSupportedSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
 
     void addSupportedCapabilities(RealtimeMediaSourceCapabilities&) const;
 
@@ -60,15 +68,75 @@ protected:
     void dispatchMediaSampleToObservers(MediaSample&);
 
 private:
-    bool supportsFrameRate(double);
 
-    Vector<IntSize> m_supportedCaptureSizes;
-    Vector<double> m_supportedFrameRates;
+    VideoPresets m_presets;
     Deque<double> m_observedFrameTimeStamps;
     double m_observedFrameRate { 0 };
     IntSize m_defaultSize;
 };
 
+struct FrameRateRange {
+    double minimum;
+    double maximum;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<FrameRateRange> decode(Decoder&);
+};
+
+template<class Encoder>
+void FrameRateRange::encode(Encoder& encoder) const
+{
+    encoder << minimum;
+    encoder << maximum;
+}
+
+template <class Decoder>
+std::optional<FrameRateRange> FrameRateRange::decode(Decoder& decoder)
+{
+    std::optional<double> minimum;
+    decoder >> minimum;
+    if (!minimum)
+        return std::nullopt;
+
+    std::optional<double> maximum;
+    decoder >> maximum;
+    if (!maximum)
+        return std::nullopt;
+
+    return FrameRateRange { *minimum, *maximum };
+}
+
+struct VideoPreset {
+    IntSize size;
+    Vector<FrameRateRange> frameRateRanges;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<VideoPreset> decode(Decoder&);
+};
+
+template<class Encoder>
+void VideoPreset::encode(Encoder& encoder) const
+{
+    encoder << size;
+    encoder << frameRateRanges;
+}
+
+template <class Decoder>
+std::optional<VideoPreset> VideoPreset::decode(Decoder& decoder)
+{
+    std::optional<IntSize> size;
+    decoder >> size;
+    if (!size)
+        return std::nullopt;
+
+    std::optional<Vector<FrameRateRange>> frameRateRanges;
+    decoder >> frameRateRanges;
+    if (!frameRateRanges)
+        return std::nullopt;
+
+    return VideoPreset { *size, *frameRateRanges };
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)
index bea8da9..0758e54 100644 (file)
@@ -145,8 +145,7 @@ void GStreamerVideoCaptureSource::stopProducingData()
     m_capturer->stop();
 
     GST_INFO("Reset height and width after stopping source");
-    setHeight(0);
-    setWidth(0);
+    setSize({ 0, 0 });
 }
 
 const RealtimeMediaSourceCapabilities& GStreamerVideoCaptureSource::capabilities() const
index d11d153..f55fef9 100644 (file)
@@ -72,7 +72,7 @@ private:
     void shutdownCaptureSession();
 
     const RealtimeMediaSourceCapabilities& capabilities() const final;
-    void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
+    void setSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
     void setFrameRate(double);
     const RealtimeMediaSourceSettings& settings() const final;
     void startProducingData() final;
index fb19dfc..f3bd410 100644 (file)
@@ -453,7 +453,7 @@ void AVVideoCaptureSource::setFrameRate(double rate)
     return;
 }
 
-void AVVideoCaptureSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
+void AVVideoCaptureSource::setSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
 {
     if (width || height)
         setPreset(bestSessionPresetForVideoDimensions(WTFMove(width), WTFMove(height)));
index e6e448c..f71493f 100644 (file)
@@ -135,8 +135,7 @@ bool ScreenDisplayCaptureSourceMac::createDisplayStream()
                 captureFailed();
                 return false;
             }
-            setWidth(screenWidth);
-            setHeight(screenHeight);
+            setSize(IntSize(screenWidth, screenHeight));
         }
 
         if (!m_captureQueue)
index 1d03c5a..9136e63 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "CaptureDevice.h"
 #include "RealtimeMediaSource.h"
+#include "RealtimeVideoSource.h"
 
 namespace WebCore {
 
@@ -54,15 +55,15 @@ struct MockMicrophoneProperties {
     int defaultSampleRate { 44100 };
 };
 
-// FIXME: Add support for other properties and serialization of colors.
+// FIXME: Add support for other properties.
 struct MockCameraProperties {
     template<class Encoder>
     void encode(Encoder& encoder) const
     {
         encoder << defaultFrameRate;
         encoder << facingMode;
-        encoder << frameRates;
-        encoder << frameSizes;
+        encoder << presets;
+        encoder << fillColor;
     }
 
     template <class Decoder>
@@ -78,23 +79,22 @@ struct MockCameraProperties {
         if (!facingMode)
             return std::nullopt;
 
-        std::optional<Vector<double>> frameRates;
-        decoder >> frameRates;
-        if (!frameRates)
+        std::optional<Vector<VideoPreset>> presets;
+        decoder >> presets;
+        if (!presets)
             return std::nullopt;
 
-        std::optional<Vector<IntSize>> frameSizes;
-        decoder >> frameSizes;
-        if (!frameSizes)
+        std::optional<Color> fillColor;
+        decoder >> fillColor;
+        if (!fillColor)
             return std::nullopt;
 
-        return MockCameraProperties { *defaultFrameRate, *facingMode, WTFMove(*frameRates), WTFMove(*frameSizes), Color::black };
+        return MockCameraProperties { *defaultFrameRate, *facingMode, WTFMove(*presets), *fillColor };
     }
 
     double defaultFrameRate { 30 };
     RealtimeMediaSourceSettings::VideoFacingMode facingMode { RealtimeMediaSourceSettings::VideoFacingMode::User };
-    Vector<double> frameRates { 30, 15 };
-    Vector<IntSize> frameSizes { { 640, 480 }, { 352, 288 }, { 320, 240 } };
+    Vector<VideoPreset> presets { { { 640, 480 }, { { 30, 30}, { 15, 15 } } } };
     Color fillColor { Color::black };
 };
 
@@ -103,6 +103,7 @@ struct MockDisplayProperties {
     void encode(Encoder& encoder) const
     {
         encoder << defaultFrameRate;
+        encoder << fillColor;
     }
 
     template <class Decoder>
@@ -113,7 +114,12 @@ struct MockDisplayProperties {
         if (!defaultFrameRate)
             return std::nullopt;
 
-        return MockDisplayProperties { *defaultFrameRate, Color::lightGray };
+        std::optional<Color> fillColor;
+        decoder >> fillColor;
+        if (!fillColor)
+            return std::nullopt;
+
+        return MockDisplayProperties { *defaultFrameRate, *fillColor };
     }
 
     double defaultFrameRate { 30 };
index d9ab733..642d3ca 100644 (file)
@@ -52,18 +52,29 @@ static inline Vector<MockMediaDevice> defaultDevices()
         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 } },
+                RealtimeMediaSourceSettings::VideoFacingMode::User, {
+                    { { 3840, 2160 }, { { 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} } },
+                    { { 1920, 1080 }, { { 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} } },
+                    { { 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} } },
+                    { { 960, 540 }, { { 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} } },
+                    { { 352, 288 }, { { 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} } },
+                    { { 320, 240 }, { { 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} } },
+                },
                 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 } },
+                RealtimeMediaSourceSettings::VideoFacingMode::Environment, {
+                    { { 1280, 720 }, { { 3, 120 } } },
+                    { { 960, 540 }, { { 3, 60 } } },
+                    { { 640, 480 }, { { 2, 30 } } },
+                    { { 352, 288 }, { { 2, 30 } } },
+                    { { 320, 240 }, { { 2, 30 } } },
+                    { { 160, 120 }, { { 2, 30 } } },
+                },
                 Color::darkGray,
             } },
 
index 2aeaf2c..0e78d56 100644 (file)
@@ -129,10 +129,9 @@ MockRealtimeVideoSource::MockRealtimeVideoSource(const String& deviceID, const S
     }
 
     auto& properties = WTF::get<MockCameraProperties>(m_device.properties);
-    setFrameRate(properties.frameRates[0]);
+    setFrameRate(properties.defaultFrameRate);
     setFacingMode(properties.facingMode);
-    setSupportedFrameRates(WTFMove(properties.frameRates));
-    setSupportedCaptureSizes(WTFMove(properties.frameSizes));
+    setSupportedPresets(WTFMove(properties.presets));
     m_fillColor = properties.fillColor;
 }
 
@@ -142,15 +141,15 @@ const RealtimeMediaSourceCapabilities& MockRealtimeVideoSource::capabilities() c
         RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints());
 
         capabilities.setDeviceId(id());
-        if (mockCamera()) {
+        if (mockCamera())
             capabilities.addFacingMode(WTF::get<MockCameraProperties>(m_device.properties).facingMode);
-            addSupportedCapabilities(capabilities);
-        } else {
+        else {
             capabilities.setWidth(CapabilityValueOrRange(72, 2880));
             capabilities.setHeight(CapabilityValueOrRange(45, 1800));
             capabilities.setFrameRate(CapabilityValueOrRange(.01, 60.0));
         }
 
+        addSupportedCapabilities(capabilities);
         m_capabilities = WTFMove(capabilities);
     }
     return m_capabilities.value();
@@ -161,7 +160,6 @@ const RealtimeMediaSourceSettings& MockRealtimeVideoSource::settings() const
     if (m_currentSettings)
         return m_currentSettings.value();
 
-
     RealtimeMediaSourceSettings settings;
     if (mockCamera())
         settings.setFacingMode(facingMode());