[MediaStream] Simplify logic when changing RealtimeMediaSource settings
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Sep 2018 15:56:44 +0000 (15:56 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Sep 2018 15:56:44 +0000 (15:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189284
<rdar://problem/44117948>

Reviewed by Youenn Fablet.

Source/WebCore:

Remove all "apply<setting>" methods from RealtimeMediaSource and derived classes, and
add a bitfield to settingsDidChange so classes can do setting-specific setup and
configuration by overriding settingsDidChange.

No new tests, no functionality changed.

* Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp:
(WebCore::CanvasCaptureMediaStreamTrack::Source::canvasResized):
* Modules/mediastream/CanvasCaptureMediaStreamTrack.h:
* platform/mediastream/MediaConstraints.h:
(WebCore::NumericConstraint::fitnessDistance const):
(WebCore::NumericConstraint::valueForDiscreteCapabilityValues const):
* platform/mediastream/RealtimeIncomingVideoSource.h:
(): Deleted.
* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::RealtimeMediaSource):
(WebCore::RealtimeMediaSource::settingsDidChange):
(WebCore::RealtimeMediaSource::fitnessDistance):
(WebCore::applyNumericConstraint):
(WebCore::RealtimeMediaSource::applyConstraint):
(WebCore::RealtimeMediaSource::applyConstraints):
(WebCore::RealtimeMediaSource::setSize):
(WebCore::RealtimeMediaSource::setWidth):
(WebCore::RealtimeMediaSource::setHeight):
(WebCore::RealtimeMediaSource::setFrameRate):
(WebCore::RealtimeMediaSource::setAspectRatio):
(WebCore::RealtimeMediaSource::setFacingMode):
(WebCore::RealtimeMediaSource::setVolume):
(WebCore::RealtimeMediaSource::setSampleRate):
(WebCore::RealtimeMediaSource::setSampleSize):
(WebCore::RealtimeMediaSource::setEchoCancellation):
* platform/mediastream/RealtimeMediaSource.h:
* platform/mediastream/RealtimeMediaSourceSettings.cpp:
(WebCore::RealtimeMediaSourceSettings::diff const):
* platform/mediastream/RealtimeMediaSourceSettings.h:
(WebCore::RealtimeMediaSourceSettings::allFlags):
* platform/mediastream/RealtimeVideoSource.cpp:
(WebCore::RealtimeVideoSource::applySize): Deleted.
(WebCore::RealtimeVideoSource::applyFrameRate): Deleted.
* platform/mediastream/RealtimeVideoSource.h:
* platform/mediastream/gstreamer/GStreamerAudioCaptureSource.cpp:
(WebCore::GStreamerAudioCaptureSource::settingsDidChange):
(WebCore::GStreamerAudioCaptureSource::applySampleRate): Deleted.
* platform/mediastream/gstreamer/GStreamerAudioCaptureSource.h:
* platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp:
(WebCore::GStreamerVideoCaptureSource::settingsDidChange):
(WebCore::GStreamerVideoCaptureSource::applySize): Deleted.
(WebCore::GStreamerVideoCaptureSource::applyFrameRate): Deleted.
* platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::settingsDidChange):
(WebCore::AVVideoCaptureSource::setPreset):
(WebCore::AVVideoCaptureSource::setFrameRate):
(WebCore::AVVideoCaptureSource::applySizeAndFrameRate):
(WebCore::AVVideoCaptureSource::processNewFrame):
(WebCore::AVVideoCaptureSource::applySize): Deleted.
(WebCore::AVVideoCaptureSource::applyFrameRate): Deleted.
* platform/mediastream/mac/CoreAudioCaptureSource.cpp:
(WebCore::CoreAudioCaptureSource::settingsDidChange):
(WebCore::CoreAudioCaptureSource::applySampleRate): Deleted.
(WebCore::CoreAudioCaptureSource::applyEchoCancellation): Deleted.
* platform/mediastream/mac/CoreAudioCaptureSource.h:
* platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp:
(WebCore::DisplayCaptureSourceCocoa::settingsDidChange):
(WebCore::DisplayCaptureSourceCocoa::startProducingData):
(WebCore::DisplayCaptureSourceCocoa::applySize): Deleted.
(WebCore::DisplayCaptureSourceCocoa::applyFrameRate): Deleted.
* platform/mediastream/mac/DisplayCaptureSourceCocoa.h:
* platform/mediastream/mac/MockRealtimeAudioSourceMac.h:
* platform/mediastream/mac/MockRealtimeAudioSourceMac.mm:
(WebCore::MockRealtimeAudioSourceMac::settingsDidChange):
(WebCore::MockRealtimeAudioSourceMac::applySampleRate): Deleted.
* platform/mediastream/mac/MockRealtimeVideoSourceMac.h:
* platform/mediastream/mac/MockRealtimeVideoSourceMac.mm:
(WebCore::MockRealtimeVideoSourceMac::settingsDidChange):
(WebCore::MockRealtimeVideoSourceMac::applySize): Deleted.
* platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm:
(WebCore::RealtimeIncomingVideoSourceCocoa::processNewSample):
* platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h:
* platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
(WebCore::ScreenDisplayCaptureSourceMac::settingsDidChange):
(WebCore::ScreenDisplayCaptureSourceMac::applySize): Deleted.
(WebCore::ScreenDisplayCaptureSourceMac::applyFrameRate): Deleted.
* platform/mock/MockRealtimeAudioSource.cpp:
(WebCore::MockRealtimeAudioSource::settingsDidChange):
* platform/mock/MockRealtimeAudioSource.h:
* platform/mock/MockRealtimeVideoSource.cpp:
(WebCore::MockRealtimeVideoSource::settingsDidChange):
(WebCore::MockRealtimeVideoSource::applySize): Deleted.
* platform/mock/MockRealtimeVideoSource.h:

Source/WebKit:

* WebProcess/cocoa/UserMediaCaptureManager.cpp:
(WebKit::UserMediaCaptureManager::Source::setSettings):

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

34 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp
Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.h
Source/WebCore/platform/mediastream/MediaConstraints.h
Source/WebCore/platform/mediastream/RealtimeIncomingVideoSource.h
Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSource.h
Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h
Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp
Source/WebCore/platform/mediastream/RealtimeVideoSource.h
Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.cpp
Source/WebCore/platform/mediastream/gstreamer/GStreamerAudioCaptureSource.h
Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp
Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h
Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm
Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp
Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h
Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp
Source/WebCore/platform/mediastream/mac/DisplayCaptureSourceCocoa.h
Source/WebCore/platform/mediastream/mac/MockRealtimeAudioSourceMac.h
Source/WebCore/platform/mediastream/mac/MockRealtimeAudioSourceMac.mm
Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h
Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm
Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm
Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h
Source/WebCore/platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm
Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp
Source/WebCore/platform/mock/MockRealtimeAudioSource.h
Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp
Source/WebCore/platform/mock/MockRealtimeVideoSource.h
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp

