Allow to set complex ISP options
This commit is contained in:
parent
08c179e22a
commit
7b69fa0063
@ -38,50 +38,110 @@ void device_option_normalize_name(char *in)
|
|||||||
*out++ = 0;
|
*out++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_set_option_string_fd(device_t *dev, int fd, const char *name, const char *value)
|
static int device_set_option_string_fd_by_id(device_t *dev, int fd, uint32_t *id, char *name, char *value)
|
||||||
{
|
{
|
||||||
struct v4l2_query_ext_ctrl qctrl = {0};
|
struct v4l2_query_ext_ctrl qctrl = { .id = *id };
|
||||||
struct v4l2_control ctl = {0};
|
void *data = NULL;
|
||||||
|
|
||||||
qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
|
if (0 != ioctl (fd, VIDIOC_QUERY_EXT_CTRL, &qctrl)) {
|
||||||
while (0 == ioctl (fd, VIDIOC_QUERY_EXT_CTRL, &qctrl)) {
|
*id = 0;
|
||||||
ctl.id = qctrl.id;
|
return 0;
|
||||||
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
|
}
|
||||||
|
*id = qctrl.id;
|
||||||
|
|
||||||
device_option_normalize_name(qctrl.name);
|
device_option_normalize_name(qctrl.name);
|
||||||
|
|
||||||
if (strcmp(qctrl.name, name) != 0)
|
if (strcmp(qctrl.name, name) != 0)
|
||||||
continue;
|
return 0;
|
||||||
|
|
||||||
if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
|
if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
|
||||||
E_LOG_INFO(dev, "The '%s' is disabled", name);
|
E_LOG_INFO(dev, "The '%s' is disabled", name);
|
||||||
continue;
|
return 0;
|
||||||
} else if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
|
} else if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
|
||||||
E_LOG_INFO(dev, "The '%s' is read-only", name);
|
E_LOG_INFO(dev, "The '%s' is read-only", name);
|
||||||
continue;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
switch(qctrl.type) {
|
|
||||||
case V4L2_CTRL_TYPE_INTEGER:
|
|
||||||
case V4L2_CTRL_TYPE_BOOLEAN:
|
|
||||||
case V4L2_CTRL_TYPE_MENU:
|
|
||||||
ctl.value = atoi(value);
|
|
||||||
E_LOG_VERBOSE(dev, "Configuring option %s (%08x) = %d", name, ctl.id, ctl.value);
|
|
||||||
E_XIOCTL(dev, fd, VIDIOC_S_CTRL, &ctl, "Can't set option %s", name);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
default:
|
|
||||||
E_LOG_INFO(dev, "The '%s' control type '%d' is not supported", name, qctrl.type);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
switch(qctrl.type) {
|
||||||
|
case V4L2_CTRL_TYPE_INTEGER:
|
||||||
|
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||||
|
case V4L2_CTRL_TYPE_MENU:
|
||||||
|
{
|
||||||
|
struct v4l2_control ctl = {
|
||||||
|
.id = *id,
|
||||||
|
.value = atoi(value)
|
||||||
|
};
|
||||||
|
E_LOG_INFO(dev, "Configuring option %s (%08x) = %d", name, ctl.id, ctl.value);
|
||||||
|
E_XIOCTL(dev, fd, VIDIOC_S_CTRL, &ctl, "Can't set option %s", name);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case V4L2_CTRL_TYPE_U8:
|
||||||
|
case V4L2_CTRL_TYPE_U16:
|
||||||
|
case V4L2_CTRL_TYPE_U32:
|
||||||
|
{
|
||||||
|
struct v4l2_ext_control ctl = {
|
||||||
|
.id = *id,
|
||||||
|
.size = qctrl.elem_size * qctrl.elems,
|
||||||
|
.ptr = data = calloc(qctrl.elems, qctrl.elem_size)
|
||||||
|
};
|
||||||
|
struct v4l2_ext_controls ctrls = {
|
||||||
|
.count = 1,
|
||||||
|
.ctrl_class = V4L2_CTRL_ID2CLASS(*id),
|
||||||
|
.controls = &ctl,
|
||||||
|
};
|
||||||
|
|
||||||
|
char *string = value;
|
||||||
|
char *token;
|
||||||
|
int tokens = 0;
|
||||||
|
|
||||||
|
for ( ; token = strsep(&string, ","); tokens++) {
|
||||||
|
if (tokens >= qctrl.elems)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch(qctrl.type) {
|
||||||
|
case V4L2_CTRL_TYPE_U8:
|
||||||
|
ctl.p_u8[tokens] = atoi(token);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V4L2_CTRL_TYPE_U16:
|
||||||
|
ctl.p_u16[tokens] = atoi(token);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V4L2_CTRL_TYPE_U32:
|
||||||
|
ctl.p_u32[tokens] = atoi(token);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
E_LOG_INFO(dev, "Configuring option %s (%08x) = [%d tokens, expected %d]", name, ctl.id, tokens, qctrl.elems);
|
||||||
|
E_XIOCTL(dev, fd, VIDIOC_S_EXT_CTRLS, &ctrls, "Can't set option %s", name);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
E_LOG_INFO(dev, "The '%s' control type '%d' is not supported", name, qctrl.type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
free(data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int device_set_option_string_fd(device_t *dev, int fd, char *name, char *value)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
uint32_t id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
|
||||||
|
while ((ret = device_set_option_string_fd_by_id(dev, fd, &id, name, value)) == 0 && id) {
|
||||||
|
id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int device_set_option_string(device_t *dev, const char *option)
|
int device_set_option_string(device_t *dev, const char *option)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@ -96,7 +156,8 @@ int device_set_option_string(device_t *dev, const char *option)
|
|||||||
|
|
||||||
device_option_normalize_name(name);
|
device_option_normalize_name(name);
|
||||||
|
|
||||||
ret = device_set_option_string_fd(dev, dev->subdev_fd, name, value);
|
if (dev->subdev_fd >= 0)
|
||||||
|
ret = device_set_option_string_fd(dev, dev->subdev_fd, name, value);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
ret = device_set_option_string_fd(dev, dev->fd, name, value);
|
ret = device_set_option_string_fd(dev, dev->fd, name, value);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user