All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Hans Verkuil <hverkuil@xs4all.nl>,
	Linux Media Mailing List <linux-media@vger.kernel.org>
Subject: Re: [PATCH 1/2] libv4lconvert: add support for extended controls
Date: Mon, 14 Jul 2014 14:28:29 +0200	[thread overview]
Message-ID: <53C3CCED.90100@redhat.com> (raw)
In-Reply-To: <53BBD035.5030608@xs4all.nl>

Hi,

On 07/08/2014 01:04 PM, Hans Verkuil wrote:
> libv4lconvert did not support the extended control API so qv4l2, which
> uses it, didn't work properly with libv4l2 since passing software
> emulated controls using the extended control API will fail as those
> controls are obviously not known to the driver.
> 
> This patch adds support for this API.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>

Looks good, feel free to push:

Reviewed by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> ---
>  lib/include/libv4lconvert.h               |   6 ++
>  lib/libv4l2/libv4l2.c                     |  15 ++++
>  lib/libv4lconvert/control/libv4lcontrol.c | 141 ++++++++++++++++++++++++++++++
>  lib/libv4lconvert/control/libv4lcontrol.h |   3 +
>  lib/libv4lconvert/libv4lconvert.c         |  15 ++++
>  5 files changed, 180 insertions(+)
> 
> diff --git a/lib/include/libv4lconvert.h b/lib/include/libv4lconvert.h
> index 2c1f199..e94d3bd 100644
> --- a/lib/include/libv4lconvert.h
> +++ b/lib/include/libv4lconvert.h
> @@ -132,6 +132,12 @@ LIBV4L_PUBLIC int v4lconvert_vidioc_g_ctrl(struct v4lconvert_data *data,
>  		void *arg);
>  LIBV4L_PUBLIC int v4lconvert_vidioc_s_ctrl(struct v4lconvert_data *data,
>  		void *arg);
> +LIBV4L_PUBLIC int v4lconvert_vidioc_g_ext_ctrls(struct v4lconvert_data *data,
> +		void *arg);
> +LIBV4L_PUBLIC int v4lconvert_vidioc_try_ext_ctrls(struct v4lconvert_data *data,
> +		void *arg);
> +LIBV4L_PUBLIC int v4lconvert_vidioc_s_ext_ctrls(struct v4lconvert_data *data,
> +		void *arg);
>  
>  /* Is the passed in pixelformat supported as destination format? */
>  LIBV4L_PUBLIC int v4lconvert_supported_dst_format(unsigned int pixelformat);
> diff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c
> index 1dcf34d..8291ebe 100644
> --- a/lib/libv4l2/libv4l2.c
> +++ b/lib/libv4l2/libv4l2.c
> @@ -1022,6 +1022,9 @@ int v4l2_ioctl(int fd, unsigned long int request, ...)
>  	case VIDIOC_QUERYCTRL:
>  	case VIDIOC_G_CTRL:
>  	case VIDIOC_S_CTRL:
> +	case VIDIOC_G_EXT_CTRLS:
> +	case VIDIOC_TRY_EXT_CTRLS:
> +	case VIDIOC_S_EXT_CTRLS:
>  	case VIDIOC_ENUM_FRAMESIZES:
>  	case VIDIOC_ENUM_FRAMEINTERVALS:
>  		is_capture_request = 1;
> @@ -1129,6 +1132,18 @@ no_capture_request:
>  		result = v4lconvert_vidioc_s_ctrl(devices[index].convert, arg);
>  		break;
>  
> +	case VIDIOC_G_EXT_CTRLS:
> +		result = v4lconvert_vidioc_g_ext_ctrls(devices[index].convert, arg);
> +		break;
> +
> +	case VIDIOC_TRY_EXT_CTRLS:
> +		result = v4lconvert_vidioc_try_ext_ctrls(devices[index].convert, arg);
> +		break;
> +
> +	case VIDIOC_S_EXT_CTRLS:
> +		result = v4lconvert_vidioc_s_ext_ctrls(devices[index].convert, arg);
> +		break;
> +
>  	case VIDIOC_QUERYCAP: {
>  		struct v4l2_capability *cap = arg;
>  
> diff --git a/lib/libv4lconvert/control/libv4lcontrol.c b/lib/libv4lconvert/control/libv4lcontrol.c
> index ee39ba7..2fd585d 100644
> --- a/lib/libv4lconvert/control/libv4lcontrol.c
> +++ b/lib/libv4lconvert/control/libv4lcontrol.c
> @@ -916,6 +916,81 @@ int v4lcontrol_vidioc_g_ctrl(struct v4lcontrol_data *data, void *arg)
>  			VIDIOC_G_CTRL, arg);
>  }
>  
> +static void v4lcontrol_alloc_valid_controls(struct v4lcontrol_data *data,
> +			const struct v4l2_ext_controls *src,
> +			struct v4l2_ext_controls *dst)
> +{
> +	struct v4l2_ext_control *ctrl;
> +	unsigned i, j;
> +
> +	*dst = *src;
> +	if (data->controls == 0)
> +		return;
> +	ctrl = malloc(src->count * sizeof(*ctrl));
> +	if (ctrl == NULL)
> +		return;
> +	dst->controls = ctrl;
> +	dst->count = 0;
> +	for (i = 0; i < src->count; i++) {
> +		for (j = 0; j < V4LCONTROL_COUNT; j++)
> +			if ((data->controls & (1 << j)) &&
> +			    src->controls[i].id == fake_controls[j].id)
> +				break;
> +		if (j == V4LCONTROL_COUNT)
> +			ctrl[dst->count++] = src->controls[i];
> +	}
> +}
> +
> +static void v4lcontrol_free_valid_controls(struct v4lcontrol_data *data,
> +			struct v4l2_ext_controls *src,
> +			struct v4l2_ext_controls *dst)
> +{
> +	unsigned i, j, k = 0;
> +	int inc_idx;
> +
> +	src->error_idx = dst->error_idx;
> +	if (dst->controls == src->controls)
> +		return;
> +
> +	inc_idx = dst->error_idx < dst->count;
> +	for (i = 0; i < src->count; i++) {
> +		for (j = 0; j < V4LCONTROL_COUNT; j++)
> +			if ((data->controls & (1 << j)) &&
> +			    src->controls[i].id == fake_controls[j].id)
> +				break;
> +		if (j == V4LCONTROL_COUNT)
> +			src->controls[i] = dst->controls[k++];
> +		else if (inc_idx)
> +			src->error_idx++;
> +	}
> +	free(dst->controls);
> +}
> +
> +int v4lcontrol_vidioc_g_ext_ctrls(struct v4lcontrol_data *data, void *arg)
> +{
> +	struct v4l2_ext_controls *ctrls = arg;
> +	struct v4l2_ext_controls dst;
> +	int i, j;
> +	int res;
> +
> +	v4lcontrol_alloc_valid_controls(data, ctrls, &dst);
> +	res = data->dev_ops->ioctl(data->dev_ops_priv, data->fd,
> +			VIDIOC_G_EXT_CTRLS, &dst);
> +	v4lcontrol_free_valid_controls(data, ctrls, &dst);
> +	if (res)
> +		return res;
> +
> +	for (i = 0; i < ctrls->count; i++) {
> +		for (j = 0; j < V4LCONTROL_COUNT; j++)
> +			if ((data->controls & (1 << j)) &&
> +			    ctrls->controls[i].id == fake_controls[j].id) {
> +				ctrls->controls[i].value = data->shm_values[j];
> +				break;
> +			}
> +	}
> +	return 0;
> +}
> +
>  int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg)
>  {
>  	int i;
> @@ -938,6 +1013,72 @@ int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg)
>  			VIDIOC_S_CTRL, arg);
>  }
>  
> +static int v4lcontrol_validate_ext_ctrls(struct v4lcontrol_data *data,
> +		struct v4l2_ext_controls *ctrls)
> +{
> +	int i, j;
> +
> +	if (data->controls == 0)
> +		return 0;
> +	for (i = 0; i < ctrls->count; i++) {
> +		for (j = 0; j < V4LCONTROL_COUNT; j++)
> +			if ((data->controls & (1 << j)) &&
> +			    ctrls->controls[i].id == fake_controls[j].id) {
> +				if (ctrls->controls[i].value > fake_controls[j].maximum ||
> +				    ctrls->controls[i].value < fake_controls[j].minimum) {
> +					ctrls->error_idx = i;
> +					errno = EINVAL;
> +					return -1;
> +				}
> +			}
> +	}
> +	return 0;
> +}
> +
> +int v4lcontrol_vidioc_try_ext_ctrls(struct v4lcontrol_data *data, void *arg)
> +{
> +	struct v4l2_ext_controls *ctrls = arg;
> +	struct v4l2_ext_controls dst;
> +	int res = v4lcontrol_validate_ext_ctrls(data, ctrls);
> +
> +	if (res)
> +		return res;
> +
> +	v4lcontrol_alloc_valid_controls(data, ctrls, &dst);
> +	res = data->dev_ops->ioctl(data->dev_ops_priv, data->fd,
> +			VIDIOC_TRY_EXT_CTRLS, &dst);
> +	v4lcontrol_free_valid_controls(data, ctrls, &dst);
> +	return res;
> +}
> +
> +int v4lcontrol_vidioc_s_ext_ctrls(struct v4lcontrol_data *data, void *arg)
> +{
> +	struct v4l2_ext_controls *ctrls = arg;
> +	struct v4l2_ext_controls dst;
> +	int i, j;
> +	int res = v4lcontrol_validate_ext_ctrls(data, ctrls);
> +
> +	if (res)
> +		return res;
> +
> +	v4lcontrol_alloc_valid_controls(data, ctrls, &dst);
> +	res = data->dev_ops->ioctl(data->dev_ops_priv, data->fd,
> +			VIDIOC_S_EXT_CTRLS, &dst);
> +	v4lcontrol_free_valid_controls(data, ctrls, &dst);
> +	if (res)
> +		return res;
> +
> +	for (i = 0; i < ctrls->count; i++) {
> +		for (j = 0; j < V4LCONTROL_COUNT; j++)
> +			if ((data->controls & (1 << j)) &&
> +			    ctrls->controls[i].id == fake_controls[j].id) {
> +				data->shm_values[j] = ctrls->controls[i].value;
> +				break;
> +			}
> +	}
> +	return 0;
> +}
> +
>  int v4lcontrol_get_bandwidth(struct v4lcontrol_data *data)
>  {
>  	return data->bandwidth;
> diff --git a/lib/libv4lconvert/control/libv4lcontrol.h b/lib/libv4lconvert/control/libv4lcontrol.h
> index 804f1c5..fa9cf42 100644
> --- a/lib/libv4lconvert/control/libv4lcontrol.h
> +++ b/lib/libv4lconvert/control/libv4lcontrol.h
> @@ -72,5 +72,8 @@ int v4lcontrol_needs_conversion(struct v4lcontrol_data *data);
>  int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg);
>  int v4lcontrol_vidioc_g_ctrl(struct v4lcontrol_data *data, void *arg);
>  int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg);
> +int v4lcontrol_vidioc_g_ext_ctrls(struct v4lcontrol_data *data, void *arg);
> +int v4lcontrol_vidioc_try_ext_ctrls(struct v4lcontrol_data *data, void *arg);
> +int v4lcontrol_vidioc_s_ext_ctrls(struct v4lcontrol_data *data, void *arg);
>  
>  #endif
> diff --git a/lib/libv4lconvert/libv4lconvert.c b/lib/libv4lconvert/libv4lconvert.c
> index acb8085..7ee7c19 100644
> --- a/lib/libv4lconvert/libv4lconvert.c
> +++ b/lib/libv4lconvert/libv4lconvert.c
> @@ -1659,6 +1659,21 @@ int v4lconvert_vidioc_s_ctrl(struct v4lconvert_data *data, void *arg)
>  	return v4lcontrol_vidioc_s_ctrl(data->control, arg);
>  }
>  
> +int v4lconvert_vidioc_g_ext_ctrls(struct v4lconvert_data *data, void *arg)
> +{
> +	return v4lcontrol_vidioc_g_ext_ctrls(data->control, arg);
> +}
> +
> +int v4lconvert_vidioc_try_ext_ctrls(struct v4lconvert_data *data, void *arg)
> +{
> +	return v4lcontrol_vidioc_try_ext_ctrls(data->control, arg);
> +}
> +
> +int v4lconvert_vidioc_s_ext_ctrls(struct v4lconvert_data *data, void *arg)
> +{
> +	return v4lcontrol_vidioc_s_ext_ctrls(data->control, arg);
> +}
> +
>  int v4lconvert_get_fps(struct v4lconvert_data *data)
>  {
>  	return data->fps;
> 

      reply	other threads:[~2014-07-14 12:28 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-08 11:04 [PATCH 1/2] libv4lconvert: add support for extended controls Hans Verkuil
2014-07-14 12:28 ` Hans de Goede [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53C3CCED.90100@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=hverkuil@xs4all.nl \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.