media: v4l2-ctrls: add v4l2_ctrl_modify_dimensions

Add a new function to modify the dimensions of an array control.

This is typically used if the array size depends on e.g. the currently
selected video format.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
Hans Verkuil 2022-07-11 12:21:09 +02:00 коммит произвёл Mauro Carvalho Chehab
Родитель 7392d87a9f
Коммит 0975274557
2 изменённых файлов: 89 добавлений и 0 удалений

Просмотреть файл

@ -989,6 +989,42 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
}
EXPORT_SYMBOL(__v4l2_ctrl_modify_range);
int __v4l2_ctrl_modify_dimensions(struct v4l2_ctrl *ctrl,
u32 dims[V4L2_CTRL_MAX_DIMS])
{
unsigned int elems = 1;
unsigned int i;
void *p_array;
lockdep_assert_held(ctrl->handler->lock);
if (!ctrl->is_array || ctrl->is_dyn_array)
return -EINVAL;
for (i = 0; i < ctrl->nr_of_dims; i++)
elems *= dims[i];
if (elems == 0)
return -EINVAL;
p_array = kvzalloc(2 * elems * ctrl->elem_size, GFP_KERNEL);
if (!p_array)
return -ENOMEM;
kvfree(ctrl->p_array);
ctrl->p_array_alloc_elems = elems;
ctrl->elems = elems;
ctrl->new_elems = elems;
ctrl->p_array = p_array;
ctrl->p_new.p = p_array;
ctrl->p_cur.p = p_array + elems * ctrl->elem_size;
for (i = 0; i < ctrl->nr_of_dims; i++)
ctrl->dims[i] = dims[i];
for (i = 0; i < elems; i++)
ctrl->type_ops->init(ctrl, i, ctrl->p_cur);
cur_to_new(ctrl);
send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_VALUE);
return 0;
}
EXPORT_SYMBOL(__v4l2_ctrl_modify_dimensions);
/* Implement VIDIOC_QUERY_EXT_CTRL */
int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)
{

Просмотреть файл

@ -957,6 +957,59 @@ static inline int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
return rval;
}
/**
*__v4l2_ctrl_modify_dimensions() - Unlocked variant of v4l2_ctrl_modify_dimensions()
*
* @ctrl: The control to update.
* @dims: The control's new dimensions.
*
* Update the dimensions of an array control on the fly. The elements of the
* array are reset to their default value, even if the dimensions are
* unchanged.
*
* An error is returned if @dims is invalid for this control.
*
* The caller is responsible for acquiring the control handler mutex on behalf
* of __v4l2_ctrl_modify_dimensions().
*
* Note: calling this function when the same control is used in pending requests
* is untested. It should work (a request with the wrong size of the control
* will drop that control silently), but it will be very confusing.
*/
int __v4l2_ctrl_modify_dimensions(struct v4l2_ctrl *ctrl,
u32 dims[V4L2_CTRL_MAX_DIMS]);
/**
* v4l2_ctrl_modify_dimensions() - Update the dimensions of an array control.
*
* @ctrl: The control to update.
* @dims: The control's new dimensions.
*
* Update the dimensions of an array control on the fly. The elements of the
* array are reset to their default value, even if the dimensions are
* unchanged.
*
* An error is returned if @dims is invalid for this control type.
*
* This function assumes that the control handler is not locked and will
* take the lock itself.
*
* Note: calling this function when the same control is used in pending requests
* is untested. It should work (a request with the wrong size of the control
* will drop that control silently), but it will be very confusing.
*/
static inline int v4l2_ctrl_modify_dimensions(struct v4l2_ctrl *ctrl,
u32 dims[V4L2_CTRL_MAX_DIMS])
{
int rval;
v4l2_ctrl_lock(ctrl);
rval = __v4l2_ctrl_modify_dimensions(ctrl, dims);
v4l2_ctrl_unlock(ctrl);
return rval;
}
/**
* v4l2_ctrl_notify() - Function to set a notify callback for a control.
*