Bug 1213517 - Add an un-flattened NormalizedConstraints type for downstream use. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Thu, 30 Jun 2016 16:08:45 -0400
changeset 388769 ff6e9bf69f9387a2805b6d892582f3a540fa4bd4
parent 388768 31ce1c0a088d81f784b78f79b5740c6c28628d52
child 388770 d22f14b07fa02cfab36877147c6761eb7dcf5ccb
push id23232
push userjbruaroey@mozilla.com
push dateSun, 17 Jul 2016 21:00:46 +0000
bugs1213517
milestone50.0a1
Bug 1213517 - Add an un-flattened NormalizedConstraints type for downstream use. MozReview-Commit-ID: 1ZUN21mgfXh
dom/media/webrtc/MediaEngineCameraVideoSource.cpp
dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
dom/media/webrtc/MediaEngineRemoteVideoSource.h
dom/media/webrtc/MediaTrackConstraints.cpp
dom/media/webrtc/MediaTrackConstraints.h
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
@@ -141,31 +141,31 @@ MediaEngineCameraVideoSource::GetBestFit
   return candidateSet[0].mDistance;
 }
 
 void
 MediaEngineCameraVideoSource::LogConstraints(
     const MediaTrackConstraintSet& aConstraints, bool aAdvanced)
 {
   NormalizedConstraintSet c(aConstraints, aAdvanced);
-  LOG(((c.mWidth.mIdeal.WasPassed()?
+  LOG(((c.mWidth.mIdeal.isSome()?
         "Constraints: width: { min: %d, max: %d, ideal: %d }" :
         "Constraints: width: { min: %d, max: %d }"),
        c.mWidth.mMin, c.mWidth.mMax,
-       c.mWidth.mIdeal.WasPassed()? c.mWidth.mIdeal.Value() : 0));
-  LOG(((c.mHeight.mIdeal.WasPassed()?
+       c.mWidth.mIdeal.valueOr(0)));
+  LOG(((c.mHeight.mIdeal.isSome()?
         "             height: { min: %d, max: %d, ideal: %d }" :
         "             height: { min: %d, max: %d }"),
        c.mHeight.mMin, c.mHeight.mMax,
-       c.mHeight.mIdeal.WasPassed()? c.mHeight.mIdeal.Value() : 0));
-  LOG(((c.mFrameRate.mIdeal.WasPassed()?
+       c.mHeight.mIdeal.valueOr(0)));
+  LOG(((c.mFrameRate.mIdeal.isSome()?
         "             frameRate: { min: %f, max: %f, ideal: %f }" :
         "             frameRate: { min: %f, max: %f }"),
        c.mFrameRate.mMin, c.mFrameRate.mMax,
-       c.mFrameRate.mIdeal.WasPassed()? c.mFrameRate.mIdeal.Value() : 0));
+       c.mFrameRate.mIdeal.valueOr(0)));
 }
 
 void
 MediaEngineCameraVideoSource::LogCapability(const char* aHeader,
     const webrtc::CaptureCapability &aCapability, uint32_t aDistance)
 {
   // RawVideoType and VideoCodecType media/webrtc/trunk/webrtc/common_types.h
   static const char* const types[] = {
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -443,22 +443,25 @@ MediaEngineRemoteVideoSource::ChooseCapa
 {
   AssertIsOnOwningThread();
 
   switch(mMediaSource) {
     case dom::MediaSourceEnum::Screen:
     case dom::MediaSourceEnum::Window:
     case dom::MediaSourceEnum::Application: {
       FlattenedConstraints c(aConstraints);
-      mCapability.width = ((c.mWidth.mIdeal.WasPassed() ?
-        c.mWidth.mIdeal.Value() : 0) & 0xffff) << 16 | (c.mWidth.mMax & 0xffff);
-      mCapability.height = ((c.mHeight.mIdeal.WasPassed() ?
-        c.mHeight.mIdeal.Value() : 0) & 0xffff) << 16 | (c.mHeight.mMax & 0xffff);
-      mCapability.maxFPS = c.mFrameRate.Clamp(c.mFrameRate.mIdeal.WasPassed() ?
-        c.mFrameRate.mIdeal.Value() : aPrefs.mFPS);
+      // The actual resolution to constrain around is not easy to find ahead of
+      // time (and may in fact change over time), so as a hack, we push ideal
+      // and max constraints down to desktop_capture_impl.cc and finish the
+      // algorithm there.
+      mCapability.width = (c.mWidth.mIdeal.valueOr(0) & 0xffff) << 16 |
+                          (c.mWidth.mMax & 0xffff);
+      mCapability.height = (c.mHeight.mIdeal.valueOr(0) & 0xffff) << 16 |
+                           (c.mHeight.mMax & 0xffff);
+      mCapability.maxFPS = c.mFrameRate.Clamp(c.mFrameRate.mIdeal.valueOr(aPrefs.mFPS));
       return true;
     }
     default:
       return MediaEngineCameraVideoSource::ChooseCapability(aConstraints, aPrefs, aDeviceId);
   }
 
 }
 
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -74,17 +74,17 @@ public:
   class AllocationHandle : public BaseAllocationHandle
   {
   public:
     AllocationHandle(const dom::MediaTrackConstraints& aConstraints)
       : mConstraints(aConstraints) {}
   private:
     ~AllocationHandle() override {}
   public:
-    dom::MediaTrackConstraints mConstraints;
+    NormalizedConstraints mConstraints;
   };
 
   nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
                     const MediaEnginePrefs& aPrefs,
                     const nsString& aDeviceId,
                     const nsACString& aOrigin,
                     BaseAllocationHandle** aOutHandle) override;
   nsresult Deallocate(BaseAllocationHandle* aHandle) override;;
--- a/dom/media/webrtc/MediaTrackConstraints.cpp
+++ b/dom/media/webrtc/MediaTrackConstraints.cpp
@@ -10,17 +10,17 @@
 namespace mozilla {
 
 template<class ValueType>
 template<class ConstrainRange>
 void
 NormalizedConstraintSet::Range<ValueType>::SetFrom(const ConstrainRange& aOther)
 {
   if (aOther.mIdeal.WasPassed()) {
-    mIdeal.Construct(aOther.mIdeal.Value());
+    mIdeal.emplace(aOther.mIdeal.Value());
   }
   if (aOther.mExact.WasPassed()) {
     mMin = aOther.mExact.Value();
     mMax = aOther.mExact.Value();
   } else {
     if (aOther.mMin.WasPassed()) {
       mMin = aOther.mMin.Value();
     }
@@ -33,53 +33,53 @@ NormalizedConstraintSet::Range<ValueType
 NormalizedConstraintSet::LongRange::LongRange(
     const dom::OwningLongOrConstrainLongRange& aOther, bool advanced)
 : Range<int32_t>(1 + INT32_MIN, INT32_MAX) // +1 avoids Windows compiler bug
 {
   if (aOther.IsLong()) {
     if (advanced) {
       mMin = mMax = aOther.GetAsLong();
     } else {
-      mIdeal.Construct(aOther.GetAsLong());
+      mIdeal.emplace(aOther.GetAsLong());
     }
   } else {
     SetFrom(aOther.GetAsConstrainLongRange());
   }
 }
 
 NormalizedConstraintSet::DoubleRange::DoubleRange(
     const dom::OwningDoubleOrConstrainDoubleRange& aOther, bool advanced)
 : Range<double>(-std::numeric_limits<double>::infinity(),
                 std::numeric_limits<double>::infinity())
 {
   if (aOther.IsDouble()) {
     if (advanced) {
       mMin = mMax = aOther.GetAsDouble();
     } else {
-      mIdeal.Construct(aOther.GetAsDouble());
+      mIdeal.emplace(aOther.GetAsDouble());
     }
   } else {
     SetFrom(aOther.GetAsConstrainDoubleRange());
   }
 }
 
 NormalizedConstraintSet::BooleanRange::BooleanRange(
     const dom::OwningBooleanOrConstrainBooleanParameters& aOther, bool advanced)
 : Range<bool>(false, true)
 {
   if (aOther.IsBoolean()) {
     if (advanced) {
       mMin = mMax = aOther.GetAsBoolean();
     } else {
-      mIdeal.Construct(aOther.GetAsBoolean());
+      mIdeal.emplace(aOther.GetAsBoolean());
     }
   } else {
     const ConstrainBooleanParameters& r = aOther.GetAsConstrainBooleanParameters();
     if (r.mIdeal.WasPassed()) {
-      mIdeal.Construct(r.mIdeal.Value());
+      mIdeal.emplace(r.mIdeal.Value());
     }
     if (r.mExact.WasPassed()) {
       mMin = r.mExact.Value();
       mMax = r.mExact.Value();
     }
   }
 }
 
@@ -173,41 +173,47 @@ NormalizedConstraintSet::StringRange::In
   }
   for (auto& entry : mExact) {
     if (aOther.mExact.find(entry) == aOther.mExact.end()) {
       mExact.erase(entry);
     }
   }
 }
 
-FlattenedConstraints::FlattenedConstraints(const dom::MediaTrackConstraints& aOther)
+NormalizedConstraints::NormalizedConstraints(const dom::MediaTrackConstraints& aOther)
 : NormalizedConstraintSet(aOther, false)
 {
   if (aOther.mAdvanced.WasPassed()) {
-    const auto& advanced = aOther.mAdvanced.Value();
-    for (size_t i = 0; i < advanced.Length(); i++) {
-      NormalizedConstraintSet set(advanced[i], true);
-      // Must only apply compatible i.e. inherently non-overconstraining sets
-      // This rule is pretty much why this code is centralized here.
-      if (mWidth.Intersects(set.mWidth) &&
-          mHeight.Intersects(set.mHeight) &&
-          mFrameRate.Intersects(set.mFrameRate)) {
-        mWidth.Intersect(set.mWidth);
-        mHeight.Intersect(set.mHeight);
-        mFrameRate.Intersect(set.mFrameRate);
-      }
-      if (mEchoCancellation.Intersects(set.mEchoCancellation)) {
-          mEchoCancellation.Intersect(set.mEchoCancellation);
-      }
-      if (mMozNoiseSuppression.Intersects(set.mMozNoiseSuppression)) {
-          mMozNoiseSuppression.Intersect(set.mMozNoiseSuppression);
-      }
-      if (mMozAutoGainControl.Intersects(set.mMozAutoGainControl)) {
-          mMozAutoGainControl.Intersect(set.mMozAutoGainControl);
-      }
+    for (auto& entry : aOther.mAdvanced.Value()) {
+      mAdvanced.AppendElement(NormalizedConstraintSet(entry, true));
+    }
+  }
+}
+
+FlattenedConstraints::FlattenedConstraints(const NormalizedConstraints& aOther)
+: NormalizedConstraintSet(aOther)
+{
+  for (auto& set : aOther.mAdvanced) {
+    // Must only apply compatible i.e. inherently non-overconstraining sets
+    // This rule is pretty much why this code is centralized here.
+    if (mWidth.Intersects(set.mWidth) &&
+        mHeight.Intersects(set.mHeight) &&
+        mFrameRate.Intersects(set.mFrameRate)) {
+      mWidth.Intersect(set.mWidth);
+      mHeight.Intersect(set.mHeight);
+      mFrameRate.Intersect(set.mFrameRate);
+    }
+    if (mEchoCancellation.Intersects(set.mEchoCancellation)) {
+        mEchoCancellation.Intersect(set.mEchoCancellation);
+    }
+    if (mMozNoiseSuppression.Intersects(set.mMozNoiseSuppression)) {
+        mMozNoiseSuppression.Intersect(set.mMozNoiseSuppression);
+    }
+    if (mMozAutoGainControl.Intersects(set.mMozAutoGainControl)) {
+        mMozAutoGainControl.Intersect(set.mMozAutoGainControl);
     }
   }
 }
 
 // MediaEngine helper
 //
 // The full algorithm for all devices. Sources that don't list capabilities
 // need to fake it and hardcode some by populating mHardcodedCapabilities above.
--- a/dom/media/webrtc/MediaTrackConstraints.h
+++ b/dom/media/webrtc/MediaTrackConstraints.h
@@ -37,25 +37,25 @@ static Enum StringToEnum(const EnumValue
 // Instead of constraining values, constrain the constraints themselves.
 
 struct NormalizedConstraintSet
 {
   template<class ValueType>
   struct Range
   {
     ValueType mMin, mMax;
-    dom::Optional<ValueType> mIdeal;
+    Maybe<ValueType> mIdeal;
 
     Range(ValueType aMin, ValueType aMax) : mMin(aMin), mMax(aMax) {}
 
     template<class ConstrainRange>
     void SetFrom(const ConstrainRange& aOther);
     ValueType Clamp(ValueType n) const { return std::max(mMin, std::min(n, mMax)); }
     ValueType Get(ValueType defaultValue) const {
-      return Clamp(mIdeal.WasPassed() ? mIdeal.Value() : defaultValue);
+      return Clamp(mIdeal.valueOr(defaultValue));
     }
     bool Intersects(const Range& aOther) const {
       return mMax >= aOther.mMin && mMin <= aOther.mMax;
     }
     void Intersect(const Range& aOther) {
       MOZ_ASSERT(Intersects(aOther));
       mMin = std::max(mMin, aOther.mMin);
       mMax = std::min(mMax, aOther.mMax);
@@ -124,19 +124,30 @@ struct NormalizedConstraintSet
   , mViewportOffsetY(aOther.mViewportOffsetY, advanced)
   , mViewportWidth(aOther.mViewportWidth, advanced)
   , mViewportHeight(aOther.mViewportHeight, advanced)
   , mEchoCancellation(aOther.mEchoCancellation, advanced)
   , mMozNoiseSuppression(aOther.mMozNoiseSuppression, advanced)
   , mMozAutoGainControl(aOther.mMozAutoGainControl, advanced) {}
 };
 
+// Used instead of MediaTrackConstraints in lower-level code.
+struct NormalizedConstraints : public NormalizedConstraintSet
+{
+  explicit NormalizedConstraints(const dom::MediaTrackConstraints& aOther);
+  nsTArray<NormalizedConstraintSet> mAdvanced;
+};
+
+// Flattened version is used in low-level code with orthogonal constraints only.
 struct FlattenedConstraints : public NormalizedConstraintSet
 {
-  explicit FlattenedConstraints(const dom::MediaTrackConstraints& aOther);
+  explicit FlattenedConstraints(const NormalizedConstraints& aOther);
+
+  explicit FlattenedConstraints(const dom::MediaTrackConstraints& aOther)
+    : FlattenedConstraints(NormalizedConstraints(aOther)) {}
 };
 
 // A helper class for MediaEngines
 
 class MediaConstraintsHelper
 {
 protected:
   template<class ValueType, class ConstrainRange>