Bug 1162412 - Part 3: Treat plain values as exact in advanced. r=jesup, a=lmandel
authorJan-Ivar Bruaroey <jib@mozilla.com>
Wed, 06 May 2015 23:01:17 -0400
changeset 260516 e3045256cb27
parent 260515 9c1d3c0257ec
child 260517 ecbce7532a0a
push id805
push userryanvm@gmail.com
push date2015-05-18 17:06 +0000
treeherdermozilla-release@4bfd19d00ed4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup, lmandel
bugs1162412
milestone38.0.5
Bug 1162412 - Part 3: Treat plain values as exact in advanced. r=jesup, a=lmandel
dom/media/webrtc/MediaEngineCameraVideoSource.cpp
dom/media/webrtc/MediaEngineCameraVideoSource.h
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
@@ -79,58 +79,61 @@ MediaEngineCameraVideoSource::FitnessDis
     return 0;
   }
   return uint32_t(ValueType((std::abs(n - aRange.mIdeal.Value()) * 1000) /
                             std::max(std::abs(n), std::abs(aRange.mIdeal.Value()))));
 }
 
 // Binding code doesn't templatize well...
 
-template<>
-/* static */ uint32_t
+/*static*/ uint32_t
 MediaEngineCameraVideoSource::FitnessDistance(int32_t n,
-    const OwningLongOrConstrainLongRange& aConstraint)
+    const OwningLongOrConstrainLongRange& aConstraint, bool aAdvanced)
 {
   if (aConstraint.IsLong()) {
     ConstrainLongRange range;
-    range.mIdeal.Construct(aConstraint.GetAsLong());
+    (aAdvanced ? range.mExact : range.mIdeal).Construct(aConstraint.GetAsLong());
     return FitnessDistance(n, range);
   } else {
     return FitnessDistance(n, aConstraint.GetAsConstrainLongRange());
   }
 }
 
-template<>
-/* static */ uint32_t
+/*static*/ uint32_t
 MediaEngineCameraVideoSource::FitnessDistance(double n,
-    const OwningDoubleOrConstrainDoubleRange& aConstraint)
+    const OwningDoubleOrConstrainDoubleRange& aConstraint,
+    bool aAdvanced)
 {
   if (aConstraint.IsDouble()) {
     ConstrainDoubleRange range;
-    range.mIdeal.Construct(aConstraint.GetAsDouble());
+    (aAdvanced ? range.mExact : range.mIdeal).Construct(aConstraint.GetAsDouble());
     return FitnessDistance(n, range);
   } else {
     return FitnessDistance(n, aConstraint.GetAsConstrainDoubleRange());
   }
 }
 
 /*static*/ uint32_t
 MediaEngineCameraVideoSource::GetFitnessDistance(const webrtc::CaptureCapability& aCandidate,
-                                                 const MediaTrackConstraintSet &aConstraints)
+                                                 const MediaTrackConstraintSet &aConstraints,
+                                                 bool aAdvanced)
 {
   // Treat width|height|frameRate == 0 on capability as "can do any".
   // This allows for orthogonal capabilities that are not in discrete steps.
 
   uint64_t distance =
     uint64_t(aCandidate.width? FitnessDistance(int32_t(aCandidate.width),
-                                               aConstraints.mWidth) : 0) +
+                                               aConstraints.mWidth,
+                                               aAdvanced) : 0) +
     uint64_t(aCandidate.height? FitnessDistance(int32_t(aCandidate.height),
-                                                aConstraints.mHeight) : 0) +
+                                                aConstraints.mHeight,
+                                                aAdvanced) : 0) +
     uint64_t(aCandidate.maxFPS? FitnessDistance(double(aCandidate.maxFPS),
-                                                aConstraints.mFrameRate) : 0);
+                                                aConstraints.mFrameRate,
+                                                aAdvanced) : 0);
   return uint32_t(std::min(distance, uint64_t(UINT32_MAX)));
 }
 
 // Find best capability by removing inferiors. May leave >1 of equal distance
 
 /* static */ void
 MediaEngineCameraVideoSource::TrimLessFitCandidates(CapabilitySet& set) {
   uint32_t best = UINT32_MAX;
@@ -147,16 +150,18 @@ MediaEngineCameraVideoSource::TrimLessFi
     }
   }
   MOZ_ASSERT(set.Length());
 }
 
 // GetBestFitnessDistance returns the best distance the capture device can offer
 // as a whole, given an accumulated number of ConstraintSets.
 // Ideal values are considered in the first ConstraintSet only.
+// Plain values are treated as Ideal in the first ConstraintSet.
+// Plain values are treated as Exact in subsequent ConstraintSets.
 // Infinity = UINT32_MAX e.g. device cannot satisfy accumulated ConstraintSets.
 // A finite result may be used to calculate this device's ranking as a choice.
 
 uint32_t
 MediaEngineCameraVideoSource::GetBestFitnessDistance(
     const nsTArray<const MediaTrackConstraintSet*>& aConstraintSets)
 {
   size_t num = NumCapabilities();
@@ -167,17 +172,17 @@ MediaEngineCameraVideoSource::GetBestFit
   }
 
   bool first = true;
   for (const MediaTrackConstraintSet* cs : aConstraintSets) {
     for (size_t i = 0; i < candidateSet.Length();  ) {
       auto& candidate = candidateSet[i];
       webrtc::CaptureCapability cap;
       GetCapability(candidate.mIndex, cap);
-      uint32_t distance = GetFitnessDistance(cap, *cs);
+      uint32_t distance = GetFitnessDistance(cap, *cs, !first);
       if (distance == UINT32_MAX) {
         candidateSet.RemoveElementAt(i);
       } else {
         ++i;
         if (first) {
           candidate.mDistance = distance;
         }
       }
@@ -207,34 +212,34 @@ MediaEngineCameraVideoSource::ChooseCapa
   }
 
   // First, filter capabilities by required constraints (min, max, exact).
 
   for (size_t i = 0; i < candidateSet.Length();) {
     auto& candidate = candidateSet[i];
     webrtc::CaptureCapability cap;
     GetCapability(candidate.mIndex, cap);
-    candidate.mDistance = GetFitnessDistance(cap, aConstraints);
+    candidate.mDistance = GetFitnessDistance(cap, aConstraints, false);
     if (candidate.mDistance == UINT32_MAX) {
       candidateSet.RemoveElementAt(i);
     } else {
       ++i;
     }
   }
 
   // Filter further with all advanced constraints (that don't overconstrain).
 
   if (aConstraints.mAdvanced.WasPassed()) {
     for (const MediaTrackConstraintSet &cs : aConstraints.mAdvanced.Value()) {
       CapabilitySet rejects;
       for (size_t i = 0; i < candidateSet.Length();) {
         auto& candidate = candidateSet[i];
         webrtc::CaptureCapability cap;
         GetCapability(candidate.mIndex, cap);
-        if (GetFitnessDistance(cap, cs) == UINT32_MAX) {
+        if (GetFitnessDistance(cap, cs, true) == UINT32_MAX) {
           rejects.AppendElement(candidate);
           candidateSet.RemoveElementAt(i);
         } else {
           ++i;
         }
       }
       if (!candidateSet.Length()) {
         candidateSet.MoveElementsFrom(rejects);
@@ -256,17 +261,17 @@ MediaEngineCameraVideoSource::ChooseCapa
     MediaTrackConstraintSet prefs;
     prefs.mWidth.SetAsLong() = aPrefs.GetWidth();
     prefs.mHeight.SetAsLong() = aPrefs.GetHeight();
     prefs.mFrameRate.SetAsDouble() = aPrefs.mFPS;
 
     for (auto& candidate : candidateSet) {
       webrtc::CaptureCapability cap;
       GetCapability(candidate.mIndex, cap);
-      candidate.mDistance = GetFitnessDistance(cap, prefs);
+      candidate.mDistance = GetFitnessDistance(cap, prefs, false);
     }
     TrimLessFitCandidates(candidateSet);
   }
 
   // Any remaining multiples all have the same distance, but may vary on
   // format. Some formats are more desirable for certain use like WebRTC.
   // E.g. I420 over RGB24 can remove a needless format conversion.
 
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.h
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.h
@@ -75,18 +75,24 @@ protected:
 
   // guts for appending data to the MSG track
   virtual bool AppendToTrack(SourceMediaStream* aSource,
                              layers::Image* aImage,
                              TrackID aID,
                              StreamTime delta);
   template<class ValueType, class ConstrainRange>
   static uint32_t FitnessDistance(ValueType n, const ConstrainRange& aRange);
+  static uint32_t FitnessDistance(int32_t n,
+      const dom::OwningLongOrConstrainLongRange& aConstraint, bool aAdvanced);
+  static uint32_t FitnessDistance(double n,
+      const dom::OwningDoubleOrConstrainDoubleRange& aConstraint, bool aAdvanced);
+
   static uint32_t GetFitnessDistance(const webrtc::CaptureCapability& aCandidate,
-                                     const dom::MediaTrackConstraintSet &aConstraints);
+                                     const dom::MediaTrackConstraintSet &aConstraints,
+                                     bool aAdvanced);
   static void TrimLessFitCandidates(CapabilitySet& set);
   virtual size_t NumCapabilities();
   virtual void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut);
   bool ChooseCapability(const dom::MediaTrackConstraints &aConstraints,
                         const MediaEnginePrefs &aPrefs);
 
   // Engine variables.