From patchwork Thu Feb 28 20:01:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 669 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D659A610B6 for ; Thu, 28 Feb 2019 21:01:30 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 15FD8100006; Thu, 28 Feb 2019 20:01:29 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:43 +0100 Message-Id: <20190228200151.2948-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 1/9] libcamera: v4l2_subdevice: Store media entity 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: Thu, 28 Feb 2019 20:01:31 -0000 Store the media entity backing the V4L2Subdevice and add a deviceName() method to retrieve the human readable name of the subdevice, which is created using the name of the associated media entity. Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_subdevice.h | 8 +++++--- src/libcamera/v4l2_subdevice.cpp | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index 82fa6685ab52..eac699a06109 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -9,9 +9,10 @@ #include +#include "media_object.h" + namespace libcamera { -class MediaEntity; struct Rectangle; struct V4L2SubdeviceFormat { @@ -31,7 +32,8 @@ public: bool isOpen() const; void close(); - std::string deviceNode() const { return deviceNode_; } + std::string deviceNode() const { return entity_->deviceNode(); } + std::string deviceName() const { return entity_->name(); } int setCrop(unsigned int pad, Rectangle *rect); int setCompose(unsigned int pad, Rectangle *rect); @@ -43,7 +45,7 @@ private: int setSelection(unsigned int pad, unsigned int target, Rectangle *rect); - std::string deviceNode_; + const MediaEntity *entity_; int fd_; }; diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index b436f73cc75f..c44cafd4b4c5 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -88,7 +88,7 @@ LOG_DEFINE_CATEGORY(V4L2Subdev) * path */ V4L2Subdevice::V4L2Subdevice(const MediaEntity *entity) - : deviceNode_(entity->deviceNode()), fd_(-1) + : entity_(entity), fd_(-1) { } @@ -106,11 +106,11 @@ int V4L2Subdevice::open() return -EBUSY; } - ret = ::open(deviceNode_.c_str(), O_RDWR); + ret = ::open(deviceNode().c_str(), O_RDWR); if (ret < 0) { ret = -errno; LOG(V4L2Subdev, Error) - << "Failed to open V4L2 subdevice '" << deviceNode_ + << "Failed to open V4L2 subdevice '" << deviceNode() << "': " << strerror(-ret); return ret; } @@ -147,6 +147,13 @@ void V4L2Subdevice::close() * \return The subdevice's device node system path */ +/** + * \fn V4L2Subdevice::deviceName() + * \brief Retrieve the name of the media entity associated with the subdevice + * + * \return The name of the media entity the subdevice is associated to + */ + /** * \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 @@ -189,7 +196,7 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format) ret = -errno; LOG(V4L2Subdev, Error) << "Unable to get format on pad " << pad - << " of " << deviceNode_ << ": " << strerror(-ret); + << " of " << deviceNode() << ": " << strerror(-ret); return ret; } @@ -255,7 +262,7 @@ int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, ret = -errno; LOG(V4L2Subdev, Error) << "Unable to set rectangle " << target << " on pad " - << pad << " of " << deviceNode_ << ": " + << pad << " of " << deviceNode() << ": " << strerror(-ret); return ret; } From patchwork Thu Feb 28 20:01:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 670 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D7FF1610BF for ; Thu, 28 Feb 2019 21:01:31 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 0D65210000A; Thu, 28 Feb 2019 20:01:30 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:44 +0100 Message-Id: <20190228200151.2948-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 2/9] libcamera: v4l2_subdevice: Inherit from Loggable 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: Thu, 28 Feb 2019 20:01:32 -0000 Prefix the V4L2Subdevice error messages with the name of the entity. Remove the manually printed name from log messages where it was used and standardize error messages while at there. Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_subdevice.h | 6 +++++- src/libcamera/v4l2_subdevice.cpp | 13 +++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index eac699a06109..669e79f9a9fd 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -9,6 +9,7 @@ #include +#include "log.h" #include "media_object.h" namespace libcamera { @@ -21,7 +22,7 @@ struct V4L2SubdeviceFormat { uint32_t height; }; -class V4L2Subdevice +class V4L2Subdevice : protected Loggable { public: explicit V4L2Subdevice(const MediaEntity *entity); @@ -41,6 +42,9 @@ public: int getFormat(unsigned int pad, V4L2SubdeviceFormat *format); int setFormat(unsigned int pad, V4L2SubdeviceFormat *format); +protected: + std::string logPrefix() const; + private: int setSelection(unsigned int pad, unsigned int target, Rectangle *rect); diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index c44cafd4b4c5..4fe59c45f000 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -154,6 +154,11 @@ void V4L2Subdevice::close() * \return The name of the media entity the subdevice is associated to */ +std::string V4L2Subdevice::logPrefix() const +{ + return "'" + deviceName() + "'"; +} + /** * \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 @@ -196,7 +201,7 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format) ret = -errno; LOG(V4L2Subdev, Error) << "Unable to get format on pad " << pad - << " of " << deviceNode() << ": " << strerror(-ret); + << ": " << strerror(-ret); return ret; } @@ -231,7 +236,8 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format) if (ret) { ret = -errno; LOG(V4L2Subdev, Error) - << "Unable to set format: " << strerror(-ret); + << "Unable to set format on pad " << pad + << ": " << strerror(-ret); return ret; } @@ -262,8 +268,7 @@ int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, ret = -errno; LOG(V4L2Subdev, Error) << "Unable to set rectangle " << target << " on pad " - << pad << " of " << deviceNode() << ": " - << strerror(-ret); + << pad << ": " << strerror(-ret); return ret; } From patchwork Thu Feb 28 20:01:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 671 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8017E610B6 for ; Thu, 28 Feb 2019 21:01:32 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 089B3100006; Thu, 28 Feb 2019 20:01:31 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:45 +0100 Message-Id: <20190228200151.2948-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 3/9] libcamera: v4l2_subdevice: Implement ENUM_FRAME_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: Thu, 28 Feb 2019 20:01:32 -0000 Implement enumFormat() methods to enumerate the available image resolutions on the subdevice. Signed-off-by: Jacopo Mondi --- src/libcamera/geometry.cpp | 34 +++++++++++ src/libcamera/include/geometry.h | 12 ++++ src/libcamera/include/v4l2_subdevice.h | 11 +++- src/libcamera/v4l2_subdevice.cpp | 84 ++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 2 deletions(-) diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index 57f4fc7716d9..f41f6975d4ce 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -46,4 +46,38 @@ namespace libcamera { * \brief The distance between the top and bottom sides */ +/** + * \struct SizeRange + * \brief Describe a range of image sizes + * + * SizeRange describes a range of image sizes included in the (maxWidth, + * maxHeight) - (minWidth, minHeight) interval. If the minimum and + * maximum sizes are identical it represents a single image resolution. + */ + +/** + * \fn SizeRange::SizeRange() + * \brief Construct a size range + */ + +/** + * \var SizeRange::minWidth + * \brief The minimum image width + */ + +/** + * \var SizeRange::minHeight + * \brief The minimum image height + */ + +/** + * \var SizeRange::maxWidth + * \brief The maximum image width + */ + +/** + * \var SizeRange::maxHeight + * \brief The maximum image height + */ + } /* namespace libcamera */ diff --git a/src/libcamera/include/geometry.h b/src/libcamera/include/geometry.h index cc146da7cb0d..eadc4ed4f9cb 100644 --- a/src/libcamera/include/geometry.h +++ b/src/libcamera/include/geometry.h @@ -17,6 +17,18 @@ struct Rectangle { unsigned int h; }; +struct SizeRange { + SizeRange(unsigned int minW, unsigned int minH, + unsigned int maxW, unsigned int maxH) + : minWidth(minW), minHeight(minH), maxWidth(maxW), + maxHeight(maxH) {} + + unsigned int minWidth; + unsigned int minHeight; + unsigned int maxWidth; + unsigned int maxHeight; +}; + } /* namespace libcamera */ #endif /* __LIBCAMERA_GEOMETRY_H__ */ diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index 669e79f9a9fd..aa7451e86962 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -7,15 +7,16 @@ #ifndef __LIBCAMERA_V4L2_SUBDEVICE_H__ #define __LIBCAMERA_V4L2_SUBDEVICE_H__ +#include #include +#include +#include "geometry.h" #include "log.h" #include "media_object.h" namespace libcamera { -struct Rectangle; - struct V4L2SubdeviceFormat { uint32_t mbus_code; uint32_t width; @@ -39,6 +40,9 @@ public: int setCrop(unsigned int pad, Rectangle *rect); int setCompose(unsigned int pad, Rectangle *rect); + const std::map> + formats(unsigned int pad); + int getFormat(unsigned int pad, V4L2SubdeviceFormat *format); int setFormat(unsigned int pad, V4L2SubdeviceFormat *format); @@ -46,6 +50,9 @@ protected: std::string logPrefix() const; private: + std::vector enumPadSizes(unsigned int pad, + unsigned int code); + int setSelection(unsigned int pad, unsigned int target, Rectangle *rect); diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 4fe59c45f000..7f191e072c61 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -183,6 +183,58 @@ int V4L2Subdevice::setCompose(unsigned int pad, Rectangle *rect) return setSelection(pad, V4L2_SEL_TGT_COMPOSE, rect); } +/** + * \brief List the sub-device image resolutions and formats on \a pad + * \param[in] pad The 0-indexed pad number to enumerate formats on + * + * Retrieve a list of image formats and sizes on the \a pad of a video + * subdevice. Subdevices are free to report a list of discrete sizes they + * support, or a single size interval expressed as a [min-max] sizes range. + * + * Each image size list is associated with a media bus pixel code for which + * the reported resolutions are supported. + * + * \return A, map of image formats associated with a list of image sizes, or + * an empty map on error or if the pad does not exists + * \sa SizeRange + */ +const std::map> +V4L2Subdevice::formats(unsigned int pad) +{ + std::map> formatMap = {}; + struct v4l2_subdev_mbus_code_enum mbusEnum = {}; + int ret; + + if (pad > entity_->pads().size()) { + LOG(V4L2Subdev, Error) + << "Format enumeration required on a non-existing pad: " + << pad; + return formatMap; + } + + mbusEnum.pad = pad; + mbusEnum.index = 0; + mbusEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; + while (true) { + ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbusEnum); + if (ret) + break; + + formatMap[mbusEnum.code] = enumPadSizes(pad, mbusEnum.code); + + mbusEnum.index++; + } + + if (ret && (errno != EINVAL && errno != ENOTTY)) { + LOG(V4L2Subdev, Error) + << "Unable to enumerate format on pad " << pad + << ": " << strerror(errno); + formatMap.clear(); + } + + return formatMap; +} + /** * \brief Retrieve the image format set on one of the V4L2 subdevice pads * \param[in] pad The 0-indexed pad number the format is to be retrieved from @@ -248,6 +300,38 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format) return 0; } +std::vector V4L2Subdevice::enumPadSizes(unsigned int pad, + unsigned int code) +{ + struct v4l2_subdev_frame_size_enum sizeEnum = {}; + std::vector sizes = {}; + int ret; + + sizeEnum.index = 0; + sizeEnum.pad = pad; + sizeEnum.code = code; + sizeEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; + while (true) { + ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &sizeEnum); + if (ret) + break; + + sizes.emplace_back(sizeEnum.min_width, sizeEnum.min_height, + sizeEnum.max_width, sizeEnum.max_height); + + sizeEnum.index++; + } + + if (ret && (errno != EINVAL && errno != ENOTTY)) { + LOG(V4L2Subdev, Error) + << "Unable to enumerate sizes on pad " << pad + << ": " << strerror(errno); + sizes.clear(); + } + + return sizes; +} + int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, Rectangle *rect) { From patchwork Thu Feb 28 20:01:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 672 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 63754610C4 for ; Thu, 28 Feb 2019 21:01:33 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id AC6FD100002; Thu, 28 Feb 2019 20:01:32 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:46 +0100 Message-Id: <20190228200151.2948-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 4/9] libcamera: v4l2_device: Add support for META_CAPTURE devices 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: Thu, 28 Feb 2019 20:01:33 -0000 Add support for devices that provide video meta-data to v4l2_device.cpp and re-arrange bufferType handling in open() method. Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/include/v4l2_device.h | 4 +++ src/libcamera/v4l2_device.cpp | 38 +++++++++++++++++------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 1d31d1b403bc..733bd69959f3 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -53,6 +53,10 @@ struct V4L2Capability final : v4l2_capability { return device_caps() & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE); } + bool isMetaCapture() const + { + return device_caps() & V4L2_CAP_META_CAPTURE; + } bool isOutput() const { return device_caps() & (V4L2_CAP_VIDEO_OUTPUT | diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 24e115554a99..9bfa10e8a151 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -79,6 +79,15 @@ LOG_DEFINE_CATEGORY(V4L2) * \return True if the device can output video frames */ +/** + * \fn bool V4L2Capability::isMetaCapture() + * \brief Identify if the device is capable of providing video meta-data + * + * TODO: add support for META_OUTPUT, introduced in Linux v5.0 + * + * \return True if the device can capture video meta-data + */ + /** * \fn bool V4L2Capability::hasStreaming() * \brief Determine if the device can perform Streaming I/O @@ -280,33 +289,32 @@ int V4L2Device::open() << "Opened device " << caps_.bus_info() << ": " << caps_.driver() << ": " << caps_.card(); - if (!caps_.isCapture() && !caps_.isOutput()) { - LOG(V4L2, Debug) << "Device is not a supported type"; - return -EINVAL; - } - if (!caps_.hasStreaming()) { LOG(V4L2, Error) << "Device does not support streaming I/O"; return -EINVAL; } - if (caps_.isCapture()) + /* + * Set buffer type and wait for read notifications on CAPTURE devices + * (POLLIN), and write notifications for OUTPUT devices (POLLOUT). + */ + if (caps_.isCapture()) { + fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); bufferType_ = caps_.isMultiplanar() ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE; - else + } else if (caps_.isOutput()) { + fdEvent_ = new EventNotifier(fd_, EventNotifier::Write); bufferType_ = caps_.isMultiplanar() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT; - - /* - * We wait for Read notifications on CAPTURE devices (POLLIN), and - * Write notifications for OUTPUT devices (POLLOUT). - */ - if (caps_.isCapture()) + } else if (caps_.isMetaCapture()) { fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); - else - fdEvent_ = new EventNotifier(fd_, EventNotifier::Write); + bufferType_ = V4L2_BUF_TYPE_META_CAPTURE; + } else { + LOG(V4L2, Debug) << "Device is not a supported type"; + return -EINVAL; + } fdEvent_->activated.connect(this, &V4L2Device::bufferAvailable); fdEvent_->setEnabled(false); From patchwork Thu Feb 28 20:01:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 673 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EF0E3610C4 for ; Thu, 28 Feb 2019 21:01:33 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 87F1610000A; Thu, 28 Feb 2019 20:01:33 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:47 +0100 Message-Id: <20190228200151.2948-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 5/9] libcamera: v4l2_subdevice: Update crop/compose rectangle 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: Thu, 28 Feb 2019 20:01:34 -0000 Update the crop/compose rectangle provided to setCrop()/setCompose() methods with the rectangle sizes set by the device driver after a S_SELECTION ioctl operation. While at there, fix the use of 'top' and 'left' field of the selection rectangle, which where wrongly used. Fixes: 468176fa07d9 ("libcamera: Add V4L2Subdevice") Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/v4l2_subdevice.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 7f191e072c61..d2f9365a9537 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -342,8 +342,8 @@ int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, sel.target = target; sel.flags = 0; - sel.r.left = rect->y; - sel.r.top = rect->x; + sel.r.left = rect->x; + sel.r.top = rect->y; sel.r.width = rect->w; sel.r.height = rect->h; @@ -356,6 +356,11 @@ int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, return ret; } + rect->x = sel.r.left; + rect->y = sel.r.top; + rect->w = sel.r.width; + rect->h = sel.r.height; + return 0; } From patchwork Thu Feb 28 20:01:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 674 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 939B7610CC for ; Thu, 28 Feb 2019 21:01:34 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 245D7100002; Thu, 28 Feb 2019 20:01:33 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:48 +0100 Message-Id: <20190228200151.2948-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 6/9] libcamera: v4l2_device: Expose the device node path 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: Thu, 28 Feb 2019 20:01:34 -0000 Provide a getter method to access the device node path. For video devices it is usually the most informative description. Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_device.h | 1 + src/libcamera/v4l2_device.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 733bd69959f3..e1f79e730ec5 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -99,6 +99,7 @@ public: const char *driverName() const { return caps_.driver(); } const char *deviceName() const { return caps_.card(); } const char *busName() const { return caps_.bus_info(); } + const std::string deviceNode() const { return deviceNode_; } int getFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format); diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 9bfa10e8a151..b498d4e0bf92 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -364,6 +364,12 @@ void V4L2Device::close() * \return The string containing the device location */ +/** + * \fn const std::string V4L2Device::deviceNode() + * \brief Retrieve the video device node path + * \return The video device deviceNode path + */ + std::string V4L2Device::logPrefix() const { return deviceNode_; From patchwork Thu Feb 28 20:01:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 675 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 96935610B7 for ; Thu, 28 Feb 2019 21:01:35 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id BABEF100006; Thu, 28 Feb 2019 20:01:34 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:49 +0100 Message-Id: <20190228200151.2948-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 7/9] test: v4l2_subdevice: Add format handling test 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: Thu, 28 Feb 2019 20:01:36 -0000 Add test for video format get and set operations on V4L2Subdevice class. Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- test/meson.build | 1 + test/v4l2_subdevice/meson.build | 10 +++ test/v4l2_subdevice/test_formats.cpp | 78 ++++++++++++++++++ test/v4l2_subdevice/v4l2_subdevice_test.cpp | 89 +++++++++++++++++++++ test/v4l2_subdevice/v4l2_subdevice_test.h | 36 +++++++++ 5 files changed, 214 insertions(+) create mode 100644 test/v4l2_subdevice/meson.build create mode 100644 test/v4l2_subdevice/test_formats.cpp create mode 100644 test/v4l2_subdevice/v4l2_subdevice_test.cpp create mode 100644 test/v4l2_subdevice/v4l2_subdevice_test.h diff --git a/test/meson.build b/test/meson.build index d515a716207e..5fb16fa6afb6 100644 --- a/test/meson.build +++ b/test/meson.build @@ -3,6 +3,7 @@ subdir('libtest') subdir('media_device') subdir('pipeline') subdir('v4l2_device') +subdir('v4l2_subdevice') public_tests = [ ['event', 'event.cpp'], diff --git a/test/v4l2_subdevice/meson.build b/test/v4l2_subdevice/meson.build new file mode 100644 index 000000000000..f45dca0d23d7 --- /dev/null +++ b/test/v4l2_subdevice/meson.build @@ -0,0 +1,10 @@ +v4l2_subdevice_tests = [ + [ 'test_formats', 'test_formats.cpp'], +] + +foreach t : v4l2_subdevice_tests + exe = executable(t[0], [t[1], 'v4l2_subdevice_test.cpp'], + link_with : test_libraries, + include_directories : test_includes_internal) + test(t[0], exe, suite: 'v4l2_subdevice', is_parallel: false) +endforeach diff --git a/test/v4l2_subdevice/test_formats.cpp b/test/v4l2_subdevice/test_formats.cpp new file mode 100644 index 000000000000..af954459a3d8 --- /dev/null +++ b/test/v4l2_subdevice/test_formats.cpp @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 Subdevice format handling test + */ + +#include +#include + +#include "v4l2_subdevice.h" +#include "v4l2_subdevice_test.h" + +using namespace std; +using namespace libcamera; + +/* Test format handling on the "Scaler" subdevice of vimc media device. */ + +class FormatHandlingTest : public V4L2SubdeviceTest +{ +protected: + int run() override; +}; + +int FormatHandlingTest::run() +{ + V4L2SubdeviceFormat format = {}; + + /* + * Get format on a non-existing Scaler pad: expect failure. + */ + int ret = scaler_->getFormat(2, &format); + if (!ret) { + cerr << "Getting format on a non existing pad should fail" << endl; + return TestFail; + } + + ret = scaler_->getFormat(0, &format); + if (ret) { + cerr << "Failed to get format" << endl; + return TestFail; + } + + /* + * Set unrealistic image resolutions and make sure it gets updated. + */ + format.width = UINT_MAX; + format.height = UINT_MAX; + ret = scaler_->setFormat(0, &format); + if (ret) { + cerr << "Failed to set format: image resolution is wrong, but " + << "setFormat() should not fail." << endl; + return TestFail; + } + + if (format.width == UINT_MAX || format.height == UINT_MAX) { + cerr << "Failed to update image format" << endl; + return TestFail; + } + + format.width = 0; + format.height = 0; + ret = scaler_->setFormat(0, &format); + if (ret) { + cerr << "Failed to set format: image resolution is wrong, but " + << "setFormat() should not fail." << endl; + return TestFail; + } + + if (format.width == 0 || format.height == 0) { + cerr << "Failed to update image format" << endl; + return TestFail; + } + + return TestPass; +} + +TEST_REGISTER(FormatHandlingTest); diff --git a/test/v4l2_subdevice/v4l2_subdevice_test.cpp b/test/v4l2_subdevice/v4l2_subdevice_test.cpp new file mode 100644 index 000000000000..a110f05339a1 --- /dev/null +++ b/test/v4l2_subdevice/v4l2_subdevice_test.cpp @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * v4l2_subdevice_test.cpp - VIMC-based V4L2 subdevice test + */ + +#include +#include +#include + +#include "device_enumerator.h" +#include "media_device.h" +#include "v4l2_subdevice.h" +#include "v4l2_subdevice_test.h" + +using namespace std; +using namespace libcamera; + +/* + * This test runs on vimc media device. For a description of vimc, in the + * context of libcamera testing, please refer to + * 'test/media_device/media_device_link_test.cpp' file. + * + * If the vimc module is not loaded, the test gets skipped. + */ + +int V4L2SubdeviceTest::init() +{ + enumerator_ = DeviceEnumerator::create(); + if (!enumerator_) { + cerr << "Failed to create device enumerator" << endl; + return TestFail; + } + + if (enumerator_->enumerate()) { + cerr << "Failed to enumerate media devices" << endl; + return TestFail; + } + + DeviceMatch dm("vimc"); + media_ = std::move(enumerator_->search(dm)); + if (!media_) { + cerr << "Unable to find \'vimc\' media device node" << endl; + return TestSkip; + } + + media_->acquire(); + + int ret = media_->open(); + if (ret) { + cerr << "Unable to open media device: " << media_->deviceNode() + << ": " << strerror(ret) << endl; + media_->release(); + return TestSkip; + } + + MediaEntity *videoEntity = media_->getEntityByName("Scaler"); + if (!videoEntity) { + cerr << "Unable to find media entity 'Scaler'" << endl; + media_->release(); + return TestFail; + } + + scaler_ = new V4L2Subdevice(videoEntity); + if (!scaler_) { + cerr << "Unable to create media device from media entity: " + << videoEntity->deviceNode(); + media_->release(); + return TestFail; + } + + ret = scaler_->open(); + if (ret) { + cerr << "Unable to open video subdevice " + << scaler_->deviceNode() << endl; + media_->release(); + return TestSkip; + } + + return 0; +} + +void V4L2SubdeviceTest::cleanup() +{ + media_->release(); + + delete scaler_; +} diff --git a/test/v4l2_subdevice/v4l2_subdevice_test.h b/test/v4l2_subdevice/v4l2_subdevice_test.h new file mode 100644 index 000000000000..1d8e08a9c2b9 --- /dev/null +++ b/test/v4l2_subdevice/v4l2_subdevice_test.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * v4l2_subdevice_test.h - VIMC-based V4L2 subdevice test + */ + +#ifndef __LIBCAMERA_V4L2_SUBDEVICE_TEST_H__ +#define __LIBCAMERA_V4L2_SUBDEVICE_TEST_H__ + +#include + +#include "device_enumerator.h" +#include "media_device.h" +#include "test.h" +#include "v4l2_subdevice.h" + +using namespace libcamera; + +class V4L2SubdeviceTest : public Test +{ +public: + V4L2SubdeviceTest() + : scaler_(nullptr){}; + +protected: + int init() override; + virtual int run() = 0; + void cleanup() override; + + std::unique_ptr enumerator_; + std::shared_ptr media_; + V4L2Subdevice *scaler_; +}; + +#endif /* __LIBCAMERA_V4L2_SUBDEVICE_TEST_H__ */ From patchwork Thu Feb 28 20:01:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 676 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C4B3610B7 for ; Thu, 28 Feb 2019 21:01:36 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id C09DA100002; Thu, 28 Feb 2019 20:01:35 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:50 +0100 Message-Id: <20190228200151.2948-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 8/9] test: v4l2_subdevice: Add ListFormat test 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: Thu, 28 Feb 2019 20:01:36 -0000 Add test to list formats on a v4l2 subdevice. Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- test/v4l2_subdevice/list_formats.cpp | 85 ++++++++++++++++++++++++++++ test/v4l2_subdevice/meson.build | 1 + 2 files changed, 86 insertions(+) create mode 100644 test/v4l2_subdevice/list_formats.cpp diff --git a/test/v4l2_subdevice/list_formats.cpp b/test/v4l2_subdevice/list_formats.cpp new file mode 100644 index 000000000000..b902a198b17e --- /dev/null +++ b/test/v4l2_subdevice/list_formats.cpp @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 Subdevice format handling test + */ + +#include +#include + +#include "geometry.h" +#include "v4l2_subdevice.h" +#include "v4l2_subdevice_test.h" + +using namespace std; +using namespace libcamera; + +/* List image formats on the "Scaler" subdevice of vimc media device. */ + +class ListFormatsTest : public V4L2SubdeviceTest +{ +protected: + int run() override; + +private: + void printFormats(unsigned int pad, unsigned code, + std::vector &formats); +}; + +void ListFormatsTest::printFormats(unsigned int pad, + unsigned int code, + std::vector &sizes) +{ + cout << "Enumerate formats on pad " << pad << endl; + for (SizeRange &size : sizes) { + cout << " Mbus code: 0x" << hex << code << endl; + cout << " min Width: " << dec << size.minWidth << endl; + cout << " min Height: " << dec << size.minHeight << endl; + cout << " max Width: " << dec << size.maxWidth << endl; + cout << " max Height: " << dec << size.maxHeight << endl; + } +} + +int ListFormatsTest::run() +{ + /* List all formats available on existing "Scaler" pads. */ + std::map> formats; + + formats = scaler_->formats(0); + if (formats.size() == 0) { + cerr << "Failed to list formats on pad 0 of subdevice " + << scaler_->deviceName() << endl; + return TestFail; + } + auto it = formats.begin(); + while (it != formats.end()) { + printFormats(0, it->first, it->second); + ++it; + } + + formats = scaler_->formats(1); + if (formats.size() == 0) { + cerr << "Failed to list formats on pad 1 of subdevice " + << scaler_->deviceName() << endl; + return TestFail; + } + it = formats.begin(); + while (it != formats.end()) { + printFormats(1, it->first, it->second); + ++it; + } + + /* List format on a non-existing pad, format vector shall be empty. */ + formats = scaler_->formats(2); + if (formats.size() != 0) { + cerr << "Listing formats on non-existing pad 2 of subdevice " + << scaler_->deviceName() + << " should return an empty format list" << endl; + return TestFail; + } + + return TestPass; +} + +TEST_REGISTER(ListFormatsTest); diff --git a/test/v4l2_subdevice/meson.build b/test/v4l2_subdevice/meson.build index f45dca0d23d7..80cfbbbf9413 100644 --- a/test/v4l2_subdevice/meson.build +++ b/test/v4l2_subdevice/meson.build @@ -1,4 +1,5 @@ v4l2_subdevice_tests = [ + [ 'list_formats', 'list_formats.cpp'], [ 'test_formats', 'test_formats.cpp'], ] From patchwork Thu Feb 28 20:01:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 677 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6D4ED610B7 for ; Thu, 28 Feb 2019 21:01:37 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 9716D100004; Thu, 28 Feb 2019 20:01:36 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Feb 2019 21:01:51 +0100 Message-Id: <20190228200151.2948-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200151.2948-1-jacopo@jmondi.org> References: <20190228200151.2948-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 9/9] test: v4l2_device: Add format handling test 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: Thu, 28 Feb 2019 20:01:37 -0000 Add test for V4L2Device set and get format methods. Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- test/v4l2_device/formats.cpp | 53 ++++++++++++++++++++++++++++++++++++ test/v4l2_device/meson.build | 1 + 2 files changed, 54 insertions(+) create mode 100644 test/v4l2_device/formats.cpp diff --git a/test/v4l2_device/formats.cpp b/test/v4l2_device/formats.cpp new file mode 100644 index 000000000000..30b8b5c3f3f5 --- /dev/null +++ b/test/v4l2_device/formats.cpp @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 device format handling test + */ + +#include +#include + +#include "v4l2_device.h" + +#include "v4l2_device_test.h" + +using namespace std; +using namespace libcamera; + +class Format : public V4L2DeviceTest +{ +protected: + int run() override; +}; + +int Format::run() +{ + V4L2DeviceFormat format = {}; + + int ret = capture_->getFormat(&format); + if (ret) { + cerr << "Failed to get format" << endl; + return TestFail; + } + + format.width = UINT_MAX; + format.height = UINT_MAX; + ret = capture_->setFormat(&format); + if (ret) { + cerr << "Failed to set format: image resolution is invalid: " + << "(UINT_MAX x UINT_MAX) but setFormat() should not fail." + << endl; + return TestFail; + } + + if (format.width == UINT_MAX || format.height == UINT_MAX) { + cerr << "Failed to update image format = (UINT_MAX x UINT_MAX)" + << endl; + return TestFail; + } + + return TestPass; +} + +TEST_REGISTER(Format); diff --git a/test/v4l2_device/meson.build b/test/v4l2_device/meson.build index 9f7a7545ac9b..aa617b6dc837 100644 --- a/test/v4l2_device/meson.build +++ b/test/v4l2_device/meson.build @@ -2,6 +2,7 @@ # They are not alphabetically sorted. v4l2_device_tests = [ [ 'double_open', 'double_open.cpp' ], + [ 'formats', 'formats.cpp' ], [ 'request_buffers', 'request_buffers.cpp' ], [ 'stream_on_off', 'stream_on_off.cpp' ], [ 'capture_async', 'capture_async.cpp' ],