diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2014-01-17 08:25:26 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-07-17 11:57:16 -0300 |
commit | 9ea1b7a4b66fddfab9e65e243b72d18371f8d9a5 (patch) | |
tree | fd8a4887e9fafdd171cb734430511e5a67bf2844 /drivers/media/v4l2-core/v4l2-ctrls.c | |
parent | 000e4f9a5bcf86fb52914c445ce5634b65e910a2 (diff) |
[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>
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ctrls.c')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ctrls.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index e7e0beab7048..1b4d37ce4afe 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1424,8 +1424,11 @@ 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); - ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); + + /* 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) { /* Note: CH_FLAGS is only set for auto clusters. */ @@ -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 */ |