Bug 1213517 - Only restart camera if net settings actually change.
MozReview-Commit-ID: h01gJ3uCom
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
@@ -382,17 +382,34 @@ MediaEngineCameraVideoSource::GetUUID(ns
}
const nsCString&
MediaEngineCameraVideoSource::GetUUID() const
{
return mUniqueId;
}
-
void
MediaEngineCameraVideoSource::SetDirectListeners(bool aHasDirectListeners)
{
LOG((__FUNCTION__));
mHasDirectListeners = aHasDirectListeners;
}
+bool operator == (const webrtc::CaptureCapability& a,
+ const webrtc::CaptureCapability& b)
+{
+ return a.width == b.width &&
+ a.height == b.height &&
+ a.maxFPS == b.maxFPS &&
+ a.rawType == b.rawType &&
+ a.codecType == b.codecType &&
+ a.expectedCaptureDelay == b.expectedCaptureDelay &&
+ a.interlaced == b.interlaced;
+};
+
+bool operator != (const webrtc::CaptureCapability& a,
+ const webrtc::CaptureCapability& b)
+{
+ return !(a == b);
+}
+
} // namespace mozilla
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.h
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.h
@@ -11,16 +11,21 @@
#include "nsDirectoryServiceDefs.h"
// conflicts with #include of scoped_ptr.h
#undef FF
#include "webrtc/video_engine/include/vie_capture.h"
namespace mozilla {
+bool operator == (const webrtc::CaptureCapability& a,
+ const webrtc::CaptureCapability& b);
+bool operator != (const webrtc::CaptureCapability& a,
+ const webrtc::CaptureCapability& b);
+
class MediaEngineCameraVideoSource : public MediaEngineVideoSource,
protected MediaConstraintsHelper
{
public:
explicit MediaEngineCameraVideoSource(int aIndex,
const char* aMonitorName = "Camera.Monitor")
: MediaEngineVideoSource(kReleased)
, mMonitor(aMonitorName)
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -290,53 +290,69 @@ MediaEngineRemoteVideoSource::Restart(Ba
const char** aOutBadConstraint)
{
AssertIsOnOwningThread();
if (!mInitDone) {
LOG(("Init not done"));
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(aHandle);
- auto handle = static_cast<AllocationHandle*>(aHandle);
- RefPtr<AllocationHandle> temp = new AllocationHandle(aConstraints);
- temp->mConstraints = NormalizedConstraints(aConstraints);
+ NormalizedConstraints constraints(aConstraints);
+ return UpdateExisting(static_cast<AllocationHandle*>(aHandle), &constraints,
+ aPrefs, aDeviceId, aOutBadConstraint);
+}
+
+nsresult
+MediaEngineRemoteVideoSource::UpdateExisting(AllocationHandle* aHandle,
+ NormalizedConstraints* aNewConstraints,
+ const MediaEnginePrefs& aPrefs,
+ const nsString& aDeviceId,
+ const char** aOutBadConstraint)
+{
+ // aHandle and/or aNewConstraints may be nullptr
AutoTArray<const NormalizedConstraints*, 10> allConstraints;
for (auto& registered : mRegisteredHandles) {
- if (registered.get() == handle) {
+ if (aNewConstraints && registered.get() == aHandle) {
continue; // Don't count old constraints
}
allConstraints.AppendElement(®istered->mConstraints);
}
- allConstraints.AppendElement(&temp->mConstraints);
+ if (aNewConstraints) {
+ allConstraints.AppendElement(aNewConstraints);
+ } else if (aHandle) {
+ // In the case of UpdateNew, the handle isn't registered yet.
+ allConstraints.AppendElement(&aHandle->mConstraints);
+ }
NormalizedConstraints netConstraints(allConstraints);
if (netConstraints.mBadConstraint) {
*aOutBadConstraint = netConstraints.mBadConstraint;
return NS_ERROR_FAILURE;
}
if (!ChooseCapability(netConstraints, aPrefs, aDeviceId)) {
*aOutBadConstraint = FindBadConstraint(netConstraints, *this, aDeviceId);
return NS_ERROR_FAILURE;
}
- if (mState != kStarted) {
- return NS_OK;
- }
+ MOZ_ASSERT(mState == kStarted || !aNewConstraints);
- mozilla::camera::GetChildAndCall(
- &mozilla::camera::CamerasChild::StopCapture,
- mCapEngine, mCaptureIndex);
- if (mozilla::camera::GetChildAndCall(
- &mozilla::camera::CamerasChild::StartCapture,
- mCapEngine, mCaptureIndex, mCapability, this)) {
- LOG(("StartCapture failed"));
- return NS_ERROR_FAILURE;
+ if (mState == kStarted && 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;
}
- handle->mConstraints = temp->mConstraints;
+ if (aHandle && aNewConstraints) {
+ aHandle->mConstraints = *aNewConstraints;
+ }
return NS_OK;
}
void
MediaEngineRemoteVideoSource::NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream* aSource,
TrackID aID, StreamTime aDesiredTime,
const PrincipalHandle& aPrincipalHandle)
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -117,17 +117,45 @@ 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;
+ /* 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).
+ * aOutBadConstraint - Result: nonzero if failed to apply. Name of culprit.
+ */
+
+ nsresult
+ UpdateExisting(AllocationHandle* aHandle,
+ NormalizedConstraints* aNewConstraints,
+ const MediaEnginePrefs& aPrefs,
+ const nsString& aDeviceId,
+ const char** aOutBadConstraint);
+
+ nsresult
+ UpdateNew(AllocationHandle* aHandle,
+ const MediaEnginePrefs& aPrefs,
+ const nsString& aDeviceId,
+ const char** aOutBadConstraint) {
+ return UpdateExisting(aHandle, nullptr, aPrefs, aDeviceId, aOutBadConstraint);
+ }
+
dom::MediaSourceEnum mMediaSource; // source of media (camera | application | screen)
mozilla::camera::CaptureEngine mCapEngine;
nsTArray<RefPtr<AllocationHandle>> mRegisteredHandles;
+
+ // To only restart camera when needed, we keep track previous settings.
+ webrtc::CaptureCapability mLastCapability;
};
}
#endif /* MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ */