mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
v4l2: implement setting controls
This commit is contained in:
parent
c5f7d3a728
commit
71d58e6445
2 changed files with 99 additions and 22 deletions
|
|
@ -266,14 +266,29 @@ static int impl_node_set_param(void *object,
|
||||||
case SPA_PARAM_Props:
|
case SPA_PARAM_Props:
|
||||||
{
|
{
|
||||||
struct props *p = &this->props;
|
struct props *p = &this->props;
|
||||||
|
struct spa_pod_object *obj = (struct spa_pod_object *) param;
|
||||||
|
struct spa_pod_prop *prop;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
if (param == NULL) {
|
if (param == NULL) {
|
||||||
reset_props(p);
|
reset_props(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
spa_pod_parse_object(param,
|
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
||||||
SPA_TYPE_OBJECT_Props, NULL,
|
switch (prop->key) {
|
||||||
SPA_PROP_device, SPA_POD_OPT_Stringn(p->device, sizeof(p->device)));
|
case SPA_PROP_device:
|
||||||
|
strncpy(p->device,
|
||||||
|
(char *)SPA_POD_CONTENTS(struct spa_pod_string, &prop->value),
|
||||||
|
sizeof(p->device)-1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = spa_v4l2_set_control(this, prop->key, prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
|
#include <spa/utils/result.h>
|
||||||
|
|
||||||
static int xioctl(int fd, int request, void *arg)
|
static int xioctl(int fd, int request, void *arg)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -1040,28 +1042,38 @@ static int query_ext_ctrl_ioctl(struct port *port, struct v4l2_query_ext_ctrl *q
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
uint32_t v4l2_id;
|
||||||
|
uint32_t spa_id;
|
||||||
|
} control_map[] = {
|
||||||
|
{ V4L2_CID_BRIGHTNESS, SPA_PROP_brightness },
|
||||||
|
{ V4L2_CID_CONTRAST, SPA_PROP_contrast },
|
||||||
|
{ V4L2_CID_SATURATION, SPA_PROP_saturation },
|
||||||
|
{ V4L2_CID_HUE, SPA_PROP_hue },
|
||||||
|
{ V4L2_CID_GAMMA, SPA_PROP_gamma },
|
||||||
|
{ V4L2_CID_EXPOSURE, SPA_PROP_exposure },
|
||||||
|
{ V4L2_CID_GAIN, SPA_PROP_gain },
|
||||||
|
{ V4L2_CID_SHARPNESS, SPA_PROP_sharpness },
|
||||||
|
};
|
||||||
|
|
||||||
static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id)
|
static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id)
|
||||||
{
|
{
|
||||||
switch (control_id) {
|
SPA_FOR_EACH_ELEMENT_VAR(control_map, c) {
|
||||||
case V4L2_CID_BRIGHTNESS:
|
if (c->v4l2_id == control_id)
|
||||||
return SPA_PROP_brightness;
|
return c->spa_id;
|
||||||
case V4L2_CID_CONTRAST:
|
|
||||||
return SPA_PROP_contrast;
|
|
||||||
case V4L2_CID_SATURATION:
|
|
||||||
return SPA_PROP_saturation;
|
|
||||||
case V4L2_CID_HUE:
|
|
||||||
return SPA_PROP_hue;
|
|
||||||
case V4L2_CID_GAMMA:
|
|
||||||
return SPA_PROP_gamma;
|
|
||||||
case V4L2_CID_EXPOSURE:
|
|
||||||
return SPA_PROP_exposure;
|
|
||||||
case V4L2_CID_GAIN:
|
|
||||||
return SPA_PROP_gain;
|
|
||||||
case V4L2_CID_SHARPNESS:
|
|
||||||
return SPA_PROP_sharpness;
|
|
||||||
default:
|
|
||||||
return SPA_PROP_START_CUSTOM + control_id;
|
|
||||||
}
|
}
|
||||||
|
return SPA_PROP_START_CUSTOM + control_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t prop_id_to_control(struct impl *impl, uint32_t prop_id)
|
||||||
|
{
|
||||||
|
SPA_FOR_EACH_ELEMENT_VAR(control_map, c) {
|
||||||
|
if (c->spa_id == prop_id)
|
||||||
|
return c->v4l2_id;
|
||||||
|
}
|
||||||
|
if (prop_id >= SPA_PROP_START_CUSTOM)
|
||||||
|
return prop_id - SPA_PROP_START_CUSTOM;
|
||||||
|
return SPA_ID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -1225,6 +1237,56 @@ spa_v4l2_enum_controls(struct impl *this, int seq,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spa_v4l2_set_control(struct impl *this, uint32_t id,
|
||||||
|
const struct spa_pod_prop *prop)
|
||||||
|
{
|
||||||
|
struct port *port = &this->out_ports[0];
|
||||||
|
struct spa_v4l2_device *dev = &port->dev;
|
||||||
|
struct v4l2_control control;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
spa_zero(control);
|
||||||
|
control.id = prop_id_to_control(this, prop->key);
|
||||||
|
if (control.id == SPA_ID_INVALID)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
switch (SPA_POD_TYPE(&prop->value)) {
|
||||||
|
case SPA_TYPE_Bool:
|
||||||
|
{
|
||||||
|
bool val;
|
||||||
|
if ((res = spa_pod_get_bool(&prop->value, &val)) < 0)
|
||||||
|
goto done;
|
||||||
|
control.value = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPA_TYPE_Int:
|
||||||
|
{
|
||||||
|
int32_t val;
|
||||||
|
if ((res = spa_pod_get_int(&prop->value, &val)) < 0)
|
||||||
|
goto done;
|
||||||
|
control.value = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (xioctl(dev->fd, VIDIOC_S_CTRL, &control) < 0) {
|
||||||
|
res = -errno;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
spa_v4l2_close(dev);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int mmap_read(struct impl *this)
|
static int mmap_read(struct impl *this)
|
||||||
{
|
{
|
||||||
struct port *port = &this->out_ports[0];
|
struct port *port = &this->out_ports[0];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue