Allow to configure controls
This commit is contained in:
parent
9eeee04560
commit
8adcd67569
@ -38,7 +38,6 @@ void libcamera_device_close(device_t *dev)
|
|||||||
{
|
{
|
||||||
if (dev->libcamera) {
|
if (dev->libcamera) {
|
||||||
if (dev->libcamera->camera) {
|
if (dev->libcamera->camera) {
|
||||||
dev->libcamera->camera->stop();
|
|
||||||
dev->libcamera->camera->release();
|
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)
|
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;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif // USE_LIBCAMERA
|
#endif // USE_LIBCAMERA
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
device_hw_t libcamera_device_hw = {
|
device_hw_t libcamera_device_hw = {
|
||||||
.device_open = libcamera_device_open,
|
.device_open = libcamera_device_open,
|
||||||
.device_close = libcamera_device_close,
|
.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_fps = libcamera_device_set_fps,
|
||||||
.device_set_option = libcamera_device_set_option,
|
.device_set_option = libcamera_device_set_option,
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ extern "C" {
|
|||||||
#include "device/buffer.h"
|
#include "device/buffer.h"
|
||||||
#include "opts/log.h"
|
#include "opts/log.h"
|
||||||
#include "opts/fourcc.h"
|
#include "opts/fourcc.h"
|
||||||
|
#include "opts/control.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_LIBCAMERA
|
#ifdef USE_LIBCAMERA
|
||||||
@ -38,6 +39,7 @@ struct pollfd;
|
|||||||
typedef struct device_libcamera_s {
|
typedef struct device_libcamera_s {
|
||||||
std::shared_ptr<libcamera::CameraManager> camera_manager;
|
std::shared_ptr<libcamera::CameraManager> camera_manager;
|
||||||
std::shared_ptr<libcamera::Camera> camera;
|
std::shared_ptr<libcamera::Camera> camera;
|
||||||
|
libcamera::ControlList controls;
|
||||||
} device_libcamera_t;
|
} device_libcamera_t;
|
||||||
|
|
||||||
typedef struct buffer_list_libcamera_s {
|
typedef struct buffer_list_libcamera_s {
|
||||||
@ -55,8 +57,6 @@ typedef struct buffer_libcamera_s {
|
|||||||
|
|
||||||
int libcamera_device_open(device_t *dev);
|
int libcamera_device_open(device_t *dev);
|
||||||
void libcamera_device_close(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_fps(device_t *dev, int desired_fps);
|
||||||
int libcamera_device_set_option(device_t *dev, const char *key, const char *value);
|
int libcamera_device_set_option(device_t *dev, const char *key, const char *value);
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#include "v4l2.h"
|
#include "v4l2.h"
|
||||||
#include "device/device.h"
|
#include "device/device.h"
|
||||||
#include "opts/log.h"
|
#include "opts/log.h"
|
||||||
|
#include "opts/control.h"
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
int v4l2_device_set_option_by_id(device_t *dev, const char *name, uint32_t id, int32_t value)
|
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;
|
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)
|
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 };
|
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;
|
*id = qctrl.id;
|
||||||
|
|
||||||
v4l2_device_option_normalize_name(qctrl.name);
|
device_option_normalize_name(qctrl.name, qctrl.name);
|
||||||
|
|
||||||
if (strcmp(qctrl.name, name) != 0)
|
if (strcmp(qctrl.name, name) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -150,7 +131,7 @@ int v4l2_device_set_option(device_t *dev, const char *key, const char *value)
|
|||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
v4l2_device_option_normalize_name(keyp);
|
device_option_normalize_name(keyp, keyp);
|
||||||
|
|
||||||
if (dev->v4l2->subdev_fd >= 0)
|
if (dev->v4l2->subdev_fd >= 0)
|
||||||
ret = v4l2_device_set_option_string_fd(dev, dev->v4l2->subdev_fd, keyp, valuep);
|
ret = v4l2_device_set_option_string_fd(dev, dev->v4l2->subdev_fd, keyp, valuep);
|
||||||
|
34
opts/control.c
Normal file
34
opts/control.c
Normal 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
1
opts/control.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
int device_option_normalize_name(const char *in, char *out);
|
Loading…
x
Reference in New Issue
Block a user