index ae7107b..f62aca1 100644 (file)
@@ -1,3 +1,103 @@
+2018-09-05  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Simplify logic when changing RealtimeMediaSource settings
+        https://bugs.webkit.org/show_bug.cgi?id=189284
+        <rdar://problem/44117948>
+
+        Reviewed by Youenn Fablet.
+
+        Remove all "apply<setting>" methods from RealtimeMediaSource and derived classes, and
+        add a bitfield to settingsDidChange so classes can do setting-specific setup and
+        configuration by overriding settingsDidChange.
+
+        No new tests, no functionality changed.
+
+        * Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp:
+        (WebCore::CanvasCaptureMediaStreamTrack::Source::canvasResized):
+        * Modules/mediastream/CanvasCaptureMediaStreamTrack.h:
+        * platform/mediastream/MediaConstraints.h:
+        (WebCore::NumericConstraint::fitnessDistance const):
+        (WebCore::NumericConstraint::valueForDiscreteCapabilityValues const):
+        * platform/mediastream/RealtimeIncomingVideoSource.h:
+        (): Deleted.
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::RealtimeMediaSource):
+        (WebCore::RealtimeMediaSource::settingsDidChange):
+        (WebCore::RealtimeMediaSource::fitnessDistance):
+        (WebCore::applyNumericConstraint):
+        (WebCore::RealtimeMediaSource::applyConstraint):
+        (WebCore::RealtimeMediaSource::applyConstraints):
+        (WebCore::RealtimeMediaSource::setSize):
+        (WebCore::RealtimeMediaSource::setWidth):
+        (WebCore::RealtimeMediaSource::setHeight):
+        (WebCore::RealtimeMediaSource::setFrameRate):
+        (WebCore::RealtimeMediaSource::setAspectRatio):
+        (WebCore::RealtimeMediaSource::setFacingMode):
+        (WebCore::RealtimeMediaSource::setVolume):
+        (WebCore::RealtimeMediaSource::setSampleRate):
+        (WebCore::RealtimeMediaSource::setSampleSize):
+        (WebCore::RealtimeMediaSource::setEchoCancellation):
+        * platform/mediastream/RealtimeMediaSource.h:
+        * platform/mediastream/RealtimeMediaSourceSettings.cpp:
+        (WebCore::RealtimeMediaSourceSettings::diff const):
+        * platform/mediastream/RealtimeMediaSourceSettings.h:
+        (WebCore::RealtimeMediaSourceSettings::allFlags):
+        * platform/mediastream/RealtimeVideoSource.cpp:
+        (WebCore::RealtimeVideoSource::applySize): Deleted.
+        (WebCore::RealtimeVideoSource::applyFrameRate): Deleted.
+        * platform/mediastream/RealtimeVideoSource.h:
+        * platform/mediastream/gstreamer/GStreamerAudioCaptureSource.cpp:
+        (WebCore::GStreamerAudioCaptureSource::settingsDidChange):
+        (WebCore::GStreamerAudioCaptureSource::applySampleRate): Deleted.
+        * platform/mediastream/gstreamer/GStreamerAudioCaptureSource.h:
+        * platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp:
+        (WebCore::GStreamerVideoCaptureSource::settingsDidChange):
+        (WebCore::GStreamerVideoCaptureSource::applySize): Deleted.
+        (WebCore::GStreamerVideoCaptureSource::applyFrameRate): Deleted.
+        * platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h:
+        * platform/mediastream/mac/AVVideoCaptureSource.h:
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSource::settingsDidChange):
+        (WebCore::AVVideoCaptureSource::setPreset):
+        (WebCore::AVVideoCaptureSource::setFrameRate):
+        (WebCore::AVVideoCaptureSource::applySizeAndFrameRate):
+        (WebCore::AVVideoCaptureSource::processNewFrame):
+        (WebCore::AVVideoCaptureSource::applySize): Deleted.
+        (WebCore::AVVideoCaptureSource::applyFrameRate): Deleted.
+        * platform/mediastream/mac/CoreAudioCaptureSource.cpp:
+        (WebCore::CoreAudioCaptureSource::settingsDidChange):
+        (WebCore::CoreAudioCaptureSource::applySampleRate): Deleted.
+        (WebCore::CoreAudioCaptureSource::applyEchoCancellation): Deleted.
+        * platform/mediastream/mac/CoreAudioCaptureSource.h:
+        * platform/mediastream/mac/DisplayCaptureSourceCocoa.cpp:
+        (WebCore::DisplayCaptureSourceCocoa::settingsDidChange):
+        (WebCore::DisplayCaptureSourceCocoa::startProducingData):
+        (WebCore::DisplayCaptureSourceCocoa::applySize): Deleted.
+        (WebCore::DisplayCaptureSourceCocoa::applyFrameRate): Deleted.
+        * platform/mediastream/mac/DisplayCaptureSourceCocoa.h:
+        * platform/mediastream/mac/MockRealtimeAudioSourceMac.h:
+        * platform/mediastream/mac/MockRealtimeAudioSourceMac.mm:
+        (WebCore::MockRealtimeAudioSourceMac::settingsDidChange):
+        (WebCore::MockRealtimeAudioSourceMac::applySampleRate): Deleted.
+        * platform/mediastream/mac/MockRealtimeVideoSourceMac.h:
+        * platform/mediastream/mac/MockRealtimeVideoSourceMac.mm:
+        (WebCore::MockRealtimeVideoSourceMac::settingsDidChange):
+        (WebCore::MockRealtimeVideoSourceMac::applySize): Deleted.
+        * platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm:
+        (WebCore::RealtimeIncomingVideoSourceCocoa::processNewSample):
+        * platform/mediastream/mac/ScreenDisplayCaptureSourceMac.h:
+        * platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm:
+        (WebCore::ScreenDisplayCaptureSourceMac::settingsDidChange):
+        (WebCore::ScreenDisplayCaptureSourceMac::applySize): Deleted.
+        (WebCore::ScreenDisplayCaptureSourceMac::applyFrameRate): Deleted.
+        * platform/mock/MockRealtimeAudioSource.cpp:
+        (WebCore::MockRealtimeAudioSource::settingsDidChange):
+        * platform/mock/MockRealtimeAudioSource.h:
+        * platform/mock/MockRealtimeVideoSource.cpp:
+        (WebCore::MockRealtimeVideoSource::settingsDidChange):
+        (WebCore::MockRealtimeVideoSource::applySize): Deleted.
+        * platform/mock/MockRealtimeVideoSource.h:
+
 2018-09-05  Zalan Bujtas <zalan@apple.com>
 
         [LFC][BFC] Move MarginCollapse class under BlockFormattingContext::Geometry
index 24b816d..cdd04b9 100644 (file)
@@ -114,10 +114,16 @@ void CanvasCaptureMediaStreamTrack::Source::canvasResized(CanvasBase& canvas)
 {
     ASSERT_UNUSED(canvas, m_canvas == &canvas);
 
+    OptionSet<RealtimeMediaSourceSettings::Flag> changed;
+    if (m_canvas->width() != m_settings.width())
+        changed.add(RealtimeMediaSourceSettings::Flag::Width);
+    if (m_canvas->height() != m_settings.height())
+        changed.add(RealtimeMediaSourceSettings::Flag::Height);
+
     m_settings.setWidth(m_canvas->width());
     m_settings.setHeight(m_canvas->height());
 
-    settingsDidChange();
+    settingsDidChange(changed);
 }
 
 void CanvasCaptureMediaStreamTrack::Source::canvasChanged(CanvasBase& canvas, const FloatRect&)
