From patchwork Wed Feb 27 17:38:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 640 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 37FB4610B7 for ; Wed, 27 Feb 2019 18:38:14 +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 98ED8100003; Wed, 27 Feb 2019 17:38:13 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:30 +0100 Message-Id: <20190227173837.6902-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/8] 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: Wed, 27 Feb 2019 17:38:14 -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 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 Wed Feb 27 17:38:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 641 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1880A610B6 for ; Wed, 27 Feb 2019 18:38:15 +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 6683A100009; Wed, 27 Feb 2019 17:38:14 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:31 +0100 Message-Id: <20190227173837.6902-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/8] 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: Wed, 27 Feb 2019 17:38:15 -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 Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_subdevice.h | 6 +++++- src/libcamera/v4l2_subdevice.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index eac699a06109..dc311034a8ee 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 { return "'" + deviceName() + "'"; } + 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..dbb54506ee41 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -196,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); + << ": " << strerror(-ret); return ret; } @@ -231,7 +231,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 +263,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 Wed Feb 27 17:38:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 642 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AF1FA610B6 for ; Wed, 27 Feb 2019 18:38:15 +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 46779100005; Wed, 27 Feb 2019 17:38:15 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:32 +0100 Message-Id: <20190227173837.6902-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 3/8] 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: Wed, 27 Feb 2019 17:38:15 -0000 Implement enumFormat() methods to enumerate the available image resolutions on the subdevice. Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_subdevice.h | 9 ++ src/libcamera/v4l2_subdevice.cpp | 122 +++++++++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index dc311034a8ee..827068ec563c 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -7,7 +7,9 @@ #ifndef __LIBCAMERA_V4L2_SUBDEVICE_H__ #define __LIBCAMERA_V4L2_SUBDEVICE_H__ +#include #include +#include #include "log.h" #include "media_object.h" @@ -39,6 +41,7 @@ public: int setCrop(unsigned int pad, Rectangle *rect); int setCompose(unsigned int pad, Rectangle *rect); + std::vector &formats(unsigned int pad); int getFormat(unsigned int pad, V4L2SubdeviceFormat *format); int setFormat(unsigned int pad, V4L2SubdeviceFormat *format); @@ -46,11 +49,17 @@ protected: std::string logPrefix() const { return "'" + deviceName() + "'"; } private: + int listPadSizes(unsigned int pad, unsigned int mbus_code, + std::vector *formats); + std::vector listPadFormats(unsigned int pad); + int setSelection(unsigned int pad, unsigned int target, Rectangle *rect); const MediaEntity *entity_; int fd_; + + std::map> formats_; }; } /* namespace libcamera */ diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index dbb54506ee41..b3a5d7a37413 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -5,6 +5,10 @@ * v4l2_subdevice.cpp - V4L2 Subdevice */ +#include +#include +#include + #include #include #include @@ -116,6 +120,9 @@ int V4L2Subdevice::open() } fd_ = ret; + for (MediaPad *pad : entity_->pads()) + formats_[pad->index()] = listPadFormats(pad->index()); + return 0; } @@ -178,6 +185,25 @@ 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 + * + * \return A vector of image formats, or an empty vector if the pad does not + * exist + */ +std::vector &V4L2Subdevice::formats(unsigned int pad) +{ + /* + * If pad does not exist, return an empty vector at position + * pads().size() + */ + if (pad > entity_->pads().size()) + pad = entity_->pads().size(); + + return formats_[pad]; +} + /** * \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 @@ -243,6 +269,102 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format) return 0; } +int V4L2Subdevice::listPadSizes(unsigned int pad, unsigned int mbus_code, + std::vector *formats) +{ + struct v4l2_subdev_frame_size_enum sizeEnum = {}; + int ret; + + sizeEnum.index = 0; + sizeEnum.pad = pad; + sizeEnum.code = mbus_code; + sizeEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; + + while (!(ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &sizeEnum))) { + V4L2SubdeviceFormat minFormat = { + .mbus_code = mbus_code, + .width = sizeEnum.min_width, + .height = sizeEnum.min_height, + }; + formats->push_back(minFormat); + + /* + * Most subdevices report discrete frame resolutions, where + * min and max sizes are identical. For continue frame + * resolutions, store the min and max sizes interval. + */ + if (sizeEnum.min_width == sizeEnum.max_width && + sizeEnum.min_height == sizeEnum.max_height) { + sizeEnum.index++; + continue; + } + + V4L2SubdeviceFormat maxFormat = { + .mbus_code = mbus_code, + .width = sizeEnum.max_width, + .height = sizeEnum.max_height, + }; + formats->push_back(maxFormat); + + sizeEnum.index++; + } + + if (ret && (errno != EINVAL && errno != ENOTTY)) { + LOG(V4L2Subdev, Error) + << "Unable to enumerate format on pad " << pad + << ": " << strerror(errno); + return ret; + } + + return 0; +} + +std::vector V4L2Subdevice::listPadFormats(unsigned int pad) +{ + struct v4l2_subdev_mbus_code_enum mbusEnum = {}; + std::vector formats = {}; + int ret; + + mbusEnum.pad = pad; + mbusEnum.index = 0; + mbusEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; + + while (!(ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbusEnum))) { + ret = listPadSizes(pad, mbusEnum.code, &formats); + if (ret) + return formats; + + mbusEnum.index++; + } + + /* + * The subdevice might not support ENUM_MBUS_CODE but might support + * ENUM_FRAME_SIZES. Try with the currently applied format. + */ + if (ret && errno == ENOTTY) { + struct V4L2SubdeviceFormat subdevFormat; + if (getFormat(pad, &subdevFormat)) { + LOG(V4L2Subdev, Error) + << "Unable to get format on pad " << pad + << ": " << strerror(errno); + return formats; + } + + ret = listPadSizes(pad, subdevFormat.mbus_code, &formats); + if (ret) + return formats; + } + + if (ret && (errno != EINVAL && errno != ENOTTY)) { + LOG(V4L2Subdev, Error) + << "Unable to enumerate format on pad " << pad + << ": " << strerror(errno); + return formats; + } + + return formats; +} + int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, Rectangle *rect) { From patchwork Wed Feb 27 17:38:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 643 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4BE27610BB for ; Wed, 27 Feb 2019 18:38:16 +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 DA52C100005; Wed, 27 Feb 2019 17:38:15 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:33 +0100 Message-Id: <20190227173837.6902-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/8] 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: Wed, 27 Feb 2019 17:38:16 -0000 Add support for devices that provide video meta-data to v4l2_device.cpp and re-arrange bufferType handling in open() method. Signed-off-by: Jacopo Mondi --- 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 Wed Feb 27 17:38:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 644 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DE8C2610BB for ; Wed, 27 Feb 2019 18:38:16 +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 74A08100003; Wed, 27 Feb 2019 17:38:16 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:34 +0100 Message-Id: <20190227173837.6902-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 5/8] 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: Wed, 27 Feb 2019 17:38:17 -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 --- 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 b3a5d7a37413..0cd531b64634 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -375,8 +375,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; @@ -389,6 +389,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 Wed Feb 27 17:38:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 645 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C98C7610B7 for ; Wed, 27 Feb 2019 18:38:17 +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 2104010000C; Wed, 27 Feb 2019 17:38:16 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:35 +0100 Message-Id: <20190227173837.6902-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 6/8] 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: Wed, 27 Feb 2019 17:38:18 -0000 Add test for video format get and set operations on V4L2Subdevice class. Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi --- test/meson.build | 1 + test/v4l2_subdevice/meson.build | 10 +++ test/v4l2_subdevice/test_formats.cpp | 79 ++++++++++++++++++ test/v4l2_subdevice/v4l2_subdevice_test.cpp | 90 +++++++++++++++++++++ test/v4l2_subdevice/v4l2_subdevice_test.h | 36 +++++++++ 5 files changed, 216 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..a4359fe1bc19 --- /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..91b460f64e7e --- /dev/null +++ b/test/v4l2_subdevice/test_formats.cpp @@ -0,0 +1,79 @@ +/* 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(); +}; + +int FormatHandlingTest::run() +{ + V4L2SubdeviceFormat format = {}; + + /* + * Get format on a non-existing Scaler pad: expect failure. + */ + int ret = scaler_->getFormat(2, &format); + if (!ret) { + cerr << "Get 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..eb1ee0046e68 --- /dev/null +++ b/test/v4l2_subdevice/v4l2_subdevice_test.cpp @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * v4l2_subdevice_test.cpp - 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 TestSkip; + } + + scaler_ = new V4L2Subdevice(videoEntity); + if (!scaler_) { + cerr << "Unable to create media device from media entity: " + << videoEntity->deviceNode(); + media_->release(); + return TestSkip; + } + + 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..7b64c6122745 --- /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 - 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(); + virtual int run() = 0; + void cleanup(); + + std::unique_ptr enumerator_; + std::shared_ptr media_; + V4L2Subdevice *scaler_; +}; + +#endif /* __LIBCAMERA_V4L2_SUBDEVICE_TEST_H_ */ From patchwork Wed Feb 27 17:38:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 646 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 69837610B7 for ; Wed, 27 Feb 2019 18:38:18 +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 00A0E10000D; Wed, 27 Feb 2019 17:38:17 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:36 +0100 Message-Id: <20190227173837.6902-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 7/8] 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: Wed, 27 Feb 2019 17:38:18 -0000 Add test to list formats on a v4l2 subdevice. Signed-off-by: Jacopo Mondi --- test/v4l2_subdevice/list_formats.cpp | 76 ++++++++++++++++++++++++++++ test/v4l2_subdevice/meson.build | 1 + 2 files changed, 77 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..b40e1f124539 --- /dev/null +++ b/test/v4l2_subdevice/list_formats.cpp @@ -0,0 +1,76 @@ +/* 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; + +/* List image formats on the "Scaler" subdevice of vimc media device. */ + +class ListFormatsTest : public V4L2SubdeviceTest +{ +protected: + int run(); + +private: + void printFormats(unsigned int pad, + std::vector &formats); +}; + +void ListFormatsTest::printFormats(unsigned int pad, + std::vector &formats) +{ + cout << "Enumerate formats on pad " << pad << endl; + for (V4L2SubdeviceFormat &format : formats) { + cout << " Mbus code: 0x" << hex << format.mbus_code << endl; + cout << " Width: " << dec << format.width << endl; + cout << " Height: " << dec << format.height << endl; + } +} + +int ListFormatsTest::run() +{ + /* List all formats available on existing "Scaler" pads. */ + std::vector formats = {}; + + formats = scaler_->formats(0); + if (formats.empty()) { + cerr << "Failed to list formats on pad 0 of subdevice " + << scaler_->deviceNode() << endl; + return TestFail; + } + printFormats(0, formats); + + formats = {}; + formats = scaler_->formats(1); + if (formats.empty()) { + cerr << "Failed to list formats on pad 1 of subdevice " + << scaler_->deviceNode() << endl; + return TestFail; + } + printFormats(1, formats); + + /* List format on a non-existing pad, format vector shall be empty. */ + formats = {}; + formats = scaler_->formats(2); + if (!formats.empty()) { + cerr << "Listing formats on non-existing pad 2 of subdevice " + << scaler_->deviceNode() + << " 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 a4359fe1bc19..6023d15e1558 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 Wed Feb 27 17:38:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 647 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3A7E1610B6 for ; Wed, 27 Feb 2019 18:38:19 +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 97253100005; Wed, 27 Feb 2019 17:38:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 27 Feb 2019 18:38:37 +0100 Message-Id: <20190227173837.6902-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190227173837.6902-1-jacopo@jmondi.org> References: <20190227173837.6902-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 8/8] 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: Wed, 27 Feb 2019 17:38:19 -0000 Add test for V4L2Device set and get format methods. Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi --- test/v4l2_device/meson.build | 1 + test/v4l2_device/test_formats.cpp | 68 +++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/v4l2_device/test_formats.cpp diff --git a/test/v4l2_device/meson.build b/test/v4l2_device/meson.build index 9f7a7545ac9b..72b22a637a2f 100644 --- a/test/v4l2_device/meson.build +++ b/test/v4l2_device/meson.build @@ -6,6 +6,7 @@ v4l2_device_tests = [ [ 'stream_on_off', 'stream_on_off.cpp' ], [ 'capture_async', 'capture_async.cpp' ], [ 'buffer_sharing', 'buffer_sharing.cpp' ], + [ 'test_formats', 'test_formats.cpp' ], ] foreach t : v4l2_device_tests diff --git a/test/v4l2_device/test_formats.cpp b/test/v4l2_device/test_formats.cpp new file mode 100644 index 000000000000..9fb1b5c73521 --- /dev/null +++ b/test/v4l2_device/test_formats.cpp @@ -0,0 +1,68 @@ +/* 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(); +}; + +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; + } + + format.width = 0; + format.height = 0; + ret = capture_->setFormat(&format); + if (ret) { + cerr << "Failed to set format: image resolution is invalid: " + << "(0 x 0) but setFormat() should not fail." + << endl; + return TestFail; + } + + if (format.width == 0 || format.height == 0) { + cerr << "Failed to update image format = (0x0)" << endl; + return TestFail; + } + + return TestPass; +} + +TEST_REGISTER(Format);