From patchwork Fri Jun 5 14:20:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3953 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 42994603C6 for ; Fri, 5 Jun 2020 16:17:41 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from localhost.localdomain (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id BF5EF20006; Fri, 5 Jun 2020 14:17:40 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Fri, 5 Jun 2020 16:20:37 +0200 Message-Id: <20200605142037.50260-1-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [libcamera-devel] [RFC] libcamera: v4l2_device: Update control info X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Jun 2020 14:17:41 -0000 Setting controls on a V4L2 device might update the limits of other related controls (in example, setting a new vertical/horizontal blanking value might modify the available exposure time duration). Add a funtion to update the ControlInfo that represents a control minimum, maximum and default values and call it after a new control has been set and format is changed on a V4L2 subdevice. Signed-off-by: Jacopo Mondi --- We'll soon need something like that. However, seems like an expensive operation to perform after every control and format update. Opinions ? --- include/libcamera/controls.h | 4 ++ include/libcamera/internal/v4l2_device.h | 2 + src/libcamera/controls.cpp | 18 +++++++++ src/libcamera/v4l2_device.cpp | 48 ++++++++++++++++++++++++ src/libcamera/v4l2_subdevice.cpp | 3 ++ 5 files changed, 75 insertions(+) -- 2.27.0 diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 80944efc133a..74b0c6b26517 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -273,6 +273,10 @@ public: const ControlValue &max() const { return max_; } const ControlValue &def() const { return def_; } + void setMin(ControlValue val) { min_ = val; } + void setMax(ControlValue val) { max_ = val; } + void setDef(ControlValue val) { def_ = val; } + std::string toString() const; bool operator==(const ControlInfo &other) const diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h index d491eafd262e..1563ec7272c7 100644 --- a/include/libcamera/internal/v4l2_device.h +++ b/include/libcamera/internal/v4l2_device.h @@ -42,6 +42,8 @@ protected: int fd() { return fd_; } + void updateControlsInfo(); + private: void listControls(); void updateControls(ControlList *ctrls, diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index dca782667d88..f92128dd1878 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -519,6 +519,24 @@ ControlInfo::ControlInfo(const ControlValue &min, * \return A ControlValue with the default value for the control */ +/** + * \fn ControlInfo::setMin() + * \brief Set the minimum value for the control + * \param[in] val The control minimum value + */ + +/** + * \fn ControlInfo::setMax() + * \brief Set the maximum value for the control + * \param[in] val The control maximum value + */ + +/** + * \fn ControlInfo::setDef() + * \brief Set the default value for the control + * \param[in] val The control default value + */ + /** * \brief Provide a string representation of the ControlInfo */ diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 56ea1ddda2c1..7e1286d7ddd0 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -346,6 +346,7 @@ int V4L2Device::setControls(ControlList *ctrls) } updateControls(ctrls, v4l2Ctrls, count); + updateControlsInfo(); return ret; } @@ -380,6 +381,53 @@ int V4L2Device::ioctl(unsigned long request, void *argp) * \return The V4L2 device file descriptor, -1 if the device node is not open */ +/** + * \brief Update the control info + * + * Update all control limits (min and max) and default value. + */ +void V4L2Device::updateControlsInfo() +{ + for (auto &it : controls_) { + const ControlId *id = it.first; + ControlInfo &info = it.second; + struct v4l2_query_ext_ctrl ctrl = {}; + ctrl.id = id->id(); + int ret = ioctl(VIDIOC_QUERY_EXT_CTRL, &ctrl); + if (ret) { + LOG(V4L2, Error) << "Unable to query control " + << ctrl.id << ": " << strerror(-ret); + return; + } + + switch (ctrl.type) { + case V4L2_CTRL_TYPE_U8: + info.setMin({ static_cast(ctrl.minimum) }); + info.setMax({ static_cast(ctrl.maximum) }); + info.setDef({ static_cast(ctrl.default_value) }); + break; + + case V4L2_CTRL_TYPE_BOOLEAN: + info.setMin({ static_cast(ctrl.minimum) }); + info.setMax({ static_cast(ctrl.maximum) }); + info.setDef({ static_cast(ctrl.default_value) }); + break; + + case V4L2_CTRL_TYPE_INTEGER64: + info.setMin({ static_cast(ctrl.minimum) }); + info.setMax({ static_cast(ctrl.maximum) }); + info.setDef({ static_cast(ctrl.default_value) }); + break; + + default: + info.setMin({ static_cast(ctrl.minimum) }); + info.setMax({ static_cast(ctrl.maximum) }); + info.setDef({ static_cast(ctrl.default_value) }); + break; + } + } +} + /* * \brief List and store information about all controls supported by the * V4L2 device diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 7aefc1be032d..c0dc036a09cc 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -411,6 +411,9 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, format->size.height = subdevFmt.format.height; format->mbus_code = subdevFmt.format.code; + /* Changing the format could update the contol limits. */ + updateControlsInfo(); + return 0; }