index 635b4b1..b006af9 100644 (file)
@@ -67,7 +67,6 @@ private:
         void stopProducingData()  final;
         const RealtimeMediaSourceCapabilities& capabilities() const final { return RealtimeMediaSourceCapabilities::emptyCapabilities(); }
         const RealtimeMediaSourceSettings& settings() const final { return m_settings; }
-        bool applySize(const IntSize&) final { return true; }
 
         void captureCanvas();
         void requestFrameTimerFired();
index 65e96ac..30ec41a 100644 (file)
@@ -193,6 +193,19 @@ public:
         return static_cast<double>(std::abs(ideal - m_ideal.value())) / std::max(std::abs(ideal), std::abs(m_ideal.value()));
     }
 
+    double fitnessDistance(const Vector<ValueType>& discreteCapabilityValues) const
+    {
+        double minDistance = std::numeric_limits<double>::infinity();
+
+        for (auto& value : discreteCapabilityValues) {
+            auto distance = fitnessDistance(value, value);
+            if (distance < minDistance)
+                minDistance = distance;
+        }
+
+        return minDistance;
+    }
+
     bool validForRange(ValueType rangeMin, ValueType rangeMax) const
     {
         if (isEmpty())
@@ -277,6 +290,46 @@ public:
         return value;
     }
 
+    ValueType valueForDiscreteCapabilityValues(ValueType current, const Vector<ValueType>& discreteCapabilityValues) const
+    {
+        ValueType value { 0 };
+        std::optional<ValueType> min;
+        std::optional<ValueType> max;
+
+        if (m_exact) {
+            ASSERT(discreteCapabilityValues.contains(m_exact.value()));
+            return m_exact.value();
+        }
+
+        if (m_min) {
+            auto index = discreteCapabilityValues.findMatching([&](ValueType value) { return m_min.value() >= value; });
+            if (index != notFound) {
+                min = value = discreteCapabilityValues[index];
+
+                // If there is no ideal, don't change if minimum is smaller than current.
+                if (!m_ideal && value < current)
+                    value = current;
+            }
+        }
+
+        if (m_max && m_max.value() >= discreteCapabilityValues[0]) {
+            for (auto& discreteValue : discreteCapabilityValues) {
+                if (m_max.value() <= discreteValue)
+                    max = value = discreteValue;
+            }
+        }
+
+        if (m_ideal && discreteCapabilityValues.contains(m_ideal.value())) {
+            value = m_ideal.value();
+            if (max)
+                value = std::min(max.value(), value);
+            if (min)
+                value = std::max(min.value(), value);
+        }
+
+        return value;
+    }
+
     bool isEmpty() const { return !m_min && !m_max && !m_exact && !m_ideal; }
     bool isMandatory() const { return m_min || m_max || m_exact; }
 
index 7247bb8..1b0bf94 100644 (file)
@@ -71,8 +71,6 @@ private:
     const RealtimeMediaSourceCapabilities& capabilities() const final;
     const RealtimeMediaSourceSettings& settings() const final;
 
-    bool applySize(const IntSize&) final { return true; }
-
     rtc::scoped_refptr<webrtc::VideoTrackInterface> m_videoTrack;
 };
 
index 2e9d965..07113fe 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
  * Copyright (C) 2015 Ericsson AB. All rights reserved.
  *
@@ -52,8 +52,6 @@ RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const Stri
     , m_type(type)
     , m_name(name)
 {
-    // FIXME(147205): Need to implement fitness score for constraints
-
     if (m_id.isEmpty())
         m_id = createCanonicalUUIDString();
     m_persistentID = m_id;
@@ -133,13 +131,12 @@ void RealtimeMediaSource::notifyMutedObservers() const
     });
 }
 
-void RealtimeMediaSource::settingsDidChange()
+void RealtimeMediaSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>)
 {
     ASSERT(isMainThread());
 
     if (m_pendingSettingsDidChangeNotification)
         return;
-
     m_pendingSettingsDidChangeNotification = true;
 
     scheduleDeferredTask([this] {
@@ -356,6 +353,9 @@ double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint)
         if (!capabilities.supportsSampleRate())
             return 0;
 
+        if (auto discreteRates = discreteSampleRates())
+            return downcast<IntConstraint>(constraint).fitnessDistance(*discreteRates);
+
         auto range = capabilities.sampleRate();
         return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
         break;
@@ -366,6 +366,9 @@ double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint)
         if (!capabilities.supportsSampleSize())
             return 0;
 
+        if (auto discreteSizes = discreteSampleSizes())
+            return downcast<IntConstraint>(constraint).fitnessDistance(*discreteSizes);
+
         auto range = capabilities.sampleSize();
         return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
         break;
@@ -421,11 +424,18 @@ double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint)
 }
 
 template <typename ValueType>
-static void applyNumericConstraint(const NumericConstraint<ValueType>& constraint, ValueType current, ValueType capabilityMin, ValueType capabilityMax, RealtimeMediaSource* source, void (RealtimeMediaSource::*applier)(ValueType))
+static void applyNumericConstraint(const NumericConstraint<ValueType>& constraint, ValueType current, std::optional<Vector<ValueType>> discreteCapabilityValues, ValueType capabilityMin, ValueType capabilityMax, RealtimeMediaSource& source, void (RealtimeMediaSource::*applier)(ValueType))
 {
+    if (discreteCapabilityValues) {
+        int value = constraint.valueForDiscreteCapabilityValues(current, *discreteCapabilityValues);
+        if (value != current)
+            (source.*applier)(value);
+        return;
+    }
+
     ValueType value = constraint.valueForCapabilityRange(current, capabilityMin, capabilityMax);
     if (value != current)
-        (source->*applier)(value);
+        (source.*applier)(value);
 }
 
 void RealtimeMediaSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
