From patchwork Tue Aug 27 09:50:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1862 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D41C160C1E for ; Tue, 27 Aug 2019 11:48:48 +0200 (CEST) Received: from uno.homenet.telecomitalia.it (unknown [87.18.63.98]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 30201100008; Tue, 27 Aug 2019 09:48:48 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 27 Aug 2019 11:50:06 +0200 Message-Id: <20190827095008.11405-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190827095008.11405-1-jacopo@jmondi.org> References: <20190827095008.11405-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/7] libcamera: v4l2_subdevice: Add selection support X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Aug 2019 09:48:49 -0000 Currently the selection API are implemented by wrappers of the setSelection method. As we add support for more targets, adding new wrapper does not scale well. Make the setSelection operation public and implement getSelection, and require callers to specify the selection target in the operation parameters list. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/include/v4l2_subdevice.h | 9 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 +- src/libcamera/v4l2_subdevice.cpp | 113 ++++++++++++++++--------- 3 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index 9c077674f997..b69b93280894 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -41,8 +41,10 @@ public: const MediaEntity *entity() const { return entity_; } - int setCrop(unsigned int pad, Rectangle *rect); - int setCompose(unsigned int pad, Rectangle *rect); + int getSelection(unsigned int pad, unsigned int target, + Rectangle *rect); + int setSelection(unsigned int pad, unsigned int target, + Rectangle *rect); ImageFormats formats(unsigned int pad); @@ -60,9 +62,6 @@ private: std::vector enumPadSizes(unsigned int pad, unsigned int code); - int setSelection(unsigned int pad, unsigned int target, - Rectangle *rect); - const MediaEntity *entity_; }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 827906d5cd2e..bd027c7f10be 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1071,11 +1071,11 @@ int ImgUDevice::configureInput(const Size &size, .w = inputFormat->size.width, .h = inputFormat->size.height, }; - ret = imgu_->setCrop(PAD_INPUT, &rect); + ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_CROP, &rect); if (ret) return ret; - ret = imgu_->setCompose(PAD_INPUT, &rect); + ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_COMPOSE, &rect); if (ret) return ret; diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index a188298de34c..262dfa23ee57 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -127,25 +127,87 @@ int V4L2Subdevice::open() */ /** - * \brief Set a crop rectangle on one of the V4L2 subdevice pads - * \param[in] pad The 0-indexed pad number the rectangle is to be applied to - * \param[inout] rect The rectangle describing crop target area + * \brief Get the V4L2_SEL_TGT_* selection \a target rectangle on \a pad + * \param[in] pad The 0-indexed pad number to get the selection target from + * \param[in] target The selection target V4L2_SEL_TGT_* as defined by the V4L2 + * selection API + * \param[out] rect The rectangle describing the returned selection target + * + * This operations wraps the VIDIOC_SUBDEV_G_SELECTION ioctl, applied to one of + * the V4L2_SEL_TGT_* targets defined by the V4L2 API on the subdevice \a pad. + * The retrieved selection rectangle is returned in the output parameter \a + * rect. + * * \return 0 on success or a negative error code otherwise */ -int V4L2Subdevice::setCrop(unsigned int pad, Rectangle *rect) +int V4L2Subdevice::getSelection(unsigned int pad, unsigned int target, + Rectangle *rect) { - return setSelection(pad, V4L2_SEL_TGT_CROP, rect); + struct v4l2_subdev_selection sel = {}; + + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; + sel.pad = pad; + sel.target = target; + + int ret = ioctl(VIDIOC_SUBDEV_G_SELECTION, &sel); + if (ret < 0) { + LOG(V4L2, Error) + << "Unable to get rectangle " << target << " on pad " + << pad << ": " << strerror(-ret); + return ret; + } + + rect->x = sel.r.left; + rect->y = sel.r.top; + rect->w = sel.r.width; + rect->h = sel.r.height; + + return 0; } /** - * \brief Set a compose rectangle on one of the V4L2 subdevice pads - * \param[in] pad The 0-indexed pad number the rectangle is to be applied to - * \param[inout] rect The rectangle describing the compose target area + * \brief Set the V4L2_SEL_TGT_* selection \a target rectangle on \a pad + * \param[in] pad The 0-indexed pad number to set the selection target on + * \param[in] target The selection target V4L2_SEL_TGT_* as defined by the V4L2 + * selection API + * \param[inout] rect The rectangle to be applied to the the selection \a target + * + * This operations wraps the VIDIOC_SUBDEV_S_SELECTION ioctl, applied to one of + * the V4L2_SEL_TGT_* targets defined by the V4L2 API on the subdevice \a pad. + * The selection rectangle to apply is described by the parameter \a rect, + * which is updated to reflect what has been actually applied on the subdevice + * when the method returns. + * * \return 0 on success or a negative error code otherwise */ -int V4L2Subdevice::setCompose(unsigned int pad, Rectangle *rect) +int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, + Rectangle *rect) { - return setSelection(pad, V4L2_SEL_TGT_COMPOSE, rect); + struct v4l2_subdev_selection sel = {}; + + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; + sel.pad = pad; + sel.target = target; + + sel.r.left = rect->x; + sel.r.top = rect->y; + sel.r.width = rect->w; + sel.r.height = rect->h; + + int ret = ioctl(VIDIOC_SUBDEV_S_SELECTION, &sel); + if (ret < 0) { + LOG(V4L2, Error) + << "Unable to set rectangle " << target << " on pad " + << pad << ": " << strerror(-ret); + return ret; + } + + rect->x = sel.r.left; + rect->y = sel.r.top; + rect->w = sel.r.width; + rect->h = sel.r.height; + + return 0; } /** @@ -329,35 +391,4 @@ std::vector V4L2Subdevice::enumPadSizes(unsigned int pad, return sizes; } -int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, - Rectangle *rect) -{ - struct v4l2_subdev_selection sel = {}; - - sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; - sel.pad = pad; - sel.target = target; - sel.flags = 0; - - sel.r.left = rect->x; - sel.r.top = rect->y; - sel.r.width = rect->w; - sel.r.height = rect->h; - - int ret = ioctl(VIDIOC_SUBDEV_S_SELECTION, &sel); - if (ret < 0) { - LOG(V4L2, Error) - << "Unable to set rectangle " << target << " on pad " - << pad << ": " << strerror(-ret); - return ret; - } - - rect->x = sel.r.left; - rect->y = sel.r.top; - rect->w = sel.r.width; - rect->h = sel.r.height; - - return 0; -} - } /* namespace libcamera */