Commit 09752745 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

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: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 7392d87a
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -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)
{
+53 −0
Original line number Diff line number Diff line
@@ -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.
 *