git: aca39076bc80 - 2023Q2 - www/{*chromium,iridium}: unbreak webcam support
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 02 May 2023 13:21:44 UTC
The branch 2023Q2 has been updated by rnagy:
URL: https://cgit.FreeBSD.org/ports/commit/?id=aca39076bc80e378f1f9d95d61fa1d4631118eaa
commit aca39076bc80e378f1f9d95d61fa1d4631118eaa
Author: Robert Nagy <rnagy@FreeBSD.org>
AuthorDate: 2023-05-02 13:18:02 +0000
Commit: Robert Nagy <rnagy@FreeBSD.org>
CommitDate: 2023-05-02 13:21:29 +0000
www/{*chromium,iridium}: unbreak webcam support
do not observ for video capture device configuration
as it seems to hang the video capture process
PR: 245250
Approved by: rene (mentor, implicit)
(cherry picked from commit 17b8c1ab3fdb1951f6bb63df8ea9c79db1cdd655)
---
www/chromium/Makefile | 1 +
..._capture_video_linux_v4l2__capture__delegate.cc | 323 ++++++++++++++++++++-
www/iridium/Makefile | 1 +
..._capture_video_linux_v4l2__capture__delegate.cc | 323 ++++++++++++++++++++-
www/ungoogled-chromium/Makefile | 1 +
..._capture_video_linux_v4l2__capture__delegate.cc | 323 ++++++++++++++++++++-
6 files changed, 930 insertions(+), 42 deletions(-)
diff --git a/www/chromium/Makefile b/www/chromium/Makefile
index 1a568a70410a..afd3edd0d6a6 100644
--- a/www/chromium/Makefile
+++ b/www/chromium/Makefile
@@ -1,5 +1,6 @@
PORTNAME= chromium
PORTVERSION= 112.0.5615.165
+PORTREVISION= 1
CATEGORIES= www wayland
MASTER_SITES= https://commondatastorage.googleapis.com/chromium-browser-official/ \
https://nerd.hu/distfiles/:external
diff --git a/www/chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc b/www/chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
index aca534b2857e..e081a554f13d 100644
--- a/www/chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
+++ b/www/chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
@@ -1,30 +1,136 @@
---- media/capture/video/linux/v4l2_capture_delegate.cc.orig 2023-04-05 11:05:06 UTC
+--- media/capture/video/linux/v4l2_capture_delegate.cc.orig 2023-05-02 13:12:51 UTC
+++ media/capture/video/linux/v4l2_capture_delegate.cc
@@ -4,8 +4,10 @@
#include "media/capture/video/linux/v4l2_capture_delegate.h"
-+#if !defined(OS_BSD)
++#if !BUILDFLAG(IS_BSD)
#include <linux/version.h>
#include <linux/videodev2.h>
+#endif
#include <poll.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
-@@ -29,10 +31,10 @@
+@@ -20,7 +22,6 @@
+ #include "base/task/single_thread_task_runner.h"
+ #include "base/trace_event/trace_event.h"
+ #include "build/build_config.h"
+-#include "media/base/bind_to_current_loop.h"
+ #include "media/base/video_frame.h"
+ #include "media/base/video_types.h"
+ #include "media/capture/mojom/image_capture_types.h"
+@@ -29,10 +30,12 @@
using media::mojom::MeteringMode;
--#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
-+// #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
++#if !BUILDFLAG(IS_BSD)
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
// 16 bit depth, Realsense F200.
#define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ')
--#endif
-+// #endif
+ #endif
++#endif
// TODO(aleksandar.stojiljkovic): Wrap this with kernel version check once the
// format is introduced to kernel.
-@@ -728,7 +730,7 @@ base::WeakPtr<V4L2CaptureDelegate> V4L2CaptureDelegate
+@@ -139,47 +142,6 @@ int GetControllingSpecialControl(int control_id) {
+ return 0;
+ }
+
+-// Determines if |control_id| is special, i.e. controls another one's state.
+-bool IsSpecialControl(int control_id) {
+- switch (control_id) {
+- case V4L2_CID_AUTO_WHITE_BALANCE:
+- case V4L2_CID_EXPOSURE_AUTO:
+- case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
+- case V4L2_CID_FOCUS_AUTO:
+- return true;
+- }
+- return false;
+-}
+-
+-// Determines if |control_id| should be skipped, https://crbug.com/697885.
+-#if !defined(V4L2_CID_PAN_SPEED)
+-#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
+-#endif
+-#if !defined(V4L2_CID_TILT_SPEED)
+-#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
+-#endif
+-#if !defined(V4L2_CID_PANTILT_CMD)
+-#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34)
+-#endif
+-bool IsBlockedControl(int control_id) {
+- switch (control_id) {
+- case V4L2_CID_PAN_RELATIVE:
+- case V4L2_CID_TILT_RELATIVE:
+- case V4L2_CID_PAN_RESET:
+- case V4L2_CID_TILT_RESET:
+- case V4L2_CID_PAN_ABSOLUTE:
+- case V4L2_CID_TILT_ABSOLUTE:
+- case V4L2_CID_ZOOM_ABSOLUTE:
+- case V4L2_CID_ZOOM_RELATIVE:
+- case V4L2_CID_ZOOM_CONTINUOUS:
+- case V4L2_CID_PAN_SPEED:
+- case V4L2_CID_TILT_SPEED:
+- case V4L2_CID_PANTILT_CMD:
+- return true;
+- }
+- return false;
+-}
+-
+ bool IsNonEmptyRange(const mojom::RangePtr& range) {
+ return range->min < range->max;
+ }
+@@ -253,6 +215,49 @@ std::vector<uint32_t> V4L2CaptureDelegate::GetListOfUs
+ return supported_formats;
+ }
+
++// Determines if |control_id| is special, i.e. controls another one's state.
++// static
++bool V4L2CaptureDelegate::IsSpecialControl(int control_id) {
++ switch (control_id) {
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ case V4L2_CID_EXPOSURE_AUTO:
++ case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
++ case V4L2_CID_FOCUS_AUTO:
++ return true;
++ }
++ return false;
++}
++
++// Determines if |control_id| should be skipped, https://crbug.com/697885.
++#if !defined(V4L2_CID_PAN_SPEED)
++#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
++#endif
++#if !defined(V4L2_CID_TILT_SPEED)
++#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
++#endif
++#if !defined(V4L2_CID_PANTILT_CMD)
++#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34)
++#endif
++// static
++bool V4L2CaptureDelegate::IsBlockedControl(int control_id) {
++ switch (control_id) {
++ case V4L2_CID_PAN_RELATIVE:
++ case V4L2_CID_TILT_RELATIVE:
++ case V4L2_CID_PAN_RESET:
++ case V4L2_CID_TILT_RESET:
++ case V4L2_CID_PAN_ABSOLUTE:
++ case V4L2_CID_TILT_ABSOLUTE:
++ case V4L2_CID_ZOOM_ABSOLUTE:
++ case V4L2_CID_ZOOM_RELATIVE:
++ case V4L2_CID_ZOOM_CONTINUOUS:
++ case V4L2_CID_PAN_SPEED:
++ case V4L2_CID_TILT_SPEED:
++ case V4L2_CID_PANTILT_CMD:
++ return true;
++ }
++ return false;
++}
++
+ V4L2CaptureDelegate::V4L2CaptureDelegate(
+ V4L2CaptureDevice* v4l2,
+ const VideoCaptureDeviceDescriptor& device_descriptor,
+@@ -728,7 +733,7 @@ base::WeakPtr<V4L2CaptureDelegate> V4L2CaptureDelegate
V4L2CaptureDelegate::~V4L2CaptureDelegate() = default;
@@ -33,7 +139,7 @@
int num_retries = 0;
for (; DoIoctl(request, argp) < 0 && num_retries < kMaxIOCtrlRetries;
++num_retries) {
-@@ -738,7 +740,7 @@ bool V4L2CaptureDelegate::RunIoctl(int request, void*
+@@ -738,7 +743,7 @@ bool V4L2CaptureDelegate::RunIoctl(int request, void*
return num_retries != kMaxIOCtrlRetries;
}
@@ -42,14 +148,11 @@
return HANDLE_EINTR(v4l2_->ioctl(device_fd_.get(), request, argp));
}
-@@ -778,6 +780,10 @@ bool V4L2CaptureDelegate::IsControllableControl(int co
+@@ -778,6 +783,7 @@ bool V4L2CaptureDelegate::IsControllableControl(int co
}
void V4L2CaptureDelegate::ReplaceControlEventSubscriptions() {
-+// these ioctls are not implemented on *BSDs
-+#if BUILDFLAG(IS_BSD)
-+ NOTIMPLEMENTED();
-+#else
++#if !BUILDFLAG(IS_BSD)
constexpr uint32_t kControlIds[] = {V4L2_CID_AUTO_EXPOSURE_BIAS,
V4L2_CID_AUTO_WHITE_BALANCE,
V4L2_CID_BRIGHTNESS,
@@ -61,3 +164,195 @@
}
mojom::RangePtr V4L2CaptureDelegate::RetrieveUserControlRange(int control_id) {
+@@ -829,100 +836,89 @@ mojom::RangePtr V4L2CaptureDelegate::RetrieveUserContr
+ }
+
+ void V4L2CaptureDelegate::ResetUserAndCameraControlsToDefault() {
+- // Set V4L2_CID_AUTO_WHITE_BALANCE to false first.
+- v4l2_control auto_white_balance = {};
+- auto_white_balance.id = V4L2_CID_AUTO_WHITE_BALANCE;
+- auto_white_balance.value = false;
+- if (!RunIoctl(VIDIOC_S_CTRL, &auto_white_balance))
+- return;
+-
+- std::vector<struct v4l2_ext_control> special_camera_controls;
+- // Set V4L2_CID_EXPOSURE_AUTO to V4L2_EXPOSURE_MANUAL.
+- v4l2_ext_control auto_exposure = {};
+- auto_exposure.id = V4L2_CID_EXPOSURE_AUTO;
+- auto_exposure.value = V4L2_EXPOSURE_MANUAL;
+- special_camera_controls.push_back(auto_exposure);
+- // Set V4L2_CID_EXPOSURE_AUTO_PRIORITY to false.
+- v4l2_ext_control priority_auto_exposure = {};
+- priority_auto_exposure.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;
+- priority_auto_exposure.value = false;
+- special_camera_controls.push_back(priority_auto_exposure);
+- // Set V4L2_CID_FOCUS_AUTO to false.
+- v4l2_ext_control auto_focus = {};
+- auto_focus.id = V4L2_CID_FOCUS_AUTO;
+- auto_focus.value = false;
+- special_camera_controls.push_back(auto_focus);
+-
+ struct v4l2_ext_controls ext_controls = {};
+- ext_controls.ctrl_class = V4L2_CID_CAMERA_CLASS;
+- ext_controls.count = special_camera_controls.size();
+- ext_controls.controls = special_camera_controls.data();
+- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0)
+- DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ ext_controls.which = V4L2_CTRL_WHICH_CUR_VAL;
++ ext_controls.count = 0;
++ const bool use_modern_s_ext_ctrls =
++ DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) == 0;
+
+ for (const auto& control : kControls) {
+ std::vector<struct v4l2_ext_control> camera_controls;
++ std::vector<struct v4l2_ext_control> manual_special_camera_controls;
++ std::vector<struct v4l2_ext_control> special_camera_controls;
+
+ v4l2_queryctrl range = {};
+- range.id = control.control_base | V4L2_CTRL_FLAG_NEXT_CTRL;
++ // Start right below the base so that the first next retrieved control ID
++ // is always the first available control ID within the class even if that
++ // control ID is equal to the base (V4L2_CID_BRIGHTNESS equals to
++ // V4L2_CID_USER_BASE).
++ range.id = (control.control_base - 1) | V4L2_CTRL_FLAG_NEXT_CTRL;
+ while (0 == DoIoctl(VIDIOC_QUERYCTRL, &range)) {
+ if (V4L2_CTRL_ID2CLASS(range.id) != V4L2_CTRL_ID2CLASS(control.class_id))
+ break;
++
++ v4l2_ext_control ext_control = {};
++ ext_control.id = range.id;
++ ext_control.value = range.default_value;
++
++ // Prepare to query for the next control as `range` is an in-out
++ // parameter.
+ range.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+
+- if (IsSpecialControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL))
++ if (range.flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_READ_ONLY)) {
++ // Permanently disabled or permanently read-only.
+ continue;
+- if (IsBlockedControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL))
++ }
++ if (IsBlockedControl(ext_control.id)) {
+ continue;
++ }
+
+- struct v4l2_ext_control ext_control = {};
+- ext_control.id = range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
+- ext_control.value = range.default_value;
+- camera_controls.push_back(ext_control);
++ if (IsSpecialControl(ext_control.id)) {
++ special_camera_controls.push_back(ext_control);
++ if (ext_control.id == V4L2_CID_EXPOSURE_AUTO) {
++ ext_control.value = V4L2_EXPOSURE_MANUAL;
++ } else {
++ ext_control.value = false; // Not automatic but manual.
++ }
++ manual_special_camera_controls.push_back(ext_control);
++ } else {
++ camera_controls.push_back(ext_control);
++ }
+ }
+
+ if (!camera_controls.empty()) {
+- struct v4l2_ext_controls ext_controls2 = {};
+- ext_controls2.ctrl_class = control.class_id;
+- ext_controls2.count = camera_controls.size();
+- ext_controls2.controls = camera_controls.data();
+- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls2) < 0)
++ // Set special controls to manual modes first.
++ if (!manual_special_camera_controls.empty()) {
++ ext_controls.which =
++ use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id;
++ ext_controls.count = manual_special_camera_controls.size();
++ ext_controls.controls = manual_special_camera_controls.data();
++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) {
++ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ }
++ }
++
++ // Set non-special controls to the default values.
++ ext_controls.which =
++ use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id;
++ ext_controls.count = camera_controls.size();
++ ext_controls.controls = camera_controls.data();
++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) {
+ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ }
+ }
+- }
+
+- // Now set the special flags to the default values
+- v4l2_queryctrl range = {};
+- range.id = V4L2_CID_AUTO_WHITE_BALANCE;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- auto_white_balance.value = range.default_value;
+- DoIoctl(VIDIOC_S_CTRL, &auto_white_balance);
+-
+- special_camera_controls.clear();
+- memset(&range, 0, sizeof(range));
+- range.id = V4L2_CID_EXPOSURE_AUTO;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- auto_exposure.value = range.default_value;
+- special_camera_controls.push_back(auto_exposure);
+-
+- memset(&range, 0, sizeof(range));
+- range.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- priority_auto_exposure.value = range.default_value;
+- special_camera_controls.push_back(priority_auto_exposure);
+-
+- memset(&range, 0, sizeof(range));
+- range.id = V4L2_CID_FOCUS_AUTO;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- auto_focus.value = range.default_value;
+- special_camera_controls.push_back(auto_focus);
+-
+- memset(&ext_controls, 0, sizeof(ext_controls));
+- ext_controls.ctrl_class = V4L2_CID_CAMERA_CLASS;
+- ext_controls.count = special_camera_controls.size();
+- ext_controls.controls = special_camera_controls.data();
+- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0)
+- DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ // Set special controls to the default values.
++ if (!special_camera_controls.empty()) {
++ ext_controls.which =
++ use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id;
++ ext_controls.count = special_camera_controls.size();
++ ext_controls.controls = special_camera_controls.data();
++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) {
++ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ }
++ }
++ }
+ }
+
+ bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) {
+@@ -985,7 +981,11 @@ void V4L2CaptureDelegate::DoCapture() {
+
+ pollfd device_pfd = {};
+ device_pfd.fd = device_fd_.get();
++#if !BUILDFLAG(IS_BSD)
+ device_pfd.events = POLLIN | POLLPRI;
++#else
++ device_pfd.events = POLLIN;
++#endif
+
+ const int result =
+ HANDLE_EINTR(v4l2_->poll(&device_pfd, 1, kCaptureTimeoutMs));
+@@ -1023,6 +1023,7 @@ void V4L2CaptureDelegate::DoCapture() {
+ timeout_count_ = 0;
+ }
+
++#if !BUILDFLAG(IS_BSD)
+ // Dequeue events if the driver has filled in some.
+ if (device_pfd.revents & POLLPRI) {
+ bool controls_changed = false;
+@@ -1057,6 +1058,7 @@ void V4L2CaptureDelegate::DoCapture() {
+ client_->OnCaptureConfigurationChanged();
+ }
+ }
++#endif
+
+ // Deenqueue, send and reenqueue a buffer if the driver has filled one in.
+ if (device_pfd.revents & POLLIN) {
diff --git a/www/iridium/Makefile b/www/iridium/Makefile
index d1053b9cbcff..b234d222a8d9 100644
--- a/www/iridium/Makefile
+++ b/www/iridium/Makefile
@@ -1,5 +1,6 @@
PORTNAME= iridium
PORTVERSION= 2023.04.112.2
+PORTREVISION= 1
CATEGORIES= www wayland
MASTER_SITES= https://downloads.iridiumbrowser.de/source/
PKGNAMESUFFIX= -browser
diff --git a/www/iridium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc b/www/iridium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
index 8662b6dde53c..e081a554f13d 100644
--- a/www/iridium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
+++ b/www/iridium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
@@ -1,30 +1,136 @@
---- media/capture/video/linux/v4l2_capture_delegate.cc.orig 2023-04-22 17:45:15 UTC
+--- media/capture/video/linux/v4l2_capture_delegate.cc.orig 2023-05-02 13:12:51 UTC
+++ media/capture/video/linux/v4l2_capture_delegate.cc
@@ -4,8 +4,10 @@
#include "media/capture/video/linux/v4l2_capture_delegate.h"
-+#if !defined(OS_BSD)
++#if !BUILDFLAG(IS_BSD)
#include <linux/version.h>
#include <linux/videodev2.h>
+#endif
#include <poll.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
-@@ -29,10 +31,10 @@
+@@ -20,7 +22,6 @@
+ #include "base/task/single_thread_task_runner.h"
+ #include "base/trace_event/trace_event.h"
+ #include "build/build_config.h"
+-#include "media/base/bind_to_current_loop.h"
+ #include "media/base/video_frame.h"
+ #include "media/base/video_types.h"
+ #include "media/capture/mojom/image_capture_types.h"
+@@ -29,10 +30,12 @@
using media::mojom::MeteringMode;
--#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
-+// #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
++#if !BUILDFLAG(IS_BSD)
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
// 16 bit depth, Realsense F200.
#define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ')
--#endif
-+// #endif
+ #endif
++#endif
// TODO(aleksandar.stojiljkovic): Wrap this with kernel version check once the
// format is introduced to kernel.
-@@ -728,7 +730,7 @@ base::WeakPtr<V4L2CaptureDelegate> V4L2CaptureDelegate
+@@ -139,47 +142,6 @@ int GetControllingSpecialControl(int control_id) {
+ return 0;
+ }
+
+-// Determines if |control_id| is special, i.e. controls another one's state.
+-bool IsSpecialControl(int control_id) {
+- switch (control_id) {
+- case V4L2_CID_AUTO_WHITE_BALANCE:
+- case V4L2_CID_EXPOSURE_AUTO:
+- case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
+- case V4L2_CID_FOCUS_AUTO:
+- return true;
+- }
+- return false;
+-}
+-
+-// Determines if |control_id| should be skipped, https://crbug.com/697885.
+-#if !defined(V4L2_CID_PAN_SPEED)
+-#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
+-#endif
+-#if !defined(V4L2_CID_TILT_SPEED)
+-#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
+-#endif
+-#if !defined(V4L2_CID_PANTILT_CMD)
+-#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34)
+-#endif
+-bool IsBlockedControl(int control_id) {
+- switch (control_id) {
+- case V4L2_CID_PAN_RELATIVE:
+- case V4L2_CID_TILT_RELATIVE:
+- case V4L2_CID_PAN_RESET:
+- case V4L2_CID_TILT_RESET:
+- case V4L2_CID_PAN_ABSOLUTE:
+- case V4L2_CID_TILT_ABSOLUTE:
+- case V4L2_CID_ZOOM_ABSOLUTE:
+- case V4L2_CID_ZOOM_RELATIVE:
+- case V4L2_CID_ZOOM_CONTINUOUS:
+- case V4L2_CID_PAN_SPEED:
+- case V4L2_CID_TILT_SPEED:
+- case V4L2_CID_PANTILT_CMD:
+- return true;
+- }
+- return false;
+-}
+-
+ bool IsNonEmptyRange(const mojom::RangePtr& range) {
+ return range->min < range->max;
+ }
+@@ -253,6 +215,49 @@ std::vector<uint32_t> V4L2CaptureDelegate::GetListOfUs
+ return supported_formats;
+ }
+
++// Determines if |control_id| is special, i.e. controls another one's state.
++// static
++bool V4L2CaptureDelegate::IsSpecialControl(int control_id) {
++ switch (control_id) {
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ case V4L2_CID_EXPOSURE_AUTO:
++ case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
++ case V4L2_CID_FOCUS_AUTO:
++ return true;
++ }
++ return false;
++}
++
++// Determines if |control_id| should be skipped, https://crbug.com/697885.
++#if !defined(V4L2_CID_PAN_SPEED)
++#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
++#endif
++#if !defined(V4L2_CID_TILT_SPEED)
++#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
++#endif
++#if !defined(V4L2_CID_PANTILT_CMD)
++#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34)
++#endif
++// static
++bool V4L2CaptureDelegate::IsBlockedControl(int control_id) {
++ switch (control_id) {
++ case V4L2_CID_PAN_RELATIVE:
++ case V4L2_CID_TILT_RELATIVE:
++ case V4L2_CID_PAN_RESET:
++ case V4L2_CID_TILT_RESET:
++ case V4L2_CID_PAN_ABSOLUTE:
++ case V4L2_CID_TILT_ABSOLUTE:
++ case V4L2_CID_ZOOM_ABSOLUTE:
++ case V4L2_CID_ZOOM_RELATIVE:
++ case V4L2_CID_ZOOM_CONTINUOUS:
++ case V4L2_CID_PAN_SPEED:
++ case V4L2_CID_TILT_SPEED:
++ case V4L2_CID_PANTILT_CMD:
++ return true;
++ }
++ return false;
++}
++
+ V4L2CaptureDelegate::V4L2CaptureDelegate(
+ V4L2CaptureDevice* v4l2,
+ const VideoCaptureDeviceDescriptor& device_descriptor,
+@@ -728,7 +733,7 @@ base::WeakPtr<V4L2CaptureDelegate> V4L2CaptureDelegate
V4L2CaptureDelegate::~V4L2CaptureDelegate() = default;
@@ -33,7 +139,7 @@
int num_retries = 0;
for (; DoIoctl(request, argp) < 0 && num_retries < kMaxIOCtrlRetries;
++num_retries) {
-@@ -738,7 +740,7 @@ bool V4L2CaptureDelegate::RunIoctl(int request, void*
+@@ -738,7 +743,7 @@ bool V4L2CaptureDelegate::RunIoctl(int request, void*
return num_retries != kMaxIOCtrlRetries;
}
@@ -42,14 +148,11 @@
return HANDLE_EINTR(v4l2_->ioctl(device_fd_.get(), request, argp));
}
-@@ -778,6 +780,10 @@ bool V4L2CaptureDelegate::IsControllableControl(int co
+@@ -778,6 +783,7 @@ bool V4L2CaptureDelegate::IsControllableControl(int co
}
void V4L2CaptureDelegate::ReplaceControlEventSubscriptions() {
-+// these ioctls are not implemented on *BSDs
-+#if BUILDFLAG(IS_BSD)
-+ NOTIMPLEMENTED();
-+#else
++#if !BUILDFLAG(IS_BSD)
constexpr uint32_t kControlIds[] = {V4L2_CID_AUTO_EXPOSURE_BIAS,
V4L2_CID_AUTO_WHITE_BALANCE,
V4L2_CID_BRIGHTNESS,
@@ -61,3 +164,195 @@
}
mojom::RangePtr V4L2CaptureDelegate::RetrieveUserControlRange(int control_id) {
+@@ -829,100 +836,89 @@ mojom::RangePtr V4L2CaptureDelegate::RetrieveUserContr
+ }
+
+ void V4L2CaptureDelegate::ResetUserAndCameraControlsToDefault() {
+- // Set V4L2_CID_AUTO_WHITE_BALANCE to false first.
+- v4l2_control auto_white_balance = {};
+- auto_white_balance.id = V4L2_CID_AUTO_WHITE_BALANCE;
+- auto_white_balance.value = false;
+- if (!RunIoctl(VIDIOC_S_CTRL, &auto_white_balance))
+- return;
+-
+- std::vector<struct v4l2_ext_control> special_camera_controls;
+- // Set V4L2_CID_EXPOSURE_AUTO to V4L2_EXPOSURE_MANUAL.
+- v4l2_ext_control auto_exposure = {};
+- auto_exposure.id = V4L2_CID_EXPOSURE_AUTO;
+- auto_exposure.value = V4L2_EXPOSURE_MANUAL;
+- special_camera_controls.push_back(auto_exposure);
+- // Set V4L2_CID_EXPOSURE_AUTO_PRIORITY to false.
+- v4l2_ext_control priority_auto_exposure = {};
+- priority_auto_exposure.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;
+- priority_auto_exposure.value = false;
+- special_camera_controls.push_back(priority_auto_exposure);
+- // Set V4L2_CID_FOCUS_AUTO to false.
+- v4l2_ext_control auto_focus = {};
+- auto_focus.id = V4L2_CID_FOCUS_AUTO;
+- auto_focus.value = false;
+- special_camera_controls.push_back(auto_focus);
+-
+ struct v4l2_ext_controls ext_controls = {};
+- ext_controls.ctrl_class = V4L2_CID_CAMERA_CLASS;
+- ext_controls.count = special_camera_controls.size();
+- ext_controls.controls = special_camera_controls.data();
+- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0)
+- DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ ext_controls.which = V4L2_CTRL_WHICH_CUR_VAL;
++ ext_controls.count = 0;
++ const bool use_modern_s_ext_ctrls =
++ DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) == 0;
+
+ for (const auto& control : kControls) {
+ std::vector<struct v4l2_ext_control> camera_controls;
++ std::vector<struct v4l2_ext_control> manual_special_camera_controls;
++ std::vector<struct v4l2_ext_control> special_camera_controls;
+
+ v4l2_queryctrl range = {};
+- range.id = control.control_base | V4L2_CTRL_FLAG_NEXT_CTRL;
++ // Start right below the base so that the first next retrieved control ID
++ // is always the first available control ID within the class even if that
++ // control ID is equal to the base (V4L2_CID_BRIGHTNESS equals to
++ // V4L2_CID_USER_BASE).
++ range.id = (control.control_base - 1) | V4L2_CTRL_FLAG_NEXT_CTRL;
+ while (0 == DoIoctl(VIDIOC_QUERYCTRL, &range)) {
+ if (V4L2_CTRL_ID2CLASS(range.id) != V4L2_CTRL_ID2CLASS(control.class_id))
+ break;
++
++ v4l2_ext_control ext_control = {};
++ ext_control.id = range.id;
++ ext_control.value = range.default_value;
++
++ // Prepare to query for the next control as `range` is an in-out
++ // parameter.
+ range.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+
+- if (IsSpecialControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL))
++ if (range.flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_READ_ONLY)) {
++ // Permanently disabled or permanently read-only.
+ continue;
+- if (IsBlockedControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL))
++ }
++ if (IsBlockedControl(ext_control.id)) {
+ continue;
++ }
+
+- struct v4l2_ext_control ext_control = {};
+- ext_control.id = range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
+- ext_control.value = range.default_value;
+- camera_controls.push_back(ext_control);
++ if (IsSpecialControl(ext_control.id)) {
++ special_camera_controls.push_back(ext_control);
++ if (ext_control.id == V4L2_CID_EXPOSURE_AUTO) {
++ ext_control.value = V4L2_EXPOSURE_MANUAL;
++ } else {
++ ext_control.value = false; // Not automatic but manual.
++ }
++ manual_special_camera_controls.push_back(ext_control);
++ } else {
++ camera_controls.push_back(ext_control);
++ }
+ }
+
+ if (!camera_controls.empty()) {
+- struct v4l2_ext_controls ext_controls2 = {};
+- ext_controls2.ctrl_class = control.class_id;
+- ext_controls2.count = camera_controls.size();
+- ext_controls2.controls = camera_controls.data();
+- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls2) < 0)
++ // Set special controls to manual modes first.
++ if (!manual_special_camera_controls.empty()) {
++ ext_controls.which =
++ use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id;
++ ext_controls.count = manual_special_camera_controls.size();
++ ext_controls.controls = manual_special_camera_controls.data();
++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) {
++ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ }
++ }
++
++ // Set non-special controls to the default values.
++ ext_controls.which =
++ use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id;
++ ext_controls.count = camera_controls.size();
++ ext_controls.controls = camera_controls.data();
++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) {
+ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ }
+ }
+- }
+
+- // Now set the special flags to the default values
+- v4l2_queryctrl range = {};
+- range.id = V4L2_CID_AUTO_WHITE_BALANCE;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- auto_white_balance.value = range.default_value;
+- DoIoctl(VIDIOC_S_CTRL, &auto_white_balance);
+-
+- special_camera_controls.clear();
+- memset(&range, 0, sizeof(range));
+- range.id = V4L2_CID_EXPOSURE_AUTO;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- auto_exposure.value = range.default_value;
+- special_camera_controls.push_back(auto_exposure);
+-
+- memset(&range, 0, sizeof(range));
+- range.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- priority_auto_exposure.value = range.default_value;
+- special_camera_controls.push_back(priority_auto_exposure);
+-
+- memset(&range, 0, sizeof(range));
+- range.id = V4L2_CID_FOCUS_AUTO;
+- DoIoctl(VIDIOC_QUERYCTRL, &range);
+- auto_focus.value = range.default_value;
+- special_camera_controls.push_back(auto_focus);
+-
+- memset(&ext_controls, 0, sizeof(ext_controls));
+- ext_controls.ctrl_class = V4L2_CID_CAMERA_CLASS;
+- ext_controls.count = special_camera_controls.size();
+- ext_controls.controls = special_camera_controls.data();
+- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0)
+- DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ // Set special controls to the default values.
++ if (!special_camera_controls.empty()) {
++ ext_controls.which =
++ use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id;
++ ext_controls.count = special_camera_controls.size();
++ ext_controls.controls = special_camera_controls.data();
++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) {
++ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS";
++ }
++ }
++ }
+ }
+
+ bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) {
+@@ -985,7 +981,11 @@ void V4L2CaptureDelegate::DoCapture() {
+
+ pollfd device_pfd = {};
+ device_pfd.fd = device_fd_.get();
++#if !BUILDFLAG(IS_BSD)
+ device_pfd.events = POLLIN | POLLPRI;
++#else
++ device_pfd.events = POLLIN;
++#endif
+
+ const int result =
+ HANDLE_EINTR(v4l2_->poll(&device_pfd, 1, kCaptureTimeoutMs));
+@@ -1023,6 +1023,7 @@ void V4L2CaptureDelegate::DoCapture() {
+ timeout_count_ = 0;
+ }
+
++#if !BUILDFLAG(IS_BSD)
+ // Dequeue events if the driver has filled in some.
+ if (device_pfd.revents & POLLPRI) {
+ bool controls_changed = false;
+@@ -1057,6 +1058,7 @@ void V4L2CaptureDelegate::DoCapture() {
+ client_->OnCaptureConfigurationChanged();
+ }
+ }
++#endif
+
+ // Deenqueue, send and reenqueue a buffer if the driver has filled one in.
+ if (device_pfd.revents & POLLIN) {
diff --git a/www/ungoogled-chromium/Makefile b/www/ungoogled-chromium/Makefile
index 11e19e01f2c7..43d5ecd055af 100644
--- a/www/ungoogled-chromium/Makefile
+++ b/www/ungoogled-chromium/Makefile
@@ -1,6 +1,7 @@
PORTNAME= ungoogled-chromium
PORTVERSION= 112.0.5615.165
UGVERSION= ${DISTVERSION}-1
+PORTREVISION= 1
CATEGORIES= www wayland
MASTER_SITES= https://commondatastorage.googleapis.com/chromium-browser-official/ \
https://nerd.hu/distfiles/:external
diff --git a/www/ungoogled-chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc b/www/ungoogled-chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
index b1ce7e967652..e081a554f13d 100644
--- a/www/ungoogled-chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
+++ b/www/ungoogled-chromium/files/patch-media_capture_video_linux_v4l2__capture__delegate.cc
@@ -1,30 +1,136 @@
---- media/capture/video/linux/v4l2_capture_delegate.cc.orig 2023-04-08 11:38:38 UTC
+--- media/capture/video/linux/v4l2_capture_delegate.cc.orig 2023-05-02 13:12:51 UTC
+++ media/capture/video/linux/v4l2_capture_delegate.cc
@@ -4,8 +4,10 @@
#include "media/capture/video/linux/v4l2_capture_delegate.h"
-+#if !defined(OS_BSD)
++#if !BUILDFLAG(IS_BSD)
#include <linux/version.h>
#include <linux/videodev2.h>
+#endif
#include <poll.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
-@@ -29,10 +31,10 @@
+@@ -20,7 +22,6 @@
+ #include "base/task/single_thread_task_runner.h"
+ #include "base/trace_event/trace_event.h"
+ #include "build/build_config.h"
+-#include "media/base/bind_to_current_loop.h"
+ #include "media/base/video_frame.h"
+ #include "media/base/video_types.h"
+ #include "media/capture/mojom/image_capture_types.h"
+@@ -29,10 +30,12 @@
using media::mojom::MeteringMode;
--#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
-+// #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
++#if !BUILDFLAG(IS_BSD)
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
// 16 bit depth, Realsense F200.
#define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ')
--#endif
-+// #endif
+ #endif
++#endif
// TODO(aleksandar.stojiljkovic): Wrap this with kernel version check once the
// format is introduced to kernel.
-@@ -728,7 +730,7 @@ base::WeakPtr<V4L2CaptureDelegate> V4L2CaptureDelegate
+@@ -139,47 +142,6 @@ int GetControllingSpecialControl(int control_id) {
+ return 0;
+ }
+
+-// Determines if |control_id| is special, i.e. controls another one's state.
+-bool IsSpecialControl(int control_id) {
+- switch (control_id) {
+- case V4L2_CID_AUTO_WHITE_BALANCE:
+- case V4L2_CID_EXPOSURE_AUTO:
+- case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
+- case V4L2_CID_FOCUS_AUTO:
+- return true;
+- }
+- return false;
+-}
+-
+-// Determines if |control_id| should be skipped, https://crbug.com/697885.
+-#if !defined(V4L2_CID_PAN_SPEED)
+-#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
+-#endif
+-#if !defined(V4L2_CID_TILT_SPEED)
+-#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
+-#endif
+-#if !defined(V4L2_CID_PANTILT_CMD)
+-#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34)
+-#endif
+-bool IsBlockedControl(int control_id) {
+- switch (control_id) {
+- case V4L2_CID_PAN_RELATIVE:
+- case V4L2_CID_TILT_RELATIVE:
+- case V4L2_CID_PAN_RESET:
+- case V4L2_CID_TILT_RESET:
+- case V4L2_CID_PAN_ABSOLUTE:
+- case V4L2_CID_TILT_ABSOLUTE:
+- case V4L2_CID_ZOOM_ABSOLUTE:
+- case V4L2_CID_ZOOM_RELATIVE:
+- case V4L2_CID_ZOOM_CONTINUOUS:
+- case V4L2_CID_PAN_SPEED:
+- case V4L2_CID_TILT_SPEED:
+- case V4L2_CID_PANTILT_CMD:
+- return true;
+- }
+- return false;
+-}
+-
+ bool IsNonEmptyRange(const mojom::RangePtr& range) {
+ return range->min < range->max;
+ }
+@@ -253,6 +215,49 @@ std::vector<uint32_t> V4L2CaptureDelegate::GetListOfUs
+ return supported_formats;
+ }
+
++// Determines if |control_id| is special, i.e. controls another one's state.
++// static
++bool V4L2CaptureDelegate::IsSpecialControl(int control_id) {
++ switch (control_id) {
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ case V4L2_CID_EXPOSURE_AUTO:
++ case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
++ case V4L2_CID_FOCUS_AUTO:
++ return true;
++ }
++ return false;
++}
++
++// Determines if |control_id| should be skipped, https://crbug.com/697885.
++#if !defined(V4L2_CID_PAN_SPEED)
++#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
++#endif
++#if !defined(V4L2_CID_TILT_SPEED)
++#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
++#endif
++#if !defined(V4L2_CID_PANTILT_CMD)
++#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34)
++#endif
++// static
++bool V4L2CaptureDelegate::IsBlockedControl(int control_id) {
++ switch (control_id) {
++ case V4L2_CID_PAN_RELATIVE:
++ case V4L2_CID_TILT_RELATIVE:
++ case V4L2_CID_PAN_RESET:
++ case V4L2_CID_TILT_RESET:
++ case V4L2_CID_PAN_ABSOLUTE:
++ case V4L2_CID_TILT_ABSOLUTE:
++ case V4L2_CID_ZOOM_ABSOLUTE:
++ case V4L2_CID_ZOOM_RELATIVE:
++ case V4L2_CID_ZOOM_CONTINUOUS:
++ case V4L2_CID_PAN_SPEED:
++ case V4L2_CID_TILT_SPEED:
++ case V4L2_CID_PANTILT_CMD:
++ return true;
++ }
++ return false;
++}
++
+ V4L2CaptureDelegate::V4L2CaptureDelegate(
+ V4L2CaptureDevice* v4l2,
+ const VideoCaptureDeviceDescriptor& device_descriptor,
+@@ -728,7 +733,7 @@ base::WeakPtr<V4L2CaptureDelegate> V4L2CaptureDelegate
V4L2CaptureDelegate::~V4L2CaptureDelegate() = default;
@@ -33,7 +139,7 @@
int num_retries = 0;
for (; DoIoctl(request, argp) < 0 && num_retries < kMaxIOCtrlRetries;
++num_retries) {
-@@ -738,7 +740,7 @@ bool V4L2CaptureDelegate::RunIoctl(int request, void*
+@@ -738,7 +743,7 @@ bool V4L2CaptureDelegate::RunIoctl(int request, void*
return num_retries != kMaxIOCtrlRetries;
}
@@ -42,14 +148,11 @@
return HANDLE_EINTR(v4l2_->ioctl(device_fd_.get(), request, argp));
}
-@@ -778,6 +780,10 @@ bool V4L2CaptureDelegate::IsControllableControl(int co
+@@ -778,6 +783,7 @@ bool V4L2CaptureDelegate::IsControllableControl(int co
}
void V4L2CaptureDelegate::ReplaceControlEventSubscriptions() {
-+// these ioctls are not implemented on *BSDs
-+#if BUILDFLAG(IS_BSD)
-+ NOTIMPLEMENTED();
-+#else
++#if !BUILDFLAG(IS_BSD)
constexpr uint32_t kControlIds[] = {V4L2_CID_AUTO_EXPOSURE_BIAS,
V4L2_CID_AUTO_WHITE_BALANCE,
V4L2_CID_BRIGHTNESS,
@@ -61,3 +164,195 @@
}
mojom::RangePtr V4L2CaptureDelegate::RetrieveUserControlRange(int control_id) {
+@@ -829,100 +836,89 @@ mojom::RangePtr V4L2CaptureDelegate::RetrieveUserContr
+ }
+
+ void V4L2CaptureDelegate::ResetUserAndCameraControlsToDefault() {
*** 188 LINES SKIPPED ***