On 8/17/23 09:25, Yunke Cao wrote: > Add string name for V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX. > > Test that V4L2_CTRL_WHICH_MIN/MAX_VAL behaves as expected. > 1. Calling G_EXT_CTRLS successes when V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX is set > and returns -ENVALID if the flag is not set. > 2. S_EXT_CTRLS and TRY_EXT_CTRLS always return fail. > > Tested with VIVID: > > ./v4l2-ctl -l -d 0 > ... > area 0x0098f90b (area) : value=1000x2000 flags=has-payload > read_only_integer_32_bits 0x0098f90c (int) : min=0 max=255 step=1 default=0 value=0 flags=read-only, has-min-max > u32_dynamic_array 0x0098f90d (u32) : min=10 max=90 step=1 default=50 elems=1 dims=[100] flags=has-payload, dynamic-array > u8_pixel_array 0x0098f90e (u8) : min=0 max=255 step=1 default=128 dims=[640][368] flags=has-payload > s32_2_element_array 0x0098f90f (int) : min=-10 max=10 step=1 default=2 dims=[2] flags=has-payload, has-min-max > s64_5_element_array 0x0098f910 (int64) : min=-10 max=10 step=1 default=4 dims=[5] flags=has-payload, has-min-max > rect 0x0098f911 (rect) : value=300x400@200x100 flags=has-payload, has-min-max > ... > ./v4l2-compliance -d 0 > ... > Total for vivid device /dev/video0: 113, Succeeded: 113, Failed: 0, Warnings: 0 > > Signed-off-by: Yunke Cao <yunkec@xxxxxxxxxx> > --- > include/linux/videodev2.h | 3 ++ > utils/common/v4l2-info.cpp | 1 + > utils/v4l2-compliance/v4l2-test-controls.cpp | 29 ++++++++++++++++++++ > 3 files changed, 33 insertions(+) > > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h > index a27ea755..28a54e18 100644 > --- a/include/linux/videodev2.h > +++ b/include/linux/videodev2.h > @@ -1801,6 +1801,8 @@ struct v4l2_ext_controls { > #define V4L2_CTRL_WHICH_CUR_VAL 0 > #define V4L2_CTRL_WHICH_DEF_VAL 0x0f000000 > #define V4L2_CTRL_WHICH_REQUEST_VAL 0x0f010000 > +#define V4L2_CTRL_WHICH_MIN_VAL 0x0f020000 > +#define V4L2_CTRL_WHICH_MAX_VAL 0x0f030000 > > enum v4l2_ctrl_type { > V4L2_CTRL_TYPE_INTEGER = 1, > @@ -1903,6 +1905,7 @@ struct v4l2_querymenu { > #define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200 > #define V4L2_CTRL_FLAG_MODIFY_LAYOUT 0x0400 > #define V4L2_CTRL_FLAG_DYNAMIC_ARRAY 0x0800 > +#define V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX 0x1000 > > /* Query flags, to be ORed with the control ID */ > #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 Same as with the previous patch: just keep all the videodev2.h changes in a single patch at the start of the series. > diff --git a/utils/common/v4l2-info.cpp b/utils/common/v4l2-info.cpp > index 4f8c2aa7..b8785245 100644 > --- a/utils/common/v4l2-info.cpp > +++ b/utils/common/v4l2-info.cpp > @@ -530,6 +530,7 @@ std::string ctrlflags2s(__u32 flags) > { V4L2_CTRL_FLAG_EXECUTE_ON_WRITE, "execute-on-write" }, > { V4L2_CTRL_FLAG_MODIFY_LAYOUT, "modify-layout" }, > { V4L2_CTRL_FLAG_DYNAMIC_ARRAY, "dynamic-array" }, > + { V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX, "has-min-max" }, > { 0, nullptr } > }; > return flags2s(flags, def); > diff --git a/utils/v4l2-compliance/v4l2-test-controls.cpp b/utils/v4l2-compliance/v4l2-test-controls.cpp > index d7f6be43..e07269e6 100644 > --- a/utils/v4l2-compliance/v4l2-test-controls.cpp > +++ b/utils/v4l2-compliance/v4l2-test-controls.cpp > @@ -973,6 +973,26 @@ int testExtendedControls(struct node *node) > if (is_vivid && ctrl.id == VIVID_CID_U32_DYN_ARRAY && > checkVividDynArray(node, ctrl, qctrl)) > return fail("dynamic array tests failed\n"); > + > + ctrls.which = V4L2_CTRL_WHICH_MIN_VAL; > + ret = doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls); > + if (qctrl.flags & V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX) { > + if (ret) > + return fail("g_ext_ctrls return an error when using WHICH_MIN (%d)\n", ret); Just use fail_on_test_val(); > + } else { > + if (ret != EINVAL && ret != EACCES) > + return fail("did not check against HAS_WHICH_MIN_MAX\n"); Ditto. But can EACCES be returned here? I don't think that can ever happen. > + } > + ctrls.which = V4L2_CTRL_WHICH_MAX_VAL; > + ret = doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls); > + if (qctrl.flags & V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX) { > + if (ret) > + return fail("g_ext_ctrls return an error when using WHICH_MAX (%d)\n", ret); > + } else { > + if (ret != EINVAL && ret != EACCES) > + return fail("did not check against HAS_WHICH_MIN_MAX\n"); > + } Same comments as above. > + > if (qctrl.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) > delete [] ctrl.string; > ctrl.string = nullptr; > @@ -1084,6 +1104,15 @@ int testExtendedControls(struct node *node) > fail_on_test(!doioctl(node, VIDIOC_S_EXT_CTRLS, &ctrls)); > fail_on_test(!doioctl(node, VIDIOC_TRY_EXT_CTRLS, &ctrls)); > fail_on_test(doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls)); > + > + ctrls.which = V4L2_CTRL_WHICH_MIN_VAL; > + fail_on_test(!doioctl(node, VIDIOC_S_EXT_CTRLS, &ctrls)); > + fail_on_test(!doioctl(node, VIDIOC_TRY_EXT_CTRLS, &ctrls)); > + > + ctrls.which = V4L2_CTRL_WHICH_MAX_VAL; > + fail_on_test(!doioctl(node, VIDIOC_S_EXT_CTRLS, &ctrls)); > + fail_on_test(!doioctl(node, VIDIOC_TRY_EXT_CTRLS, &ctrls)); > + > return 0; > } > Regards, Hans