Bug 1003274 - Part 1 - refactor template types. r=jesup
authorJan-Ivar Bruaroey <jib@mozilla.com>
Wed, 24 Sep 2014 11:17:33 -0400
changeset 212233 d48c270e62c97747c1093a620f8e4f14a028be20
parent 212232 5a26c66bc295bdf6a18a852f855a67b460a762f8
child 212234 c2233448b59c0d2ff25486c33b9c019ac3a600c3
push id27702
push userkwierso@gmail.com
push dateFri, 24 Oct 2014 22:05:50 +0000
treeherdermozilla-central@c70f62375f7d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1003274
milestone36.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 1003274 - Part 1 - refactor template types. r=jesup
dom/media/MediaManager.cpp
dom/media/MediaManager.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -282,17 +282,17 @@ private:
  */
 class DeviceSuccessCallbackRunnable: public nsRunnable
 {
 public:
   DeviceSuccessCallbackRunnable(
     uint64_t aWindowID,
     nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback>& aSuccess,
     nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError,
-    nsTArray<nsCOMPtr<nsIMediaDevice> >* aDevices)
+    nsTArray<nsRefPtr<MediaDevice>>* aDevices)
     : mDevices(aDevices)
     , mWindowID(aWindowID)
     , mManager(MediaManager::GetInstance())
   {
     mSuccess.swap(aSuccess);
     mError.swap(aError);
   }
 
@@ -333,17 +333,17 @@ public:
 
     mSuccess->OnSuccess(devices);
     return NS_OK;
   }
 
 private:
   nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mSuccess;
   nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
-  nsAutoPtr<nsTArray<nsCOMPtr<nsIMediaDevice> > > mDevices;
+  nsAutoPtr<nsTArray<nsRefPtr<MediaDevice>>> mDevices;
   uint64_t mWindowID;
   nsRefPtr<MediaManager> mManager;
 };
 
 // Handle removing GetUserMediaCallbackMediaStreamListener from main thread
 class GetUserMediaListenerRemove: public nsRunnable
 {
 public:
@@ -366,24 +366,16 @@ protected:
   nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
 };
 
 /**
  * nsIMediaDevice implementation.
  */
 NS_IMPL_ISUPPORTS(MediaDevice, nsIMediaDevice)
 
-MediaDevice* MediaDevice::Create(MediaEngineVideoSource* source) {
-  return new VideoDevice(source);
-}
-
-MediaDevice* MediaDevice::Create(MediaEngineAudioSource* source) {
-  return new AudioDevice(source);
-}
-
 MediaDevice::MediaDevice(MediaEngineSource* aSource)
   : mHasFacingMode(false)
   , mSource(aSource) {
   mSource->GetName(mName);
   mSource->GetUUID(mID);
 }
 
 VideoDevice::VideoDevice(MediaEngineVideoSource* aSource)
@@ -416,19 +408,54 @@ VideoDevice::VideoDevice(MediaEngineVide
   if (mName.Find(NS_LITERAL_STRING("Face")) != -1) {
     mHasFacingMode = true;
     mFacingMode = dom::VideoFacingModeEnum::User;
   }
 #endif
   mMediaSource = aSource->GetMediaSource();
 }
 
+/**
+ * Helper functions that implement the constraints algorithm from
+ * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5
+ */
+
+// Reminder: add handling for new constraints both here and in GetSources below!
+
+bool
+VideoDevice::SatisfyConstraintSet(const MediaTrackConstraintSet &aConstraints)
+{
+  if (aConstraints.mFacingMode.WasPassed()) {
+    nsString s;
+    GetFacingMode(s);
+    if (!s.EqualsASCII(dom::VideoFacingModeEnumValues::strings[
+        uint32_t(aConstraints.mFacingMode.Value())].value)) {
+      return false;
+    }
+  }
+  nsString s;
+  GetMediaSource(s);
+  if (!s.EqualsASCII(dom::MediaSourceEnumValues::strings[
+      uint32_t(aConstraints.mMediaSource)].value)) {
+    return false;
+  }
+  // TODO: Add more video-specific constraints
+  return true;
+}
+
 AudioDevice::AudioDevice(MediaEngineAudioSource* aSource)
   : MediaDevice(aSource) {}
 
