Commit 5ab765e2 authored by Antonio Ospite's avatar Antonio Ospite Committed by Kamal Mostafa

[media] media/v4l2-ctrls: fix setting autocluster to manual with VIDIOC_S_CTRL

commit 759b26a1 upstream.

Since commit 5d0360a4 it's not possible
anymore to set auto clusters from auto to manual using VIDIOC_S_CTRL.

For example, setting autogain to manual with gspca/ov534 driver and this
sequence of commands does not work:

  v4l2-ctl --set-ctrl=gain_automatic=1
  v4l2-ctl --list-ctrls | grep gain_automatic
  # The following does not work
  v4l2-ctl --set-ctrl=gain_automatic=0
  v4l2-ctl --list-ctrls | grep gain_automatic

Changing the value using VIDIOC_S_EXT_CTRLS (like qv4l2 does) works
fine.

The apparent cause by looking at the changes in 5d0360a4 and comparing
with the code path for VIDIOC_S_EXT_CTRLS seems to be that the code in
v4l2-ctrls.c::set_ctrl() is not calling user_to_new() anymore after
calling update_from_auto_cluster(master).

However the root cause of the problem is that calling
update_from_auto_cluster(master) overrides also the _master_ control
state calling cur_to_new() while it was supposed to only update the
volatile controls.

Calling user_to_new() after update_from_auto_cluster(master) was just
masking the original bug by restoring the correct new value of the
master control before making the changes permanent.

Fix the original bug by making update_from_auto_cluster() not override
the new master control value.
Signed-off-by: default avatarAntonio Ospite <ao2@ao2.it>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
parent 5d475c4f
...@@ -3042,7 +3042,7 @@ static void update_from_auto_cluster(struct v4l2_ctrl *master) ...@@ -3042,7 +3042,7 @@ static void update_from_auto_cluster(struct v4l2_ctrl *master)
{ {
int i; int i;
for (i = 0; i < master->ncontrols; i++) for (i = 1; i < master->ncontrols; i++)
cur_to_new(master->cluster[i]); cur_to_new(master->cluster[i]);
if (!call_op(master, g_volatile_ctrl)) if (!call_op(master, g_volatile_ctrl))
for (i = 1; i < master->ncontrols; i++) for (i = 1; i < master->ncontrols; i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment