Allow to configure controls

This commit is contained in:
Kamil Trzcinski 2022-04-11 12:42:17 +02:00
parent 9eeee04560
commit 8adcd67569
6 changed files with 101 additions and 38 deletions

View File

@ -38,7 +38,6 @@ void libcamera_device_close(device_t *dev)
{
if (dev->libcamera) {
if (dev->libcamera->camera) {
dev->libcamera->camera->stop();
dev->libcamera->camera->release();
}
@ -47,23 +46,73 @@ void libcamera_device_close(device_t *dev)
}
}
int libcamera_device_set_decoder_start(device_t *dev, bool do_on)
{
return -1;
}
int libcamera_device_video_force_key(device_t *dev)
{
return -1;
}
int libcamera_device_set_fps(device_t *dev, int desired_fps)
{
int64_t frame_time = 1000000 / desired_fps;
dev->libcamera->controls.set(libcamera::controls::FrameDurationLimits, { frame_time, frame_time });
return -1;
}
int libcamera_device_set_option(device_t *dev, const char *key, const char *value)
std::string libcamera_device_option_normalize(std::string key)
{
key.resize(device_option_normalize_name(key.data(), key.data()));
return key;
}
int libcamera_device_set_option(device_t *dev, const char *keyp, const char *value)
{
auto key = libcamera_device_option_normalize(keyp);
for (auto const &control : dev->libcamera->camera->controls()) {
if (!control.first)
continue;
auto control_id = control.first;
auto control_key = libcamera_device_option_normalize(control_id->name());
if (key != control_key)
continue;
libcamera::ControlValue control_value;
switch (control_id->type()) {
case libcamera::ControlTypeBool:
control_value.set<bool>(atoi(value));
break;
case libcamera::ControlTypeByte:
control_value.set<unsigned char>(atoi(value));
break;
case libcamera::ControlTypeInteger32:
control_value.set<int32_t>(atoi(value));
break;
case libcamera::ControlTypeInteger64:
control_value.set<int64_t>(atoi(value));
break;
case libcamera::ControlTypeFloat:
control_value.set<float>(atof(value));
break;
case libcamera::ControlTypeString:
case libcamera::ControlTypeRectangle:
case libcamera::ControlTypeSize:
break;
}
if (control_value.isNone()) {
E_LOG_ERROR(dev, "The `%s` type `%d` is not supported.", control_key.c_str(), control_id->type());
}
E_LOG_INFO(dev, "Configuring option %s (%08x, type=%d) = %s",
control_key.c_str(), control_id->id(), control_id->type(),
control_value.toString().c_str());
dev->libcamera->controls.set(control_id->id(), control_value);
return 0;
}
error:
return -1;
}
#endif // USE_LIBCAMERA

View File

@ -4,8 +4,6 @@
device_hw_t libcamera_device_hw = {
.device_open = libcamera_device_open,
.device_close = libcamera_device_close,
.device_set_decoder_start = libcamera_device_set_decoder_start,
.device_video_force_key = libcamera_device_video_force_key,
.device_set_fps = libcamera_device_set_fps,
.device_set_option = libcamera_device_set_option,

View File

@ -12,6 +12,7 @@ extern "C" {
#include "device/buffer.h"
#include "opts/log.h"
#include "opts/fourcc.h"
#include "opts/control.h"
};
#ifdef USE_LIBCAMERA
@ -38,6 +39,7 @@ struct pollfd;
typedef struct device_libcamera_s {
std::shared_ptr<libcamera::CameraManager> camera_manager;
std::shared_ptr<libcamera::Camera> camera;
libcamera::ControlList controls;
} device_libcamera_t;
typedef struct buffer_list_libcamera_s {
@ -55,8 +57,6 @@ typedef struct buffer_libcamera_s {
int libcamera_device_open(device_t *dev);
void libcamera_device_close(device_t *dev);
int libcamera_device_set_decoder_start(device_t *dev, bool do_on);
int libcamera_device_video_force_key(device_t *dev);
int libcamera_device_set_fps(device_t *dev, int desired_fps);
int libcamera_device_set_option(device_t *dev, const char *key, const char *value);

View File

@ -1,8 +1,7 @@
#include "v4l2.h"
#include "device/device.h"
#include "opts/log.h"
#include <ctype.h>
#include "opts/control.h"
int v4l2_device_set_option_by_id(device_t *dev, const char *name, uint32_t id, int32_t value)
{
@ -21,24 +20,6 @@ error:
return -1;
}
void v4l2_device_option_normalize_name(char *in)
{
char *out = in;
while (*in) {
if (isalnum(*in)) {
*out++ = tolower(*in++);
} else if (isprint(*in)) {
*out++ = '_';
while (*++in && isprint(*in) && !isalnum(*in));
} else {
in++;
}
}
*out++ = 0;
}
static int v4l2_device_set_option_string_fd_iter_id(device_t *dev, int fd, uint32_t *id, char *name, char *value)
{
struct v4l2_query_ext_ctrl qctrl = { .id = *id };
@ -50,7 +31,7 @@ static int v4l2_device_set_option_string_fd_iter_id(device_t *dev, int fd, uint3
}
*id = qctrl.id;
v4l2_device_option_normalize_name(qctrl.name);
device_option_normalize_name(qctrl.name, qctrl.name);
if (strcmp(qctrl.name, name) != 0)
return 0;
@ -150,7 +131,7 @@ int v4l2_device_set_option(device_t *dev, const char *key, const char *value)
int ret = 0;
v4l2_device_option_normalize_name(keyp);
device_option_normalize_name(keyp, keyp);
if (dev->v4l2->subdev_fd >= 0)
ret = v4l2_device_set_option_string_fd(dev, dev->v4l2->subdev_fd, keyp, valuep);

34
opts/control.c Normal file
View File

@ -0,0 +1,34 @@
#include "control.h"
#include <ctype.h>
#include <stdbool.h>
int device_option_normalize_name(const char *in, char *outp)
{
// The output is always shorter, so `outp=in`
// colour_correction_matrix => ColourCorrectionMatrix
// Colour Correction Matrix => ColourCorrectionMatrix
// ColourCorrectionMatrix => ColourCorrectionMatrix
char *out = outp;
bool upper = true;
while (*in) {
if (isalnum(*in)) {
if (upper) {
*out++ = toupper(*in++);
upper = false;
} else {
*out++ = *in++;
}
} else if (isprint(*in)) {
upper = true;
while (*++in && isprint(*in) && !isalnum(*in));
} else {
in++;
}
}
*out++ = 0;
return out - outp;
}

1
opts/control.h Normal file
View File

@ -0,0 +1 @@
int device_option_normalize_name(const char *in, char *out);