mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
libcamera: Default to auto-focus & auto-exposure
libcamera says that cameras should default to manual focus mode. This means that unless pipewire clients specifically change this control, users with an autofocus-capable camera are left with an out-of-focus image. This patch sets the autofocus mode to continuous and enables auto-exposure (as the default for this is unspecified). Testing with an imx708 on Raspberry Pi OS on a Raspberry Pi 4, before this patch the image was generally out of focus in Firefox/webrtc, after this patch autofocus works correctly.
This commit is contained in:
parent
82229b3d87
commit
3a0ffe21e6
2 changed files with 29 additions and 1 deletions
|
|
@ -163,6 +163,7 @@ struct impl {
|
|||
struct spa_source source = {};
|
||||
|
||||
ControlList ctrls;
|
||||
ControlList initial_controls;
|
||||
bool active = false;
|
||||
bool acquired = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,30 @@
|
|||
#include <linux/media.h>
|
||||
#include <libcamera/control_ids.h>
|
||||
|
||||
static void setup_initial_controls(const ControlInfoMap& ctrl_infos, ControlList& ctrls)
|
||||
{
|
||||
/* Libcamera recommends cameras default to manual focus mode, but we don't
|
||||
* expose any focus controls. So, specifically enable autofocus on
|
||||
* cameras which support it. */
|
||||
auto af_it = ctrl_infos.find(libcamera::controls::AF_MODE);
|
||||
if (af_it != ctrl_infos.end()) {
|
||||
const ControlInfo &ctrl_info = af_it->second;
|
||||
auto is_af_continuous = [](const ControlValue &value) {
|
||||
return value.get<int32_t>() == libcamera::controls::AfModeContinuous;
|
||||
};
|
||||
if (std::any_of(ctrl_info.values().begin(),
|
||||
ctrl_info.values().end(), is_af_continuous)) {
|
||||
ctrls.set(libcamera::controls::AF_MODE,
|
||||
libcamera::controls::AfModeContinuous);
|
||||
}
|
||||
}
|
||||
|
||||
auto ae_it = ctrl_infos.find(libcamera::controls::AE_ENABLE);
|
||||
if (ae_it != ctrl_infos.end()) {
|
||||
ctrls.set(libcamera::controls::AE_ENABLE, true);
|
||||
}
|
||||
}
|
||||
|
||||
int spa_libcamera_open(struct impl *impl)
|
||||
{
|
||||
if (impl->acquired)
|
||||
|
|
@ -26,6 +50,9 @@ int spa_libcamera_open(struct impl *impl)
|
|||
|
||||
impl->allocator = new FrameBufferAllocator(impl->camera);
|
||||
|
||||
const ControlInfoMap &controls = impl->camera->controls();
|
||||
setup_initial_controls(controls, impl->initial_controls);
|
||||
|
||||
impl->acquired = true;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -990,7 +1017,7 @@ static int spa_libcamera_stream_on(struct impl *impl)
|
|||
impl->camera->requestCompleted.connect(impl, &impl::requestComplete);
|
||||
|
||||
spa_log_info(impl->log, "starting camera %s", impl->device_id.c_str());
|
||||
if ((res = impl->camera->start()) < 0)
|
||||
if ((res = impl->camera->start(&impl->initial_controls)) < 0)
|
||||
goto error;
|
||||
|
||||
for (Request *req : impl->pendingRequests) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue