[{"id":5048,"web_url":"https://patchwork.libcamera.org/comment/5048/","msgid":"<20200605150359.GC26752@pendragon.ideasonboard.com>","date":"2020-06-05T15:03:59","subject":"Re: [libcamera-devel] [RFC] libcamera: v4l2_device: Update control\n\tinfo","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Fri, Jun 05, 2020 at 04:20:37PM +0200, Jacopo Mondi wrote:\n> Setting controls on a V4L2 device might update the limits of other\n> related controls (in example, setting a new vertical/horizontal blanking\n> value might modify the available exposure time duration).\n> \n> Add a funtion to update the ControlInfo that represents a control\n> minimum, maximum and default values and call it after a new control has\n> been set and format is changed on a V4L2 subdevice.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n> \n> We'll soon need something like that.\n> However, seems like an expensive operation to perform after every control\n> and format update.\n> \n> Opinions ?\n\nI'd rather avoid this if we can. For the example you mention above, I'd\nrather expose a fixed value to express the minimum margin between the\nexposure time and the vertical total size (even possibly hardcoding it\nin userspace like we do today). I hope we'll be able to find similar\nsolutions for the other cases that could benefit from control updates.\nOtherwise, if we *really* have to do this, V4L2 should give us control\ninfo change events.\n\n> ---\n>  include/libcamera/controls.h             |  4 ++\n>  include/libcamera/internal/v4l2_device.h |  2 +\n>  src/libcamera/controls.cpp               | 18 +++++++++\n>  src/libcamera/v4l2_device.cpp            | 48 ++++++++++++++++++++++++\n>  src/libcamera/v4l2_subdevice.cpp         |  3 ++\n>  5 files changed, 75 insertions(+)\n> \n> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> index 80944efc133a..74b0c6b26517 100644\n> --- a/include/libcamera/controls.h\n> +++ b/include/libcamera/controls.h\n> @@ -273,6 +273,10 @@ public:\n>  \tconst ControlValue &max() const { return max_; }\n>  \tconst ControlValue &def() const { return def_; }\n> \n> +\tvoid setMin(ControlValue val) { min_ = val; }\n> +\tvoid setMax(ControlValue val) { max_ = val; }\n> +\tvoid setDef(ControlValue val) { def_ = val; }\n> +\n>  \tstd::string toString() const;\n> \n>  \tbool operator==(const ControlInfo &other) const\n> diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n> index d491eafd262e..1563ec7272c7 100644\n> --- a/include/libcamera/internal/v4l2_device.h\n> +++ b/include/libcamera/internal/v4l2_device.h\n> @@ -42,6 +42,8 @@ protected:\n> \n>  \tint fd() { return fd_; }\n> \n> +\tvoid updateControlsInfo();\n> +\n>  private:\n>  \tvoid listControls();\n>  \tvoid updateControls(ControlList *ctrls,\n> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\n> index dca782667d88..f92128dd1878 100644\n> --- a/src/libcamera/controls.cpp\n> +++ b/src/libcamera/controls.cpp\n> @@ -519,6 +519,24 @@ ControlInfo::ControlInfo(const ControlValue &min,\n>   * \\return A ControlValue with the default value for the control\n>   */\n> \n> +/**\n> + * \\fn ControlInfo::setMin()\n> + * \\brief Set the minimum value for the control\n> + * \\param[in] val The control minimum value\n> + */\n> +\n> +/**\n> + * \\fn ControlInfo::setMax()\n> + * \\brief Set the maximum value for the control\n> + * \\param[in] val The control maximum value\n> + */\n> +\n> +/**\n> + * \\fn ControlInfo::setDef()\n> + * \\brief Set the default value for the control\n> + * \\param[in] val The control default value\n> + */\n> +\n>  /**\n>   * \\brief Provide a string representation of the ControlInfo\n>   */\n> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> index 56ea1ddda2c1..7e1286d7ddd0 100644\n> --- a/src/libcamera/v4l2_device.cpp\n> +++ b/src/libcamera/v4l2_device.cpp\n> @@ -346,6 +346,7 @@ int V4L2Device::setControls(ControlList *ctrls)\n>  \t}\n> \n>  \tupdateControls(ctrls, v4l2Ctrls, count);\n> +\tupdateControlsInfo();\n> \n>  \treturn ret;\n>  }\n> @@ -380,6 +381,53 @@ int V4L2Device::ioctl(unsigned long request, void *argp)\n>   * \\return The V4L2 device file descriptor, -1 if the device node is not open\n>   */\n> \n> +/**\n> + * \\brief Update the control info\n> + *\n> + * Update all control limits (min and max) and default value.\n> + */\n> +void V4L2Device::updateControlsInfo()\n> +{\n> +\tfor (auto &it : controls_) {\n> +\t\tconst ControlId *id = it.first;\n> +\t\tControlInfo &info = it.second;\n> +\t\tstruct v4l2_query_ext_ctrl ctrl = {};\n> +\t\tctrl.id = id->id();\n> +\t\tint ret = ioctl(VIDIOC_QUERY_EXT_CTRL, &ctrl);\n> +\t\tif (ret) {\n> +\t\t\tLOG(V4L2, Error) << \"Unable to query control \"\n> +\t\t\t\t\t << ctrl.id << \": \" << strerror(-ret);\n> +\t\t\treturn;\n> +\t\t}\n> +\n> +\t\tswitch (ctrl.type) {\n> +\t\tcase V4L2_CTRL_TYPE_U8:\n> +\t\t\tinfo.setMin({ static_cast<uint8_t>(ctrl.minimum) });\n> +\t\t\tinfo.setMax({ static_cast<uint8_t>(ctrl.maximum) });\n> +\t\t\tinfo.setDef({ static_cast<uint8_t>(ctrl.default_value) });\n> +\t\t\tbreak;\n> +\n> +\t\tcase V4L2_CTRL_TYPE_BOOLEAN:\n> +\t\t\tinfo.setMin({ static_cast<bool>(ctrl.minimum) });\n> +\t\t\tinfo.setMax({ static_cast<bool>(ctrl.maximum) });\n> +\t\t\tinfo.setDef({ static_cast<bool>(ctrl.default_value) });\n> +\t\t\tbreak;\n> +\n> +\t\tcase V4L2_CTRL_TYPE_INTEGER64:\n> +\t\t\tinfo.setMin({ static_cast<bool>(ctrl.minimum) });\n> +\t\t\tinfo.setMax({ static_cast<bool>(ctrl.maximum) });\n> +\t\t\tinfo.setDef({ static_cast<bool>(ctrl.default_value) });\n> +\t\t\tbreak;\n> +\n> +\t\tdefault:\n> +\t\t\tinfo.setMin({ static_cast<bool>(ctrl.minimum) });\n> +\t\t\tinfo.setMax({ static_cast<bool>(ctrl.maximum) });\n> +\t\t\tinfo.setDef({ static_cast<bool>(ctrl.default_value) });\n> +\t\t\tbreak;\n> +\t\t}\n> +\t}\n> +}\n> +\n>  /*\n>   * \\brief List and store information about all controls supported by the\n>   * V4L2 device\n> diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp\n> index 7aefc1be032d..c0dc036a09cc 100644\n> --- a/src/libcamera/v4l2_subdevice.cpp\n> +++ b/src/libcamera/v4l2_subdevice.cpp\n> @@ -411,6 +411,9 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format,\n>  \tformat->size.height = subdevFmt.format.height;\n>  \tformat->mbus_code = subdevFmt.format.code;\n> \n> +\t/* Changing the format could update the contol limits. */\n> +\tupdateControlsInfo();\n> +\n>  \treturn 0;\n>  }\n>","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id AE9ED603C6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  5 Jun 2020 17:04:18 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 20F7B27C;\n\tFri,  5 Jun 2020 17:04:18 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"X6tcj8Dg\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1591369458;\n\tbh=fWPfQK1+qa2jRbVo+KhdJbDMu0v7bPPZov0U9dm1Py8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=X6tcj8Dgc82C7gIFYLH/Z2V3OpPTCN9F/NrrPgC62W4ILiUUnkNZ21cAaNt7LSV+m\n\tEepiS7DT3OgO9gSjr710/Q3iYRezpOgZ0KMfR4uvs5y9lvAaiO8CK+lxUMcGfF/B7s\n\tmt3WPk9jt466nOJPfoGyPpM5r47cZitxWE4t9FBo=","Date":"Fri, 5 Jun 2020 18:03:59 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200605150359.GC26752@pendragon.ideasonboard.com>","References":"<20200605142037.50260-1-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20200605142037.50260-1-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [RFC] libcamera: v4l2_device: Update control\n\tinfo","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Fri, 05 Jun 2020 15:04:18 -0000"}}]