Skip to content

Commit

Permalink
core: Add HDR option, with a stop-gap implementation using V4L2 control
Browse files Browse the repository at this point in the history
Signed-off-by: Nick Hollinghurst <[email protected]>
  • Loading branch information
njhollinghurst authored and naushir committed Jan 4, 2023
1 parent bce2788 commit 4fea2ee
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
37 changes: 37 additions & 0 deletions core/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
*
* options.cpp - common program options helpers
*/
#include <fcntl.h>
#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <algorithm>
#include <iomanip>
#include <iostream>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions core/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string>(&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<bool>(&hdr)->default_value(false)->implicit_value(true),
"Enable (1) or disable (0) High Dynamic Range, where supported")
("metadata", value<std::string>(&metadata),
"Save captured image metadata to a file or \"-\" for stdout")
("metadata-format", value<std::string>(&metadata_format)->default_value("json"),
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 4fea2ee

Please sign in to comment.