+bool
+AudioDevice::SatisfyConstraintSet(const MediaTrackConstraintSet &aConstraints)
+{
+  // TODO: Add audio-specific constraints
+  return true;
+}
+
 NS_IMETHODIMP
 MediaDevice::GetName(nsAString& aName)
 {
   aName.Assign(mName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -479,26 +506,26 @@ MediaDevice::GetMediaSource(nsAString& a
     aMediaSource.Assign(NS_LITERAL_STRING("window"));
   } else { // all the rest are shared
     aMediaSource.Assign(NS_ConvertUTF8toUTF16(
       dom::MediaSourceEnumValues::strings[uint32_t(mMediaSource)].value));
   }
   return NS_OK;
 }
 
-MediaEngineVideoSource*
+VideoDevice::Source*
 VideoDevice::GetSource()
 {
-  return static_cast<MediaEngineVideoSource*>(&*mSource);
+  return static_cast<Source*>(&*mSource);
 }
 
-MediaEngineAudioSource*
+AudioDevice::Source*
 AudioDevice::GetSource()
 {
-  return static_cast<MediaEngineAudioSource*>(&*mSource);
+  return static_cast<Source*>(&*mSource);
 }
 
 /**
  * A subclass that we only use to stash internal pointers to MediaStreamGraph objects
  * that need to be cleaned up.
  */
 class nsDOMUserMediaStream : public DOMLocalMediaStream
 {
@@ -881,110 +908,73 @@ IsOn(const OwningBooleanOrMediaTrackCons
 
 static const MediaTrackConstraints&
 GetInvariant(const OwningBooleanOrMediaTrackConstraints &aUnion) {
   static const MediaTrackConstraints empty;
   return aUnion.IsMediaTrackConstraints() ?
       aUnion.GetAsMediaTrackConstraints() : empty;
 }
 
-/**
- * Helper functions that implement the constraints algorithm from
- * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5
- */
-
-// Reminder: add handling for new constraints both here and in GetSources below!
-
-static bool SatisfyConstraintSet(const MediaEngineVideoSource *,
-                                 const MediaTrackConstraintSet &aConstraints,
-                                 nsIMediaDevice &aCandidate)
-{
-  nsString s;
-  if (aConstraints.mFacingMode.WasPassed()) {
-    aCandidate.GetFacingMode(s);
-    if (!s.EqualsASCII(dom::VideoFacingModeEnumValues::strings[
-        uint32_t(aConstraints.mFacingMode.Value())].value)) {
-      return false;
-    }
-  }
-  aCandidate.GetMediaSource(s);
-  if (!s.EqualsASCII(dom::MediaSourceEnumValues::strings[
-      uint32_t(aConstraints.mMediaSource)].value)) {
-    return false;
-  }
-  // TODO: Add more video-specific constraints
-  return true;
-}
-
-static bool SatisfyConstraintSet(const MediaEngineAudioSource *,
-                                 const MediaTrackConstraintSet &aConstraints,
-                                 nsIMediaDevice &aCandidate)
-{
-  // TODO: Add audio-specific constraints
-  return true;
-}
-
-typedef nsTArray<nsCOMPtr<nsIMediaDevice> > SourceSet;
-
 // Source getter that constrains list returned
 
-template<class SourceType, class ConstraintsType>
-static SourceSet *
+template<class DeviceType, class ConstraintsType>
+static void
   GetSources(MediaEngine *engine,
              ConstraintsType &aConstraints,
-             void (MediaEngine::* aEnumerate)(MediaSourceType, nsTArray<nsRefPtr<SourceType> >*),
+             void (MediaEngine::* aEnumerate)(MediaSourceType,
+                 nsTArray<nsRefPtr<typename DeviceType::Source> >*),
+             nsTArray<nsRefPtr<DeviceType>>& aResult,
              const char* media_device_name = nullptr)
 {
-  ScopedDeletePtr<SourceSet> result(new SourceSet);
+  typedef nsTArray<nsRefPtr<DeviceType>> SourceSet;
 
-  const SourceType * const type = nullptr;
   nsString deviceName;
   // First collect sources
   SourceSet candidateSet;
   {
-    nsTArray<nsRefPtr<SourceType> > sources;
+    nsTArray<nsRefPtr<typename DeviceType::Source> > sources;
     // all MediaSourceEnums are contained in MediaSourceType
     (engine->*aEnumerate)((MediaSourceType)((int)aConstraints.mMediaSource), &sources);
     /**
       * We're allowing multiple tabs to access the same camera for parity
       * with Chrome.  See bug 811757 for some of the issues surrounding
       * this decision.  To disallow, we'd filter by IsAvailable() as we used
       * to.
       */
     for (uint32_t len = sources.Length(), i = 0; i < len; i++) {
       sources[i]->GetName(deviceName);
       if (media_device_name && strlen(media_device_name) > 0)  {
         if (deviceName.EqualsASCII(media_device_name)) {
-          candidateSet.AppendElement(MediaDevice::Create(sources[i]));
+          candidateSet.AppendElement(new DeviceType(sources[i]));
           break;
         }
       } else {
-        candidateSet.AppendElement(MediaDevice::Create(sources[i]));
+        candidateSet.AppendElement(new DeviceType(sources[i]));
       }
     }
   }
 
   // Apply constraints to the list of sources.
 
   auto& c = aConstraints;
   if (c.mUnsupportedRequirement) {
     // Check upfront the names of required constraints that are unsupported for
     // this media-type. The spec requires these to fail, so getting them out of
     // the way early provides a necessary invariant for the remaining algorithm
     // which maximizes code-reuse by ignoring constraints of the other type
     // (specifically, SatisfyConstraintSet is reused for the advanced algorithm
     // where the spec requires it to ignore constraints of the other type)
-    return result.forget();
+    return;
   }
 
   // Now on to the actual algorithm: First apply required constraints.
 
   for (uint32_t i = 0; i < candidateSet.Length();) {
     // Overloading instead of template specialization keeps things local
-    if (!SatisfyConstraintSet(type, c.mRequired, *candidateSet[i])) {
+    if (!candidateSet[i]->SatisfyConstraintSet(c.mRequired)) {
       candidateSet.RemoveElementAt(i);
     } else {
       ++i;
     }
   }
 
   // TODO(jib): Proper non-ordered handling of nonrequired constraints (907352)
   //
@@ -1015,32 +1005,31 @@ static SourceSet *
   SourceSet tailSet;
 
   if (c.mAdvanced.WasPassed()) {
     auto &array = c.mAdvanced.Value();
 
     for (int i = 0; i < int(array.Length()); i++) {
       SourceSet rejects;
       for (uint32_t j = 0; j < candidateSet.Length();) {
-        if (!SatisfyConstraintSet(type, array[i], *candidateSet[j])) {
+        if (!candidateSet[j]->SatisfyConstraintSet(array[i])) {
           rejects.AppendElement(candidateSet[j]);
           candidateSet.RemoveElementAt(j);
         } else {
           ++j;
         }
       }
       (candidateSet.Length()? tailSet : candidateSet).MoveElementsFrom(rejects);
     }
   }
 
   // TODO: Proper non-ordered handling of nonrequired constraints (Bug 907352)
 
-  result->MoveElementsFrom(candidateSet);
-  result->MoveElementsFrom(tailSet);
-  return result.forget();
+  aResult.MoveElementsFrom(candidateSet);
+  aResult.MoveElementsFrom(tailSet);
 }
 
 /**
  * Runs on a seperate thread and is responsible for enumerating devices.
  * Depending on whether a picture or stream was asked for, either
  * ProcessGetUserMedia is called, and the results are sent back to the DOM.
  *
  * Do not run this on the main thread. The success and error callbacks *MUST*
@@ -1188,39 +1177,38 @@ public:
 
   nsresult
   SelectDevice(MediaEngine* backend)
   {
     MOZ_ASSERT(mSuccess);
     MOZ_ASSERT(mError);
     if (IsOn(mConstraints.mVideo)) {
       VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo));
-      ScopedDeletePtr<SourceSet> sources(GetSources(backend, constraints,
-                               &MediaEngine::EnumerateVideoDevices));
+      nsTArray<nsRefPtr<VideoDevice>> sources;
+      GetSources(backend, constraints, &MediaEngine::EnumerateVideoDevices, sources);
 
-      if (!sources->Length()) {
+      if (!sources.Length()) {
         Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND"));
         return NS_ERROR_FAILURE;
       }
       // Pick the first available device.
-      mVideoDevice = do_QueryObject((*sources)[0]);
+      mVideoDevice = sources[0];
       LOG(("Selected video device"));
     }
-
     if (IsOn(mConstraints.mAudio)) {
       AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio));
-      ScopedDeletePtr<SourceSet> sources (GetSources(backend, constraints,
-          &MediaEngine::EnumerateAudioDevices));
+      nsTArray<nsRefPtr<AudioDevice>> sources;
+      GetSources(backend, constraints, &MediaEngine::EnumerateAudioDevices, sources);
 
-      if (!sources->Length()) {
+      if (!sources.Length()) {
         Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND"));
         return NS_ERROR_FAILURE;
       }
       // Pick the first available device.
-      mAudioDevice = do_QueryObject((*sources)[0]);
+      mAudioDevice = sources[0];
       LOG(("Selected audio device"));
     }
 
     return NS_OK;
   }
 
   /**
    * Allocates a video or audio device and returns a MediaStream via
@@ -1336,30 +1324,36 @@ public:
     NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
     nsRefPtr<MediaEngine> backend;
     if (mConstraints.mFake)
       backend = new MediaEngineDefault();
     else
       backend = mManager->GetBackend(mWindowId);
 
+    typedef nsTArray<nsRefPtr<MediaDevice>> SourceSet;
+
     ScopedDeletePtr<SourceSet> final(new SourceSet);
     if (IsOn(mConstraints.mVideo)) {
       VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo));
-      ScopedDeletePtr<SourceSet> s(GetSources(backend, constraints,
-              &MediaEngine::EnumerateVideoDevices,
-              mLoopbackVideoDevice.get()));
-      final->MoveElementsFrom(*s);
+      nsTArray<nsRefPtr<VideoDevice>> s;
+      GetSources(backend, constraints, &MediaEngine::EnumerateVideoDevices, s,
+                 mLoopbackVideoDevice.get());
+      for (uint32_t i = 0; i < s.Length(); i++) {
+        final->AppendElement(s[i]);
+      }
     }
     if (IsOn(mConstraints.mAudio)) {
       AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio));
-      ScopedDeletePtr<SourceSet> s (GetSources(backend, constraints,
-          &MediaEngine::EnumerateAudioDevices,
-          mLoopbackAudioDevice.get()));
-      final->MoveElementsFrom(*s);
+      nsTArray<nsRefPtr<AudioDevice>> s;
+      GetSources(backend, constraints, &MediaEngine::EnumerateAudioDevices, s,
+                 mLoopbackAudioDevice.get());
+      for (uint32_t i = 0; i < s.Length(); i++) {
+        final->AppendElement(s[i]);
+      }
     }
 
     NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(mWindowId,
                                                               mSuccess, mError,
                                                               final.forget()));
     // DeviceSuccessCallbackRunnable should have taken these.
     MOZ_ASSERT(!mSuccess && !mError);
   }
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -41,16 +41,17 @@
 #include "DOMCameraManager.h"
 #endif
 
 namespace mozilla {
 namespace dom {
 struct MediaStreamConstraints;
 class NavigatorUserMediaSuccessCallback;
 class NavigatorUserMediaErrorCallback;
+struct MediaTrackConstraintSet;
 }
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* GetMediaManagerLog();
 #define MM_LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
 #else
 #define MM_LOG(msg)
 #endif
@@ -496,44 +497,47 @@ typedef nsTArray<nsRefPtr<GetUserMediaCa
 typedef nsClassHashtable<nsUint64HashKey, StreamListeners> WindowTable;
 
 class MediaDevice : public nsIMediaDevice
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIMEDIADEVICE
 
-  static MediaDevice* Create(MediaEngineVideoSource* source);
-  static MediaDevice* Create(MediaEngineAudioSource* source);
-
 protected:
   virtual ~MediaDevice() {}
   explicit MediaDevice(MediaEngineSource* aSource);
   nsString mName;
   nsString mID;
   bool mHasFacingMode;
   dom::VideoFacingModeEnum mFacingMode;
   MediaSourceType mMediaSource;
   nsRefPtr<MediaEngineSource> mSource;
 };
 
 class VideoDevice : public MediaDevice
 {
 public:
-  explicit VideoDevice(MediaEngineVideoSource* aSource);
+  typedef MediaEngineVideoSource Source;
+
+  explicit VideoDevice(Source* aSource);
   NS_IMETHOD GetType(nsAString& aType);
-  MediaEngineVideoSource* GetSource();
+  Source* GetSource();
+  bool SatisfyConstraintSet(const dom::MediaTrackConstraintSet &aConstraints);
 };
 
 class AudioDevice : public MediaDevice
 {
 public:
-  explicit AudioDevice(MediaEngineAudioSource* aSource);
+  typedef MediaEngineAudioSource Source;
+
+  explicit AudioDevice(Source* aSource);
   NS_IMETHOD GetType(nsAString& aType);
-  MediaEngineAudioSource* GetSource();
+  Source* GetSource();
+  bool SatisfyConstraintSet(const dom::MediaTrackConstraintSet &aConstraints);
 };
 
 // we could add MediaManager if needed
 typedef void (*WindowListenerCallback)(MediaManager *aThis,
                                        uint64_t aWindowID,
                                        StreamListeners *aListeners,
                                        void *aData);