Enable PipeWire camera support for RHEL 10
Also backport upstream fixes for PipeWire camera support. Resolves: RHEL-64749
This commit is contained in:
parent
aa98dd5570
commit
85157a42c7
@ -0,0 +1,116 @@
|
||||
From 92643d686bed8f3e4f2c1aae194925b6dc9dea86 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Fri, 28 Jun 2024 18:13:15 +0000
|
||||
Subject: [PATCH] Bug 1905335 - WebRTC backport: PipeWire capture: hide cursor
|
||||
when it goes off screen or is not visible r=pehrsons,webrtc-reviewers
|
||||
|
||||
This is a simple backport of an WebRTC upstream change.
|
||||
|
||||
Upstream commit: e6ad337d633c145c48a5a4ae54968c14c16081c7
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D215197
|
||||
---
|
||||
.../wayland/mouse_cursor_monitor_pipewire.cc | 14 +++--
|
||||
.../linux/wayland/shared_screencast_stream.cc | 52 +++++++++++--------
|
||||
.../e6ad337d63.no-op-cherry-pick-msg | 1 +
|
||||
3 files changed, 39 insertions(+), 28 deletions(-)
|
||||
create mode 100644 third_party/libwebrtc/moz-patch-stack/e6ad337d63.no-op-cherry-pick-msg
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
|
||||
index 3d33b0fbb8e6e..00b07f341b16a 100644
|
||||
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
|
||||
@@ -40,6 +40,14 @@ void MouseCursorMonitorPipeWire::Capture() {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_DCHECK(callback_);
|
||||
|
||||
+ absl::optional<DesktopVector> mouse_cursor_position =
|
||||
+ options_.screencast_stream()->CaptureCursorPosition();
|
||||
+ // Invalid cursor or position
|
||||
+ if (!mouse_cursor_position) {
|
||||
+ callback_->OnMouseCursor(nullptr);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
std::unique_ptr<MouseCursor> mouse_cursor =
|
||||
options_.screencast_stream()->CaptureCursor();
|
||||
|
||||
@@ -48,11 +56,7 @@ void MouseCursorMonitorPipeWire::Capture() {
|
||||
}
|
||||
|
||||
if (mode_ == SHAPE_AND_POSITION) {
|
||||
- absl::optional<DesktopVector> mouse_cursor_position =
|
||||
- options_.screencast_stream()->CaptureCursorPosition();
|
||||
- if (mouse_cursor_position) {
|
||||
- callback_->OnMouseCursorPosition(mouse_cursor_position.value());
|
||||
- }
|
||||
+ callback_->OnMouseCursorPosition(mouse_cursor_position.value());
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
|
||||
index ab9054f1a1676..b8cac318ffeb9 100644
|
||||
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
|
||||
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
|
||||
@@ -690,32 +690,38 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
||||
const struct spa_meta_cursor* cursor =
|
||||
static_cast<struct spa_meta_cursor*>(spa_buffer_find_meta_data(
|
||||
spa_buffer, SPA_META_Cursor, sizeof(*cursor)));
|
||||
- if (cursor && spa_meta_cursor_is_valid(cursor)) {
|
||||
- struct spa_meta_bitmap* bitmap = nullptr;
|
||||
-
|
||||
- if (cursor->bitmap_offset)
|
||||
- bitmap =
|
||||
- SPA_MEMBER(cursor, cursor->bitmap_offset, struct spa_meta_bitmap);
|
||||
-
|
||||
- if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) {
|
||||
- const uint8_t* bitmap_data =
|
||||
- SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
|
||||
- BasicDesktopFrame* mouse_frame = new BasicDesktopFrame(
|
||||
- DesktopSize(bitmap->size.width, bitmap->size.height));
|
||||
- mouse_frame->CopyPixelsFrom(
|
||||
- bitmap_data, bitmap->stride,
|
||||
- DesktopRect::MakeWH(bitmap->size.width, bitmap->size.height));
|
||||
- mouse_cursor_ = std::make_unique<MouseCursor>(
|
||||
- mouse_frame, DesktopVector(cursor->hotspot.x, cursor->hotspot.y));
|
||||
|
||||
- if (observer_) {
|
||||
- observer_->OnCursorShapeChanged();
|
||||
+ if (cursor) {
|
||||
+ if (spa_meta_cursor_is_valid(cursor)) {
|
||||
+ struct spa_meta_bitmap* bitmap = nullptr;
|
||||
+
|
||||
+ if (cursor->bitmap_offset)
|
||||
+ bitmap =
|
||||
+ SPA_MEMBER(cursor, cursor->bitmap_offset, struct spa_meta_bitmap);
|
||||
+
|
||||
+ if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) {
|
||||
+ const uint8_t* bitmap_data =
|
||||
+ SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
|
||||
+ BasicDesktopFrame* mouse_frame = new BasicDesktopFrame(
|
||||
+ DesktopSize(bitmap->size.width, bitmap->size.height));
|
||||
+ mouse_frame->CopyPixelsFrom(
|
||||
+ bitmap_data, bitmap->stride,
|
||||
+ DesktopRect::MakeWH(bitmap->size.width, bitmap->size.height));
|
||||
+ mouse_cursor_ = std::make_unique<MouseCursor>(
|
||||
+ mouse_frame, DesktopVector(cursor->hotspot.x, cursor->hotspot.y));
|
||||
+
|
||||
+ if (observer_) {
|
||||
+ observer_->OnCursorShapeChanged();
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
- mouse_cursor_position_.set(cursor->position.x, cursor->position.y);
|
||||
+ mouse_cursor_position_.set(cursor->position.x, cursor->position.y);
|
||||
|
||||
- if (observer_) {
|
||||
- observer_->OnCursorPositionChanged();
|
||||
+ if (observer_) {
|
||||
+ observer_->OnCursorPositionChanged();
|
||||
+ }
|
||||
+ } else {
|
||||
+ // Indicate an invalid cursor
|
||||
+ mouse_cursor_position_.set(-1, -1);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
From fef1904f95dc592deef7044debe71a02c5d7046c Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Sat, 20 Jul 2024 07:04:27 +0000
|
||||
Subject: [PATCH] Bug 1907013 - WebRTC backport: PipeWire camera: support
|
||||
additional formats and fix RGB/BGR mapping r=jib,webrtc-reviewers
|
||||
|
||||
This is a simple backprot of an WebRTC upstream change.
|
||||
|
||||
Upstream commit: b1ebcfbfd6afb57f314b6689ca001aca1b13a5b4
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D216138
|
||||
---
|
||||
.../modules/video_capture/linux/pipewire_session.cc | 6 ++++++
|
||||
.../video_capture/linux/video_capture_pipewire.cc | 12 ++++++++++--
|
||||
.../moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg | 1 +
|
||||
3 files changed, 17 insertions(+), 2 deletions(-)
|
||||
create mode 100644 third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
index d52d6aacc8005..107ea3dfbd954 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
@@ -35,12 +35,18 @@ VideoType PipeWireRawFormatToVideoType(uint32_t id) {
|
||||
return VideoType::kYUY2;
|
||||
case SPA_VIDEO_FORMAT_UYVY:
|
||||
return VideoType::kUYVY;
|
||||
+ case SPA_VIDEO_FORMAT_RGB16:
|
||||
+ return VideoType::kRGB565;
|
||||
case SPA_VIDEO_FORMAT_RGB:
|
||||
+ return VideoType::kBGR24;
|
||||
+ case SPA_VIDEO_FORMAT_BGR:
|
||||
return VideoType::kRGB24;
|
||||
case SPA_VIDEO_FORMAT_BGRA:
|
||||
return VideoType::kARGB;
|
||||
case SPA_VIDEO_FORMAT_RGBA:
|
||||
return VideoType::kABGR;
|
||||
+ case SPA_VIDEO_FORMAT_ARGB:
|
||||
+ return VideoType::kBGRA;
|
||||
default:
|
||||
return VideoType::kUnknown;
|
||||
}
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
index 9ff4fdb9b1c98..1672b7583f582 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
@@ -34,10 +34,15 @@ struct {
|
||||
{SPA_VIDEO_FORMAT_YUY2, VideoType::kYUY2},
|
||||
{SPA_VIDEO_FORMAT_UYVY, VideoType::kUYVY},
|
||||
// PipeWire is big-endian for the formats, while libyuv is little-endian
|
||||
- // This means that BGRA == ARGB and RGBA == ABGR
|
||||
+ // This means that BGRA == ARGB, RGBA == ABGR and similar
|
||||
+ // This follows mapping in libcamera PipeWire plugin:
|
||||
+ // https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/libcamera/libcamera-utils.cpp
|
||||
{SPA_VIDEO_FORMAT_BGRA, VideoType::kARGB},
|
||||
{SPA_VIDEO_FORMAT_RGBA, VideoType::kABGR},
|
||||
- {SPA_VIDEO_FORMAT_RGB, VideoType::kRGB24},
|
||||
+ {SPA_VIDEO_FORMAT_ARGB, VideoType::kBGRA},
|
||||
+ {SPA_VIDEO_FORMAT_RGB, VideoType::kBGR24},
|
||||
+ {SPA_VIDEO_FORMAT_BGR, VideoType::kRGB24},
|
||||
+ {SPA_VIDEO_FORMAT_RGB16, VideoType::kRGB565},
|
||||
};
|
||||
|
||||
VideoType VideoCaptureModulePipeWire::PipeWireRawFormatToVideoType(
|
||||
@@ -302,13 +307,16 @@ void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) {
|
||||
break;
|
||||
case VideoType::kYUY2:
|
||||
case VideoType::kUYVY:
|
||||
+ case VideoType::kRGB565:
|
||||
stride = configured_capability_.width * 2;
|
||||
break;
|
||||
case VideoType::kRGB24:
|
||||
+ case VideoType::kBGR24:
|
||||
stride = configured_capability_.width * 3;
|
||||
break;
|
||||
case VideoType::kARGB:
|
||||
case VideoType::kABGR:
|
||||
+ case VideoType::kBGRA:
|
||||
stride = configured_capability_.width * 4;
|
||||
break;
|
||||
default:
|
||||
diff --git a/third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg
|
||||
new file mode 100644
|
||||
index 0000000000000..e795b816b1382
|
||||
--- /dev/null
|
||||
+++ b/third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg
|
||||
@@ -0,0 +1 @@
|
||||
+We cherry-picked this in bug 1907013.
|
@ -0,0 +1,231 @@
|
||||
From 286575b387cff9b3ec318d3cf90cf20d2f3c2ce4 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Mon, 2 Sep 2024 11:07:20 +0000
|
||||
Subject: [PATCH] Bug 1913286 - WebRTC backport: PipeWire camera: filter out
|
||||
devices with no capabilities r=pehrsons,webrtc-reviewers
|
||||
|
||||
Filter out devices that do not support any format supported by WebRTC.
|
||||
This will for example be IR cameras that show as duplicated in the list
|
||||
of cameras, but support only GRAY8 format and for that reason do not
|
||||
work at all.
|
||||
|
||||
This is a simple backport of an WebRTC upstream change.
|
||||
|
||||
Upstream commit: b4aba7834e6c94adace1cb4c20e2e1ee70eb9cc5
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D219224
|
||||
---
|
||||
.../linux/device_info_pipewire.cc | 20 ++++-----
|
||||
.../video_capture/linux/pipewire_session.cc | 43 +++++++++++++------
|
||||
.../video_capture/linux/pipewire_session.h | 21 ++++++---
|
||||
.../b4aba7834e.no-op-cherry-pick-msg | 1 +
|
||||
4 files changed, 58 insertions(+), 27 deletions(-)
|
||||
create mode 100644 third_party/libwebrtc/moz-patch-stack/b4aba7834e.no-op-cherry-pick-msg
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
|
||||
index 31d922035b3f8..db2a3c7099169 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
|
||||
@@ -57,31 +57,31 @@ int32_t DeviceInfoPipeWire::GetDeviceName(uint32_t deviceNumber,
|
||||
if (deviceNumber >= NumberOfDevices())
|
||||
return -1;
|
||||
|
||||
- const PipeWireNode& node = pipewire_session_->nodes().at(deviceNumber);
|
||||
+ const auto& node = pipewire_session_->nodes().at(deviceNumber);
|
||||
|
||||
- if (deviceNameLength <= node.display_name().length()) {
|
||||
+ if (deviceNameLength <= node->display_name().length()) {
|
||||
RTC_LOG(LS_INFO) << "deviceNameUTF8 buffer passed is too small";
|
||||
return -1;
|
||||
}
|
||||
- if (deviceUniqueIdUTF8Length <= node.unique_id().length()) {
|
||||
+ if (deviceUniqueIdUTF8Length <= node->unique_id().length()) {
|
||||
RTC_LOG(LS_INFO) << "deviceUniqueIdUTF8 buffer passed is too small";
|
||||
return -1;
|
||||
}
|
||||
if (productUniqueIdUTF8 &&
|
||||
- productUniqueIdUTF8Length <= node.model_id().length()) {
|
||||
+ productUniqueIdUTF8Length <= node->model_id().length()) {
|
||||
RTC_LOG(LS_INFO) << "productUniqueIdUTF8 buffer passed is too small";
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(deviceNameUTF8, 0, deviceNameLength);
|
||||
- node.display_name().copy(deviceNameUTF8, deviceNameLength);
|
||||
+ node->display_name().copy(deviceNameUTF8, deviceNameLength);
|
||||
|
||||
memset(deviceUniqueIdUTF8, 0, deviceUniqueIdUTF8Length);
|
||||
- node.unique_id().copy(deviceUniqueIdUTF8, deviceUniqueIdUTF8Length);
|
||||
+ node->unique_id().copy(deviceUniqueIdUTF8, deviceUniqueIdUTF8Length);
|
||||
|
||||
if (productUniqueIdUTF8) {
|
||||
memset(productUniqueIdUTF8, 0, productUniqueIdUTF8Length);
|
||||
- node.model_id().copy(productUniqueIdUTF8, productUniqueIdUTF8Length);
|
||||
+ node->model_id().copy(productUniqueIdUTF8, productUniqueIdUTF8Length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -92,11 +92,11 @@ int32_t DeviceInfoPipeWire::CreateCapabilityMap(
|
||||
RTC_CHECK(pipewire_session_);
|
||||
|
||||
for (auto& node : pipewire_session_->nodes()) {
|
||||
- if (node.unique_id().compare(deviceUniqueIdUTF8) != 0)
|
||||
+ if (node->unique_id().compare(deviceUniqueIdUTF8) != 0)
|
||||
continue;
|
||||
|
||||
- _captureCapabilities = node.capabilities();
|
||||
- _lastUsedDeviceNameLength = node.unique_id().length();
|
||||
+ _captureCapabilities = node->capabilities();
|
||||
+ _lastUsedDeviceNameLength = node->unique_id().length();
|
||||
_lastUsedDeviceName = static_cast<char*>(
|
||||
realloc(_lastUsedDeviceName, _lastUsedDeviceNameLength + 1));
|
||||
memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8,
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
index 107ea3dfbd954..dbac09274bb31 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
@@ -52,6 +52,19 @@ VideoType PipeWireRawFormatToVideoType(uint32_t id) {
|
||||
}
|
||||
}
|
||||
|
||||
+void PipeWireNode::PipeWireNodeDeleter::operator()(
|
||||
+ PipeWireNode* node) const noexcept {
|
||||
+ pw_proxy_destroy(node->proxy_);
|
||||
+ spa_hook_remove(&node->node_listener_);
|
||||
+}
|
||||
+
|
||||
+// static
|
||||
+PipeWireNode::PipeWireNodePtr PipeWireNode::Create(PipeWireSession* session,
|
||||
+ uint32_t id,
|
||||
+ const spa_dict* props) {
|
||||
+ return PipeWireNodePtr(new PipeWireNode(session, id, props));
|
||||
+}
|
||||
+
|
||||
PipeWireNode::PipeWireNode(PipeWireSession* session,
|
||||
uint32_t id,
|
||||
const spa_dict* props)
|
||||
@@ -73,11 +86,6 @@ PipeWireNode::PipeWireNode(PipeWireSession* session,
|
||||
pw_node_add_listener(proxy_, &node_listener_, &node_events, this);
|
||||
}
|
||||
|
||||
-PipeWireNode::~PipeWireNode() {
|
||||
- pw_proxy_destroy(proxy_);
|
||||
- spa_hook_remove(&node_listener_);
|
||||
-}
|
||||
-
|
||||
// static
|
||||
void PipeWireNode::OnNodeInfo(void* data, const pw_node_info* info) {
|
||||
PipeWireNode* that = static_cast<PipeWireNode*>(data);
|
||||
@@ -99,7 +107,9 @@ void PipeWireNode::OnNodeInfo(void* data, const pw_node_info* info) {
|
||||
pid.value());
|
||||
that->model_id_ = model_str;
|
||||
}
|
||||
- } else if (info->change_mask & PW_NODE_CHANGE_MASK_PARAMS) {
|
||||
+ }
|
||||
+
|
||||
+ if (info->change_mask & PW_NODE_CHANGE_MASK_PARAMS) {
|
||||
for (uint32_t i = 0; i < info->n_params; i++) {
|
||||
uint32_t id = info->params[i].id;
|
||||
if (id == SPA_PARAM_EnumFormat &&
|
||||
@@ -350,6 +360,14 @@ void PipeWireSession::OnCoreDone(void* data, uint32_t id, int seq) {
|
||||
if (id == PW_ID_CORE) {
|
||||
if (seq == that->sync_seq_) {
|
||||
RTC_LOG(LS_VERBOSE) << "Enumerating PipeWire camera devices complete.";
|
||||
+
|
||||
+ // Remove camera devices with no capabilities
|
||||
+ auto it = std::remove_if(that->nodes_.begin(), that->nodes_.end(),
|
||||
+ [](const PipeWireNode::PipeWireNodePtr& node) {
|
||||
+ return node->capabilities().empty();
|
||||
+ });
|
||||
+ that->nodes_.erase(it, that->nodes_.end());
|
||||
+
|
||||
that->Finish(VideoCaptureOptions::Status::SUCCESS);
|
||||
}
|
||||
}
|
||||
@@ -366,8 +384,8 @@ void PipeWireSession::OnRegistryGlobal(void* data,
|
||||
|
||||
// Skip already added nodes to avoid duplicate camera entries
|
||||
if (std::find_if(that->nodes_.begin(), that->nodes_.end(),
|
||||
- [id](const PipeWireNode& node) {
|
||||
- return node.id() == id;
|
||||
+ [id](const PipeWireNode::PipeWireNodePtr& node) {
|
||||
+ return node->id() == id;
|
||||
}) != that->nodes_.end())
|
||||
return;
|
||||
|
||||
@@ -381,7 +399,7 @@ void PipeWireSession::OnRegistryGlobal(void* data,
|
||||
if (!node_role || strcmp(node_role, "Camera"))
|
||||
return;
|
||||
|
||||
- that->nodes_.emplace_back(that, id, props);
|
||||
+ that->nodes_.push_back(PipeWireNode::Create(that, id, props));
|
||||
that->PipeWireSync();
|
||||
}
|
||||
|
||||
@@ -389,9 +407,10 @@ void PipeWireSession::OnRegistryGlobal(void* data,
|
||||
void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
|
||||
PipeWireSession* that = static_cast<PipeWireSession*>(data);
|
||||
|
||||
- auto it = std::remove_if(
|
||||
- that->nodes_.begin(), that->nodes_.end(),
|
||||
- [id](const PipeWireNode& node) { return node.id() == id; });
|
||||
+ auto it = std::remove_if(that->nodes_.begin(), that->nodes_.end(),
|
||||
+ [id](const PipeWireNode::PipeWireNodePtr& node) {
|
||||
+ return node->id() == id;
|
||||
+ });
|
||||
that->nodes_.erase(it, that->nodes_.end());
|
||||
}
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
|
||||
index fdc06a6b2a27a..84273ea695277 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
|
||||
@@ -37,8 +37,15 @@ class VideoCaptureModulePipeWire;
|
||||
// So they all represent one camera that is available via PipeWire.
|
||||
class PipeWireNode {
|
||||
public:
|
||||
- PipeWireNode(PipeWireSession* session, uint32_t id, const spa_dict* props);
|
||||
- ~PipeWireNode();
|
||||
+ struct PipeWireNodeDeleter {
|
||||
+ void operator()(PipeWireNode* node) const noexcept;
|
||||
+ };
|
||||
+
|
||||
+ using PipeWireNodePtr =
|
||||
+ std::unique_ptr<PipeWireNode, PipeWireNode::PipeWireNodeDeleter>;
|
||||
+ static PipeWireNodePtr Create(PipeWireSession* session,
|
||||
+ uint32_t id,
|
||||
+ const spa_dict* props);
|
||||
|
||||
uint32_t id() const { return id_; }
|
||||
std::string display_name() const { return display_name_; }
|
||||
@@ -48,6 +55,9 @@ class PipeWireNode {
|
||||
return capabilities_;
|
||||
}
|
||||
|
||||
+ protected:
|
||||
+ PipeWireNode(PipeWireSession* session, uint32_t id, const spa_dict* props);
|
||||
+
|
||||
private:
|
||||
static void OnNodeInfo(void* data, const pw_node_info* info);
|
||||
static void OnNodeParam(void* data,
|
||||
@@ -87,8 +97,9 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
|
||||
|
||||
void Init(VideoCaptureOptions::Callback* callback,
|
||||
int fd = kInvalidPipeWireFd);
|
||||
-
|
||||
- const std::deque<PipeWireNode>& nodes() const { return nodes_; }
|
||||
+ const std::deque<PipeWireNode::PipeWireNodePtr>& nodes() const {
|
||||
+ return nodes_;
|
||||
+ }
|
||||
|
||||
friend class CameraPortalNotifier;
|
||||
friend class PipeWireNode;
|
||||
@@ -134,7 +145,7 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
|
||||
|
||||
int sync_seq_ = 0;
|
||||
|
||||
- std::deque<PipeWireNode> nodes_;
|
||||
+ std::deque<PipeWireNode::PipeWireNodePtr> nodes_;
|
||||
std::unique_ptr<CameraPortal> portal_;
|
||||
std::unique_ptr<CameraPortalNotifier> portal_notifier_;
|
||||
};
|
@ -0,0 +1,52 @@
|
||||
From b10c1d09729794c46f9c04d04c07c18d514d396e Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Wed, 4 Sep 2024 13:43:29 +0000
|
||||
Subject: [PATCH] Bug 1912785 - Always query information about camera
|
||||
availability r=pehrsons
|
||||
|
||||
We have to always update camera availability information, even when we
|
||||
don't request cameras, because the WebRTC backend automatically creates
|
||||
camera video engine and not having this information we might hitting an
|
||||
assert later, where we assume the status of camera availability is not
|
||||
unknown.
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D219062
|
||||
---
|
||||
dom/media/MediaManager.cpp | 17 ++++++++++++-----
|
||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp
|
||||
index 2ade297d31e84..3cc716e6836ac 100644
|
||||
--- a/dom/media/MediaManager.cpp
|
||||
+++ b/dom/media/MediaManager.cpp
|
||||
@@ -2153,9 +2153,15 @@ MediaManager::MaybeRequestPermissionAndEnumerateRawDevices(
|
||||
}
|
||||
|
||||
if (!deviceAccessPromise) {
|
||||
- // No device access request needed. Proceed directly.
|
||||
- deviceAccessPromise =
|
||||
- NativePromise::CreateAndResolve(CamerasAccessStatus::Granted, __func__);
|
||||
+ // No device access request needed. We can proceed directly, but we still
|
||||
+ // need to update camera availability, because the camera engine is always
|
||||
+ // created together with the WebRTC backend, which is done because
|
||||
+ // devicechange events must work before prompting in cases where persistent
|
||||
+ // permission has already been given. Making a request to camera access not
|
||||
+ // allowing a permission request does exactly what we need in this case.
|
||||
+ ipc::PBackgroundChild* backgroundChild =
|
||||
+ ipc::BackgroundChild::GetOrCreateForCurrentThread();
|
||||
+ deviceAccessPromise = backgroundChild->SendRequestCameraAccess(false);
|
||||
}
|
||||
|
||||
return deviceAccessPromise->Then(
|
||||
@@ -2190,8 +2196,9 @@ MediaManager::MaybeRequestPermissionAndEnumerateRawDevices(
|
||||
"rejected");
|
||||
}
|
||||
|
||||
- if (aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest)) {
|
||||
- MOZ_ASSERT(aValue.ResolveValue() == CamerasAccessStatus::Granted);
|
||||
+ if (aParams.VideoInputType() == MediaSourceEnum::Camera &&
|
||||
+ aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest) &&
|
||||
+ aValue.ResolveValue() == CamerasAccessStatus::Granted) {
|
||||
EnsureNoPlaceholdersInDeviceCache();
|
||||
}
|
||||
|
@ -0,0 +1,293 @@
|
||||
From df57b21200c7cde7ac34705e8fceab2fbe933bc5 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
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<webrtc::VideoCaptureModule::DeviceInfo>
|
||||
+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<int, bool, true>;
|
||||
- InvokeAsync(
|
||||
- mVideoCaptureThread, __func__,
|
||||
- [this, self = RefPtr(this), aCapEngine] {
|
||||
- int num = -1;
|
||||
- if (auto* engine = EnsureInitialized(aCapEngine)) {
|
||||
- if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
|
||||
- num = static_cast<int>(devInfo->NumberOfDevices());
|
||||
- }
|
||||
- }
|
||||
+ InvokeAsync(mVideoCaptureThread, __func__,
|
||||
+ [this, self = RefPtr(this), aCapEngine] {
|
||||
+ int num = -1;
|
||||
+ if (auto devInfo = GetDeviceInfo(aCapEngine)) {
|
||||
+ num = static_cast<int>(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<webrtc::VideoCaptureCapability, int, true>;
|
||||
- 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<uint32_t, webrtc::VideoCaptureCapability>
|
||||
- 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<uint32_t, webrtc::VideoCaptureCapability>
|
||||
+ 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<nsCString, nsCString, pid_t, bool, int>;
|
||||
using Promise = MozPromise<Data, bool, true>;
|
||||
- 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<webrtc::VideoCaptureModule::DeviceInfo> 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<webrtc::VideoCaptureModule::DeviceInfo>
|
||||
-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<webrtc::VideoCaptureModule::DeviceInfo>
|
||||
- GetOrCreateVideoCaptureDeviceInfo();
|
||||
+ GetOrCreateVideoCaptureDeviceInfo(webrtc::VideoInputFeedBack* callBack);
|
||||
|
||||
/**
|
||||
* Destroys existing DeviceInfo.
|
@ -0,0 +1,36 @@
|
||||
From 7dd135852be020d5755af42fa45470df259ba945 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Wed, 4 Sep 2024 13:43:40 +0000
|
||||
Subject: [PATCH] Bug 1830275 - WebRTC backport: PipeWire camera: make member
|
||||
variable with the PipeWire status updated r=pehrsons,webrtc-reviewers
|
||||
|
||||
We keep information about the PipeWire camera status as a member of the
|
||||
PipeWire session, but it's never updated and remains in uninitialized
|
||||
state. Make sure it gets updated once PipeWire is initialized or when it
|
||||
fails. There is currently no use for this member variable, but there is
|
||||
a plan to use it so I'm rather keeping it instead of removing it.
|
||||
|
||||
This is a simple backport of an WebRTC upstream change.
|
||||
|
||||
Upstream commit: 3881cb65cfcec90b6f0a56ce7223a471aa0115f2
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D220895
|
||||
---
|
||||
.../libwebrtc/modules/video_capture/linux/pipewire_session.cc | 2 ++
|
||||
.../libwebrtc/moz-patch-stack/3881cb65cf.no-op-cherry-pick-msg | 1 +
|
||||
2 files changed, 3 insertions(+)
|
||||
create mode 100644 third_party/libwebrtc/moz-patch-stack/3881cb65cf.no-op-cherry-pick-msg
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
index dbac09274bb31..ac12d0437290e 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
@@ -415,6 +415,8 @@ void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
|
||||
}
|
||||
|
||||
void PipeWireSession::Finish(VideoCaptureOptions::Status status) {
|
||||
+ status_ = status;
|
||||
+
|
||||
webrtc::MutexLock lock(&callback_lock_);
|
||||
|
||||
if (callback_) {
|
@ -0,0 +1,190 @@
|
||||
From a4eb4517f2bdeb6591c05a09109b4b543b83fef1 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Thu, 5 Sep 2024 16:04:48 +0000
|
||||
Subject: [PATCH] Bug 1830275 - Add missing support for device change
|
||||
notifications r=pehrsons,webrtc-reviewers
|
||||
|
||||
Registers each DeviceInfoPipeWire in PipeWireSession we use and calls
|
||||
DeviceChange() for each once there is a new camera added or removed to
|
||||
invoke OnDeviceChange() for every registered VideoInputFeedback.
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D219218
|
||||
---
|
||||
.../linux/device_info_pipewire.cc | 10 +++-
|
||||
.../video_capture/linux/pipewire_session.cc | 47 ++++++++++++++++++-
|
||||
.../video_capture/linux/pipewire_session.h | 26 +++++++++-
|
||||
3 files changed, 79 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
|
||||
index db2a3c7099..a0607b4aba 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
|
||||
@@ -29,13 +29,19 @@
|
||||
namespace webrtc {
|
||||
namespace videocapturemodule {
|
||||
DeviceInfoPipeWire::DeviceInfoPipeWire(VideoCaptureOptions* options)
|
||||
- : DeviceInfoImpl(), pipewire_session_(options->pipewire_session()) {}
|
||||
+ : DeviceInfoImpl(), pipewire_session_(options->pipewire_session()) {
|
||||
+ const bool ret = pipewire_session_->RegisterDeviceInfo(this);
|
||||
+ RTC_CHECK(ret);
|
||||
+}
|
||||
|
||||
int32_t DeviceInfoPipeWire::Init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-DeviceInfoPipeWire::~DeviceInfoPipeWire() = default;
|
||||
+DeviceInfoPipeWire::~DeviceInfoPipeWire() {
|
||||
+ const bool ret = pipewire_session_->DeRegisterDeviceInfo(this);
|
||||
+ RTC_CHECK(ret);
|
||||
+}
|
||||
|
||||
uint32_t DeviceInfoPipeWire::NumberOfDevices() {
|
||||
RTC_CHECK(pipewire_session_);
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
index ac12d04372..0b78c16df2 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "modules/video_capture/linux/pipewire_session.h"
|
||||
+#include "modules/video_capture/linux/device_info_pipewire.h"
|
||||
|
||||
#include <spa/monitor/device.h>
|
||||
#include <spa/param/format-utils.h>
|
||||
@@ -274,6 +275,28 @@ void PipeWireSession::InitPipeWire(int fd) {
|
||||
Finish(VideoCaptureOptions::Status::ERROR);
|
||||
}
|
||||
|
||||
+bool PipeWireSession::RegisterDeviceInfo(DeviceInfoPipeWire* device_info) {
|
||||
+ RTC_CHECK(device_info);
|
||||
+ MutexLock lock(&device_info_lock_);
|
||||
+ auto it = std::find(device_info_list_.begin(), device_info_list_.end(), device_info);
|
||||
+ if (it == device_info_list_.end()) {
|
||||
+ device_info_list_.push_back(device_info);
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool PipeWireSession::DeRegisterDeviceInfo(DeviceInfoPipeWire* device_info) {
|
||||
+ RTC_CHECK(device_info);
|
||||
+ MutexLock lock(&device_info_lock_);
|
||||
+ auto it = std::find(device_info_list_.begin(), device_info_list_.end(), device_info);
|
||||
+ if (it != device_info_list_.end()) {
|
||||
+ device_info_list_.erase(it);
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
bool PipeWireSession::StartPipeWire(int fd) {
|
||||
pw_init(/*argc=*/nullptr, /*argv=*/nullptr);
|
||||
|
||||
@@ -344,6 +367,21 @@ void PipeWireSession::PipeWireSync() {
|
||||
sync_seq_ = pw_core_sync(pw_core_, PW_ID_CORE, sync_seq_);
|
||||
}
|
||||
|
||||
+void PipeWireSession::NotifyDeviceChange() {
|
||||
+ RTC_LOG(LS_INFO) << "Notify about device list changes";
|
||||
+ MutexLock lock(&device_info_lock_);
|
||||
+
|
||||
+ // It makes sense to notify about device changes only once we are
|
||||
+ // properly initialized.
|
||||
+ if (status_ != VideoCaptureOptions::Status::SUCCESS) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (auto* deviceInfo : device_info_list_) {
|
||||
+ deviceInfo->DeviceChange();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// static
|
||||
void PipeWireSession::OnCoreError(void* data,
|
||||
uint32_t id,
|
||||
@@ -401,6 +439,8 @@ void PipeWireSession::OnRegistryGlobal(void* data,
|
||||
|
||||
that->nodes_.push_back(PipeWireNode::Create(that, id, props));
|
||||
that->PipeWireSync();
|
||||
+
|
||||
+ that->NotifyDeviceChange();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -412,10 +452,15 @@ void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
|
||||
return node->id() == id;
|
||||
});
|
||||
that->nodes_.erase(it, that->nodes_.end());
|
||||
+
|
||||
+ that->NotifyDeviceChange();
|
||||
}
|
||||
|
||||
void PipeWireSession::Finish(VideoCaptureOptions::Status status) {
|
||||
- status_ = status;
|
||||
+ {
|
||||
+ MutexLock lock(&device_info_lock_);
|
||||
+ status_ = status;
|
||||
+ }
|
||||
|
||||
webrtc::MutexLock lock(&callback_lock_);
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
|
||||
index 84273ea695..1f3a00614f 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
|
||||
@@ -29,6 +29,7 @@
|
||||
namespace webrtc {
|
||||
namespace videocapturemodule {
|
||||
|
||||
+class DeviceInfoPipeWire;
|
||||
class PipeWireSession;
|
||||
class VideoCaptureModulePipeWire;
|
||||
|
||||
@@ -97,6 +98,21 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
|
||||
|
||||
void Init(VideoCaptureOptions::Callback* callback,
|
||||
int fd = kInvalidPipeWireFd);
|
||||
+
|
||||
+ // [De]Register DeviceInfo for device change updates
|
||||
+ // These methods will add or remove references to DeviceInfo
|
||||
+ // objects that we want to notify about device changes.
|
||||
+ // NOTE: We do not take ownership of these objects and
|
||||
+ // they should never be released by us. All the instances
|
||||
+ // of DeviceInfoPipeWire must outlive their registration.
|
||||
+
|
||||
+ // Returns true when DeviceInfo was successfuly registered
|
||||
+ // or false otherwise, when it was already registered before.
|
||||
+ bool RegisterDeviceInfo(DeviceInfoPipeWire* device_info);
|
||||
+ // Returns true when DeviceInfo was successfuly unregistered
|
||||
+ // or false otherwise, when it was not previously registered.
|
||||
+ bool DeRegisterDeviceInfo(DeviceInfoPipeWire* device_info);
|
||||
+
|
||||
const std::deque<PipeWireNode::PipeWireNodePtr>& nodes() const {
|
||||
return nodes_;
|
||||
}
|
||||
@@ -111,6 +127,8 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
|
||||
void StopPipeWire();
|
||||
void PipeWireSync();
|
||||
|
||||
+ void NotifyDeviceChange();
|
||||
+
|
||||
static void OnCoreError(void* data,
|
||||
uint32_t id,
|
||||
int seq,
|
||||
@@ -133,7 +151,13 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
|
||||
VideoCaptureOptions::Callback* callback_ RTC_GUARDED_BY(&callback_lock_) =
|
||||
nullptr;
|
||||
|
||||
- VideoCaptureOptions::Status status_;
|
||||
+ webrtc::Mutex device_info_lock_;
|
||||
+ std::vector<DeviceInfoPipeWire*> device_info_list_
|
||||
+ RTC_GUARDED_BY(device_info_lock_);
|
||||
+ // Guard with device_info_lock, because currently it's the only place where
|
||||
+ // we use this status information.
|
||||
+ VideoCaptureOptions::Status status_
|
||||
+ RTC_GUARDED_BY(device_info_lock_);
|
||||
|
||||
struct pw_thread_loop* pw_main_loop_ = nullptr;
|
||||
struct pw_context* pw_context_ = nullptr;
|
@ -0,0 +1,52 @@
|
||||
From 9d035f728745f13311ed13d057565ca3b45523aa Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Tue, 24 Sep 2024 11:20:02 +0000
|
||||
Subject: [PATCH] Bug 1920460 - WebRTC backport: PipeWire camera: get max FPS
|
||||
for each format when specified as list r=pehrsons,webrtc-reviewers
|
||||
|
||||
In many cases, the framerate can be specified as list of possible values
|
||||
and in that case, we would end up with max FPS to be set to 0 as this
|
||||
case was not handled.
|
||||
|
||||
This is a simple backport of an WebRTC upstream change.
|
||||
|
||||
Upstream commit: 3aa47cfd30dc965446cf1405bb062b756a62e6d1
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D223112
|
||||
---
|
||||
.../modules/video_capture/linux/pipewire_session.cc | 12 ++++++++++--
|
||||
.../moz-patch-stack/3aa47cfd30.no-op-cherry-pick-msg | 1 +
|
||||
2 files changed, 11 insertions(+), 2 deletions(-)
|
||||
create mode 100644 third_party/libwebrtc/moz-patch-stack/3aa47cfd30.no-op-cherry-pick-msg
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
index d9bc49d521b03..e5db278ff6a99 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <spa/param/video/raw.h>
|
||||
#include <spa/pod/parser.h>
|
||||
|
||||
+#include <algorithm>
|
||||
+
|
||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "modules/video_capture/device_info_impl.h"
|
||||
#include "rtc_base/logging.h"
|
||||
@@ -152,9 +154,15 @@ void PipeWireNode::OnNodeParam(void* data,
|
||||
|
||||
fract = static_cast<spa_fraction*>(SPA_POD_BODY(val));
|
||||
|
||||
- if (choice == SPA_CHOICE_None)
|
||||
+ if (choice == SPA_CHOICE_None) {
|
||||
cap.maxFPS = 1.0 * fract[0].num / fract[0].denom;
|
||||
- else if (choice == SPA_CHOICE_Range && fract[1].num > 0)
|
||||
+ } else if (choice == SPA_CHOICE_Enum) {
|
||||
+ for (uint32_t i = 1; i < n_items; i++) {
|
||||
+ cap.maxFPS = std::max(
|
||||
+ static_cast<int32_t>(1.0 * fract[i].num / fract[i].denom),
|
||||
+ cap.maxFPS);
|
||||
+ }
|
||||
+ } else if (choice == SPA_CHOICE_Range && fract[1].num > 0)
|
||||
cap.maxFPS = 1.0 * fract[1].num / fract[1].denom;
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
From ca88b4994e140370ca5795c60f46559301458a98 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Wed, 25 Sep 2024 06:52:35 +0000
|
||||
Subject: [PATCH] Bug 1920472 - WebRTC backport: PipeWire camera: use exact
|
||||
stream parameters specified by capability r=pehrsons,webrtc-reviewers
|
||||
|
||||
We currently specify stream parameters to be a range for both framerate
|
||||
and resolution, where preferred value is specified. The preferred value
|
||||
doesn't seem to be taken into account and we end up accepting resolution
|
||||
from 1x1 to MAX_INTxMAX_INT. In case the other side tries to first match
|
||||
with lower resolution than requested, we will happily match it and start
|
||||
streaming low quality video. We should instead request the exact stream
|
||||
parameters as specified by requested capability. This capability always
|
||||
come from what has been originally reported as supported so it shouldn't
|
||||
happen we don't find a matching stream. This also applies to requested
|
||||
video format. We previously requested mjpg for streams with resolution
|
||||
higher than 640x480, but it doesn't necessarily mean the camera supports
|
||||
mjpg for the requested resolution. Again, refer to requested capability
|
||||
in this case as it should indicate what is supported and we know we can
|
||||
request exactly the same video format. It can happen that framerate is
|
||||
set to 0 as unspecified. In that case keep using a range as before, but
|
||||
with more sane values.
|
||||
|
||||
This is a simple backport of an WebRTC upstream change.
|
||||
|
||||
Upstream commit: 9703f8474f156e08e4a96dc36253f1cdccd549e1
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D223119
|
||||
---
|
||||
.../linux/video_capture_pipewire.cc | 85 +++++++++++--------
|
||||
.../linux/video_capture_pipewire.h | 1 +
|
||||
.../9703f8474f.no-op-cherry-pick-msg | 1 +
|
||||
3 files changed, 52 insertions(+), 35 deletions(-)
|
||||
create mode 100644 third_party/libwebrtc/moz-patch-stack/9703f8474f.no-op-cherry-pick-msg
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
index 1672b7583f..2338fa6d87 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
@@ -51,10 +51,20 @@ VideoType VideoCaptureModulePipeWire::PipeWireRawFormatToVideoType(
|
||||
if (spa_and_pixel_format.spa_format == spa_format)
|
||||
return spa_and_pixel_format.video_type;
|
||||
}
|
||||
- RTC_LOG(LS_INFO) << "Unsupported pixel format: " << spa_format;
|
||||
+ RTC_LOG(LS_WARNING) << "Unsupported pixel format: " << spa_format;
|
||||
return VideoType::kUnknown;
|
||||
}
|
||||
|
||||
+uint32_t VideoCaptureModulePipeWire::VideoTypeToPipeWireRawFormat(
|
||||
+ VideoType type) {
|
||||
+ for (const auto& spa_and_pixel_format : kSupportedFormats) {
|
||||
+ if (spa_and_pixel_format.video_type == type)
|
||||
+ return spa_and_pixel_format.spa_format;
|
||||
+ }
|
||||
+ RTC_LOG(LS_WARNING) << "Unsupported video type: " << static_cast<int>(type);
|
||||
+ return SPA_VIDEO_FORMAT_UNKNOWN;
|
||||
+}
|
||||
+
|
||||
VideoCaptureModulePipeWire::VideoCaptureModulePipeWire(
|
||||
VideoCaptureOptions* options)
|
||||
: VideoCaptureImpl(),
|
||||
@@ -87,45 +97,53 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) {
|
||||
}
|
||||
|
||||
static spa_pod* BuildFormat(spa_pod_builder* builder,
|
||||
- uint32_t format,
|
||||
+ VideoType video_type,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
float frame_rate) {
|
||||
- spa_pod_frame frames[2];
|
||||
+ spa_pod_frame frame;
|
||||
+
|
||||
+ const uint32_t media_subtype = video_type == VideoType::kMJPEG
|
||||
+ ? SPA_MEDIA_SUBTYPE_mjpg
|
||||
+ : SPA_MEDIA_SUBTYPE_raw;
|
||||
|
||||
- spa_pod_builder_push_object(builder, &frames[0], SPA_TYPE_OBJECT_Format,
|
||||
+ spa_pod_builder_push_object(builder, &frame, SPA_TYPE_OBJECT_Format,
|
||||
SPA_PARAM_EnumFormat);
|
||||
spa_pod_builder_add(builder, SPA_FORMAT_mediaType,
|
||||
SPA_POD_Id(SPA_MEDIA_TYPE_video), SPA_FORMAT_mediaSubtype,
|
||||
- SPA_POD_Id(format), 0);
|
||||
-
|
||||
- if (format == SPA_MEDIA_SUBTYPE_raw) {
|
||||
- spa_pod_builder_prop(builder, SPA_FORMAT_VIDEO_format, 0);
|
||||
- spa_pod_builder_push_choice(builder, &frames[1], SPA_CHOICE_Enum, 0);
|
||||
- spa_pod_builder_id(builder, kSupportedFormats[0].spa_format);
|
||||
- for (const auto& spa_and_pixel_format : kSupportedFormats)
|
||||
- spa_pod_builder_id(builder, spa_and_pixel_format.spa_format);
|
||||
- spa_pod_builder_pop(builder, &frames[1]);
|
||||
- }
|
||||
+ SPA_POD_Id(media_subtype), 0);
|
||||
|
||||
- spa_rectangle preferred_size = spa_rectangle{width, height};
|
||||
- spa_rectangle min_size = spa_rectangle{1, 1};
|
||||
- spa_rectangle max_size = spa_rectangle{4096, 4096};
|
||||
- spa_pod_builder_add(
|
||||
- builder, SPA_FORMAT_VIDEO_size,
|
||||
- SPA_POD_CHOICE_RANGE_Rectangle(&preferred_size, &min_size, &max_size), 0);
|
||||
+ if (media_subtype == SPA_MEDIA_SUBTYPE_raw) {
|
||||
+ const uint32_t format =
|
||||
+ VideoCaptureModulePipeWire::VideoTypeToPipeWireRawFormat(video_type);
|
||||
+ RTC_CHECK(format != SPA_VIDEO_FORMAT_UNKNOWN);
|
||||
+ spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_format, SPA_POD_Id(format),
|
||||
+ 0);
|
||||
+ }
|
||||
|
||||
- spa_fraction preferred_frame_rate =
|
||||
- spa_fraction{static_cast<uint32_t>(frame_rate), 1};
|
||||
- spa_fraction min_frame_rate = spa_fraction{0, 1};
|
||||
- spa_fraction max_frame_rate = spa_fraction{INT32_MAX, 1};
|
||||
- spa_pod_builder_add(
|
||||
- builder, SPA_FORMAT_VIDEO_framerate,
|
||||
- SPA_POD_CHOICE_RANGE_Fraction(&preferred_frame_rate, &min_frame_rate,
|
||||
- &max_frame_rate),
|
||||
- 0);
|
||||
+ spa_rectangle resolution = spa_rectangle{width, height};
|
||||
+ spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_size,
|
||||
+ SPA_POD_Rectangle(&resolution), 0);
|
||||
+
|
||||
+ // Framerate can be also set to 0 to be unspecified
|
||||
+ if (frame_rate) {
|
||||
+ spa_fraction framerate = spa_fraction{static_cast<uint32_t>(frame_rate), 1};
|
||||
+ spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_framerate,
|
||||
+ SPA_POD_Fraction(&framerate), 0);
|
||||
+ } else {
|
||||
+ // Default to some reasonable values
|
||||
+ spa_fraction preferred_frame_rate =
|
||||
+ spa_fraction{static_cast<uint32_t>(30), 1};
|
||||
+ spa_fraction min_frame_rate = spa_fraction{1, 1};
|
||||
+ spa_fraction max_frame_rate = spa_fraction{30, 1};
|
||||
+ spa_pod_builder_add(
|
||||
+ builder, SPA_FORMAT_VIDEO_framerate,
|
||||
+ SPA_POD_CHOICE_RANGE_Fraction(&preferred_frame_rate, &min_frame_rate,
|
||||
+ &max_frame_rate),
|
||||
+ 0);
|
||||
+ }
|
||||
|
||||
- return static_cast<spa_pod*>(spa_pod_builder_pop(builder, &frames[0]));
|
||||
+ return static_cast<spa_pod*>(spa_pod_builder_pop(builder, &frame));
|
||||
}
|
||||
|
||||
int32_t VideoCaptureModulePipeWire::StartCapture(
|
||||
@@ -176,13 +194,10 @@ int32_t VideoCaptureModulePipeWire::StartCapture(
|
||||
uint32_t width = capability.width;
|
||||
uint32_t height = capability.height;
|
||||
uint32_t frame_rate = capability.maxFPS;
|
||||
- bool prefer_jpeg = (width > 640) || (height > 480);
|
||||
+ VideoType video_type = capability.videoType;
|
||||
|
||||
params.push_back(
|
||||
- BuildFormat(&builder, SPA_MEDIA_SUBTYPE_raw, width, height, frame_rate));
|
||||
- params.insert(
|
||||
- prefer_jpeg ? params.begin() : params.end(),
|
||||
- BuildFormat(&builder, SPA_MEDIA_SUBTYPE_mjpg, width, height, frame_rate));
|
||||
+ BuildFormat(&builder, video_type, width, height, frame_rate));
|
||||
|
||||
int res = pw_stream_connect(
|
||||
stream_, PW_DIRECTION_INPUT, node_id_,
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h
|
||||
index eeb3b9497c..789f2034d3 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h
|
||||
@@ -28,6 +28,7 @@ class VideoCaptureModulePipeWire : public VideoCaptureImpl {
|
||||
int32_t CaptureSettings(VideoCaptureCapability& settings) override;
|
||||
|
||||
static VideoType PipeWireRawFormatToVideoType(uint32_t format);
|
||||
+ static uint32_t VideoTypeToPipeWireRawFormat(VideoType type);
|
||||
|
||||
private:
|
||||
static void OnStreamParamChanged(void* data,
|
@ -0,0 +1,61 @@
|
||||
From 12b7d28d858fdcfa80795a2af49a71d3b5142733 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <grulja@gmail.com>
|
||||
Date: Tue, 12 Nov 2024 12:28:19 +0000
|
||||
Subject: [PATCH] Bug 1930598 - WebRTC backport: PipeWire camera: use better
|
||||
unique device name for camera devices r=pehrsons,webrtc-reviewers
|
||||
|
||||
Originally we used node id from PipeWire as an unique device name and
|
||||
while this works, it will change everytime PipeWire is restarted. This
|
||||
has an impact on default camera selection, where for example Firefox can
|
||||
automatically request a camera device that was used before, but this can
|
||||
break with the next PipeWire restart.
|
||||
|
||||
This is a simple backport of an WebRTC upstream change.
|
||||
|
||||
Upstream commit: a5d71009ac1dce7da23813dc9413c03073cfa8ca
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D228635
|
||||
---
|
||||
.../modules/video_capture/linux/pipewire_session.cc | 2 +-
|
||||
.../video_capture/linux/video_capture_pipewire.cc | 11 +++++++----
|
||||
.../moz-patch-stack/a5d71009ac.no-op-cherry-pick-msg | 1 +
|
||||
3 files changed, 9 insertions(+), 5 deletions(-)
|
||||
create mode 100644 third_party/libwebrtc/moz-patch-stack/a5d71009ac.no-op-cherry-pick-msg
|
||||
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
index 641e5238ea..dd187c0358 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
|
||||
@@ -74,7 +74,7 @@ PipeWireNode::PipeWireNode(PipeWireSession* session,
|
||||
: session_(session),
|
||||
id_(id),
|
||||
display_name_(spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION)),
|
||||
- unique_id_(rtc::ToString(id)) {
|
||||
+ unique_id_(spa_dict_lookup(props, PW_KEY_NODE_NAME)) {
|
||||
RTC_LOG(LS_VERBOSE) << "Found Camera: " << display_name_;
|
||||
|
||||
proxy_ = static_cast<pw_proxy*>(pw_registry_bind(
|
||||
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
index 2338fa6d87..888b8f386f 100644
|
||||
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
|
||||
@@ -82,12 +82,15 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) {
|
||||
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
|
||||
RTC_DCHECK_RUN_ON(&api_checker_);
|
||||
|
||||
- absl::optional<int> id;
|
||||
- id = rtc::StringToNumber<int>(deviceUniqueId);
|
||||
- if (id == absl::nullopt)
|
||||
+ auto node =
|
||||
+ std::find_if(session_->nodes_.begin(), session_->nodes_.end(),
|
||||
+ [deviceUniqueId](const PipeWireNode::PipeWireNodePtr& node) {
|
||||
+ return node->unique_id() == deviceUniqueId;
|
||||
+ });
|
||||
+ if (node == session_->nodes_.end())
|
||||
return -1;
|
||||
|
||||
- node_id_ = id.value();
|
||||
+ node_id_ = (*node)->id();
|
||||
|
||||
const int len = strlen(deviceUniqueId);
|
||||
_deviceUniqueId = new (std::nothrow) char[len + 1];
|
507
firefox-system-nss-replace-xyber-with-mlkem.patch
Normal file
507
firefox-system-nss-replace-xyber-with-mlkem.patch
Normal file
File diff suppressed because one or more lines are too long
53
firefox.spec
53
firefox.spec
@ -51,6 +51,12 @@ end}
|
||||
|
||||
%global rhel_minor_version %{lua:print(dist_to_rhel_minor(rpm.expand("%dist")))}
|
||||
|
||||
%if 0%{?rhel} == 10
|
||||
%global use_pipewire_camera 1
|
||||
%else
|
||||
%global use_pipewire_camera 0
|
||||
%endif
|
||||
|
||||
# System libraries options
|
||||
%global system_nss 1
|
||||
%global bundle_nss 0
|
||||
@ -138,7 +144,7 @@ end}
|
||||
Summary: Mozilla Firefox Web browser
|
||||
Name: firefox
|
||||
Version: 128.4.0
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
URL: https://www.mozilla.org/firefox/
|
||||
License: MPLv1.1 or GPLv2+ or LGPLv2+
|
||||
|
||||
@ -209,6 +215,7 @@ Patch08: disable-pipewire.patch
|
||||
Patch09: rhbz-2131158-webrtc-nss-fix.patch
|
||||
Patch10: build-ffvpx.patch
|
||||
Patch11: build-disable-gamepad.patch
|
||||
Patch12: firefox-system-nss-replace-xyber-with-mlkem.patch
|
||||
|
||||
# -- Upstreamed patches --
|
||||
Patch51: mozilla-bmo1170092.patch
|
||||
@ -241,6 +248,28 @@ Patch200: webrtc-128.0.patch.patch
|
||||
Patch201: D224587.1728128070.diff
|
||||
Patch202: D224588.1728128098.diff
|
||||
|
||||
# --- Upstream PipeWire camera and screencast fixes ----
|
||||
# https://phabricator.services.mozilla.com/D215197
|
||||
Patch250: 001-libwebrtc-pipewire-screencast-hide-cursor-when-goes-off-screen-or-is-invisible.patch
|
||||
# https://phabricator.services.mozilla.com/D216138
|
||||
Patch251: 002-libwebrtc-pipewire-camera-support-additional-formats-and-fix-rgb-bgr-mapping.patch
|
||||
# https://phabricator.services.mozilla.com/D219224
|
||||
Patch252: 003-libwebrtc-pipewire-camera-filter-out-devices-without-capabilities.patch
|
||||
# https://phabricator.services.mozilla.com/D219062
|
||||
Patch253: 004-firefox-always-query-information-about-camera-availability.patch
|
||||
# https://phabricator.services.mozilla.com/D219060
|
||||
Patch254: 005-firefox-always-register-video-input-feedback-for-newly-created-deviceinfo.patch
|
||||
# https://phabricator.services.mozilla.com/D220895
|
||||
Patch255: 006-libwebrtc-pipewire-camera-make-member-variable-with-pipewire-status-updated.patch
|
||||
# https://phabricator.services.mozilla.com/D219218
|
||||
Patch256: 007-firefox-add-missing-support-for-device-change-notifications.patch
|
||||
# https://phabricator.services.mozilla.com/D223112
|
||||
Patch257: 008-libwebrtc-pipewire-camera-get-max-fps-for-each-format-when-specified-as-list.patch
|
||||
# https://phabricator.services.mozilla.com/D223119
|
||||
Patch258: 009-libwebrtc-pipewire-camera-use-exact-stream-parameters-specified-by-capability.patch
|
||||
# https://phabricator.services.mozilla.com/D228635
|
||||
Patch259: 010-libwebrtc-pipewire-camera-use-better-unique-device-name-for-camera-devices.patch
|
||||
|
||||
|
||||
# ---- Test patches ----
|
||||
# Generate without context by
|
||||
@ -1151,6 +1180,7 @@ echo "--------------------------------------------"
|
||||
%endif
|
||||
%patch -P9 -p1 -b .rhbz-2131158-webrtc-nss-fix
|
||||
%patch -P10 -p1 -b .build-ffvpx
|
||||
%patch -P12 -p1 -b .system-nss-replace-xyber-with-mlkem
|
||||
|
||||
# -- Upstreamed patches --
|
||||
%patch -P51 -p1 -b .mozilla-bmo1170092
|
||||
@ -1183,6 +1213,17 @@ echo "--------------------------------------------"
|
||||
%patch -P202 -p1 -b .D224588
|
||||
%endif
|
||||
|
||||
# --- Upstream PipeWire camera and screencast fixes ----
|
||||
%patch -P250 -p1 -b .pipewire-screencast-hide-cursor-when-goes-off-screen-or-is-invisible
|
||||
%patch -P251 -p1 -b .pipewire-camera-support-additional-formats-and-fix-rgb-bgr-mapping
|
||||
%patch -P252 -p1 -b .pipewire-camera-filter-out-devices-without-capabilities
|
||||
%patch -P253 -p1 -b .always-query-information-about-camera-availability
|
||||
%patch -P254 -p1 -b .always-register-video-input-feedback-for-newly-created-deviceinfo
|
||||
%patch -P255 -p1 -b .pipewire-camera-make-member-variable-with-pipewire-status-updated
|
||||
%patch -P256 -p1 -b .add-missing-support-for-device-change-notifications
|
||||
%patch -P257 -p1 -b .pipewire-camera-get-max-fps-for-each-format-when-specified-as-list
|
||||
%patch -P258 -p1 -b .pipewire-camera-use-exact-stream-parameters-specified-by-capability
|
||||
%patch -P259 -p1 -b .pipewire-camera-use-better-unique-device-name-for-camera-devices
|
||||
|
||||
# ---- Security patches ----
|
||||
|
||||
@ -1730,6 +1771,11 @@ ln -s %{_datadir}/myspell %{buildroot}%{mozappdir}/dictionaries
|
||||
%{__cp} failures-* %{buildroot}/%{version}-%{release}/ || true
|
||||
%endif
|
||||
|
||||
|
||||
%if %{?use_pipewire_camera}
|
||||
echo 'pref("media.webrtc.camera.allow-pipewire", true);' >> %{buildroot}%{mozappdir}/defaults/preferences/all-redhat.js
|
||||
%endif
|
||||
|
||||
# Add distribution.ini
|
||||
%{__mkdir_p} %{buildroot}%{mozappdir}/distribution
|
||||
%{__sed} -e "s/__NAME__/%(source /etc/os-release; echo ${NAME})/g" \
|
||||
@ -1871,6 +1917,11 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
%changelog
|
||||
* Mon Nov 25 2024 Jan Grulich <jgrulich@redhat.com - 128.4.0-2
|
||||
- Enable PipeWire camera support for RHEL 10
|
||||
+ backport upstream fixes for PipeWire camera support
|
||||
Resolves: RHEL-64749
|
||||
|
||||
* Tue Oct 22 2024 Eike Rathke <erack@redhat.com> - 128.4.0-1
|
||||
- Update to 128.4.0 build1
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user