From patchwork Tue Aug 27 09:50:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1857 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DCD5360C37 for ; Tue, 27 Aug 2019 11:48:44 +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 3DD25100003; Tue, 27 Aug 2019 09:48:44 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 27 Aug 2019 11:50:01 +0200 Message-Id: <20190827095008.11405-2-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 1/7] [TEMP] include: linux: Update v4l2-controls.h 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:45 -0000 Import a temporary version of the v4l2-controls.h with the newly added definition of V4L2_CID_CAMERA_SENSOR_LOCATION control. This patch should be temporary applied waiting for the newly added control to land in the mainline kernel version. Signed-off-by: Jacopo Mondi Acked-by: Laurent Pinchart --- include/linux/v4l2-controls.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/v4l2-controls.h b/include/linux/v4l2-controls.h index 06479f2fb3ae..28061cde5303 100644 --- a/include/linux/v4l2-controls.h +++ b/include/linux/v4l2-controls.h @@ -881,6 +881,13 @@ enum v4l2_auto_focus_range { #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32) #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33) +#define V4L2_CID_CAMERA_SENSOR_LOCATION (V4L2_CID_CAMERA_CLASS_BASE+34) +#define V4L2_LOCATION_FRONT 0 +#define V4L2_LOCATION_BACK 1 +#define V4L2_LOCATION_EXTERNAL 2 + +#define V4L2_CID_CAMERA_SENSOR_ROTATION (V4L2_CID_CAMERA_CLASS_BASE+35) + /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) From patchwork Tue Aug 27 09:50:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1858 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 9D4F660C37 for ; Tue, 27 Aug 2019 11:48:45 +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 168F2100003; Tue, 27 Aug 2019 09:48:44 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 27 Aug 2019 11:50:02 +0200 Message-Id: <20190827095008.11405-3-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 2/7] libcamera: controls: Document control_ids.h 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:45 -0000 The control identifiers documentation was not generated as they're not part of the controls.h file documented in controls.cpp. Move documentation for control id to the end of the controls.cpp and document the control_ids.h file to have documentation for controls properly generated. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/libcamera/controls.cpp | 100 ++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 727fdbd9450d..9adc3badc254 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -181,53 +181,6 @@ std::string ControlValue::toString() const return ""; } -/** - * \enum ControlId - * \brief Numerical control ID - */ - -/** - * \var AwbEnable - * ControlType: Bool - * - * Enables or disables the AWB. See also \a libcamera::ControlId::ManualGain - */ - -/** - * \var Brightness - * ControlType: Integer - * - * Specify a fixed brightness parameter. - */ - -/** - * \var Contrast - * ControlType: Integer - * - * Specify a fixed contrast parameter. - */ - -/** - * \var Saturation - * ControlType: Integer - * - * Specify a fixed saturation parameter. - */ - -/** - * \var ManualExposure - * ControlType: Integer - * - * Specify a fixed exposure time in milli-seconds - */ - -/** - * \var ManualGain - * ControlType: Integer - * - * Specify a fixed gain parameter - */ - /** * \struct ControlIdentifier * \brief Describe a ControlId with control specific constant meta-data @@ -549,4 +502,57 @@ void ControlList::update(const ControlList &other) } } +/** + * \file control_ids.h + * \brief Definition of numerical identifiers for libcamera control and + * properties + */ + +/** + * \enum ControlId + * \brief Numerical control ID + */ + +/** + * \var AwbEnable + * ControlType: Bool + * + * Enables or disables the AWB. See also \a libcamera::ControlId::ManualGain + */ + +/** + * \var Brightness + * ControlType: Integer + * + * Specify a fixed brightness parameter. + */ + +/** + * \var Contrast + * ControlType: Integer + * + * Specify a fixed contrast parameter. + */ + +/** + * \var Saturation + * ControlType: Integer + * + * Specify a fixed saturation parameter. + */ + +/** + * \var ManualExposure + * ControlType: Integer + * + * Specify a fixed exposure time in milli-seconds + */ + +/** + * \var ManualGain + * ControlType: Integer + * + * Specify a fixed gain parameter + */ + } /* namespace libcamera */ From patchwork Tue Aug 27 09:50:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1859 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 8256C60E38 for ; Tue, 27 Aug 2019 11:48:46 +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 C8C3C100003; Tue, 27 Aug 2019 09:48:45 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 27 Aug 2019 11:50:03 +0200 Message-Id: <20190827095008.11405-4-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 3/7] libcamera: controls: Add camera properties IDs 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:46 -0000 Add the PropertyID enumeration where to list the camera static properties supported by libcamera. Initially add the Location and Rotation properties Signed-off-by: Jacopo Mondi --- include/libcamera/control_ids.h | 11 +++++++ src/libcamera/controls.cpp | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/include/libcamera/control_ids.h b/include/libcamera/control_ids.h index 75b6a2d5cafe..d8c3c3265ee6 100644 --- a/include/libcamera/control_ids.h +++ b/include/libcamera/control_ids.h @@ -21,6 +21,17 @@ enum ControlId { ManualGain, }; +enum CameraLocation { + CAMERA_LOCATION_EXTERNAL, + CAMERA_LOCATION_FRONT, + CAMERA_LOCATION_BACK, +}; + +enum PropertyId { + Location, + Rotation, +}; + } /* namespace libcamera */ namespace std { diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 9adc3badc254..9562ecc189bb 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -555,4 +555,59 @@ void ControlList::update(const ControlList &other) * Specify a fixed gain parameter */ +/** + * \enum CameraLocation + * \brief List the supported mounting location of a camera + */ + +/** + * \var CameraLocation::CAMERA_LOCATION_EXTERNAL + * \brief Identify an external camera + * + * The camera is connected to the main device through extension cables + * and is freely movable. Typical examples of externally mounted cameras are + * webcams and digital camera devices. + */ + +/** + * \var CameraLocation::CAMERA_LOCATION_FRONT + * \brief Identify a camera mounted in the device front location + * + * The camera is mounted on the front side of the device, which is typically + * the user facing side. + */ + +/** + * \var CameraLocation::CAMERA_LOCATION_BACK + * \brief Identify a camera mounted in the device back location + * + * The camera is mounted on the back side of the device, which is typically + * the side opposed to the front one. + */ + +/** + * \enum PropertyId + * \brief Numerical properties ID + * + * List the identifiers of the static properties exposed by a Camera. + */ + +/** + * \var PropertyId::Location + * \brief The camera mounting location + * + * The Camera device location is expressed as the position relative to the + * device intended usage orientation. Possible values are identified by the + * libcamera::CameraLocation enumeration. + */ + +/** + * \var PropertyId::Rotation + * \brief The camera sensor rotation + * + * The Camera rotation is expressed as counter-clockwise rotation in degrees + * in respect to the intended device orientation. Typical values are 0 for + * upright mounted cameras, and 180 for cameras mounted upside down. + */ + } /* namespace libcamera */ From patchwork Tue Aug 27 09:50:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1860 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 4C72161924 for ; Tue, 27 Aug 2019 11:48:47 +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 AD7CF10000D; Tue, 27 Aug 2019 09:48:46 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 27 Aug 2019 11:50:04 +0200 Message-Id: <20190827095008.11405-5-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 4/7] libcamera: v4l2_controls: Construct from a list of ids 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:47 -0000 Add a constructor for the V4L2ControlList class that accepts a list of V4L2 control IDs (V4L2_CID_*). The constructor returns a V4L2ControlList instance to be used for reading controls only. Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_controls.h | 3 +++ src/libcamera/v4l2_controls.cpp | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index 10b726504951..86c84e06d741 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -65,6 +65,9 @@ public: using iterator = std::vector::iterator; using const_iterator = std::vector::const_iterator; + V4L2ControlList() {} + V4L2ControlList(std::vector ids); + iterator begin() { return controls_.begin(); } const_iterator begin() const { return controls_.begin(); } iterator end() { return controls_.end(); } diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index 84258d9954d0..eeb325cbfff9 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -202,6 +202,23 @@ V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl) * and prepare to be re-used for a new control write/read sequence. */ +/** + * \brief Construct a V4L2ControlList from a list of V4L2 controls identifiers + * \param ids A list of V4L2 control identifiers (V4L2_CID_*) + * + * Construct a V4L2ControlList from a list of control identifiers without any + * value associated. This constructor is particularly useful to create a + * V4L2ControlList that is used to read the values of all controls in the + * \a ids list. The created V4L2ControlList should not be used to write control + * values unless it is cleared first and then controls with an associated value + * are manually added to it. + */ +V4L2ControlList::V4L2ControlList(std::vector ids) +{ + for (auto id : ids) + add(id); +} + /** * \typedef V4L2ControlList::iterator * \brief Iterator on the V4L2 controls contained in the instance From patchwork Tue Aug 27 09:50:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1861 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 0534461580 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 796BF100008; Tue, 27 Aug 2019 09:48:47 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 27 Aug 2019 11:50:05 +0200 Message-Id: <20190827095008.11405-6-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 5/7] libcamera: camera_sensor: Collect camera properties 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:48 -0000 Store the camera sensor location and rotation by parsing the associated V4L2 controls. Signed-off-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 39 +++++++++++++++++++++++++++ src/libcamera/include/camera_sensor.h | 4 +++ 2 files changed, 43 insertions(+) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index a7670b449b31..fc7fdcdcaf5b 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -89,6 +89,45 @@ int CameraSensor::init() if (ret < 0) return ret; + /* Retrieve and store the camera sensor properties. */ + V4L2ControlList controls({ + V4L2_CID_CAMERA_SENSOR_LOCATION, + V4L2_CID_CAMERA_SENSOR_ROTATION, + }); + ret = subdev_->getControls(&controls); + if (ret) { + LOG(CameraSensor, Error) + << "Failed to get camera sensor controls: " << ret; + return ret; + } + + V4L2Control *control = controls[V4L2_CID_CAMERA_SENSOR_LOCATION]; + int64_t value = control->value(); + switch (value) { + case V4L2_LOCATION_EXTERNAL: + location_ = CAMERA_LOCATION_EXTERNAL; + break; + case V4L2_LOCATION_FRONT: + location_ = CAMERA_LOCATION_FRONT; + break; + case V4L2_LOCATION_BACK: + location_ = CAMERA_LOCATION_BACK; + break; + default: + LOG(CameraSensor, Error) + << "Unsupported camera location: " << value; + return -EINVAL; + } + + control = controls[V4L2_CID_CAMERA_SENSOR_ROTATION]; + value = control->value(); + if (value < 0 || value > 360) { + LOG(CameraSensor, Error) + << "Unsupported camera rotation: " << value; + return -EINVAL; + } + rotation_ = value; + /* Enumerate and cache media bus codes and sizes. */ const ImageFormats formats = subdev_->formats(0); if (formats.isEmpty()) { diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h index fe033fb374c1..32d39127b275 100644 --- a/src/libcamera/include/camera_sensor.h +++ b/src/libcamera/include/camera_sensor.h @@ -10,6 +10,7 @@ #include #include +#include #include #include "log.h" @@ -55,6 +56,9 @@ private: std::vector mbusCodes_; std::vector sizes_; + + CameraLocation location_; + unsigned int rotation_; }; } /* namespace libcamera */ 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 */ From patchwork Tue Aug 27 09:50:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1863 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 BB6A160C1E for ; Tue, 27 Aug 2019 11:48:49 +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 0EB59100008; 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:07 +0200 Message-Id: <20190827095008.11405-8-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 7/7] libcamera: camera_sensor: Retrieve sensor sizes 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 Retrieve the camera sensor pixel array sizes and the active pixel area using the V4L2Subdevice selection API. Signed-off-by: Jacopo Mondi --- include/libcamera/geometry.h | 1 + src/libcamera/camera_sensor.cpp | 51 +++++++++++++++++++++++++++ src/libcamera/geometry.cpp | 24 +++++++++++++ src/libcamera/include/camera_sensor.h | 4 +++ 4 files changed, 80 insertions(+) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 52f4d010de76..b91fcfa1dd17 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -42,6 +42,7 @@ struct Size { unsigned int height; const std::string toString() const; + bool contains(const Rectangle &rectangle) const; }; bool operator==(const Size &lhs, const Size &rhs); diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index fc7fdcdcaf5b..b6ccaae0930b 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -128,6 +128,28 @@ int CameraSensor::init() } rotation_ = value; + /* + * Retrieve and store the sensor pixel array size and active area + * rectangle. + */ + Rectangle rect; + ret = subdev_->getSelection(0, V4L2_SEL_TGT_NATIVE_SIZE, &rect); + if (ret) + return ret; + pixelArray_.width = rect.w; + pixelArray_.height = rect.h; + + ret = subdev_->getSelection(0, V4L2_SEL_TGT_CROP_BOUNDS, &rect); + if (ret) + return ret; + + if (!pixelArray_.contains(rect)) { + LOG(CameraSensor, Error) + << "Invalid camera sensor pixel array dimension"; + return -EINVAL; + } + activeArea_ = rect; + /* Enumerate and cache media bus codes and sizes. */ const ImageFormats formats = subdev_->formats(0); if (formats.isEmpty()) { @@ -192,6 +214,35 @@ const Size &CameraSensor::resolution() const return sizes_.back(); } +/** + * \fn CameraSensor::pixelArray() + * \brief Retrieve the camera sensor pixel array dimension + * \return The number of horizontal and vertical pixel units installed on the + * camera sensor + * + * The returned pixel array size is the number of pixels units physically + * installed on the sensor, including non-active ones, such as pixels used + * for calibration or testing. + */ + +/** + * \fn CameraSensor::activeArea() + * \brief Retrieve the active pixels area + * \return A rectangle describing the active pixel area + * + * The returned rectangle is contained in the larger pixel array area, + * returned by the CameraSensor::pixelArray() operation. + * + * \todo This operation collides with CameraSensor::resolution() as they + * both reports the same information (bugs in the driver code apart). + * Also, for some sensors, the maximum available resolution might depend on + * the image size ratio (ie the maximumx resolution for images in 4:3 format + * is different from the maximum available resolution for 16:9 format). This + * has to be sorted out as well. + * + * \sa Size::contains() + */ + /** * \brief Retrieve the best sensor format for a desired output * \param[in] mbusCodes The list of acceptable media bus codes diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index 32b0faeadc63..9b60768a57a7 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -116,6 +116,30 @@ const std::string Size::toString() const return std::to_string(width) + "x" + std::to_string(height); } +/** + * \fn Size::contains() + * \param rectangle The rectangle to verify + * \return True if \a rectangle is contained in the area represented by this + * Size, false otherwise + * + * Return true if \a rectangle is completely contained in the area represented + * by the width and height of this Size, with its top left corner assumed to be + * at coordinates (0, 0). The rectangle 'x' and 'y' fields represent the + * horizontal and vertical positive displacement from the Size top left corner, + * from where the rectangle's horizontal and vertical sizes are calculated. + */ +bool Size::contains(const Rectangle &rectangle) const +{ + if (rectangle.x < 0 || rectangle.y < 0) + return false; + + if (rectangle.x + rectangle.w > width || + rectangle.y + rectangle.h > height) + return false; + + return true; +} + /** * \brief Compare sizes for equality * \return True if the two sizes are equal, false otherwise diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h index 32d39127b275..abf5344cf9d8 100644 --- a/src/libcamera/include/camera_sensor.h +++ b/src/libcamera/include/camera_sensor.h @@ -38,6 +38,8 @@ public: const std::vector &mbusCodes() const { return mbusCodes_; } const std::vector &sizes() const { return sizes_; } const Size &resolution() const; + const Size pixelArray() const { return pixelArray_; } + const Rectangle activeArea() const { return activeArea_; } V4L2SubdeviceFormat getFormat(const std::vector &mbusCodes, const Size &size) const; @@ -59,6 +61,8 @@ private: CameraLocation location_; unsigned int rotation_; + Size pixelArray_; + Rectangle activeArea_; }; } /* namespace libcamera */