@@ -442,35 +452,17 @@ void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
 {
     auto& capabilities = this->capabilities();
     switch (constraint.constraintType()) {
-    case MediaConstraintType::Width: {
-        ASSERT(constraint.isInt());
-        if (!capabilities.supportsWidth())
-            return;
-
-        auto range = capabilities.width();
-        applyNumericConstraint(downcast<IntConstraint>(constraint), size().width(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setWidth);
+    case MediaConstraintType::Width:
+        ASSERT_NOT_REACHED();
         break;
-    }
-
-    case MediaConstraintType::Height: {
-        ASSERT(constraint.isInt());
-        if (!capabilities.supportsHeight())
-            return;
 
-        auto range = capabilities.height();
-        applyNumericConstraint(downcast<IntConstraint>(constraint), size().height(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setHeight);
+    case MediaConstraintType::Height:
+        ASSERT_NOT_REACHED();
         break;
-    }
-
-    case MediaConstraintType::FrameRate: {
-        ASSERT(constraint.isDouble());
-        if (!capabilities.supportsFrameRate())
-            return;
 
-        auto range = capabilities.frameRate();
-        applyNumericConstraint(downcast<DoubleConstraint>(constraint), frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setFrameRate);
+    case MediaConstraintType::FrameRate:
+        ASSERT_NOT_REACHED();
         break;
-    }
 
     case MediaConstraintType::AspectRatio: {
         ASSERT(constraint.isDouble());
@@ -478,7 +470,7 @@ void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
             return;
 
         auto range = capabilities.aspectRatio();
-        applyNumericConstraint(downcast<DoubleConstraint>(constraint), aspectRatio(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setAspectRatio);
+        applyNumericConstraint(downcast<DoubleConstraint>(constraint), aspectRatio(), { }, range.rangeMin().asDouble, range.rangeMax().asDouble, *this, &RealtimeMediaSource::setAspectRatio);
         break;
     }
 
@@ -488,7 +480,7 @@ void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
             return;
 
         auto range = capabilities.volume();
-        applyNumericConstraint(downcast<DoubleConstraint>(constraint), volume(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setVolume);
+        applyNumericConstraint(downcast<DoubleConstraint>(constraint), volume(), { }, range.rangeMin().asDouble, range.rangeMax().asDouble, *this, &RealtimeMediaSource::setVolume);
         break;
     }
 
@@ -498,7 +490,7 @@ void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
             return;
 
         auto range = capabilities.sampleRate();
-        applyNumericConstraint(downcast<IntConstraint>(constraint), sampleRate(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setSampleRate);
+        applyNumericConstraint(downcast<IntConstraint>(constraint), sampleRate(), discreteSampleRates(), range.rangeMin().asInt, range.rangeMax().asInt, *this, &RealtimeMediaSource::setSampleRate);
         break;
     }
 
@@ -508,7 +500,7 @@ void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
             return;
 
         auto range = capabilities.sampleSize();
-        applyNumericConstraint(downcast<IntConstraint>(constraint), sampleSize(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setSampleSize);
+        applyNumericConstraint(downcast<IntConstraint>(constraint), sampleSize(), { }, range.rangeMin().asInt, range.rangeMax().asInt, *this, &RealtimeMediaSource::setSampleSize);
         break;
     }
 
@@ -823,8 +815,6 @@ void RealtimeMediaSource::applyConstraints(const FlattenedConstraint& constraint
         }
     }
 
-    // FIXME: applySizeAndFrameRate should take MediaConstraint* instead of std::optional<> so it can see if a constraint is an exact, min, max,
-    // or ideal, and choose the correct value for properties with non-discreet capabilities when necessary.
     if (width || height || frameRate)
         applySizeAndFrameRate(WTFMove(width), WTFMove(height), WTFMove(frameRate));
 
@@ -865,11 +855,14 @@ void RealtimeMediaSource::setSize(const IntSize& size)
     if (size == m_size)
         return;
 
-    if (!applySize(size))
-        return;
+    OptionSet<RealtimeMediaSourceSettings::Flag> changed;
+    if (m_size.width() != size.width())
+        changed.add(RealtimeMediaSourceSettings::Flag::Width);
+    if (m_size.height() != size.height())
+        changed.add(RealtimeMediaSourceSettings::Flag::Height);
 
     m_size = size;
-    settingsDidChange();
+    settingsDidChange(changed);
 }
 
 void RealtimeMediaSource::setWidth(int width)
@@ -877,15 +870,11 @@ void RealtimeMediaSource::setWidth(int width)
     if (width == m_size.width())
         return;
 
-    int height = m_aspectRatio ? width / m_aspectRatio : m_size.height();
-    if (!applySize(IntSize(width, height)))
-        return;
-
     m_size.setWidth(width);
     if (m_aspectRatio)
         m_size.setHeight(width / m_aspectRatio);
 
-    settingsDidChange();
+    settingsDidChange({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height });
 }
 
 void RealtimeMediaSource::setHeight(int height)
@@ -893,79 +882,85 @@ void RealtimeMediaSource::setHeight(int height)
     if (height == m_size.height())
         return;
 
-    int width = m_aspectRatio ? height * m_aspectRatio : m_size.width();
-    if (!applySize(IntSize(width, height)))
-        return;
-
     if (m_aspectRatio)
-        m_size.setWidth(width);
+        m_size.setWidth(height * m_aspectRatio);
     m_size.setHeight(height);
 
-    settingsDidChange();
+    settingsDidChange({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height });
 }
 
 void RealtimeMediaSource::setFrameRate(double rate)
 {
-    if (m_frameRate == rate || !applyFrameRate(rate))
+    if (m_frameRate == rate)
         return;
 
     m_frameRate = rate;
-    settingsDidChange();
+    settingsDidChange(RealtimeMediaSourceSettings::Flag::FrameRate);
 }
 
 void RealtimeMediaSource::setAspectRatio(double ratio)
 {
-    if (m_aspectRatio == ratio || !applyAspectRatio(ratio))
+    if (m_aspectRatio == ratio)
         return;
 
     m_aspectRatio = ratio;
     m_size.setHeight(m_size.width() / ratio);
-    settingsDidChange();
+    settingsDidChange({ RealtimeMediaSourceSettings::Flag::AspectRatio, RealtimeMediaSourceSettings::Flag::Height });
 }
 
 void RealtimeMediaSource::setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
 {
-    if (m_facingMode == mode || !applyFacingMode(mode))
+    if (m_facingMode == mode)
         return;
 
     m_facingMode = mode;
-    settingsDidChange();
+    settingsDidChange(RealtimeMediaSourceSettings::Flag::FacingMode);
 }
 
 void RealtimeMediaSource::setVolume(double volume)
 {
-    if (m_volume == volume || !applyVolume(volume))
+    if (m_volume == volume)
         return;
 
     m_volume = volume;
-    settingsDidChange();
+    settingsDidChange(RealtimeMediaSourceSettings::Flag::Volume);
 }
 
 void RealtimeMediaSource::setSampleRate(int rate)
 {
-    if (m_sampleRate == rate || !applySampleRate(rate))
+    if (m_sampleRate == rate)
         return;
 
     m_sampleRate = rate;
-    settingsDidChange();
+    settingsDidChange(RealtimeMediaSourceSettings::Flag::SampleRate);
+}
+
+std::optional<Vector<int>> RealtimeMediaSource::discreteSampleRates() const
+{
+    return std::nullopt;
 }
 
 void RealtimeMediaSource::setSampleSize(int size)
 {
-    if (m_sampleSize == size || !applySampleSize(size))
+    if (m_sampleSize == size)
         return;
 
     m_sampleSize = size;
-    settingsDidChange();
+    settingsDidChange(RealtimeMediaSourceSettings::Flag::SampleSize);
+}
+
+std::optional<Vector<int>> RealtimeMediaSource::discreteSampleSizes() const
+{
+    return std::nullopt;
 }
 
 void RealtimeMediaSource::setEchoCancellation(bool echoCancellation)
 {
-    if (m_echoCancellation == echoCancellation || !applyEchoCancellation(echoCancellation))
+    if (m_echoCancellation == echoCancellation)
         return;
 
     m_echoCancellation = echoCancellation;
-    settingsDidChange();
+    settingsDidChange(RealtimeMediaSourceSettings::Flag::EchoCancellation);
 }
 
 void RealtimeMediaSource::scheduleDeferredTask(WTF::Function<void()>&& function)
index 48419ba..e08e656 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2011 Ericsson AB. All rights reserved.
  * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Redistribution and use in source and binary forms, with or without
@@ -169,35 +169,29 @@ public:
     void setHeight(int);
     void setSize(const IntSize&);
     const IntSize& size() const { return m_size; }
-    virtual bool applySize(const IntSize&) { return false; }
 
     double frameRate() const { return m_frameRate; }
     void setFrameRate(double);
-    virtual bool applyFrameRate(double) { return false; }
 
     double aspectRatio() const { return m_aspectRatio; }
     void setAspectRatio(double);
-    virtual bool applyAspectRatio(double) { return false; }
 
     RealtimeMediaSourceSettings::VideoFacingMode facingMode() const { return m_facingMode; }
     void setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode);
-    virtual bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) { return false; }
 
     double volume() const { return m_volume; }
     void setVolume(double);
-    virtual bool applyVolume(double) { return false; }
 
     int sampleRate() const { return m_sampleRate; }
     void setSampleRate(int);
-    virtual bool applySampleRate(int) { return false; }
+    virtual std::optional<Vector<int>> discreteSampleRates() const;
 
     int sampleSize() const { return m_sampleSize; }
     void setSampleSize(int);
-    virtual bool applySampleSize(int) { return false; }
+    virtual std::optional<Vector<int>> discreteSampleSizes() const;
 
     bool echoCancellation() const { return m_echoCancellation; }
     void setEchoCancellation(bool);
-    virtual bool applyEchoCancellation(bool) { return false; }
 
     virtual const RealtimeMediaSourceCapabilities& capabilities() const = 0;
     virtual const RealtimeMediaSourceSettings& settings() const = 0;
@@ -210,7 +204,7 @@ public:
     bool supportsConstraints(const MediaConstraints&, String&);
     bool supportsConstraint(const MediaConstraint&) const;
 
-    virtual void settingsDidChange();
+    virtual void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>);
 
     virtual bool isIsolated() const { return false; }
 
@@ -274,8 +268,8 @@ private:
     double m_fitnessScore { std::numeric_limits<double>::infinity() };
     RealtimeMediaSourceSettings::VideoFacingMode m_facingMode { RealtimeMediaSourceSettings::User};
 
-    bool m_echoCancellation { false };
     bool m_pendingSettingsDidChangeNotification { false };
+    bool m_echoCancellation { false };
     bool m_isProducingData { false };
     bool m_interrupted { false };
     bool m_captureDidFailed { false };
index 6a6dcfe..3aadd24 100644 (file)
@@ -69,6 +69,43 @@ RealtimeMediaSourceSettings::VideoFacingMode RealtimeMediaSourceSettings::videoF
     return RealtimeMediaSourceSettings::Unknown;
 }
 
+OptionSet<RealtimeMediaSourceSettings::Flag> RealtimeMediaSourceSettings::difference(const RealtimeMediaSourceSettings& that) const
+{
+    OptionSet<RealtimeMediaSourceSettings::Flag> difference;
+
+    if (width() != that.width())
+        difference.add(RealtimeMediaSourceSettings::Width);
+    if (height() != that.height())
+        difference.add(RealtimeMediaSourceSettings::Height);
+    if (aspectRatio() != that.aspectRatio())
+        difference.add(RealtimeMediaSourceSettings::AspectRatio);
+    if (frameRate() != that.frameRate())
+        difference.add(RealtimeMediaSourceSettings::FrameRate);
+    if (facingMode() != that.facingMode())
+        difference.add(RealtimeMediaSourceSettings::FacingMode);
+    if (volume() != that.volume())
+        difference.add(RealtimeMediaSourceSettings::Volume);
+    if (sampleRate() != that.sampleRate())
+        difference.add(RealtimeMediaSourceSettings::SampleRate);
+    if (sampleSize() != that.sampleSize())
+        difference.add(RealtimeMediaSourceSettings::SampleSize);
+    if (echoCancellation() != that.echoCancellation())
+        difference.add(RealtimeMediaSourceSettings::EchoCancellation);
+    if (deviceId() != that.deviceId())
+        difference.add(RealtimeMediaSourceSettings::DeviceId);
+    if (groupId() != that.groupId())
+        difference.add(RealtimeMediaSourceSettings::GroupId);
+    if (label() != that.label())
+        difference.add(RealtimeMediaSourceSettings::Label);
+    if (displaySurface() != that.displaySurface())
+        difference.add(RealtimeMediaSourceSettings::DisplaySurface);
+    if (logicalSurface() != that.logicalSurface())
+        difference.add(RealtimeMediaSourceSettings::LogicalSurface);
+
+    return difference;
+}
+
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)
index 01c1523..b044c5c 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "RealtimeMediaSourceSupportedConstraints.h"
 #include <wtf/EnumTraits.h>
+#include <wtf/OptionSet.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 #include <wtf/text/AtomicString.h>
@@ -43,6 +44,27 @@ public:
     static String facingMode(RealtimeMediaSourceSettings::VideoFacingMode);
     static RealtimeMediaSourceSettings::VideoFacingMode videoFacingModeEnum(const String&);
 
+    enum Flag {
+        Width = 1 << 0,
+        Height = 1 << 1,
+        AspectRatio = 1 << 2,
+        FrameRate = 1 << 3,
+        FacingMode = 1 << 4,
+        Volume = 1 << 5,
+        SampleRate = 1 << 6,
+        SampleSize = 1 << 7,
+        EchoCancellation = 1 << 8,
+        DeviceId = 1 << 9,
+        GroupId = 1 << 10,
+        Label = 1 << 11,
+        DisplaySurface = 1 << 12,
+        LogicalSurface = 1 << 13,
+    };
+
+    static constexpr OptionSet<Flag> allFlags() { return { Width, Height, AspectRatio, FrameRate, FacingMode, Volume, SampleRate, SampleSize, EchoCancellation, DeviceId, GroupId, Label, DisplaySurface, LogicalSurface }; }
+
+    WEBCORE_EXPORT OptionSet<RealtimeMediaSourceSettings::Flag> difference(const RealtimeMediaSourceSettings&) const;
+
     explicit RealtimeMediaSourceSettings() = default;
 
     bool supportsWidth() const { return m_supportedConstraints.supportsWidth(); }
index 2d1faea..f3fc4ea 100644 (file)
@@ -125,17 +125,6 @@ IntSize RealtimeVideoSource::bestSupportedCaptureSizeForWidthAndHeight(std::opti
     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) {
@@ -168,11 +157,6 @@ void RealtimeVideoSource::dispatchMediaSampleToObservers(MediaSample& sample)
     videoSampleAvailable(sample);
 }
 
-bool RealtimeVideoSource::applyFrameRate(double rate)
-{
-    return supportsFrameRate(rate);
-}
-
 bool RealtimeVideoSource::supportsFrameRate(double frameRate)
 {
     double epsilon = 0.001;
index 1c257f6..6a2d4a1 100644 (file)
@@ -46,8 +46,6 @@ 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;
-    bool applySize(const IntSize&) override;
-    bool applyFrameRate(double) final;
 
     void setSupportedFrameRates(Vector<double>&&);
     void setSupportedCaptureSizes(const Vector<IntSize>&& sizes) { m_supportedCaptureSizes = sizes; }
index 0d57b23..7e21673 100644 (file)
@@ -172,9 +172,12 @@ const RealtimeMediaSourceCapabilities& GStreamerAudioCaptureSource::capabilities
     return m_capabilities.value();
 }
 
-bool GStreamerAudioCaptureSource::applySampleRate(int sampleRate)
+void GStreamerAudioCaptureSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
-    return m_capturer->setSampleRate(sampleRate);
+    if (settings.contains(RealtimeMediaSourceSettings::Flag::SampleRate))
+        m_capturer->setSampleRate(sampleRate());
+
+    RealtimeMediaSource::settingsDidChange(settings);
 }
 
 const RealtimeMediaSourceSettings& GStreamerAudioCaptureSource::settings() const
index 3fa4a9c..985a2e4 100644 (file)
@@ -50,9 +50,8 @@ protected:
     mutable std::optional<RealtimeMediaSourceSettings> m_currentSettings;
 
 private:
-    bool applySampleRate(int) final;
     bool isCaptureSource() const final { return true; }
-    bool applyVolume(double) final { return true; }
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
 
     std::unique_ptr<GStreamerAudioCapturer> m_capturer;
 
index 5a9dfb5..bea8da9 100644 (file)
@@ -107,18 +107,14 @@ GStreamerVideoCaptureSource::~GStreamerVideoCaptureSource()
 {
 }
 
-bool GStreamerVideoCaptureSource::applySize(const IntSize &size)
+void GStreamerVideoCaptureSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
-    m_capturer->setSize(size.width(), size.height());
+    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height }))
+        m_capturer->setSize(size().width(), size().height());
+    if (settings.contains(RealtimeMediaSourceSettings::Flag::FrameRate))
+        m_capturer->setFrameRate(frameRate());
 
-    return true;
-}
-
-bool GStreamerVideoCaptureSource::applyFrameRate(double framerate)
-{
-    m_capturer->setFrameRate(framerate);
-
-    return true;
+    RealtimeMediaSource::settingsDidChange(settings);
 }
 
 void GStreamerVideoCaptureSource::startProducingData()
index 379ba7e..1609b00 100644 (file)
@@ -37,7 +37,6 @@ public:
     GstElement* pipeline() { return m_capturer->pipeline(); }
     GStreamerCapturer* capturer() { return m_capturer.get(); }
 
-
 protected:
     GStreamerVideoCaptureSource(const String& deviceID, const String& name, const gchar * source_factory);
     GStreamerVideoCaptureSource(GStreamerCaptureDevice);
@@ -52,9 +51,7 @@ private:
     static GstFlowReturn newSampleCallback(GstElement*, GStreamerVideoCaptureSource*);
 
     bool isCaptureSource() const final { return true; }
-    bool applySize(const IntSize&) final;
-    bool applyFrameRate(double) final;
-    bool applyAspectRatio(double) final { return true; }
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
 
     std::unique_ptr<GStreamerVideoCapturer> m_capturer;
 };
index 748e480..d11d153 100644 (file)
@@ -73,13 +73,12 @@ private:
 
     const RealtimeMediaSourceCapabilities& capabilities() const final;
     void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
-    bool applySize(const IntSize&) final;
-    bool applyFrameRate(double) final;
+    void setFrameRate(double);
     const RealtimeMediaSourceSettings& settings() const final;
     void startProducingData() final;
     void stopProducingData() final;
     bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
-    void settingsDidChange() final;
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
     void monitorOrientation(OrientationNotifier&) final;
     void beginConfiguration() final;
     void commitConfiguration() final;
index 17e0556..6d900a8 100644 (file)
@@ -270,10 +270,10 @@ void AVVideoCaptureSource::commitConfiguration()
         [m_session commitConfiguration];
 }
 
-void AVVideoCaptureSource::settingsDidChange()
+void AVVideoCaptureSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
     m_currentSettings = std::nullopt;
-    RealtimeMediaSource::settingsDidChange();
+    RealtimeMediaSource::settingsDidChange(settings);
 }
 
 const RealtimeMediaSourceSettings& AVVideoCaptureSource::settings() const
@@ -357,17 +357,6 @@ const RealtimeMediaSourceCapabilities& AVVideoCaptureSource::capabilities() cons
     return *m_capabilities;
 }
 
-bool AVVideoCaptureSource::applySize(const IntSize& size)
-{
-    NSString *preset = bestSessionPresetForVideoDimensions(size.width(), size.height());
-    if (!preset || ![session() canSetSessionPreset:preset]) {
-        LOG(Media, "AVVideoCaptureSource::applySize(%p), unable find or set preset for width: %i, height: %i", this, size.width(), size.height());
-        return false;
-    }
-
-    return setPreset(preset);
-}
-
 IntSize AVVideoCaptureSource::sizeForPreset(NSString* preset)
 {
     if (!preset)
@@ -405,14 +394,14 @@ bool AVVideoCaptureSource::setPreset(NSString *preset)
         [m_videoOutput setVideoSettings:settingsDictionary];
 #endif
     } @catch(NSException *exception) {
-        LOG(Media, "AVVideoCaptureSource::applySize(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
+        LOG(Media, "AVVideoCaptureSource::setPreset(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
         return false;
     }
 
     return true;
 }
 
-bool AVVideoCaptureSource::applyFrameRate(double rate)
+void AVVideoCaptureSource::setFrameRate(double rate)
 {
     using namespace PAL;
     double epsilon = 0.00001;
@@ -425,8 +414,8 @@ bool AVVideoCaptureSource::applyFrameRate(double rate)
     }
 
     if (!bestFrameRateRange || !isFrameRateSupported(rate)) {
-        LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), frame rate %f not supported by video device", this, rate);
-        return false;
+        LOG(Media, "AVVideoCaptureSource::setFrameRate(%p), frame rate %f not supported by video device", this, rate);
+        return;
     }
 
     NSError *error = nil;
@@ -442,17 +431,17 @@ bool AVVideoCaptureSource::applyFrameRate(double rate)
             [device() unlockForConfiguration];
         }
     } @catch(NSException *exception) {
-        LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
-        return false;
+        LOG(Media, "AVVideoCaptureSource::setFrameRate(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
+        return;
     }
 
     if (error) {
-        LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
-        return false;
+        LOG(Media, "AVVideoCaptureSource::setFrameRate(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
+        return;
     }
 
-    LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p) - set frame rate range to %f", this, rate);
-    return true;
+    LOG(Media, "AVVideoCaptureSource::setFrameRate(%p) - set frame rate range to %f", this, rate);
+    return;
 }
 
 void AVVideoCaptureSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
@@ -461,7 +450,7 @@ void AVVideoCaptureSource::applySizeAndFrameRate(std::optional<int> width, std::
         setPreset(bestSessionPresetForVideoDimensions(WTFMove(width), WTFMove(height)));
 
     if (frameRate)
-        applyFrameRate(frameRate.value());
+        setFrameRate(frameRate.value());
 }
 
 static inline int sensorOrientation(AVCaptureVideoOrientation videoOrientation)
@@ -627,10 +616,15 @@ void AVVideoCaptureSource::processNewFrame(RetainPtr<CMSampleBufferRef> sampleBu
         std::swap(dimensions.width, dimensions.height);
 
     if (dimensions.width != m_width || dimensions.height != m_height) {
+        OptionSet<RealtimeMediaSourceSettings::Flag> changed;
+        if (m_width != dimensions.width)
+            changed.add(RealtimeMediaSourceSettings::Flag::Width);
+        if (m_height != dimensions.height)
+            changed.add(RealtimeMediaSourceSettings::Flag::Height);
+
         m_width = dimensions.width;
         m_height = dimensions.height;
-
-        settingsDidChange();
+        settingsDidChange(changed);
     }
 
     videoSampleAvailable(MediaSampleAVFObjC::create(m_buffer.get(), m_sampleRotation, [connection isVideoMirrored]));
index 6c74407..7d727cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -876,39 +876,19 @@ const RealtimeMediaSourceSettings& CoreAudioCaptureSource::settings() const
     return m_currentSettings.value();
 }
 
