[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: Hans Verkuil <hans.verkuil@cisco.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
000e4f9a5b
commit
9ea1b7a4b6
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue