Bug 1213517 - Wire up getSettings(). draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Mon, 20 Jun 2016 00:38:25 -0400
changeset 388781 c85859b71a965bfdca8cf0f1de6853a8ba3ce03d
parent 388780 4634d50dff3a843d148ae6e5e17b60c1b45bde94
child 388782 e184aff156d1ed338e0b0a9eedb336f732fb0bd0
push id23232
push userjbruaroey@mozilla.com
push dateSun, 17 Jul 2016 21:00:46 +0000
bugs1213517
milestone50.0a1
Bug 1213517 - Wire up getSettings(). MozReview-Commit-ID: EX5FIo3rCoi
dom/media/MediaManager.cpp
dom/media/MediaStreamTrack.cpp
dom/media/MediaStreamTrack.h
dom/media/webrtc/MediaEngine.h
dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
dom/media/webrtc/MediaEngineRemoteVideoSource.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -351,16 +351,23 @@ public:
   bool CapturingBrowser()
   {
     MOZ_ASSERT(NS_IsMainThread());
     return mVideoDevice && !mStopped &&
            mVideoDevice->GetSource()->IsAvailable() &&
            mVideoDevice->GetMediaSource() == dom::MediaSourceEnum::Browser;
   }
 
+  void GetSettings(dom::MediaTrackSettings& aOutSettings)
+  {
+    if (mVideoDevice) {
+      mVideoDevice->GetSource()->GetSettings(aOutSettings);
+    }
+  }
+
   // implement in .cpp to avoid circular dependency with MediaOperationTask
   // Can be invoked from EITHER MainThread or MSG thread
   void Stop();
 
   void
   AudioConfig(bool aEchoOn, uint32_t aEcho,
               bool aAgcOn, uint32_t aAGC,
               bool aNoiseOn, uint32_t aNoise,
@@ -1130,16 +1137,21 @@ public:
             p->Reject(new MediaStreamError(aWindow,
                                            NS_LITERAL_STRING("AbortError"),
                                            NS_LITERAL_STRING("In shutdown")));
             return p.forget();
           }
           return mListener->ApplyConstraintsToTrack(aWindow, mTrackID, aConstraints);
         }
 
+        void
+        GetSettings(dom::MediaTrackSettings& aOutSettings) override
+        {
+          mListener->GetSettings(aOutSettings);
+        }
 
         void Stop() override
         {
           if (mListener) {
             mListener->StopTrack(mTrackID);
             mListener = nullptr;
           }
         }
--- a/dom/media/MediaStreamTrack.cpp
+++ b/dom/media/MediaStreamTrack.cpp
@@ -245,24 +245,26 @@ MediaStreamTrack::Stop()
   DOMMediaStream::TrackPort* port = mOwningStream->FindOwnedTrackPort(*this);
   MOZ_ASSERT(port, "A MediaStreamTrack must exist in its owning DOMMediaStream");
   RefPtr<Pledge<bool>> p = port->BlockSourceTrackId(mInputTrackID, BlockingMode::CREATION);
   Unused << p;
 
   mReadyState = MediaStreamTrackState::Ended;
 }
 
-void MediaStreamTrack::GetConstraints(dom::MediaTrackConstraints& aResult)
+void
+MediaStreamTrack::GetConstraints(dom::MediaTrackConstraints& aResult)
 {
   aResult = mConstraints;
 }
 
-void MediaStreamTrack::GetSettings(dom::MediaTrackSettings& aResult)
+void
+MediaStreamTrack::GetSettings(dom::MediaTrackSettings& aResult)
 {
-  aResult = mSettings;
+  GetSource().GetSettings(aResult);
 }
 
 already_AddRefed<Promise>
 MediaStreamTrack::ApplyConstraints(const MediaTrackConstraints& aConstraints,
                                    ErrorResult &aRv)
 {
   if (MOZ_LOG_TEST(gMediaStreamTrackLog, LogLevel::Info)) {
     nsString str;
--- a/dom/media/MediaStreamTrack.h
+++ b/dom/media/MediaStreamTrack.h
@@ -130,16 +130,22 @@ public:
    * We provide a fallback solution to ApplyConstraints() here.
    * Sources that support ApplyConstraints() will have to override it.
    */
   virtual already_AddRefed<PledgeVoid>
   ApplyConstraints(nsPIDOMWindowInner* aWindow,
                    const dom::MediaTrackConstraints& aConstraints);
 
   /**
+   * Same for GetSettings (no-op).
+   */
+  virtual void
+  GetSettings(dom::MediaTrackSettings& aResult) {};
+
+  /**
    * Called by the source interface when all registered sinks have unregistered.
    */
   virtual void Stop() = 0;
 
   /**
    * Called by each MediaStreamTrack clone on initialization.
    */
   void RegisterSink(Sink* aSink)
@@ -208,16 +214,19 @@ public:
                                        const MediaSourceEnum aMediaSource =
                                          MediaSourceEnum::Other)
     : MediaStreamTrackSource(aPrincipal, true, nsString())
     , mMediaSource(aMediaSource)
   {}
 
   MediaSourceEnum GetMediaSource() const override { return mMediaSource; }
 
+  void
+  GetSettings(dom::MediaTrackSettings& aResult) override {}
+
   void Stop() override {}
 
 protected:
   ~BasicUnstoppableTrackSource() {}
 
   const MediaSourceEnum mMediaSource;
 };
 
@@ -431,15 +440,14 @@ protected:
   // so we can remove them in |Destory|.
   nsTArray<RefPtr<MediaStreamTrackListener>> mTrackListeners;
   nsTArray<RefPtr<DirectMediaStreamTrackListener>> mDirectTrackListeners;
   nsString mID;
   MediaStreamTrackState mReadyState;
   bool mEnabled;
   const bool mRemote;
   dom::MediaTrackConstraints mConstraints;
-  dom::MediaTrackSettings mSettings;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* MEDIASTREAMTRACK_H_ */
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -192,16 +192,22 @@ public:
                             const nsACString& aOrigin,
                             BaseAllocationHandle** aOutHandle,
                             const char** aOutBadConstraint) = 0;
 
   virtual uint32_t GetBestFitnessDistance(
       const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) const = 0;
 
+  void GetSettings(dom::MediaTrackSettings& aOutSettings)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    aOutSettings = mSettings;
+  }
+
 protected:
   // Only class' own members can be initialized in constructor initializer list.
   explicit MediaEngineSource(MediaEngineState aState)
     : mState(aState)
 #ifdef DEBUG
     , mOwningThread(PR_GetCurrentThread())
 #endif
     , mHasFakeTracks(false)
@@ -212,16 +218,18 @@ protected:
     MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread);
   }
 
   MediaEngineState mState;
 #ifdef DEBUG
   PRThread* mOwningThread;
 #endif
   bool mHasFakeTracks;
+  // Main-thread only:
+  dom::MediaTrackSettings mSettings;
 };
 
 /**
  * Video source and friends.
  */
 class MediaEnginePrefs {
 public:
   MediaEnginePrefs()
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -31,16 +31,19 @@ MediaEngineRemoteVideoSource::MediaEngin
   int aIndex, mozilla::camera::CaptureEngine aCapEngine,
   dom::MediaSourceEnum aMediaSource, const char* aMonitorName)
   : MediaEngineCameraVideoSource(aIndex, aMonitorName),
     mMediaSource(aMediaSource),
     mCapEngine(aCapEngine),
     mInShutdown(false)
 {
   MOZ_ASSERT(aMediaSource != dom::MediaSourceEnum::Other);
+  mSettings.mWidth.Construct(0);
+  mSettings.mHeight.Construct(0);
+  mSettings.mFrameRate.Construct(0);
   Init();
 }
 
 void
 MediaEngineRemoteVideoSource::Init()
 {
   LOG((__PRETTY_FUNCTION__));
   char deviceName[kMaxDeviceNameLength];
@@ -322,47 +325,64 @@ MediaEngineRemoteVideoSource::UpdateExis
       MOZ_ASSERT(!mRegisteredHandles.Length());
       if (camera::GetChildAndCall(&camera::CamerasChild::AllocateCaptureDevice,
                                   mCapEngine, GetUUID().get(),
                                   kMaxUniqueIdLength, mCaptureIndex,
                                   aHandle->mOrigin)) {
         return NS_ERROR_FAILURE;
       }
       mState = kAllocated;
-      mLastCapability = mCapability;
+      SetLastCapability(mCapability);
       LOG(("Video device %d allocated for %s", mCaptureIndex,
            aHandle->mOrigin.get()));
       break;
 
     case kStarted:
       if (mCapability != mLastCapability) {
         camera::GetChildAndCall(&camera::CamerasChild::StopCapture,
                                 mCapEngine, mCaptureIndex);
         if (camera::GetChildAndCall(&camera::CamerasChild::StartCapture,
                                     mCapEngine, mCaptureIndex, mCapability,
                                     this)) {
           LOG(("StartCapture failed"));
           return NS_ERROR_FAILURE;
         }
-        mLastCapability = mCapability;
+        SetLastCapability(mCapability);
       }
       break;
 
     default:
       LOG(("Video device %d %s in ignored state %d", mCaptureIndex,
              (aHandle? aHandle->mOrigin.get() : ""), mState));
       break;
   }
   if (aHandle && aNewConstraints) {
     aHandle->mConstraints = *aNewConstraints;
   }
   return NS_OK;
 }
 
 void
+MediaEngineRemoteVideoSource::SetLastCapability(
+    const webrtc::CaptureCapability& aCapability)
+{
+  mLastCapability = mCapability;
+
+  webrtc::CaptureCapability cap = aCapability;
+  RefPtr<MediaEngineRemoteVideoSource> that = this;
+
+  NS_DispatchToMainThread(media::NewRunnableFrom([this, that, cap]() mutable {
+    mSettings.mWidth.Value() = cap.width;
+    mSettings.mHeight.Value() = cap.height;
+    mSettings.mFrameRate.Value() = cap.maxFPS;
+    return NS_OK;
+  }));
+}
+
+void
 MediaEngineRemoteVideoSource::NotifyPull(MediaStreamGraph* aGraph,
                                          SourceMediaStream* aSource,
                                          TrackID aID, StreamTime aDesiredTime,
                                          const PrincipalHandle& aPrincipalHandle)
 {
   VideoSegment segment;
 
   MonitorAutoLock lock(mMonitor);
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -125,16 +125,17 @@ public:
 protected:
   ~MediaEngineRemoteVideoSource() { Shutdown(); }
 
 private:
   // Initialize the needed Video engine interfaces.
   void Init();
   size_t NumCapabilities() const override;
   void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut) const override;
+  void SetLastCapability(const webrtc::CaptureCapability& aCapability);
 
   /* UpdateExisting - Centralized function to apply constraints and restart
    * device as needed, considering all allocations and changes to one.
    *
    * aHandle           - New or existing handle, or null to update after removal.
    * aNewConstraints   - Constraints to be applied to existing handle, or null.
    * aPrefs            - As passed in (in case of changes in about:config).
    * aDeviceId         - As passed in (origin dependent).