diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2014-01-17 06:25:26 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-07-17 10:57:16 -0400 |
commit | 9ea1b7a4b66fddfab9e65e243b72d18371f8d9a5 (patch) | |
tree | fd8a4887e9fafdd171cb734430511e5a67bf2844 /drivers/media/v4l2-core | |
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')
-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) | |||
1424 | 1424 | ||
1425 | if (ctrl == NULL) | 1425 | if (ctrl == NULL) |
1426 | return; | 1426 | return; |
1427 | changed = !ctrl->type_ops->equal(ctrl, ctrl->p_cur, ctrl->p_new); | 1427 | |
1428 | ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); | 1428 | /* has_changed is set by cluster_changed */ |
1429 | changed = ctrl->has_changed; | ||
1430 | if (changed) | ||
1431 | ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); | ||
1429 | 1432 | ||
1430 | if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { | 1433 | if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { |
1431 | /* Note: CH_FLAGS is only set for auto clusters. */ | 1434 | /* Note: CH_FLAGS is only set for auto clusters. */ |
@@ -1462,17 +1465,19 @@ static void cur_to_new(struct v4l2_ctrl *ctrl) | |||
1462 | value that differs from the current value. */ | 1465 | value that differs from the current value. */ |
1463 | static int cluster_changed(struct v4l2_ctrl *master) | 1466 | static int cluster_changed(struct v4l2_ctrl *master) |
1464 | { | 1467 | { |
1465 | int diff = 0; | 1468 | bool changed = false; |
1466 | int i; | 1469 | int i; |
1467 | 1470 | ||
1468 | for (i = 0; !diff && i < master->ncontrols; i++) { | 1471 | for (i = 0; i < master->ncontrols; i++) { |
1469 | struct v4l2_ctrl *ctrl = master->cluster[i]; | 1472 | struct v4l2_ctrl *ctrl = master->cluster[i]; |
1470 | 1473 | ||
1471 | if (ctrl == NULL) | 1474 | if (ctrl == NULL) |
1472 | continue; | 1475 | continue; |
1473 | diff = !ctrl->type_ops->equal(ctrl, ctrl->p_cur, ctrl->p_new); | 1476 | ctrl->has_changed = !ctrl->type_ops->equal(ctrl, |
1477 | ctrl->p_cur, ctrl->p_new); | ||
1478 | changed |= ctrl->has_changed; | ||
1474 | } | 1479 | } |
1475 | return diff; | 1480 | return changed; |
1476 | } | 1481 | } |
1477 | 1482 | ||
1478 | /* Control range checking */ | 1483 | /* Control range checking */ |