Bug 912342 - Move code SelectSettings to MediaConstraintsHelper. r=jesup
authorJan-Ivar Bruaroey <jib@mozilla.com>
Sat, 19 Sep 2015 02:00:48 -0400
changeset 296085 6124439438d464ef26de8d5970006a94403a028e
parent 296084 e01353044b85bde8d04c0a332365f05c8e4adf3c
child 296086 1ff3901d09898110232f23b02d989c7c152aa1ad
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs912342
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 912342 - Move code SelectSettings to MediaConstraintsHelper. r=jesup
dom/media/MediaManager.cpp
dom/media/webrtc/MediaTrackConstraints.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -74,18 +74,16 @@
 
 #if defined(XP_MACOSX)
 #include "nsCocoaFeatures.h"
 #endif
 #if defined (XP_WIN)
 #include "mozilla/WindowsVersion.h"
 #endif
 
-#include <map>
-
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with MediaStream::GetCurrentTime.
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 
 // XXX Workaround for bug 986974 to maintain the existing broken semantics
 template<>
@@ -1152,137 +1150,16 @@ GetSources(MediaEngine *engine, dom::Med
     }
   } else {
     for (auto& source : sources) {
       aResult.AppendElement(new DeviceType(source));
     }
   }
 }
 
-template<class DeviceType>
-static bool
-AreUnfitSettings(const MediaTrackConstraints &aConstraints,
-                 nsTArray<nsRefPtr<DeviceType>>& aSources)
-{
-  nsTArray<const MediaTrackConstraintSet*> aggregateConstraints;
-  aggregateConstraints.AppendElement(&aConstraints);
-
-  for (auto& source : aSources) {
-    if (source->GetBestFitnessDistance(aggregateConstraints) != UINT32_MAX) {
-      return false;
-    }
-  }
-  return true;
-}
-
-// Apply constrains to a supplied list of sources (removes items from the list)
-
-template<class DeviceType>
-static const char*
-SelectSettings(const MediaTrackConstraints &aConstraints,
-               nsTArray<nsRefPtr<DeviceType>>& aSources)
-{
-  auto& c = aConstraints;
-
-  // First apply top-level constraints.
-
-  // Stack constraintSets that pass, starting with the required one, because the
-  // whole stack must be re-satisfied each time a capability-set is ruled out
-  // (this avoids storing state or pushing algorithm into the lower-level code).
-  nsTArray<nsRefPtr<DeviceType>> unsatisfactory;
-  nsTArray<const MediaTrackConstraintSet*> aggregateConstraints;
-  aggregateConstraints.AppendElement(&c);
-
-  std::multimap<uint32_t, nsRefPtr<DeviceType>> ordered;
-
-  for (uint32_t i = 0; i < aSources.Length();) {
-    uint32_t distance = aSources[i]->GetBestFitnessDistance(aggregateConstraints);
-    if (distance == UINT32_MAX) {
-      unsatisfactory.AppendElement(aSources[i]);
-      aSources.RemoveElementAt(i);
-    } else {
-      ordered.insert(std::pair<uint32_t, nsRefPtr<DeviceType>>(distance,
-                                                               aSources[i]));
-      ++i;
-    }
-  }
-  if (!aSources.Length()) {
-    // None selected. The spec says to report a constraint that satisfies NONE
-    // of the sources. Unfortunately, this is a bit laborious to find out, and
-    // requires updating as new constraints are added!
-
-    if (c.mDeviceId.IsConstrainDOMStringParameters()) {
-      MediaTrackConstraints fresh;
-      fresh.mDeviceId = c.mDeviceId;
-      if (AreUnfitSettings(fresh, unsatisfactory)) {
-        return "deviceId";
-      }
-    }
-    if (c.mWidth.IsConstrainLongRange()) {
-      MediaTrackConstraints fresh;
-      fresh.mWidth = c.mWidth;
-      if (AreUnfitSettings(fresh, unsatisfactory)) {
-        return "width";
-      }
-    }
-    if (c.mHeight.IsConstrainLongRange()) {
-      MediaTrackConstraints fresh;
-      fresh.mHeight = c.mHeight;
-      if (AreUnfitSettings(fresh, unsatisfactory)) {
-        return "height";
-      }
-    }
-    if (c.mFrameRate.IsConstrainDoubleRange()) {
-      MediaTrackConstraints fresh;
-      fresh.mFrameRate = c.mFrameRate;
-      if (AreUnfitSettings(fresh, unsatisfactory)) {
-        return "frameRate";
-      }
-    }
-    if (c.mFacingMode.IsConstrainDOMStringParameters()) {
-      MediaTrackConstraints fresh;
-      fresh.mFacingMode = c.mFacingMode;
-      if (AreUnfitSettings(fresh, unsatisfactory)) {
-        return "facingMode";
-      }
-    }
-    return "";
-  }
-
-  // Order devices by shortest distance
-  for (auto& ordinal : ordered) {
-    aSources.RemoveElement(ordinal.second);
-    aSources.AppendElement(ordinal.second);
-  }
-
-  // Then apply advanced constraints.
-
-  if (c.mAdvanced.WasPassed()) {
-    auto &array = c.mAdvanced.Value();
-
-    for (int i = 0; i < int(array.Length()); i++) {
-      aggregateConstraints.AppendElement(&array[i]);
-      nsTArray<nsRefPtr<DeviceType>> rejects;
-      for (uint32_t j = 0; j < aSources.Length();) {
-        if (aSources[j]->GetBestFitnessDistance(aggregateConstraints) == UINT32_MAX) {
-          rejects.AppendElement(aSources[j]);
-          aSources.RemoveElementAt(j);
-        } else {
-          ++j;
-        }
-      }
-      if (!aSources.Length()) {
-        aSources.AppendElements(Move(rejects));
-        aggregateConstraints.RemoveElementAt(aggregateConstraints.Length() - 1);
-      }
-    }
-  }
-  return nullptr;
-}
-
 static const char*
 SelectSettings(MediaStreamConstraints &aConstraints,
                nsTArray<nsRefPtr<MediaDevice>>& aSources)
 {
   // Since the advanced part of the constraints algorithm needs to know when
   // a candidate set is overconstrained (zero members), we must split up the
   // list into videos and audios, and put it back together again at the end.
 
@@ -1299,23 +1176,25 @@ SelectSettings(MediaStreamConstraints &a
     }
   }
   aSources.Clear();
   MOZ_ASSERT(!aSources.Length());
 
   const char* badConstraint = nullptr;
 
   if (IsOn(aConstraints.mVideo)) {
-    badConstraint = SelectSettings(GetInvariant(aConstraints.mVideo), videos);
+    badConstraint = MediaConstraintsHelper::SelectSettings(
+        GetInvariant(aConstraints.mVideo), videos);
     for (auto& video : videos) {
       aSources.AppendElement(video);
     }
   }
   if (audios.Length() && IsOn(aConstraints.mAudio)) {
-    badConstraint = SelectSettings(GetInvariant(aConstraints.mAudio), audios);
+    badConstraint = MediaConstraintsHelper::SelectSettings(
+        GetInvariant(aConstraints.mAudio), audios);
     for (auto& audio : audios) {
       aSources.AppendElement(audio);
     }
   }
   return badConstraint;
 }
 
 /**
--- a/dom/media/webrtc/MediaTrackConstraints.h
+++ b/dom/media/webrtc/MediaTrackConstraints.h
@@ -7,16 +7,18 @@
 #ifndef MEDIATRACKCONSTRAINTS_H_
 #define MEDIATRACKCONSTRAINTS_H_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/MediaStreamTrackBinding.h"
 #include "mozilla/dom/MediaTrackConstraintSetBinding.h"
 #include "mozilla/dom/MediaTrackSupportedConstraintsBinding.h"
 
+#include <map>
+
 namespace mozilla {
 
 template<class EnumValuesStrings, class Enum>
 static const char* EnumToASCII(const EnumValuesStrings& aStrings, Enum aValue) {
   return aStrings[uint32_t(aValue)].value;
 }
 
 template<class EnumValuesStrings, class Enum>
@@ -99,13 +101,135 @@ protected:
     bool aAdvanced);
   static uint32_t FitnessDistance(nsString aN,
       const dom::ConstrainDOMStringParameters& aParams);
 
   static uint32_t
   GetMinimumFitnessDistance(const dom::MediaTrackConstraintSet &aConstraints,
                             bool aAdvanced,
                             const nsString& aDeviceId);
+
+  template<class DeviceType>
+  static bool
+  AreUnfitSettings(const dom::MediaTrackConstraints &aConstraints,
+                   nsTArray<nsRefPtr<DeviceType>>& aSources)
+  {
+    nsTArray<const dom::MediaTrackConstraintSet*> aggregateConstraints;
+    aggregateConstraints.AppendElement(&aConstraints);
+
+    for (auto& source : aSources) {
+      if (source->GetBestFitnessDistance(aggregateConstraints) != UINT32_MAX) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+public:
+  // Apply constrains to a supplied list of sources (removes items from the list)
+
+  template<class DeviceType>
+  static const char*
+  SelectSettings(const dom::MediaTrackConstraints &aConstraints,
+                 nsTArray<nsRefPtr<DeviceType>>& aSources)
+  {
+    auto& c = aConstraints;
+
+    // First apply top-level constraints.
+
+    // Stack constraintSets that pass, starting with the required one, because the
+    // whole stack must be re-satisfied each time a capability-set is ruled out
+    // (this avoids storing state or pushing algorithm into the lower-level code).
+    nsTArray<nsRefPtr<DeviceType>> unsatisfactory;
+    nsTArray<const dom::MediaTrackConstraintSet*> aggregateConstraints;
+    aggregateConstraints.AppendElement(&c);
+
+    std::multimap<uint32_t, nsRefPtr<DeviceType>> ordered;
+
+    for (uint32_t i = 0; i < aSources.Length();) {
+      uint32_t distance = aSources[i]->GetBestFitnessDistance(aggregateConstraints);
+      if (distance == UINT32_MAX) {
+        unsatisfactory.AppendElement(aSources[i]);
+        aSources.RemoveElementAt(i);
+      } else {
+        ordered.insert(std::pair<uint32_t, nsRefPtr<DeviceType>>(distance,
+                                                                 aSources[i]));
+        ++i;
+      }
+    }
+    if (!aSources.Length()) {
+      // None selected. The spec says to report a constraint that satisfies NONE
+      // of the sources. Unfortunately, this is a bit laborious to find out, and
+      // requires updating as new constraints are added!
+
+      if (c.mDeviceId.IsConstrainDOMStringParameters()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mDeviceId = c.mDeviceId;
+        if (AreUnfitSettings(fresh, unsatisfactory)) {
+          return "deviceId";
+        }
+      }
+      if (c.mWidth.IsConstrainLongRange()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mWidth = c.mWidth;
+        if (AreUnfitSettings(fresh, unsatisfactory)) {
+          return "width";
+        }
+      }
+      if (c.mHeight.IsConstrainLongRange()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mHeight = c.mHeight;
+        if (AreUnfitSettings(fresh, unsatisfactory)) {
+          return "height";
+        }
+      }
+      if (c.mFrameRate.IsConstrainDoubleRange()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mFrameRate = c.mFrameRate;
+        if (AreUnfitSettings(fresh, unsatisfactory)) {
+          return "frameRate";
+        }
+      }
+      if (c.mFacingMode.IsConstrainDOMStringParameters()) {
+        dom::MediaTrackConstraints fresh;
+        fresh.mFacingMode = c.mFacingMode;
+        if (AreUnfitSettings(fresh, unsatisfactory)) {
+          return "facingMode";
+        }
+      }
+      return "";
+    }
+
+    // Order devices by shortest distance
+    for (auto& ordinal : ordered) {
+      aSources.RemoveElement(ordinal.second);
+      aSources.AppendElement(ordinal.second);
+    }
+
+    // Then apply advanced constraints.
+
+    if (c.mAdvanced.WasPassed()) {
+      auto &array = c.mAdvanced.Value();
+
+      for (int i = 0; i < int(array.Length()); i++) {
+        aggregateConstraints.AppendElement(&array[i]);
+        nsTArray<nsRefPtr<DeviceType>> rejects;
+        for (uint32_t j = 0; j < aSources.Length();) {
+          if (aSources[j]->GetBestFitnessDistance(aggregateConstraints) == UINT32_MAX) {
+            rejects.AppendElement(aSources[j]);
+            aSources.RemoveElementAt(j);
+          } else {
+            ++j;
+          }
+        }
+        if (!aSources.Length()) {
+          aSources.AppendElements(Move(rejects));
+          aggregateConstraints.RemoveElementAt(aggregateConstraints.Length() - 1);
+        }
+      }
+    }
+    return nullptr;
+  }
 };
 
 } // namespace mozilla
 
 #endif /* MEDIATRACKCONSTRAINTS_H_ */