Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[media] v4l2-ctrls: compare values only once



When setting a control the control's new value is compared to the current
value twice: once by new_to_cur(), once by cluster_changed(). Not a big
deal when dealing with simple values, but it can be a problem when dealing
with compound types or arrays. So fix this: cluster_changed() sets the
has_changed flag, which is used by new_to_cur() instead of having to do
another compare.

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 000e4f9a
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -1424,7 +1424,10 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)

	if (ctrl == NULL)
		return;
	changed = !ctrl->type_ops->equal(ctrl, ctrl->p_cur, ctrl->p_new);

	/* has_changed is set by cluster_changed */
	changed = ctrl->has_changed;
	if (changed)
		ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur);

	if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) {
@@ -1462,17 +1465,19 @@ static void cur_to_new(struct v4l2_ctrl *ctrl)
   value that differs from the current value. */
static int cluster_changed(struct v4l2_ctrl *master)
{
	int diff = 0;
	bool changed = false;
	int i;

	for (i = 0; !diff && i < master->ncontrols; i++) {
	for (i = 0; i < master->ncontrols; i++) {
		struct v4l2_ctrl *ctrl = master->cluster[i];

		if (ctrl == NULL)
			continue;
		diff = !ctrl->type_ops->equal(ctrl, ctrl->p_cur, ctrl->p_new);
		ctrl->has_changed = !ctrl->type_ops->equal(ctrl,
						ctrl->p_cur, ctrl->p_new);
		changed |= ctrl->has_changed;
	}
	return diff;
	return changed;
}

/* Control range checking */
+3 −0
Original line number Diff line number Diff line
@@ -96,6 +96,8 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
  * @is_new:	Set when the user specified a new value for this control. It
  *		is also set when called from v4l2_ctrl_handler_setup. Drivers
  *		should never set this flag.
  * @has_changed: Set when the current value differs from the new value. Drivers
  *		should never use this flag.
  * @is_private: If set, then this control is private to its handler and it
  *		will not be added to any other handlers. Drivers can set
  *		this flag.
@@ -158,6 +160,7 @@ struct v4l2_ctrl {
	unsigned int done:1;

	unsigned int is_new:1;
	unsigned int has_changed:1;
	unsigned int is_private:1;
	unsigned int is_auto:1;
	unsigned int is_int:1;