Bug 1213517 - Consider competing constraints in getUserMedia+applyConstraints.
MozReview-Commit-ID: 9jzjNrJVUMX
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -108,45 +108,61 @@ MediaEngineRemoteVideoSource::Allocate(
LOG((__PRETTY_FUNCTION__));
AssertIsOnOwningThread();
if (!mInitDone) {
LOG(("Init not done"));
return NS_ERROR_FAILURE;
}
+ AutoTArray<const NormalizedConstraints*, 10> allConstraints;
+ for (auto& registered : mRegisteredHandles) {
+ allConstraints.AppendElement(®istered->mConstraints);
+ }
RefPtr<AllocationHandle> handle = new AllocationHandle(aConstraints);
- mRegisteredHandles.AppendElement(handle);
+ allConstraints.AppendElement(&handle->mConstraints);
+
+ NormalizedConstraints netConstraints(allConstraints);
+ if (netConstraints.mOverconstrained) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!ChooseCapability(netConstraints, aPrefs, aDeviceId)) {
+ return NS_ERROR_FAILURE;
+ }
if (mState == kReleased) {
- // Note: if shared, we don't allow a later opener to affect the resolution.
- // (This may change depending on spec changes for Constraints/settings)
-
- if (!ChooseCapability(handle->mConstraints, aPrefs, aDeviceId)) {
- return NS_ERROR_UNEXPECTED;
- }
-
if (mozilla::camera::GetChildAndCall(
&mozilla::camera::CamerasChild::AllocateCaptureDevice,
mCapEngine, GetUUID().get(), kMaxUniqueIdLength, mCaptureIndex, aOrigin)) {
return NS_ERROR_FAILURE;
}
mState = kAllocated;
LOG(("Video device %d allocated for %s", mCaptureIndex,
PromiseFlatCString(aOrigin).get()));
- } else if (MOZ_LOG_TEST(GetMediaManagerLog(), mozilla::LogLevel::Debug)) {
- MonitorAutoLock lock(mMonitor);
- if (mSources.IsEmpty()) {
- MOZ_ASSERT(mPrincipalHandles.IsEmpty());
- LOG(("Video device %d reallocated", mCaptureIndex));
- } else {
- LOG(("Video device %d allocated shared", mCaptureIndex));
+ } else {
+ camera::GetChildAndCall(&camera::CamerasChild::StopCapture, mCapEngine,
+ mCaptureIndex);
+ if (camera::GetChildAndCall(&camera::CamerasChild::StartCapture, mCapEngine,
+ mCaptureIndex, mCapability, this)) {
+ LOG(("StartCapture failed"));
+ return NS_ERROR_FAILURE;
+ }
+ if (MOZ_LOG_TEST(GetMediaManagerLog(), mozilla::LogLevel::Debug)) {
+ MonitorAutoLock lock(mMonitor);
+ if (mSources.IsEmpty()) {
+ MOZ_ASSERT(mPrincipalHandles.IsEmpty());
+ LOG(("Video device %d reallocated", mCaptureIndex));
+ } else {
+ LOG(("Video device %d allocated shared", mCaptureIndex));
+ }
}
}
+ mRegisteredHandles.AppendElement(handle);
++mNrAllocations;
handle.forget(aOutHandle);
return NS_OK;
}
nsresult
MediaEngineRemoteVideoSource::Deallocate(BaseAllocationHandle* aHandle)
{
@@ -271,33 +287,50 @@ MediaEngineRemoteVideoSource::Restart(Ba
{
AssertIsOnOwningThread();
if (!mInitDone) {
LOG(("Init not done"));
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(aHandle);
auto handle = static_cast<AllocationHandle*>(aHandle);
- handle->mConstraints = NormalizedConstraints(aConstraints);
- if (!ChooseCapability(handle->mConstraints, aPrefs, aDeviceId)) {
- return NS_ERROR_NOT_AVAILABLE;
+ RefPtr<AllocationHandle> temp = new AllocationHandle(aConstraints);
+ temp->mConstraints = NormalizedConstraints(aConstraints);
+
+ AutoTArray<const NormalizedConstraints*, 10> allConstraints;
+ for (auto& registered : mRegisteredHandles) {
+ if (registered.get() == handle) {
+ continue; // Don't count old constraints
+ }
+ allConstraints.AppendElement(®istered->mConstraints);
+ }
+ allConstraints.AppendElement(&temp->mConstraints);
+
+ NormalizedConstraints netConstraints(allConstraints);
+ if (netConstraints.mOverconstrained) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!ChooseCapability(netConstraints, aPrefs, aDeviceId)) {
+ return NS_ERROR_FAILURE;
}
if (mState != kStarted) {
return NS_OK;
}
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;
}
+ handle->mConstraints = temp->mConstraints;
return NS_OK;
}
void
MediaEngineRemoteVideoSource::NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream* aSource,
TrackID aID, StreamTime aDesiredTime,
const PrincipalHandle& aPrincipalHandle)