From 4fea2eed68300dcc88e89aa30da6079d10dce822 Mon Sep 17 00:00:00 2001 From: Nick Hollinghurst Date: Tue, 3 Jan 2023 18:31:03 +0000 Subject: [PATCH] core: Add HDR option, with a stop-gap implementation using V4L2 control Signed-off-by: Nick Hollinghurst --- core/options.cpp | 37 +++++++++++++++++++++++++++++++++++++ core/options.hpp | 3 +++ 2 files changed, 40 insertions(+) diff --git a/core/options.cpp b/core/options.cpp index ae99b7a0..9e456f42 100644 --- a/core/options.cpp +++ b/core/options.cpp @@ -4,6 +4,10 @@ * * options.cpp - common program options helpers */ +#include +#include +#include +#include #include #include #include @@ -47,6 +51,16 @@ std::string Mode::ToString() const } } +static int xioctl(int fd, unsigned long ctl, void *arg) +{ + int ret, num_tries = 10; + do + { + ret = ioctl(fd, ctl, arg); + } while (ret == -1 && errno == EINTR && num_tries-- > 0); + return ret; +} + bool Options::Parse(int argc, char *argv[]) { using namespace boost::program_options; @@ -79,6 +93,27 @@ bool Options::Parse(int argc, char *argv[]) else if (!lens_position_.empty()) throw std::runtime_error("Invalid lens position: " + lens_position_); + // HDR control. Set this before opening or listing any cameras. + // Currently this does not exist in libcamera, so go directly to V4L2 + // XXX it's not obvious which v4l2-subdev to use for which camera! + { + bool ok = false; + for (int i = 0; i < 4 && !ok; i++) + { + std::string dev("/dev/v4l-subdev"); + dev += (char)('0' + i); + int fd = open(dev.c_str(), O_RDWR, 0); + if (fd < 0) + continue; + + v4l2_control ctrl { V4L2_CID_WIDE_DYNAMIC_RANGE, hdr }; + ok = !xioctl(fd, VIDIOC_S_CTRL, &ctrl); + close(fd); + } + if (hdr && !ok) + LOG_ERROR("WARNING: Unable to set HDR mode"); + } + // Set the verbosity LibcameraApp::verbosity = verbose; @@ -349,6 +384,8 @@ void Options::Print() const << afWindow_height << std::endl; if (!lens_position_.empty()) std::cerr << " lens-position: " << lens_position_ << std::endl; + if (hdr) + std::cerr << " hdr: enabled" << hdr << std::endl; std::cerr << " mode: " << mode.ToString() << std::endl; std::cerr << " viewfinder-mode: " << viewfinder_mode.ToString() << std::endl; if (buffer_count > 0) diff --git a/core/options.hpp b/core/options.hpp index b1ef2a27..09fa3aa1 100644 --- a/core/options.hpp +++ b/core/options.hpp @@ -146,6 +146,8 @@ struct Options "Sets AfMetering to AfMeteringWindows an set region used, e.g. 0.25,0.25,0.5,0.5") ("lens-position", value(&lens_position_)->default_value(""), "Set the lens to a particular focus position, expressed as a reciprocal distance (0 moves the lens to infinity), or \"default\" for the hyperfocal distance") + ("hdr", value(&hdr)->default_value(false)->implicit_value(true), + "Enable (1) or disable (0) High Dynamic Range, where supported") ("metadata", value(&metadata), "Save captured image metadata to a file or \"-\" for stdout") ("metadata-format", value(&metadata_format)->default_value("json"), @@ -221,6 +223,7 @@ struct Options bool af_on_capture; std::string metadata; std::string metadata_format; + bool hdr; virtual bool Parse(int argc, char *argv[]); virtual void Print() const;