commit ffa9e3b01a63d6cf936f87de1c5000aae0a07aa5
parent c5cf2acb3a092bc98fd4a2a708724b5f72f12d77
Author: Andreas Pehrson <apehrson@mozilla.com>
Date: Mon, 17 Nov 2025 23:27:22 +0000
Bug 1999640 - In CamerasParent handle failure to create capturer. r=jib
Differential Revision: https://phabricator.services.mozilla.com/D272241
Diffstat:
2 files changed, 39 insertions(+), 26 deletions(-)
diff --git a/dom/media/systemservices/CamerasParent.cpp b/dom/media/systemservices/CamerasParent.cpp
@@ -396,6 +396,9 @@ std::unique_ptr<AggregateCapturer> AggregateCapturer::Create(
CamerasParent* aParent) {
MOZ_ASSERT(aVideoCaptureThread->IsOnCurrentThread());
int captureId = aEngine->CreateVideoCapture(aUniqueId.get(), aWindowId);
+ if (captureId < 0) {
+ return nullptr;
+ }
auto capturer = WrapUnique(
new AggregateCapturer(aVideoCaptureThread, aCapEng, aEngine, aUniqueId,
captureId, std::move(aCapabilities)));
@@ -1087,8 +1090,7 @@ ipc::IPCResult CamerasParent::RecvAllocateCapture(
LOG("CamerasParent(%p)::%s: Verifying permissions", this, __func__);
using Promise1 = MozPromise<bool, bool, true>;
- using Data = std::tuple<int, int>;
- using Promise2 = MozPromise<Data, bool, true>;
+ using Promise2 = MozPromise<Maybe<int>, bool, true>;
InvokeAsync(
GetMainThreadSerialEventTarget(), __func__,
[aWindowID] {
@@ -1116,8 +1118,7 @@ ipc::IPCResult CamerasParent::RecvAllocateCapture(
VideoEngine* engine = EnsureInitialized(aCapEngine);
if (!engine) {
return Promise2::CreateAndResolve(
- std::make_tuple(-1, -1),
- "CamerasParent::RecvAllocateCapture no engine");
+ Nothing(), "CamerasParent::RecvAllocateCapture no engine");
}
bool allowed = aValue.ResolveValue();
if (!allowed && IsWindowCapturing(aWindowID, unique_id)) {
@@ -1126,8 +1127,7 @@ ipc::IPCResult CamerasParent::RecvAllocateCapture(
}
if (!allowed) {
return Promise2::CreateAndResolve(
- std::make_tuple(-1, -1),
- "CamerasParent::RecvAllocateCapture");
+ Nothing(), "CamerasParent::RecvAllocateCapture");
}
nsTArray<webrtc::VideoCaptureCapability> capabilities;
@@ -1138,34 +1138,27 @@ ipc::IPCResult CamerasParent::RecvAllocateCapture(
auto created = GetOrCreateCapturer(aCapEngine, aWindowID, unique_id,
std::move(capabilities));
- int error = -1;
- engine->WithEntry(created.mCapturer->mCaptureId,
- [&](VideoEngine::CaptureEntry& cap) {
- if (cap.VideoCapture()) {
- error = 0;
- }
- });
return Promise2::CreateAndResolve(
- std::make_tuple(created.mStreamId, error),
+ created.mCapturer ? Some(created.mStreamId) : Nothing(),
"CamerasParent::RecvAllocateCapture");
})
->Then(
mPBackgroundEventTarget, __func__,
[this, self = RefPtr(this)](Promise2::ResolveOrRejectValue&& aValue) {
- const auto [captureId, error] = aValue.ResolveValue();
+ const Maybe<int> captureId = aValue.ResolveValue();
if (mDestroyed) {
LOG("RecvAllocateCapture: child not alive");
return;
}
- if (error != 0) {
+ if (!captureId) {
(void)SendReplyFailure();
- LOG("RecvAllocateCapture: WithEntry error");
+ LOG("RecvAllocateCapture: failed to create capturer");
return;
}
- LOG("Allocated device nr %d", captureId);
- (void)SendReplyAllocateCapture(captureId);
+ LOG("Allocated device nr %d", *captureId);
+ (void)SendReplyAllocateCapture(*captureId);
});
return IPC_OK();
}
@@ -1353,9 +1346,13 @@ auto CamerasParent::GetOrCreateCapturer(
return {.mCapturer = capturer.get(), .mStreamId = streamId};
}
}
- NotNull capturer = mCapturers->AppendElement(
+ std::unique_ptr aggregate =
AggregateCapturer::Create(mVideoCaptureThread, aEngine, engine, aUniqueId,
- aWindowId, std::move(aCapabilities), this));
+ aWindowId, std::move(aCapabilities), this);
+ if (!aggregate) {
+ return {};
+ }
+ NotNull capturer = mCapturers->AppendElement(std::move(aggregate));
ensureShmemPool(capturer->get()->mCaptureId);
return {.mCapturer = capturer->get(),
.mStreamId = capturer->get()->mCaptureId};
diff --git a/dom/media/systemservices/VideoEngine.cpp b/dom/media/systemservices/VideoEngine.cpp
@@ -51,28 +51,44 @@ int32_t VideoEngine::CreateVideoCapture(const char* aDeviceUniqueIdUTF8,
LOG(("%s", __PRETTY_FUNCTION__));
MOZ_ASSERT(aDeviceUniqueIdUTF8);
- int32_t id = GenerateId();
- LOG(("CaptureDeviceType=%s id=%d", EnumValueToString(mCaptureDevType), id));
-
for (auto& it : mSharedCapturers) {
if (it.second.VideoCapture() &&
it.second.VideoCapture()->CurrentDeviceName() &&
strcmp(it.second.VideoCapture()->CurrentDeviceName(),
aDeviceUniqueIdUTF8) == 0) {
+ int32_t id = GenerateId();
+ LOG(("%sVideoEngine::%s(device=\"%s\", window=%" PRIu64
+ "): Reusing capturer with id %d. stream id=%d",
+ EnumValueToString(mCaptureDevType), __func__, aDeviceUniqueIdUTF8,
+ aWindowID, it.first, id));
mIdToCapturerMap.emplace(id, CaptureHandle{.mCaptureEntryNum = it.first,
.mWindowID = aWindowID});
return id;
}
}
- CaptureEntry entry = {-1, nullptr, nullptr};
+ int32_t id = GenerateId();
VideoCaptureFactory::CreateVideoCaptureResult capturer =
mVideoCaptureFactory->CreateVideoCapture(id, aDeviceUniqueIdUTF8,
mCaptureDevType);
- entry =
+
+ if (!capturer.mCapturer) {
+ LOG(("%sVideoEngine::%s(device=\"%s\", window=%" PRIu64
+ "): Creating video capturer for id %d failed.",
+ EnumValueToString(mCaptureDevType), __func__, aDeviceUniqueIdUTF8,
+ aWindowID, id));
+ return -1;
+ }
+
+ auto entry =
CaptureEntry(id, std::move(capturer.mCapturer), capturer.mDesktopImpl);
+ LOG(("%sVideoEngine::%s(device=\"%s\", window=%" PRIu64
+ "): Created new video capturer for id %d.",
+ EnumValueToString(mCaptureDevType), __func__, aDeviceUniqueIdUTF8,
+ aWindowID, id));
+
mSharedCapturers.emplace(id, std::move(entry));
mIdToCapturerMap.emplace(
id, CaptureHandle{.mCaptureEntryNum = id, .mWindowID = aWindowID});