From df57b21200c7cde7ac34705e8fceab2fbe933bc5 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Tue, 3 Sep 2024 07:56:39 +0000 Subject: [PATCH] Bug 1912778 - Always register video input feedback for newly created DeviceInfo r=pehrsons Make sure to always register video input feedback when a new DeviceInfo is created. We always destroy DeviceInfo once request to camera access is resolved, making it to be created again, but this time skipping the part where video input feedback is registered as we use already existing VideoEngine. There is now just one place where DeviceInfo gets created and the logic for video input feedback registration has been moved to VideoEngine as it's the only place where we know when new DeviceInfo is created. Differential Revision: https://phabricator.services.mozilla.com/D219060 --- dom/media/systemservices/CamerasParent.cpp | 164 ++++++++++----------- dom/media/systemservices/CamerasParent.h | 5 + dom/media/systemservices/VideoEngine.cpp | 7 +- dom/media/systemservices/VideoEngine.h | 2 +- 4 files changed, 91 insertions(+), 87 deletions(-) diff --git a/dom/media/systemservices/CamerasParent.cpp b/dom/media/systemservices/CamerasParent.cpp index 048d07b7fa..d6fe5986da 100644 --- a/dom/media/systemservices/CamerasParent.cpp +++ b/dom/media/systemservices/CamerasParent.cpp @@ -405,15 +405,25 @@ void CamerasParent::CloseEngines() { Unused << ReleaseCapture(capEngine, streamNum); } - if (VideoEngine* engine = mEngines->ElementAt(CameraEngine); engine) { - auto device_info = engine->GetOrCreateVideoCaptureDeviceInfo(); - MOZ_ASSERT(device_info); - if (device_info) { - device_info->DeRegisterVideoInputFeedBack(this); - } + auto device_info = GetDeviceInfo(CameraEngine); + MOZ_ASSERT(device_info); + if (device_info) { + device_info->DeRegisterVideoInputFeedBack(this); } } +std::shared_ptr +CamerasParent::GetDeviceInfo(int aEngine) { + MOZ_ASSERT(mVideoCaptureThread->IsOnCurrentThread()); + LOG_VERBOSE("CamerasParent(%p)::%s", this, __func__); + + auto* engine = EnsureInitialized(aEngine); + if (!engine) { + return nullptr; + } + return engine->GetOrCreateVideoCaptureDeviceInfo(this); +} + VideoEngine* CamerasParent::EnsureInitialized(int aEngine) { MOZ_ASSERT(mVideoCaptureThread->IsOnCurrentThread()); LOG_VERBOSE("CamerasParent(%p)::%s", this, __func__); @@ -449,14 +459,6 @@ VideoEngine* CamerasParent::EnsureInitialized(int aEngine) { return nullptr; } - if (capEngine == CameraEngine) { - auto device_info = engine->GetOrCreateVideoCaptureDeviceInfo(); - MOZ_ASSERT(device_info); - if (device_info) { - device_info->RegisterVideoInputFeedBack(this); - } - } - return mEngines->ElementAt(capEngine) = std::move(engine); } @@ -474,19 +476,16 @@ ipc::IPCResult CamerasParent::RecvNumberOfCaptureDevices( LOG("CaptureEngine=%d", aCapEngine); using Promise = MozPromise; - InvokeAsync( - mVideoCaptureThread, __func__, - [this, self = RefPtr(this), aCapEngine] { - int num = -1; - if (auto* engine = EnsureInitialized(aCapEngine)) { - if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) { - num = static_cast(devInfo->NumberOfDevices()); - } - } + InvokeAsync(mVideoCaptureThread, __func__, + [this, self = RefPtr(this), aCapEngine] { + int num = -1; + if (auto devInfo = GetDeviceInfo(aCapEngine)) { + num = static_cast(devInfo->NumberOfDevices()); + } - return Promise::CreateAndResolve( - num, "CamerasParent::RecvNumberOfCaptureDevices"); - }) + return Promise::CreateAndResolve( + num, "CamerasParent::RecvNumberOfCaptureDevices"); + }) ->Then( mPBackgroundEventTarget, __func__, [this, self = RefPtr(this)](Promise::ResolveOrRejectValue&& aValue) { @@ -558,10 +557,8 @@ ipc::IPCResult CamerasParent::RecvNumberOfCapabilities( mVideoCaptureThread, __func__, [this, self = RefPtr(this), id = nsCString(aUniqueId), aCapEngine]() { int num = -1; - if (auto* engine = EnsureInitialized(aCapEngine)) { - if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) { - num = devInfo->NumberOfCapabilities(id.get()); - } + if (auto devInfo = GetDeviceInfo(aCapEngine)) { + num = devInfo->NumberOfCapabilities(id.get()); } return Promise::CreateAndResolve( num, "CamerasParent::RecvNumberOfCapabilities"); @@ -599,36 +596,34 @@ ipc::IPCResult CamerasParent::RecvGetCaptureCapability( aIndex); using Promise = MozPromise; - InvokeAsync( - mVideoCaptureThread, __func__, - [this, self = RefPtr(this), id = nsCString(aUniqueId), aCapEngine, - aIndex] { - webrtc::VideoCaptureCapability webrtcCaps; - int error = -1; - if (auto* engine = EnsureInitialized(aCapEngine)) { - if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) { - error = devInfo->GetCapability(id.get(), aIndex, webrtcCaps); - } - } + InvokeAsync(mVideoCaptureThread, __func__, + [this, self = RefPtr(this), id = nsCString(aUniqueId), aCapEngine, + aIndex] { + webrtc::VideoCaptureCapability webrtcCaps; + int error = -1; + if (auto devInfo = GetDeviceInfo(aCapEngine)) { + error = devInfo->GetCapability(id.get(), aIndex, webrtcCaps); + } - if (!error && aCapEngine == CameraEngine) { - auto iter = mAllCandidateCapabilities.find(id); - if (iter == mAllCandidateCapabilities.end()) { - std::map - candidateCapabilities; - candidateCapabilities.emplace(aIndex, webrtcCaps); - mAllCandidateCapabilities.emplace(id, candidateCapabilities); - } else { - (iter->second).emplace(aIndex, webrtcCaps); - } - } - if (error) { - return Promise::CreateAndReject( - error, "CamerasParent::RecvGetCaptureCapability"); - } - return Promise::CreateAndResolve( - webrtcCaps, "CamerasParent::RecvGetCaptureCapability"); - }) + if (!error && aCapEngine == CameraEngine) { + auto iter = mAllCandidateCapabilities.find(id); + if (iter == mAllCandidateCapabilities.end()) { + std::map + candidateCapabilities; + candidateCapabilities.emplace(aIndex, webrtcCaps); + mAllCandidateCapabilities.emplace(id, + candidateCapabilities); + } else { + (iter->second).emplace(aIndex, webrtcCaps); + } + } + if (error) { + return Promise::CreateAndReject( + error, "CamerasParent::RecvGetCaptureCapability"); + } + return Promise::CreateAndResolve( + webrtcCaps, "CamerasParent::RecvGetCaptureCapability"); + }) ->Then( mPBackgroundEventTarget, __func__, [this, self = RefPtr(this)](Promise::ResolveOrRejectValue&& aValue) { @@ -664,33 +659,32 @@ ipc::IPCResult CamerasParent::RecvGetCaptureDevice( using Data = std::tuple; using Promise = MozPromise; - InvokeAsync( - mVideoCaptureThread, __func__, - [this, self = RefPtr(this), aCapEngine, aDeviceIndex] { - char deviceName[MediaEngineSource::kMaxDeviceNameLength]; - char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength]; - nsCString name; - nsCString uniqueId; - pid_t devicePid = 0; - bool placeholder = false; - int error = -1; - if (auto* engine = EnsureInitialized(aCapEngine)) { - if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) { - error = devInfo->GetDeviceName( - aDeviceIndex, deviceName, sizeof(deviceName), deviceUniqueId, - sizeof(deviceUniqueId), nullptr, 0, &devicePid, &placeholder); - } - } - if (error == 0) { - name.Assign(deviceName); - uniqueId.Assign(deviceUniqueId); - } + InvokeAsync(mVideoCaptureThread, __func__, + [this, self = RefPtr(this), aCapEngine, aDeviceIndex] { + char deviceName[MediaEngineSource::kMaxDeviceNameLength]; + char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength]; + nsCString name; + nsCString uniqueId; + pid_t devicePid = 0; + bool placeholder = false; + int error = -1; + if (auto devInfo = GetDeviceInfo(aCapEngine)) { + error = devInfo->GetDeviceName( + aDeviceIndex, deviceName, sizeof(deviceName), + deviceUniqueId, sizeof(deviceUniqueId), nullptr, 0, + &devicePid, &placeholder); + } - return Promise::CreateAndResolve( - std::make_tuple(std::move(name), std::move(uniqueId), devicePid, - placeholder, error), - "CamerasParent::RecvGetCaptureDevice"); - }) + if (error == 0) { + name.Assign(deviceName); + uniqueId.Assign(deviceUniqueId); + } + + return Promise::CreateAndResolve( + std::make_tuple(std::move(name), std::move(uniqueId), + devicePid, placeholder, error), + "CamerasParent::RecvGetCaptureDevice"); + }) ->Then( mPBackgroundEventTarget, __func__, [this, self = RefPtr(this)](Promise::ResolveOrRejectValue&& aValue) { diff --git a/dom/media/systemservices/CamerasParent.h b/dom/media/systemservices/CamerasParent.h index 9d6a6f2f35..11a5229629 100644 --- a/dom/media/systemservices/CamerasParent.h +++ b/dom/media/systemservices/CamerasParent.h @@ -144,6 +144,11 @@ class CamerasParent final : public PCamerasParent, // VideoInputFeedBack void OnDeviceChange() override; + // Creates a new DeviceInfo or returns an existing DeviceInfo for given + // capture engine. Returns a nullptr in case capture engine failed to be + // initialized. Video capture thread only. + std::shared_ptr GetDeviceInfo( + int aEngine); VideoEngine* EnsureInitialized(int aEngine); // Stops any ongoing capturing and releases resources. Called on diff --git a/dom/media/systemservices/VideoEngine.cpp b/dom/media/systemservices/VideoEngine.cpp index d03149e3ac..ec4657d755 100644 --- a/dom/media/systemservices/VideoEngine.cpp +++ b/dom/media/systemservices/VideoEngine.cpp @@ -112,7 +112,8 @@ int VideoEngine::ReleaseVideoCapture(const int32_t aId) { } std::shared_ptr -VideoEngine::GetOrCreateVideoCaptureDeviceInfo() { +VideoEngine::GetOrCreateVideoCaptureDeviceInfo( + webrtc::VideoInputFeedBack* callBack) { LOG(("%s", __PRETTY_FUNCTION__)); webrtc::Timestamp currentTime = webrtc::Timestamp::Micros(0); @@ -157,6 +158,10 @@ VideoEngine::GetOrCreateVideoCaptureDeviceInfo() { mDeviceInfo = mVideoCaptureFactory->CreateDeviceInfo(mId, mCaptureDevInfo.type); + if (mDeviceInfo && mCaptureDevInfo.type == CaptureDeviceType::Camera) { + mDeviceInfo->RegisterVideoInputFeedBack(callBack); + } + LOG(("EXIT %s", __PRETTY_FUNCTION__)); return mDeviceInfo; } diff --git a/dom/media/systemservices/VideoEngine.h b/dom/media/systemservices/VideoEngine.h index 588be92c27..289a1ab181 100644 --- a/dom/media/systemservices/VideoEngine.h +++ b/dom/media/systemservices/VideoEngine.h @@ -88,7 +88,7 @@ class VideoEngine { * @see bug 1305212 https://bugzilla.mozilla.org/show_bug.cgi?id=1305212 */ std::shared_ptr - GetOrCreateVideoCaptureDeviceInfo(); + GetOrCreateVideoCaptureDeviceInfo(webrtc::VideoInputFeedBack* callBack); /** * Destroys existing DeviceInfo.