-void CoreAudioCaptureSource::settingsDidChange()
+void CoreAudioCaptureSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
-    m_currentSettings = std::nullopt;
-    RealtimeMediaSource::settingsDidChange();
-}
-
-bool CoreAudioCaptureSource::applySampleRate(int sampleRate)
-{
-    // FIXME: We should be able to describe sample rate as a discreet range constraint so that we only enter here with values that can be applied.
-    switch (sampleRate) {
-    case 8000:
-    case 16000:
-    case 32000:
-    case 44100:
-    case 48000:
-    case 96000:
-        break;
-    default:
-        return false;
+    if (settings.contains(RealtimeMediaSourceSettings::Flag::EchoCancellation)) {
+        CoreAudioSharedUnit::singleton().setEnableEchoCancellation(echoCancellation());
+        scheduleReconfiguration();
+    }
+    if (settings.contains(RealtimeMediaSourceSettings::Flag::SampleRate)) {
+        CoreAudioSharedUnit::singleton().setSampleRate(sampleRate());
+        scheduleReconfiguration();
     }
 
-    CoreAudioSharedUnit::singleton().setSampleRate(sampleRate);
-
-    scheduleReconfiguration();
-    return true;
-}
-
-bool CoreAudioCaptureSource::applyEchoCancellation(bool enableEchoCancellation)
-{
-    CoreAudioSharedUnit::singleton().setEnableEchoCancellation(enableEchoCancellation);
-
-    scheduleReconfiguration();
-    return true;
+    m_currentSettings = std::nullopt;
+    RealtimeMediaSource::settingsDidChange(settings);
 }
 
 void CoreAudioCaptureSource::scheduleReconfiguration()
index 792eaf0..c40d3c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -84,13 +84,11 @@ private:
     void startProducingData() final;
     void stopProducingData() final;
 
-    bool applyVolume(double) final { return true; }
-    bool applySampleRate(int) final;
-    bool applyEchoCancellation(bool) final;
+    std::optional<Vector<int>> discreteSampleRates() const final { return { { 8000, 16000, 32000, 44100, 48000, 96000 } }; }
 
     const RealtimeMediaSourceCapabilities& capabilities() const final;
     const RealtimeMediaSourceSettings& settings() const final;
-    void settingsDidChange() final;
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
 
     bool interrupted() const final;
 
index e74cbee..3ecd5ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -98,10 +98,17 @@ const RealtimeMediaSourceSettings& DisplayCaptureSourceCocoa::settings() const
     return m_currentSettings.value();
 }
 
-void DisplayCaptureSourceCocoa::settingsDidChange()
+void DisplayCaptureSourceCocoa::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
+    if (settings.contains(RealtimeMediaSourceSettings::Flag::FrameRate) && m_timer.isActive())
+        m_timer.startRepeating(1_s / frameRate());
+
+    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height }))
+        m_bufferAttributes = nullptr;
+
     m_currentSettings = std::nullopt;
-    RealtimeMediaSource::settingsDidChange();
+
+    RealtimeMediaSource::settingsDidChange(settings);
 }
 
 void DisplayCaptureSourceCocoa::startProducingData()
@@ -111,7 +118,7 @@ void DisplayCaptureSourceCocoa::startProducingData()
 #endif
 
     m_startTime = MonotonicTime::now();
-    m_timer.startRepeating(1_ms * lround(1000 / frameRate()));
+    m_timer.startRepeating(1_s / frameRate());
 }
 
 void DisplayCaptureSourceCocoa::stopProducingData()
@@ -129,23 +136,6 @@ Seconds DisplayCaptureSourceCocoa::elapsedTime()
     return m_elapsedTime + (MonotonicTime::now() - m_startTime);
 }
 
-bool DisplayCaptureSourceCocoa::applySize(const IntSize& newSize)
-{
-    if (size() == newSize)
-        return true;
-
-    m_bufferAttributes = nullptr;
-    return true;
-}
-
-bool DisplayCaptureSourceCocoa::applyFrameRate(double rate)
-{
-    if (m_timer.isActive())
-        m_timer.startRepeating(1_ms * lround(1000 / rate));
-
-    return true;
-}
-
 void DisplayCaptureSourceCocoa::emitFrame()
 {
     if (muted())
index 7877e0b..484c1b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -54,21 +54,20 @@ protected:
     void stopProducingData() override;
 
     Seconds elapsedTime();
-    bool applyFrameRate(double) override;
-    bool applySize(const IntSize&) override;
 
     RetainPtr<CMSampleBufferRef> sampleBufferFromPixelBuffer(CVPixelBufferRef);
 #if HAVE(IOSURFACE)
     RetainPtr<CVPixelBufferRef> pixelBufferFromIOSurface(IOSurfaceRef);
 #endif
 
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
+
 private:
 
     bool isCaptureSource() const final { return true; }
 
     const RealtimeMediaSourceCapabilities& capabilities() const final;
     const RealtimeMediaSourceSettings& settings() const final;
-    void settingsDidChange() final;
 
     void emitFrame();
 
index 6d14b03..99d78ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-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
@@ -50,8 +50,8 @@ private:
     friend class MockRealtimeAudioSource;
     MockRealtimeAudioSourceMac(const String& deviceID, const String& name);
 
-    bool applySampleRate(int) final;
-    bool applySampleSize(int) final { return false; }
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
+    std::optional<Vector<int>> discreteSampleRates() const final { return { { 44100, 48000 } }; }
 
     void emitSampleBuffers(uint32_t);
     void render(Seconds) final;
index 5abb8f2..0c8a4bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-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
@@ -158,30 +158,27 @@ void MockRealtimeAudioSourceMac::render(Seconds delta)
     }
 }
 
-bool MockRealtimeAudioSourceMac::applySampleRate(int sampleRate)
+void MockRealtimeAudioSourceMac::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
-    if (sampleRate < 44100 || sampleRate > 48000)
-        return false;
+    if (settings.contains(RealtimeMediaSourceSettings::Flag::SampleRate)) {
+        m_formatDescription = nullptr;
+        m_audioBufferList = nullptr;
 
-    if (sampleRate == this->sampleRate())
-        return true;
+        auto rate = sampleRate();
+        size_t sampleCount = 2 * rate;
 
-    m_formatDescription = nullptr;
-    m_audioBufferList = nullptr;
+        m_bipBopBuffer.grow(sampleCount);
+        m_bipBopBuffer.fill(0);
 
-    size_t sampleCount = 2 * sampleRate;
+        size_t bipBopSampleCount = ceil(BipBopDuration * rate);
+        size_t bipStart = 0;
+        size_t bopStart = rate;
 
-    m_bipBopBuffer.grow(sampleCount);
-    m_bipBopBuffer.fill(0);
-
-    size_t bipBopSampleCount = ceil(BipBopDuration * sampleRate);
-    size_t bipStart = 0;
-    size_t bopStart = sampleRate;
-
-    addHum(BipBopVolume, BipFrequency, sampleRate, 0, m_bipBopBuffer.data() + bipStart, bipBopSampleCount);
-    addHum(BipBopVolume, BopFrequency, sampleRate, 0, m_bipBopBuffer.data() + bopStart, bipBopSampleCount);
+        addHum(BipBopVolume, BipFrequency, rate, 0, m_bipBopBuffer.data() + bipStart, bipBopSampleCount);
+        addHum(BipBopVolume, BopFrequency, rate, 0, m_bipBopBuffer.data() + bopStart, bipBopSampleCount);
+    }
 
-    return true;
+    MockRealtimeAudioSource::settingsDidChange(settings);
 }
 
 } // namespace WebCore
index f583671..73129e1 100644 (file)
@@ -56,7 +56,7 @@ private:
 
     PlatformLayer* platformLayer() const;
     void updateSampleBuffer() final;
-    bool applySize(const IntSize&) final;
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
 
     void orientationChanged(int orientation) final;
     void monitorOrientation(OrientationNotifier&) final;
index 4ccee19..17b35ba 100644 (file)
@@ -154,13 +154,11 @@ void MockRealtimeVideoSourceMac::updateSampleBuffer()
     dispatchMediaSampleToObservers(MediaSampleAVFObjC::create(sampleBuffer.get(), m_deviceOrientation));
 }
 
-bool MockRealtimeVideoSourceMac::applySize(const IntSize& newSize)
+void MockRealtimeVideoSourceMac::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
-    if (!MockRealtimeVideoSource::applySize(newSize))
-        return false;
-
-    m_bufferPool = nullptr;
-    return true;
+    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height }))
+        m_bufferPool = nullptr;
+    MockRealtimeVideoSource::settingsDidChange(settings);
 }
 
 void MockRealtimeVideoSourceMac::orientationChanged(int orientation)
index 4b425f9..bbac8da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -173,9 +173,15 @@ void RealtimeIncomingVideoSourceCocoa::processNewSample(CMSampleBufferRef sample
 {
     m_buffer = sample;
     if (width != m_currentSettings.width() || height != m_currentSettings.height()) {
+        OptionSet<RealtimeMediaSourceSettings::Flag> changed;
+        if (width != m_currentSettings.width())
+            changed.add(RealtimeMediaSourceSettings::Flag::Width);
+        if (height != m_currentSettings.height())
+            changed.add(RealtimeMediaSourceSettings::Flag::Height);
+
         m_currentSettings.setWidth(width);
         m_currentSettings.setHeight(height);
-        settingsDidChange();
+        settingsDidChange(changed);
     }
 
     videoSampleAvailable(MediaSampleAVFObjC::create(sample, rotation));
index d26a294..0b1f3ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -59,8 +59,7 @@ private:
     void generateFrame() final;
     void startProducingData() final;
     void stopProducingData() final;
-    bool applySize(const IntSize&) final;
-    bool applyFrameRate(double) final;
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
     void commitConfiguration() final;
 
     bool createDisplayStream();
index b17e7c2..e6e448c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -253,21 +253,12 @@ void ScreenDisplayCaptureSourceMac::startDisplayStream()
     m_isRunning = true;
 }
 
-bool ScreenDisplayCaptureSourceMac::applySize(const IntSize& newSize)
+void ScreenDisplayCaptureSourceMac::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
-    if (!DisplayCaptureSourceCocoa::applySize(newSize))
-        return false;
-
-    m_displayStream = nullptr;
-    return true;
-}
-
-bool ScreenDisplayCaptureSourceMac::applyFrameRate(double rate)
-{
-    if (frameRate() != rate)
+    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height, RealtimeMediaSourceSettings::Flag::FrameRate }))
         m_displayStream = nullptr;
 
-    return DisplayCaptureSourceCocoa::applyFrameRate(rate);
+    return DisplayCaptureSourceCocoa::settingsDidChange(settings);
 }
 
 void ScreenDisplayCaptureSourceMac::commitConfiguration()
index f3c937f..9657270 100644 (file)
@@ -134,10 +134,10 @@ const RealtimeMediaSourceCapabilities& MockRealtimeAudioSource::capabilities() c
     return m_capabilities.value();
 }
 
-void MockRealtimeAudioSource::settingsDidChange()
+void MockRealtimeAudioSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
     m_currentSettings = std::nullopt;
-    RealtimeMediaSource::settingsDidChange();
+    RealtimeMediaSource::settingsDidChange(settings);
 }
 
 void MockRealtimeAudioSource::startProducingData()
index 443dd07..79c6678 100644 (file)
@@ -54,18 +54,13 @@ protected:
     void stopProducingData() final;
 
     virtual void render(Seconds) { }
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
 
     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; }
-
     const RealtimeMediaSourceCapabilities& capabilities() const final;
     const RealtimeMediaSourceSettings& settings() const final;
-    void settingsDidChange() final;
 
     void tick();
 
index 1eec441..2aeaf2c 100644 (file)
@@ -192,10 +192,17 @@ const RealtimeMediaSourceSettings& MockRealtimeVideoSource::settings() const
     return m_currentSettings.value();
 }
 
-void MockRealtimeVideoSource::settingsDidChange()
+void MockRealtimeVideoSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
 {
     m_currentSettings = std::nullopt;
-    RealtimeVideoSource::settingsDidChange();
+    if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height })) {
+        m_baseFontSize = size().height() * .08;
+        m_bipBopFontSize = m_baseFontSize * 2.5;
+        m_statsFontSize = m_baseFontSize * .5;
+        m_imageBuffer = nullptr;
+    }
+
+    RealtimeVideoSource::settingsDidChange(settings);
 }
 
 void MockRealtimeVideoSource::startCaptureTimer()
@@ -225,19 +232,6 @@ Seconds MockRealtimeVideoSource::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;
-}
-
 void MockRealtimeVideoSource::drawAnimation(GraphicsContext& context)
 {
     float radius = size().width() * .09;
index 6ac7358..91f656a 100644 (file)
@@ -60,12 +60,11 @@ protected:
     ImageBuffer* imageBuffer() const;
 
     Seconds elapsedTime();
-    bool applySize(const IntSize&) override;
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
 
 private:
     const RealtimeMediaSourceCapabilities& capabilities() const final;
     const RealtimeMediaSourceSettings& settings() const final;
-    void settingsDidChange() final;
 
     void startProducingData() final;
     void stopProducingData() final;
@@ -74,9 +73,6 @@ private:
     void drawText(GraphicsContext&);
     void drawBoxes(GraphicsContext&);
 
-    bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) override { return true; }
-    bool applyAspectRatio(double) override { return true; }
-
     bool isCaptureSource() const final { return true; }
 
     void generateFrame();
index 266104c..4183fd0 100644 (file)
@@ -1,3 +1,14 @@
+2018-09-05  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Simplify logic when changing RealtimeMediaSource settings
+        https://bugs.webkit.org/show_bug.cgi?id=189284
+        <rdar://problem/44117948>
+
+        Reviewed by Youenn Fablet.
+
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+        (WebKit::UserMediaCaptureManager::Source::setSettings):
+
 2018-09-04  Frederic Wang  <fwang@igalia.com>
 
         Add basic support for ScrollIntoViewOptions
index 8240d50..bc39dcc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -74,8 +74,9 @@ public:
     const RealtimeMediaSourceSettings& settings() const final { return m_settings; }
     void setSettings(RealtimeMediaSourceSettings&& settings)
     {
+        auto changed = m_settings.difference(settings);
         m_settings = WTFMove(settings);
-        settingsDidChange();
+        settingsDidChange(changed);
     }
 
     const CAAudioStreamDescription& description() const { return m_description; }