From patchwork Tue Jul 14 10:41:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8776 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5E019BD792 for ; Tue, 14 Jul 2020 10:38:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 38DCF607DE; Tue, 14 Jul 2020 12:38:49 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 159CD60486 for ; Tue, 14 Jul 2020 12:38:48 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 4151024000F; Tue, 14 Jul 2020 10:38:47 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:41:53 +0200 Message-Id: <20200714104212.48683-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 01/20] libcamera: geometry: Add helper functions to the Size class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Laurent Pinchart Pipeline handlers commonly have to calculate the minimum or maximum of multiple sizes, or align a size's width and height. Add helper functions to the Size class to perform those tasks. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- include/libcamera/geometry.h | 33 +++++++++++++++++++++++++++++++++ src/libcamera/geometry.cpp | 36 ++++++++++++++++++++++++++++++++++++ test/geometry.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 7d4b8bcfe3d8..d217cfd50c86 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -8,6 +8,7 @@ #ifndef __LIBCAMERA_GEOMETRY_H__ #define __LIBCAMERA_GEOMETRY_H__ +#include #include namespace libcamera { @@ -43,6 +44,38 @@ struct Size { bool isNull() const { return !width && !height; } const std::string toString() const; + + Size alignedDownTo(unsigned int hAlignment, unsigned int vAlignment) const + { + return { + width / hAlignment * hAlignment, + height / vAlignment * vAlignment + }; + } + + Size alignedUpTo(unsigned int hAlignment, unsigned int vAlignment) const + { + return { + (width + hAlignment - 1) / hAlignment * hAlignment, + (height + vAlignment - 1) / vAlignment * vAlignment + }; + } + + Size boundedTo(const Size &bound) const + { + return { + std::min(width, bound.width), + std::min(height, bound.height) + }; + } + + Size expandedTo(const Size &expand) const + { + return { + std::max(width, expand.width), + std::max(height, expand.height) + }; + } }; bool operator==(const Size &lhs, const Size &rhs); diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index 24c44fb43acf..4594f9ff435f 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -122,6 +122,42 @@ const std::string Size::toString() const return std::to_string(width) + "x" + std::to_string(height); } +/** + * \fn Size::alignedDownTo(unsigned int hAlignment, unsigned int vAlignment) + * \brief Align the size down horizontally and vertically + * \param[in] hAlignment Horizontal alignment + * \param[in] vAlignment Vertical alignment + * \return A Size whose width and height are equal to the width and height of + * this size rounded down to the nearest multiple of \a hAlignment and + * \a vAlignment respectively + */ + +/** + * \fn Size::alignedUpTo(unsigned int hAlignment, unsigned int vAlignment) + * \brief Align the size up horizontally and vertically + * \param[in] hAlignment Horizontal alignment + * \param[in] vAlignment Vertical alignment + * \return A Size whose width and height are equal to the width and height of + * this size rounded up to the nearest multiple of \a hAlignment and + * \a vAlignment respectively + */ + +/** + * \fn Size::boundedTo(const Size &bound) + * \brief Bound the size to \a bound + * \param[in] bound The maximum size + * \return A Size whose width and height are the minimum of the width and + * height of this size and the \a bound size + */ + +/** + * \fn Size::expandedTo(const Size &expand) + * \brief Expand the size to \a expand + * \param[in] expand The minimum size + * \return A Size whose width and height are the maximum of the width and + * height of this size and the \a expand size + */ + /** * \brief Compare sizes for equality * \return True if the two sizes are equal, false otherwise diff --git a/test/geometry.cpp b/test/geometry.cpp index 904ad92c9448..fd0132c03b02 100644 --- a/test/geometry.cpp +++ b/test/geometry.cpp @@ -46,6 +46,35 @@ protected: return TestFail; } + /* Test alignedDownTo(), alignedUpTo(), boundedTo() and expandedTo() */ + if (Size(0, 0).alignedDownTo(16, 8) != Size(0, 0) || + Size(1, 1).alignedDownTo(16, 8) != Size(0, 0) || + Size(16, 8).alignedDownTo(16, 8) != Size(16, 8)) { + cout << "Size::alignedDownTo() test failed" << endl; + return TestFail; + } + + if (Size(0, 0).alignedUpTo(16, 8) != Size(0, 0) || + Size(1, 1).alignedUpTo(16, 8) != Size(16, 8) || + Size(16, 8).alignedUpTo(16, 8) != Size(16, 8)) { + cout << "Size::alignedUpTo() test failed" << endl; + return TestFail; + } + + if (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) || + Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) || + Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) { + cout << "Size::boundedTo() test failed" << endl; + return TestFail; + } + + if (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) || + Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) || + Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) { + cout << "Size::expandedTo() test failed" << endl; + return TestFail; + } + /* Test Size equality and inequality. */ if (!compare(Size(100, 100), Size(100, 100), &operator==, "==", true)) return TestFail; From patchwork Tue Jul 14 10:41:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8777 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7F7DDBD792 for ; Tue, 14 Jul 2020 10:38:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 58F5260839; Tue, 14 Jul 2020 12:38:51 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5D112607BD for ; Tue, 14 Jul 2020 12:38:49 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 30717240017; Tue, 14 Jul 2020 10:38:48 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:41:54 +0200 Message-Id: <20200714104212.48683-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 02/20] libcamera: ipu3: Rename mbusCodesToInfo X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The mbusCodesToInfo map actually maps media bus codes to PixelFormat instances. Rename the map according to its actual function and while at it drop the 'static' keyword as the map is already defined in an anonymous namespace. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/cio2.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index cb8c80a4a9ca..77f54da47e28 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -22,7 +22,7 @@ LOG_DECLARE_CATEGORY(IPU3) namespace { -static const std::map mbusCodesToInfo = { +const std::map mbusCodesToPixelFormat = { { MEDIA_BUS_FMT_SBGGR10_1X10, formats::SBGGR10_IPU3 }, { MEDIA_BUS_FMT_SGBRG10_1X10, formats::SGBRG10_IPU3 }, { MEDIA_BUS_FMT_SGRBG10_1X10, formats::SGRBG10_IPU3 }, @@ -94,7 +94,7 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index) * utils::set_overlap requires the ranges to be sorted, keep the * cio2Codes vector sorted in ascending order. */ - std::vector cio2Codes = utils::map_keys(mbusCodesToInfo); + std::vector cio2Codes = utils::map_keys(mbusCodesToPixelFormat); const std::vector &sensorCodes = sensor_->mbusCodes(); if (!utils::set_overlap(sensorCodes.begin(), sensorCodes.end(), cio2Codes.begin(), cio2Codes.end())) { @@ -134,7 +134,7 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat) * Apply the selected format to the sensor, the CSI-2 receiver and * the CIO2 output device. */ - std::vector mbusCodes = utils::map_keys(mbusCodesToInfo); + std::vector mbusCodes = utils::map_keys(mbusCodesToPixelFormat); sensorFormat = sensor_->getFormat(mbusCodes, size); ret = sensor_->setFormat(&sensorFormat); if (ret) @@ -144,8 +144,8 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat) if (ret) return ret; - const auto &itInfo = mbusCodesToInfo.find(sensorFormat.mbus_code); - if (itInfo == mbusCodesToInfo.end()) + const auto &itInfo = mbusCodesToPixelFormat.find(sensorFormat.mbus_code); + if (itInfo == mbusCodesToPixelFormat.end()) return -EINVAL; const PixelFormatInfo &info = PixelFormatInfo::info(itInfo->second); @@ -173,7 +173,7 @@ CIO2Device::generateConfiguration(Size size) const size = sensor_->resolution(); /* Query the sensor static information for closest match. */ - std::vector mbusCodes = utils::map_keys(mbusCodesToInfo); + std::vector mbusCodes = utils::map_keys(mbusCodesToPixelFormat); V4L2SubdeviceFormat sensorFormat = sensor_->getFormat(mbusCodes, size); if (!sensorFormat.mbus_code) { LOG(IPU3, Error) << "Sensor does not support mbus code"; @@ -181,7 +181,7 @@ CIO2Device::generateConfiguration(Size size) const } cfg.size = sensorFormat.size; - cfg.pixelFormat = mbusCodesToInfo.at(sensorFormat.mbus_code); + cfg.pixelFormat = mbusCodesToPixelFormat.at(sensorFormat.mbus_code); cfg.bufferCount = CIO2_BUFFER_COUNT; return cfg; From patchwork Tue Jul 14 10:41:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8778 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 00910BD792 for ; Tue, 14 Jul 2020 10:38:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 90E6860889; Tue, 14 Jul 2020 12:38:51 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B937E60486 for ; Tue, 14 Jul 2020 12:38:49 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 5C15A240011; Tue, 14 Jul 2020 10:38:49 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:41:55 +0200 Message-Id: <20200714104212.48683-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 03/20] libcamera: utils: Add alignUp and alignDown functions X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add to libcamera utils library two functions to round up or down a value to an alignment and add a test in test/utils.cpp for the two new functions. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- include/libcamera/internal/utils.h | 3 +++ src/libcamera/utils.cpp | 22 ++++++++++++++++++++++ test/utils.cpp | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h index 8d026cc6c0fe..25eb24ec2d16 100644 --- a/include/libcamera/internal/utils.h +++ b/include/libcamera/internal/utils.h @@ -200,6 +200,9 @@ details::StringSplitter split(const std::string &str, const std::string &delim); std::string libcameraBuildPath(); std::string libcameraSourcePath(); +unsigned int alignUp(unsigned int value, unsigned int alignment); +unsigned int alignDown(unsigned int value, unsigned int alignment); + } /* namespace utils */ } /* namespace libcamera */ diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp index 0567328fe31b..52fb0bb171d8 100644 --- a/src/libcamera/utils.cpp +++ b/src/libcamera/utils.cpp @@ -444,6 +444,28 @@ std::string libcameraSourcePath() return path + "/"; } +/** + * \brief Align \a value to \a alignment + * \param[in] value The value to align + * \param[in] alignment The alignment + * \return The value rounded up to the nearest multiple of \a alignment + */ +unsigned int alignUp(unsigned int value, unsigned int alignment) +{ + return (value + alignment - 1) / alignment * alignment; +} + +/** + * \brief Align \a value to \a alignment + * \param[in] value The value to align + * \param[in] alignment The alignment + * \return The value rounded down to the nearest multiple of \a alignment + */ +unsigned int alignDown(unsigned int value, unsigned int alignment) +{ + return value / alignment * alignment; +} + } /* namespace utils */ } /* namespace libcamera */ diff --git a/test/utils.cpp b/test/utils.cpp index f482e6a1d829..02054f46b00e 100644 --- a/test/utils.cpp +++ b/test/utils.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -166,6 +167,23 @@ protected: return TestFail; } + /* utils::alignUp() and utils::alignDown() tests. */ + random_device random; + unsigned int val = random(); + unsigned int align = random() % (val / 10); + unsigned int roundUp = (val + align - 1) / align; + unsigned int roundDown = val / align; + + if (utils::alignUp(val, align) != align * roundUp) { + cerr << "utils::alignUp test failed" << endl; + return TestFail; + } + + if (utils::alignDown(val, align) != align * roundDown) { + cerr << "utils::alignDown test failed" << endl; + return TestFail; + } + return TestPass; } }; From patchwork Tue Jul 14 10:41:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8779 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7BB33BD792 for ; Tue, 14 Jul 2020 10:38:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2930960890; Tue, 14 Jul 2020 12:38:52 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 758B860745 for ; Tue, 14 Jul 2020 12:38:50 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id DACCA24000F; Tue, 14 Jul 2020 10:38:49 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:41:56 +0200 Message-Id: <20200714104212.48683-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 04/20] libcamera: geometry: Add isNull() function to Rectangle class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" It's common for code to check if a rectangle is null. Add a helper function to do so and test the function in test/geometry.cpp Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- include/libcamera/geometry.h | 1 + src/libcamera/geometry.cpp | 6 ++++++ test/geometry.cpp | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index d217cfd50c86..98a919eb01f1 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -19,6 +19,7 @@ struct Rectangle { unsigned int width; unsigned int height; + bool isNull() const { return !width && !height; } const std::string toString() const; }; diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index 4594f9ff435f..f79f769bf88e 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -49,6 +49,12 @@ namespace libcamera { * \brief The distance between the top and bottom sides */ +/** + * \fn bool Rectangle::isNull() const + * \brief Check if the rectangle is null + * \return True if both the width and height are 0, or false otherwise + */ + /** * \brief Assemble and return a string describing the rectangle * \return A string describing the Rectangle diff --git a/test/geometry.cpp b/test/geometry.cpp index fd0132c03b02..72d938b40e54 100644 --- a/test/geometry.cpp +++ b/test/geometry.cpp @@ -36,6 +36,12 @@ protected: int run() { + Rectangle r{}; + if (!r.isNull()) { + cout << "Null rectangle incorrectly reported as not null" << endl; + return TestFail; + } + if (!Size().isNull() || !Size(0, 0).isNull()) { cout << "Null size incorrectly reported as not null" << endl; return TestFail; From patchwork Tue Jul 14 10:41:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8780 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C8DB3BD792 for ; Tue, 14 Jul 2020 10:38:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A2A3B60839; Tue, 14 Jul 2020 12:38:54 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 69D0B60876 for ; Tue, 14 Jul 2020 12:38:51 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 999A9240014; Tue, 14 Jul 2020 10:38:50 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:41:57 +0200 Message-Id: <20200714104212.48683-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/20] libcamera: ipu3: Remove streams from generateConfiguration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Remove stream assignment from the IPU3 pipeline handler generateConfiguration() implementation. The function aims to provide a suitable default for the requested use cases. Defer stream assignment to validation and only initialize sizes and formats. Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 103 ++++++++------------------- 1 file changed, 29 insertions(+), 74 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index eb00eecfd10a..f291fbb786af 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -31,6 +31,15 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPU3) +static constexpr unsigned int IPU3_BUFFER_COUNT = 4; +static constexpr unsigned int IPU3_MAX_STREAMS = 3; +static const Size IMGU_OUTPUT_MIN_SIZE = { 2, 2 }; +static const Size IMGU_OUTPUT_MAX_SIZE = { 4480, 34004 }; +static constexpr unsigned int IMGU_OUTPUT_WIDTH_ALIGN = 64; +static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4; +static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64; +static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32; + class IPU3CameraData : public CameraData { public: @@ -61,9 +70,6 @@ public: const std::vector &streams() { return streams_; } private: - static constexpr unsigned int IPU3_BUFFER_COUNT = 4; - static constexpr unsigned int IPU3_MAX_STREAMS = 3; - void assignStreams(); void adjustStream(StreamConfiguration &cfg, bool scale); @@ -299,94 +305,49 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, { IPU3CameraData *data = cameraData(camera); IPU3CameraConfiguration *config = new IPU3CameraConfiguration(camera, data); - std::set streams = { - &data->outStream_, - &data->vfStream_, - &data->rawStream_, - }; if (roles.empty()) return config; + Size sensorResolution = data->cio2_.sensor()->resolution(); for (const StreamRole role : roles) { StreamConfiguration cfg = {}; - Stream *stream = nullptr; - - cfg.pixelFormat = formats::NV12; switch (role) { case StreamRole::StillCapture: /* - * Pick the output stream by default as the Viewfinder - * and VideoRecording roles are not allowed on - * the output stream. - */ - if (streams.find(&data->outStream_) != streams.end()) { - stream = &data->outStream_; - } else if (streams.find(&data->vfStream_) != streams.end()) { - stream = &data->vfStream_; - } else { - LOG(IPU3, Error) - << "No stream available for requested role " - << role; - break; - } - - /* - * FIXME: Soraka: the maximum resolution reported by - * both sensors (2592x1944 for ov5670 and 4224x3136 for - * ov13858) are returned as default configurations but - * they're not correctly processed by the ImgU. - * Resolutions up tp 2560x1920 have been validated. - * - * \todo Clarify ImgU alignment requirements. + * Use the sensor resolution aligned to the ImgU + * output constraints and required frame margin + * by rounding down to the closest alignment. */ - cfg.size = { 2560, 1920 }; + cfg.size = sensorResolution.boundedTo(IMGU_OUTPUT_MAX_SIZE); + cfg.size.width = utils::alignDown(cfg.size.width - 1, + IMGU_OUTPUT_WIDTH_MARGIN); + cfg.size.height = utils::alignDown(cfg.size.height - 1, + IMGU_OUTPUT_HEIGHT_MARGIN); + cfg.pixelFormat = formats::NV12; + cfg.bufferCount = IPU3_BUFFER_COUNT; break; case StreamRole::StillCaptureRaw: { - if (streams.find(&data->rawStream_) == streams.end()) { - LOG(IPU3, Error) - << "Multiple raw streams are not supported"; - break; - } - - stream = &data->rawStream_; - - cfg.size = data->cio2_.sensor()->resolution(); + cfg = data->cio2_.generateConfiguration(sensorResolution); - cfg = data->cio2_.generateConfiguration(cfg.size); break; } case StreamRole::Viewfinder: case StreamRole::VideoRecording: { /* - * We can't use the 'output' stream for viewfinder or - * video capture roles. - * - * \todo This is an artificial limitation until we - * figure out the exact capabilities of the hardware. + * Default viewfinder and videorecording to 1280x720, + * capped to the maximum sensor resolution and aligned + * to the ImgU output constraints. */ - if (streams.find(&data->vfStream_) == streams.end()) { - LOG(IPU3, Error) - << "No stream available for requested role " - << role; - break; - } - - stream = &data->vfStream_; - - /* - * Align the default viewfinder size to the maximum - * available sensor resolution and to the IPU3 - * alignment constraints. - */ - const Size &res = data->cio2_.sensor()->resolution(); - unsigned int width = std::min(1280U, res.width); - unsigned int height = std::min(720U, res.height); - cfg.size = { width & ~7, height & ~3 }; + cfg.size = sensorResolution.boundedTo({ 1280, 720 }) + .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN, + IMGU_OUTPUT_HEIGHT_ALIGN); + cfg.pixelFormat = formats::NV12; + cfg.bufferCount = IPU3_BUFFER_COUNT; break; } @@ -394,16 +355,10 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, default: LOG(IPU3, Error) << "Requested stream role not supported: " << role; - break; - } - - if (!stream) { delete config; return nullptr; } - streams.erase(stream); - config->addConfiguration(cfg); } From patchwork Tue Jul 14 10:41:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8781 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 178C7BDB1C for ; Tue, 14 Jul 2020 10:38:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CE872608EB; Tue, 14 Jul 2020 12:38:54 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3AB7260745 for ; Tue, 14 Jul 2020 12:38:52 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 7D55B240011; Tue, 14 Jul 2020 10:38:51 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:41:58 +0200 Message-Id: <20200714104212.48683-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/20] libcamera: ipu3: Make sure the config is valid X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Inspect the return status of validate() in the IPU3 pipeline handler generateConfigurtion() implementation. If the generated configuration is not valid, return a an empty configuration to the application. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f291fbb786af..2d1959316ac7 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -362,7 +362,8 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, config->addConfiguration(cfg); } - config->validate(); + if (config->validate() == CameraConfiguration::Invalid) + return {}; return config; } From patchwork Tue Jul 14 10:41:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8782 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 750A8BD792 for ; Tue, 14 Jul 2020 10:38:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 36D8F60900; Tue, 14 Jul 2020 12:38:55 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B6F9060832 for ; Tue, 14 Jul 2020 12:38:52 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 57019240015; Tue, 14 Jul 2020 10:38:52 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:41:59 +0200 Message-Id: <20200714104212.48683-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/20] libcamera: ipu3: cio2: Report format and sizes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add two methods to the CIO2Device class to retrieve all the supported PixelFormats and sizes. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/libcamera/pipeline/ipu3/cio2.cpp | 40 ++++++++++++++++++++++++++++ src/libcamera/pipeline/ipu3/cio2.h | 5 ++++ 2 files changed, 45 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 77f54da47e28..ff436e0dae41 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -9,6 +9,7 @@ #include +#include #include #include @@ -43,6 +44,45 @@ CIO2Device::~CIO2Device() delete sensor_; } +/** + * \brief Retrieve the list of supported PixelFormats + * + * Retrieve the list of supported pixel formats by matching the sensor produced + * media bus codes with the formats supported by the CIO2 unit. + * + * \return The list of supported PixelFormat + */ +std::vector CIO2Device::formats() const +{ + if (!sensor_) + return {}; + + std::vector formats; + for (unsigned int code : sensor_->mbusCodes()) { + auto it = mbusCodesToPixelFormat.find(code); + if (it != mbusCodesToPixelFormat.end()) + formats.push_back(it->second); + } + + return formats; +} + +/** + * \brief Retrieve the list of supported size ranges + * \return The list of supported SizeRange + */ +std::vector CIO2Device::sizes() const +{ + if (!sensor_) + return {}; + + std::vector sizes; + for (const Size &size : sensor_->sizes()) + sizes.emplace_back(size, size); + + return sizes; +} + /** * \brief Initialize components of the CIO2 device with \a index * \param[in] media The CIO2 media device diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h index 4fd949f8e513..f905d97fa79d 100644 --- a/src/libcamera/pipeline/ipu3/cio2.h +++ b/src/libcamera/pipeline/ipu3/cio2.h @@ -20,7 +20,9 @@ namespace libcamera { class CameraSensor; class FrameBuffer; class MediaDevice; +class PixelFormat; class Request; +class SizeRange; class V4L2Subdevice; struct Size; struct StreamConfiguration; @@ -33,6 +35,9 @@ public: CIO2Device(); ~CIO2Device(); + std::vector formats() const; + std::vector sizes() const; + int init(const MediaDevice *media, unsigned int index); int configure(const Size &size, V4L2DeviceFormat *outputFormat); From patchwork Tue Jul 14 10:42:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8783 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 06DB5BDB1C for ; Tue, 14 Jul 2020 10:38:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BFAD0608A0; Tue, 14 Jul 2020 12:38:55 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8F093607BD for ; Tue, 14 Jul 2020 12:38:53 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id D1D86240011; Tue, 14 Jul 2020 10:38:52 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:00 +0200 Message-Id: <20200714104212.48683-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/20] libcamera: ipu3: Do not overwrite StreamConfiguration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The validate function overwrites the generated StreamConfiguration with the one reported by the CIO2 unit when inspecting the RAW stream configuration. As we prepare to add StreamFormats to the IPU3 StreamConfiguration, assigning to the CIO2 generated configuration would delete the StreamFormats. Fix this by updating relevant fields only in order to keep the assigned StreamFormats. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 2d1959316ac7..517d9bd11fbf 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -270,7 +270,9 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() const Stream *stream = streams_[i]; if (stream == &data_->rawStream_) { - cfg = cio2Configuration_; + cfg.size = cio2Configuration_.size; + cfg.pixelFormat = cio2Configuration_.pixelFormat; + cfg.bufferCount = cio2Configuration_.bufferCount; } else { bool scale = stream == &data_->vfStream_; adjustStream(config_[i], scale); From patchwork Tue Jul 14 10:42:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8784 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5A456BD792 for ; Tue, 14 Jul 2020 10:38:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 335AF607EB; Tue, 14 Jul 2020 12:38:58 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4BC1B60839 for ; Tue, 14 Jul 2020 12:38:54 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id B0686240014; Tue, 14 Jul 2020 10:38:53 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:01 +0200 Message-Id: <20200714104212.48683-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/20] libcamera: ipu3: Report StreamFormats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Report StreamFormats associated to each StreamConfiguration generated by the IPU3 pipeline handler. The StreamFormats are generated differently for RAW and processed streams, with the former using the sensor enumerated resolutions and the latter using a continuous range of sizes constructed by matching the sensor capabilities with the platform constraints. Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 45 +++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 517d9bd11fbf..b480d41f89ab 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -313,7 +313,10 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, Size sensorResolution = data->cio2_.sensor()->resolution(); for (const StreamRole role : roles) { - StreamConfiguration cfg = {}; + std::map> streamFormats; + unsigned int bufferCount; + PixelFormat pixelFormat; + Size size; switch (role) { case StreamRole::StillCapture: @@ -322,18 +325,26 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, * output constraints and required frame margin * by rounding down to the closest alignment. */ - cfg.size = sensorResolution.boundedTo(IMGU_OUTPUT_MAX_SIZE); - cfg.size.width = utils::alignDown(cfg.size.width - 1, - IMGU_OUTPUT_WIDTH_MARGIN); - cfg.size.height = utils::alignDown(cfg.size.height - 1, - IMGU_OUTPUT_HEIGHT_MARGIN); - cfg.pixelFormat = formats::NV12; - cfg.bufferCount = IPU3_BUFFER_COUNT; + size = sensorResolution.boundedTo(IMGU_OUTPUT_MAX_SIZE); + size.width = utils::alignDown(size.width - 1, + IMGU_OUTPUT_WIDTH_MARGIN); + size.height = utils::alignDown(size.height - 1, + IMGU_OUTPUT_HEIGHT_MARGIN); + pixelFormat = formats::NV12; + bufferCount = IPU3_BUFFER_COUNT; + streamFormats[pixelFormat] = { { IMGU_OUTPUT_MIN_SIZE, size } }; break; case StreamRole::StillCaptureRaw: { - cfg = data->cio2_.generateConfiguration(sensorResolution); + StreamConfiguration cio2Config = + data->cio2_.generateConfiguration(sensorResolution); + pixelFormat = cio2Config.pixelFormat; + size = cio2Config.size; + bufferCount = cio2Config.bufferCount; + + for (const PixelFormat &format : data->cio2_.formats()) + streamFormats[format] = data->cio2_.sizes(); break; } @@ -345,11 +356,12 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, * capped to the maximum sensor resolution and aligned * to the ImgU output constraints. */ - cfg.size = sensorResolution.boundedTo({ 1280, 720 }) - .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN, - IMGU_OUTPUT_HEIGHT_ALIGN); - cfg.pixelFormat = formats::NV12; - cfg.bufferCount = IPU3_BUFFER_COUNT; + size = sensorResolution.boundedTo({ 1280, 720 }) + .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN, + IMGU_OUTPUT_HEIGHT_ALIGN); + pixelFormat = formats::NV12; + bufferCount = IPU3_BUFFER_COUNT; + streamFormats[pixelFormat] = { { IMGU_OUTPUT_MIN_SIZE, size } }; break; } @@ -361,6 +373,11 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, return nullptr; } + StreamFormats formats(streamFormats); + StreamConfiguration cfg(formats); + cfg.size = size; + cfg.pixelFormat = pixelFormat; + cfg.bufferCount = bufferCount; config->addConfiguration(cfg); } From patchwork Tue Jul 14 10:42:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8785 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 8CBB7BDB1C for ; Tue, 14 Jul 2020 10:38:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 67E3660906; Tue, 14 Jul 2020 12:38:58 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2A2B5608E0 for ; Tue, 14 Jul 2020 12:38:55 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 6E392240011; Tue, 14 Jul 2020 10:38:54 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:02 +0200 Message-Id: <20200714104212.48683-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/20] libcamera: ipu3: Remove initialization of Size X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Size struct constructor defaults the width and height to 0. Remove the empty braced-list initialization as it is not required. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index b480d41f89ab..6a93a48c2402 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -246,7 +246,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() * only. If no resolution is requested for any stream, or if no sensor * resolution is large enough, pick the largest one. */ - Size size = {}; + Size size; for (const StreamConfiguration &cfg : config_) { if (cfg.size.width > size.width) From patchwork Tue Jul 14 10:42:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8786 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id F05A9BD792 for ; Tue, 14 Jul 2020 10:38:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B42F86090C; Tue, 14 Jul 2020 12:38:58 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 061F6605B2 for ; Tue, 14 Jul 2020 12:38:56 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 44B2924000F; Tue, 14 Jul 2020 10:38:55 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:03 +0200 Message-Id: <20200714104212.48683-12-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 11/20] libcamera: ipu3: Validate the stream combination X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The IPU3 pipeline handler supports 2 processed RGB/YUV streams and one RAW stream. Validate that the requested stream combination is supported in the pipeline handler validate() implementation and return an error in case it's not. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 6a93a48c2402..19e07fd57e39 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -241,19 +241,34 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() } /* - * Select the sensor format by collecting the maximum width and height - * and picking the closest larger match, as the IPU3 can downscale - * only. If no resolution is requested for any stream, or if no sensor - * resolution is large enough, pick the largest one. + * Validate the requested stream configuration and select the sensor + * format by collecting the maximum width and height and picking the + * closest larger match, as the IPU3 can downscale only. If no + * resolution is requested for any stream, or if no sensor resolution is + * large enough, pick the largest one. */ + unsigned int rawCount = 0; + unsigned int yuvCount = 0; Size size; for (const StreamConfiguration &cfg : config_) { + const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); + + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + rawCount++; + else + yuvCount++; + if (cfg.size.width > size.width) size.width = cfg.size.width; if (cfg.size.height > size.height) size.height = cfg.size.height; } + if (rawCount > 1 || yuvCount > 2) { + LOG(IPU3, Debug) + << "Camera configuration not supported"; + return Invalid; + } /* Generate raw configuration from CIO2. */ cio2Configuration_ = data_->cio2_.generateConfiguration(size); From patchwork Tue Jul 14 10:42:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8787 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 72910BDB1C for ; Tue, 14 Jul 2020 10:38:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 36041605AC; Tue, 14 Jul 2020 12:38:59 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CA810605B2 for ; Tue, 14 Jul 2020 12:38:56 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 20270240018; Tue, 14 Jul 2020 10:38:55 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:04 +0200 Message-Id: <20200714104212.48683-13-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 12/20] libcamera: camera: Zero streams before validate() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The current implementation of the Camera::configure() method zeroes the stream pointers assigned to the StreamConfiguration items before calling the pipeline handler configure() operation, just after the CameraConfiguration has been validated. This discards the stream assignment performed at pipeline hander validation time, requiring platforms that need to perform that early assignment to maintain the association in place with custom data structures. To allow pipeline handlers to use StreamConfiguration::setStream() at validate() time, zero the stream assignment before calling validate(). Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/camera.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 69a1b4428e3f..ca88c48b2830 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -753,6 +753,9 @@ int Camera::configure(CameraConfiguration *config) if (ret < 0) return ret; + for (auto it : *config) + it.setStream(nullptr); + if (config->validate() != CameraConfiguration::Valid) { LOG(Camera, Error) << "Can't configure camera with invalid configuration"; @@ -763,7 +766,6 @@ int Camera::configure(CameraConfiguration *config) for (unsigned int index = 0; index < config->size(); ++index) { StreamConfiguration &cfg = config->at(index); - cfg.setStream(nullptr); msg << " (" << index << ") " << cfg.toString(); } From patchwork Tue Jul 14 10:42:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8788 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CE573BD792 for ; Tue, 14 Jul 2020 10:39:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A9FC760906; Tue, 14 Jul 2020 12:39:01 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 501C3605B2 for ; Tue, 14 Jul 2020 12:38:57 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id E9C3924000C; Tue, 14 Jul 2020 10:38:56 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:05 +0200 Message-Id: <20200714104212.48683-14-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 13/20] libcamera: ipu3: cio2: Mark sensor() as const X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Mark the CIO2Device::sensor() method as const, and allow to call it on const instances of the class. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/cio2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h index f905d97fa79d..0f75b0bc4572 100644 --- a/src/libcamera/pipeline/ipu3/cio2.h +++ b/src/libcamera/pipeline/ipu3/cio2.h @@ -49,7 +49,7 @@ public: int start(); int stop(); - CameraSensor *sensor() { return sensor_; } + CameraSensor *sensor() const { return sensor_; } int queueBuffer(Request *request, FrameBuffer *rawBuffer); void tryReturnBuffer(FrameBuffer *buffer); From patchwork Tue Jul 14 10:42:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8789 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 09679BDB1C for ; Tue, 14 Jul 2020 10:39:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CF32E60914; Tue, 14 Jul 2020 12:39:01 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E27B5605AC for ; Tue, 14 Jul 2020 12:38:57 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 7525E24000C; Tue, 14 Jul 2020 10:38:57 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:06 +0200 Message-Id: <20200714104212.48683-15-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 14/20] libcamera: ipu3: Adjust and assign streams in validate() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Remove the adjustStream() and assignStream() methods, and perform stream adjustment and assignment while iterating the StreamConfiguration items. The adjustStream() implementation had some arbitrary assumption, like the main output having to be as large as the sensor resolution, and did not take into account the different alignment requirements between the main output and the viewfinder output. The assignStream() implementation also assumes only full-size streams can be produced by the main output, and having it as a separate function prevents adjusting streams according to which output they are assigned. Blend the two implementation in a single loop and perform the required stream adjustment and assignment in one go. As streams are now assigned at validate() time, remove the same operation from the configure() function. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 247 ++++++++++++--------------- 1 file changed, 108 insertions(+), 139 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 19e07fd57e39..1161987a4322 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -70,9 +70,6 @@ public: const std::vector &streams() { return streams_; } private: - void assignStreams(); - void adjustStream(StreamConfiguration &cfg, bool scale); - /* * The IPU3CameraData instance is guaranteed to be valid as long as the * corresponding Camera instance is valid. In order to borrow a @@ -137,96 +134,6 @@ IPU3CameraConfiguration::IPU3CameraConfiguration(Camera *camera, data_ = data; } -void IPU3CameraConfiguration::assignStreams() -{ - /* - * Verify and update all configuration entries, and assign a stream to - * each of them. The viewfinder stream can scale, while the output - * stream can crop only, so select the output stream when the requested - * resolution is equal to the sensor resolution, and the viewfinder - * stream otherwise. - */ - std::set availableStreams = { - &data_->outStream_, - &data_->vfStream_, - &data_->rawStream_, - }; - - /* - * The caller is responsible to limit the number of requested streams - * to a number supported by the pipeline before calling this function. - */ - ASSERT(availableStreams.size() >= config_.size()); - - streams_.clear(); - streams_.reserve(config_.size()); - - for (const StreamConfiguration &cfg : config_) { - const PixelFormatInfo &info = - PixelFormatInfo::info(cfg.pixelFormat); - const Stream *stream; - - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) - stream = &data_->rawStream_; - else if (cfg.size == cio2Configuration_.size) - stream = &data_->outStream_; - else - stream = &data_->vfStream_; - - if (availableStreams.find(stream) == availableStreams.end()) - stream = *availableStreams.begin(); - - streams_.push_back(stream); - availableStreams.erase(stream); - } -} - -void IPU3CameraConfiguration::adjustStream(StreamConfiguration &cfg, bool scale) -{ - /* The only pixel format the driver supports is NV12. */ - cfg.pixelFormat = formats::NV12; - - if (scale) { - /* - * Provide a suitable default that matches the sensor aspect - * ratio. - */ - if (cfg.size.isNull()) { - cfg.size.width = 1280; - cfg.size.height = 1280 * cio2Configuration_.size.height - / cio2Configuration_.size.width; - } - - /* - * \todo: Clamp the size to the hardware bounds when we will - * figure them out. - * - * \todo: Handle the scaler (BDS) restrictions. The BDS can - * only scale with the same factor in both directions, and the - * scaling factor is limited to a multiple of 1/32. At the - * moment the ImgU driver hides these constraints by applying - * additional cropping, this should be fixed on the driver - * side, and cropping should be exposed to us. - */ - } else { - /* - * \todo: Properly support cropping when the ImgU driver - * interface will be cleaned up. - */ - cfg.size = cio2Configuration_.size; - } - - /* - * Clamp the size to match the ImgU alignment constraints. The width - * shall be a multiple of 8 pixels and the height a multiple of 4 - * pixels. - */ - if (cfg.size.width % 8 || cfg.size.height % 4) { - cfg.size.width &= ~7; - cfg.size.height &= ~3; - } -} - CameraConfiguration::Status IPU3CameraConfiguration::validate() { Status status = Valid; @@ -242,71 +149,141 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() /* * Validate the requested stream configuration and select the sensor - * format by collecting the maximum width and height and picking the - * closest larger match, as the IPU3 can downscale only. If no - * resolution is requested for any stream, or if no sensor resolution is - * large enough, pick the largest one. + * format by collecting the maximum RAW stream width and height and + * picking the closest larger match, as the IPU3 can downscale only. If + * no resolution is requested for the RAW stream, use the one from the + * largest YUV stream, plus margins pixels for the IF and BDS to scale. + * If no resolution is requested for any stream, pick the largest one. */ unsigned int rawCount = 0; unsigned int yuvCount = 0; - Size size; + Size maxYuvSize; + Size maxRawSize; for (const StreamConfiguration &cfg : config_) { const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { rawCount++; - else + maxRawSize = maxRawSize.expandedTo(cfg.size); + } else { yuvCount++; - - if (cfg.size.width > size.width) - size.width = cfg.size.width; - if (cfg.size.height > size.height) - size.height = cfg.size.height; + maxYuvSize = maxYuvSize.expandedTo(cfg.size); + } } if (rawCount > 1 || yuvCount > 2) { LOG(IPU3, Debug) << "Camera configuration not supported"; return Invalid; } + if (maxRawSize.isNull()) { + maxRawSize.width = utils::alignUp(maxYuvSize.width, + IMGU_OUTPUT_WIDTH_MARGIN); + maxRawSize.height = utils::alignUp(maxYuvSize.height, + IMGU_OUTPUT_HEIGHT_MARGIN); + maxRawSize = maxRawSize.boundedTo(data_->cio2_.sensor()->resolution()); + } - /* Generate raw configuration from CIO2. */ - cio2Configuration_ = data_->cio2_.generateConfiguration(size); + /* + * Generate raw configuration from CIO2. + * + * The output YUV streams will be limited in size to the maximum + * frame size requested for the RAW stream. + */ + cio2Configuration_ = data_->cio2_.generateConfiguration(maxRawSize); if (!cio2Configuration_.pixelFormat.isValid()) return Invalid; - /* Assign streams to each configuration entry. */ - assignStreams(); + LOG(IPU3, Debug) << "CIO2 configuration: " << cio2Configuration_.toString(); - /* Verify and adjust configuration if needed. */ + /* + * Adjust the configurations if needed and assign streams while + * iterating them. + */ + bool mainOutputAvailable = true; for (unsigned int i = 0; i < config_.size(); ++i) { - StreamConfiguration &cfg = config_[i]; - const StreamConfiguration oldCfg = cfg; - const Stream *stream = streams_[i]; - - if (stream == &data_->rawStream_) { - cfg.size = cio2Configuration_.size; - cfg.pixelFormat = cio2Configuration_.pixelFormat; - cfg.bufferCount = cio2Configuration_.bufferCount; + const PixelFormatInfo &info = PixelFormatInfo::info(config_[i].pixelFormat); + const StreamConfiguration originalCfg = config_[i]; + StreamConfiguration *cfg = &config_[i]; + + LOG(IPU3, Debug) << "Validating configuration: " << config_[i].toString(); + + + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { + /* Initialize the RAW stream with the CIO2 configuration. */ + cfg->size = cio2Configuration_.size; + cfg->pixelFormat = cio2Configuration_.pixelFormat; + cfg->bufferCount = cio2Configuration_.bufferCount; + cfg->stride = info.stride(cfg->size.width, 0, 64); + cfg->frameSize = info.frameSize(cfg->size, 64); + cfg->setStream(const_cast(&data_->rawStream_)); + + LOG(IPU3, Debug) << "Assigned " << cfg->toString() + << " to the raw stream"; } else { - bool scale = stream == &data_->vfStream_; - adjustStream(config_[i], scale); - cfg.bufferCount = IPU3_BUFFER_COUNT; + /* Assign and configure the main and viewfinder outputs. */ + + /* + * Clamp the size to match the ImgU size limits and the + * margins from the CIO2 output frame size. + * + * The ImgU outputs needs to be rounded down to 64 + * pixels in width and 32 pixels in height from the + * input frame size. + * + * \todo Verify this assumption and find out if it + * depends on the BDS scaling factor of 1/32, as the + * main output has no YUV scaler as the viewfinder + * output has. + */ + unsigned int limit; + limit = utils::alignDown(cio2Configuration_.size.width - 1, + IMGU_OUTPUT_WIDTH_MARGIN); + cfg->size.width = utils::clamp(cfg->size.width, + IMGU_OUTPUT_MIN_SIZE.width, + limit); + + limit = utils::alignDown(cio2Configuration_.size.height - 1, + IMGU_OUTPUT_HEIGHT_MARGIN); + cfg->size.height = utils::clamp(cfg->size.height, + IMGU_OUTPUT_MIN_SIZE.height, + limit); + + cfg->size = cfg->size.alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN, + IMGU_OUTPUT_HEIGHT_ALIGN); + + cfg->pixelFormat = formats::NV12; + cfg->bufferCount = IPU3_BUFFER_COUNT; + cfg->stride = info.stride(cfg->size.width, 0, 1); + cfg->frameSize = info.frameSize(cfg->size, 1); + + /* + * Use the main output stream in case only one stream is + * requested or if the current configuration is the one with + * the maximum YUV output size. + */ + if (mainOutputAvailable && + (originalCfg.size == maxYuvSize || yuvCount == 1)) { + cfg->setStream(const_cast(&data_->outStream_)); + mainOutputAvailable = false; + + LOG(IPU3, Debug) << "Assigned " << cfg->toString() + << " to the main output"; + } else { + cfg->setStream(const_cast(&data_->vfStream_)); + + LOG(IPU3, Debug) << "Assigned " << cfg->toString() + << " to the viewfinder output"; + } } - if (cfg.pixelFormat != oldCfg.pixelFormat || - cfg.size != oldCfg.size) { + if (cfg->pixelFormat != originalCfg.pixelFormat || + cfg->size != originalCfg.size) { LOG(IPU3, Debug) << "Stream " << i << " configuration adjusted to " - << cfg.toString(); + << cfg->toString(); status = Adjusted; } - - const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); - bool packedRaw = info.colourEncoding == PixelFormatInfo::ColourEncodingRAW; - - cfg.stride = info.stride(cfg.size.width, 0, packedRaw ? 64 : 1); - cfg.frameSize = info.frameSize(cfg.size, packedRaw ? 64 : 1); } return status; @@ -475,16 +452,8 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) bool vfActive = false; for (unsigned int i = 0; i < config->size(); ++i) { - /* - * Use a const_cast<> here instead of storing a mutable stream - * pointer in the configuration to let the compiler catch - * unwanted modifications of camera data in the configuration - * validate() implementation. - */ - Stream *stream = const_cast(config->streams()[i]); StreamConfiguration &cfg = (*config)[i]; - - cfg.setStream(stream); + Stream *stream = cfg.stream(); if (stream == outStream) { ret = imgu->configureOutput(cfg, &outputFormat); From patchwork Tue Jul 14 10:42:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8790 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7806EBDB1D for ; Tue, 14 Jul 2020 10:39:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3E047608E0; Tue, 14 Jul 2020 12:39:02 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9C88C608E0 for ; Tue, 14 Jul 2020 12:38:58 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 111E0240011; Tue, 14 Jul 2020 10:38:57 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:07 +0200 Message-Id: <20200714104212.48683-16-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 15/20] libcamera: ipu3: Remove streams from IPU3CameraConfiguration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The IPU3CameraConfiguration::streams_ field was used to keep an association between the StreamConfiguration and the assigned streams before CameraConfiguration::setStream() was called at configure() time. The stream assignment was based on the order in which elements were inserted in the vector, implementing a fragile association between streams and their intended configurations. As it is now possible to assign streams at validation time, there is no need to keep that association in place, and the streams_ vector is now unused. Remove it and the associated accessor method from the IPU3CameraConfiguration class. Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 1161987a4322..2d8b3c501294 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -67,7 +67,6 @@ public: Status validate() override; const StreamConfiguration &cio2Format() const { return cio2Configuration_; }; - const std::vector &streams() { return streams_; } private: /* @@ -79,7 +78,6 @@ private: const IPU3CameraData *data_; StreamConfiguration cio2Configuration_; - std::vector streams_; }; class PipelineHandlerIPU3 : public PipelineHandler From patchwork Tue Jul 14 10:42:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8791 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 099C5BD792 for ; Tue, 14 Jul 2020 10:39:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BB06F6087E; Tue, 14 Jul 2020 12:39:02 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 586596090F for ; Tue, 14 Jul 2020 12:38:59 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id C08ED240013; Tue, 14 Jul 2020 10:38:58 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:08 +0200 Message-Id: <20200714104212.48683-17-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 16/20] libcamera: ipu3: Remove camera_ from IPU3CameraConfiguration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The IPU3CameraConfiguration::camera_ shared pointer is not used. Remove it. Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 2d8b3c501294..804d68d47c92 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -62,7 +62,7 @@ public: class IPU3CameraConfiguration : public CameraConfiguration { public: - IPU3CameraConfiguration(Camera *camera, IPU3CameraData *data); + IPU3CameraConfiguration(IPU3CameraData *data); Status validate() override; @@ -74,7 +74,6 @@ private: * corresponding Camera instance is valid. In order to borrow a * reference to the camera data, store a new reference to the camera. */ - std::shared_ptr camera_; const IPU3CameraData *data_; StreamConfiguration cio2Configuration_; @@ -124,11 +123,9 @@ private: MediaDevice *imguMediaDev_; }; -IPU3CameraConfiguration::IPU3CameraConfiguration(Camera *camera, - IPU3CameraData *data) +IPU3CameraConfiguration::IPU3CameraConfiguration(IPU3CameraData *data) : CameraConfiguration() { - camera_ = camera->shared_from_this(); data_ = data; } @@ -296,7 +293,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, const StreamRoles &roles) { IPU3CameraData *data = cameraData(camera); - IPU3CameraConfiguration *config = new IPU3CameraConfiguration(camera, data); + IPU3CameraConfiguration *config = new IPU3CameraConfiguration(data); if (roles.empty()) return config; From patchwork Tue Jul 14 10:42:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8792 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 952B1BDB1C for ; Tue, 14 Jul 2020 10:39:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4E52D60905; Tue, 14 Jul 2020 12:39:03 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 20CB96081E for ; Tue, 14 Jul 2020 12:39:00 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 7AC2A24000C; Tue, 14 Jul 2020 10:38:59 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:09 +0200 Message-Id: <20200714104212.48683-18-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 17/20] libcamera: ipu3: imgu: Calculate ImgU pipe configuration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Instrument the ImgU component to dynamically calculate the image manipulation pipeline intermediate sizes. To correctly configure the ImgU it is necessary to program the IF, BDS and GDC sizes, which are currently fixed to the input frame size. The procedure used to calculate the intermediate sizes has been ported from the pipe_config.py python script, available at: https://github.com/intel/intel-ipu3-pipecfg at revision: 61e83f2f7606 ("Add more information into README") Define two structures (ImgUDevice::Pipe and ImgUDevice::PipeConfig) to allow the pipeline handler to supply and retrieve configuration parameters from the ImgU. Finally, add a new operation to the ImgUDevice that calculates the pipe configuration parameters based on the requested input and output sizes. Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- -- 2.27.0 diff from v2: #include "libcamera/internal/log.h" #include "libcamera/internal/media_device.h" +#include "libcamera/internal/utils.h" namespace libcamera { @@ -113,37 +114,25 @@ bool isSameRatio(const Size &in, const Size &out) return true; } -unsigned int alignIncrease(unsigned int len, unsigned int align) -{ - if (len % align) - return (std::floor(static_cast(len) / - static_cast(align)) + 1) * align; - return len; -} - void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc, unsigned int bdsWidth, float bdsSF) { unsigned int minIFHeight = iif.height - IF_CROP_MAX_H; unsigned int minBDSHeight = gdc.height + FILTER_H * 2; + unsigned int ifHeight; float bdsHeight; if (!isSameRatio(pipe->input, gdc)) { bool found = false; - float estIFHeight = static_cast(iif.width) * - static_cast(gdc.height) / + float estIFHeight = static_cast(iif.width * gdc.height) / static_cast(gdc.width); - estIFHeight = utils::clamp(estIFHeight, - static_cast(minIFHeight), - static_cast(iif.height)); - float ifHeight = - static_cast(alignIncrease(static_cast(estIFHeight), - IF_ALIGN_H)); - while (ifHeight >= minIFHeight && (ifHeight / bdsSF >= minBDSHeight)) { - bdsHeight = ifHeight / bdsSF; + estIFHeight = utils::clamp(estIFHeight, minIFHeight, iif.height); + ifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H); + while (ifHeight >= minIFHeight && + static_cast(ifHeight) / bdsSF >= minBDSHeight) { + bdsHeight = static_cast(ifHeight) / bdsSF; if (std::fmod(bdsHeight, 1.0) == 0) { - unsigned int bdsIntHeight = - static_cast(bdsHeight); + unsigned int bdsIntHeight = static_cast(bdsHeight); if (!(bdsIntHeight % BDS_ALIGN_H)) { found = true; break; @@ -153,15 +142,12 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc ifHeight -= IF_ALIGN_H; } - ifHeight = static_cast( - alignIncrease(static_cast(estIFHeight), - IF_ALIGN_H)); - - while (ifHeight <= iif.height && ifHeight / bdsSF >= minBDSHeight) { - bdsHeight = ifHeight / bdsSF; + ifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H); + while (ifHeight <= iif.height && + static_cast(ifHeight) / bdsSF >= minBDSHeight) { + bdsHeight = static_cast(ifHeight) / bdsSF; if (std::fmod(bdsHeight, 1.0) == 0) { - unsigned int bdsIntHeight = - static_cast(bdsHeight); + unsigned int bdsIntHeight = static_cast(bdsHeight); if (!(bdsIntHeight % BDS_ALIGN_H)) { found = true; break; @@ -172,23 +158,22 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc } if (found) { - unsigned int ifIntHeight = static_cast(ifHeight); unsigned int bdsIntHeight = static_cast(bdsHeight); - pipeConfigs.push_back({ bdsSF, { iif.width, ifIntHeight }, + pipeConfigs.push_back({ bdsSF, { iif.width, ifHeight }, { bdsWidth, bdsIntHeight }, gdc }); return; } } else { - float ifHeight = static_cast(alignIncrease(iif.height, IF_ALIGN_H)); - while (ifHeight > minIFHeight && (ifHeight / bdsSF > minBDSHeight)) { + ifHeight = utils::alignUp(iif.height, IF_ALIGN_H); + while (ifHeight > minIFHeight && + static_cast(ifHeight) / bdsSF >= minBDSHeight) { bdsHeight = ifHeight / bdsSF; if (std::fmod(ifHeight, 1.0) == 0 && std::fmod(bdsHeight, 1.0) == 0) { - unsigned int ifIntHeight = static_cast(ifHeight); unsigned int bdsIntHeight = static_cast(bdsHeight); - if (!(ifIntHeight % IF_ALIGN_H) && + if (!(ifHeight % IF_ALIGN_H) && !(bdsIntHeight % BDS_ALIGN_H)) { - pipeConfigs.push_back({ bdsSF, { iif.width, ifIntHeight }, + pipeConfigs.push_back({ bdsSF, { iif.width, ifHeight }, { bdsWidth, bdsIntHeight }, gdc }); } } @@ -240,8 +225,7 @@ Size calculateGDC(ImgUDevice::Pipe *pipe) if (!vf.isNull()) { gdc.width = main.width; - float ratio = static_cast(main.width) * - static_cast(vf.height) / + float ratio = static_cast(main.width * vf.height) / static_cast(vf.width); gdc.height = std::max(static_cast(main.height), ratio); @@ -271,8 +255,8 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe) float inW = static_cast(in.width); float inH = static_cast(in.height); - float ifCropW = static_cast(in.width) - static_cast(pipe.iif.width); - float ifCropH = static_cast(in.height) - static_cast(pipe.iif.height); + float ifCropW = static_cast(in.width - pipe.iif.width); + float ifCropH = static_cast(in.height - pipe.iif.height); float gdcCropW = static_cast(pipe.bds.width - pipe.gdc.width) * pipe.bds_sf; float gdcCropH = static_cast(pipe.bds.height - pipe.gdc.height) * pipe.bds_sf; fov.w = (inW - (ifCropW + gdcCropW)) / inW; @@ -400,7 +384,7 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe) const Size &in = pipe->input; Size gdc = calculateGDC(pipe); - unsigned int ifWidth = alignIncrease(in.width, IF_ALIGN_W); + unsigned int ifWidth = utils::alignUp(in.width, IF_ALIGN_W); unsigned int ifHeight = in.height; unsigned int minIfWidth = in.width - IF_CROP_MAX_W; float bdsSF = static_cast(in.width) / --- src/libcamera/pipeline/ipu3/imgu.cpp | 349 +++++++++++++++++++++++++++ src/libcamera/pipeline/ipu3/imgu.h | 20 ++ 2 files changed, 369 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index d7f4173d3607..ff0062a0e95c 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -7,6 +7,9 @@ #include "imgu.h" +#include +#include + #include #include @@ -14,11 +17,300 @@ #include "libcamera/internal/log.h" #include "libcamera/internal/media_device.h" +#include "libcamera/internal/utils.h" namespace libcamera { LOG_DECLARE_CATEGORY(IPU3) +namespace { + +static constexpr unsigned int FILTER_H = 4; + +static constexpr unsigned int IF_ALIGN_W = 2; +static constexpr unsigned int IF_ALIGN_H = 4; + +static constexpr unsigned int BDS_ALIGN_W = 2; +static constexpr unsigned int BDS_ALIGN_H = 4; + +static constexpr unsigned int IF_CROP_MAX_W = 40; +static constexpr unsigned int IF_CROP_MAX_H = 540; + +static constexpr float BDS_SF_MAX = 2.5; +static constexpr float BDS_SF_MIN = 1.0; +static constexpr float BDS_SF_STEP = 0.03125; + +/* BSD scaling factors: min=1, max=2.5, step=1/32 */ +const std::vector bdsScalingFactors = { + 1, 1.03125, 1.0625, 1.09375, 1.125, 1.15625, 1.1875, 1.21875, 1.25, + 1.28125, 1.3125, 1.34375, 1.375, 1.40625, 1.4375, 1.46875, 1.5, 1.53125, + 1.5625, 1.59375, 1.625, 1.65625, 1.6875, 1.71875, 1.75, 1.78125, 1.8125, + 1.84375, 1.875, 1.90625, 1.9375, 1.96875, 2, 2.03125, 2.0625, 2.09375, + 2.125, 2.15625, 2.1875, 2.21875, 2.25, 2.28125, 2.3125, 2.34375, 2.375, + 2.40625, 2.4375, 2.46875, 2.5 +}; + +/* GDC scaling factors: min=1, max=16, step=1/4 */ +const std::vector gdcScalingFactors = { + 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, + 4.5, 4.75, 5, 5.25, 5.5, 5.75, 6, 6.25, 6.5, 6.75, 7, 7.25, 7.5, 7.75, + 8, 8.25, 8.5, 8.75, 9, 9.25, 9.5, 9.75, 10, 10.25, 10.5, 10.75, 11, + 11.25, 11.5, 11.75, 12, 12.25, 12.5, 12.75, 13, 13.25, 13.5, 13.75, 14, + 14.25, 14.5, 14.75, 15, 15.25, 15.5, 15.75, 16, +}; + +std::vector pipeConfigs; + +struct FOV { + float w; + float h; + + bool isLarger(const FOV &other) + { + if (w > other.w) + return true; + if (w == other.w && h > other.h) + return true; + return false; + } +}; + +/* Approximate a scaling factor sf to the closest one available in a range. */ +float findScaleFactor(float sf, const std::vector &range, + bool roundDown = false) +{ + if (sf <= range[0]) + return range[0]; + if (sf >= range[range.size() - 1]) + return range[range.size() - 1]; + + + float bestDiff = std::numeric_limits::max(); + unsigned int index = 0; + for (unsigned int i = 0; i < range.size(); ++i) { + float diff = std::abs(sf - range[i]); + if (diff < bestDiff) { + bestDiff = diff; + index = i; + } + } + + if (roundDown && index > 0 && sf < range[index]) + index--; + + return range[index]; +} + +bool isSameRatio(const Size &in, const Size &out) +{ + float inRatio = static_cast(in.width) / + static_cast(in.height); + float outRatio = static_cast(out.width) / + static_cast(out.height); + + if (std::abs(inRatio - outRatio) > 0.1) + return false; + + return true; +} + +void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc, + unsigned int bdsWidth, float bdsSF) +{ + unsigned int minIFHeight = iif.height - IF_CROP_MAX_H; + unsigned int minBDSHeight = gdc.height + FILTER_H * 2; + unsigned int ifHeight; + float bdsHeight; + + if (!isSameRatio(pipe->input, gdc)) { + bool found = false; + float estIFHeight = static_cast(iif.width * gdc.height) / + static_cast(gdc.width); + estIFHeight = utils::clamp(estIFHeight, minIFHeight, iif.height); + ifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H); + while (ifHeight >= minIFHeight && + static_cast(ifHeight) / bdsSF >= minBDSHeight) { + bdsHeight = static_cast(ifHeight) / bdsSF; + if (std::fmod(bdsHeight, 1.0) == 0) { + unsigned int bdsIntHeight = static_cast(bdsHeight); + if (!(bdsIntHeight % BDS_ALIGN_H)) { + found = true; + break; + } + } + + ifHeight -= IF_ALIGN_H; + } + + ifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H); + while (ifHeight <= iif.height && + static_cast(ifHeight) / bdsSF >= minBDSHeight) { + bdsHeight = static_cast(ifHeight) / bdsSF; + if (std::fmod(bdsHeight, 1.0) == 0) { + unsigned int bdsIntHeight = static_cast(bdsHeight); + if (!(bdsIntHeight % BDS_ALIGN_H)) { + found = true; + break; + } + } + + ifHeight += IF_ALIGN_H; + } + + if (found) { + unsigned int bdsIntHeight = static_cast(bdsHeight); + pipeConfigs.push_back({ bdsSF, { iif.width, ifHeight }, + { bdsWidth, bdsIntHeight }, gdc }); + return; + } + } else { + ifHeight = utils::alignUp(iif.height, IF_ALIGN_H); + while (ifHeight > minIFHeight && + static_cast(ifHeight) / bdsSF >= minBDSHeight) { + bdsHeight = ifHeight / bdsSF; + if (std::fmod(ifHeight, 1.0) == 0 && std::fmod(bdsHeight, 1.0) == 0) { + unsigned int bdsIntHeight = static_cast(bdsHeight); + + if (!(ifHeight % IF_ALIGN_H) && + !(bdsIntHeight % BDS_ALIGN_H)) { + pipeConfigs.push_back({ bdsSF, { iif.width, ifHeight }, + { bdsWidth, bdsIntHeight }, gdc }); + } + } + + ifHeight -= IF_ALIGN_H; + } + } +} + +void calculateBDS(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc, + float bdsSF) +{ + unsigned int minBDSWidth = gdc.width + FILTER_H * 2; + + float sf = bdsSF; + while (sf <= BDS_SF_MAX && sf >= BDS_SF_MIN) { + float bdsWidth = static_cast(iif.width) / sf; + + if (std::fmod(bdsWidth, 1.0) == 0) { + unsigned int bdsIntWidth = static_cast(bdsWidth); + if (!(bdsIntWidth % BDS_ALIGN_W) && bdsWidth >= minBDSWidth) + calculateBDSHeight(pipe, iif, gdc, bdsIntWidth, sf); + } + + sf += BDS_SF_STEP; + } + + sf = bdsSF; + while (sf <= BDS_SF_MAX && sf >= BDS_SF_MIN) { + float bdsWidth = static_cast(iif.width) / sf; + + if (std::fmod(bdsWidth, 1.0) == 0) { + unsigned int bdsIntWidth = static_cast(bdsWidth); + if (!(bdsIntWidth % BDS_ALIGN_W) && bdsWidth >= minBDSWidth) + calculateBDSHeight(pipe, iif, gdc, bdsIntWidth, sf); + } + + sf -= BDS_SF_STEP; + } +} + +Size calculateGDC(ImgUDevice::Pipe *pipe) +{ + const Size &in = pipe->input; + const Size &main = pipe->output; + const Size &vf = pipe->viewfinder; + Size gdc; + + if (!vf.isNull()) { + gdc.width = main.width; + + float ratio = static_cast(main.width * vf.height) / + static_cast(vf.width); + gdc.height = std::max(static_cast(main.height), ratio); + + return gdc; + } + + if (!isSameRatio(in, main)) { + gdc = main; + return gdc; + } + + float totalSF = static_cast(in.width) / + static_cast(main.width); + float bdsSF = totalSF > 2 ? 2 : 1; + float yuvSF = totalSF / bdsSF; + float sf = findScaleFactor(yuvSF, gdcScalingFactors); + + gdc.width = static_cast(main.width) * sf; + gdc.height = static_cast(main.height) * sf; + + return gdc; +} + +FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe) +{ + FOV fov{}; + + float inW = static_cast(in.width); + float inH = static_cast(in.height); + float ifCropW = static_cast(in.width - pipe.iif.width); + float ifCropH = static_cast(in.height - pipe.iif.height); + float gdcCropW = static_cast(pipe.bds.width - pipe.gdc.width) * pipe.bds_sf; + float gdcCropH = static_cast(pipe.bds.height - pipe.gdc.height) * pipe.bds_sf; + fov.w = (inW - (ifCropW + gdcCropW)) / inW; + fov.h = (inH - (ifCropH + gdcCropH)) / inH; + + return fov; +} + +} /* namespace */ + +/** + * \struct PipeConfig + * \brief The ImgU pipe configuration parameters + * + * The ImgU image pipeline is composed of several hardware blocks that crop + * and scale the input image to obtain the desired output sizes. The + * scaling/cropping operations of those components is configured though the + * V4L2 selection API and the V4L2 subdev API applied to the ImgU media entity. + * + * The configurable components in the pipeline are: + * - IF: image feeder + * - BDS: bayer downscaler + * - GDC: geometric distorsion correction + * + * The IF crop rectangle is controlled by the V4L2_SEL_TGT_CROP selection target + * applied to the ImgU media entity sink pad number 0. The BDS scaler is + * controlled by the V4L2_SEL_TGT_COMPOSE target on the same pad, while the GDC + * output size is configured with the VIDIOC_SUBDEV_S_FMT IOCTL, again on pad + * number 0. + * + * The PipeConfig structure collects the sizes of each of those components + * plus the BDS scaling factor used to calculate the field of view + * of the final images. + */ + +/** + * \struct Pipe + * \brief Describe the ImgU requested configuration + * + * The ImgU unit processes images through several components, which have + * to be properly configured inspecting the input image size and the desired + * output sizes. This structure collects the ImgU input configuration and the + * requested main output and viewfinder configurations. + * + * \var Pipe::input + * \brief The input image size + * + * \var Pipe::output + * \brief The requested main output size + * + * \var Pipe::viewfinder + * \brief The requested viewfinder size + */ + /** * \brief Initialize components of the ImgU instance * \param[in] mediaDevice The ImgU instance media device @@ -74,6 +366,63 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index) return 0; } +/** + * \brief Calculate the ImgU pipe configuration parameters + * \param[in] pipe The requested ImgU configuration + * \return An ImgUDevice::PipeConfig instance on success, an empty configuration + * otherwise + */ +ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe) +{ + pipeConfigs.clear(); + + LOG(IPU3, Debug) << "Calculating pipe configuration for: "; + LOG(IPU3, Debug) << "input: " << pipe->input.toString(); + LOG(IPU3, Debug) << "main: " << pipe->output.toString(); + LOG(IPU3, Debug) << "vf: " << pipe->viewfinder.toString(); + + const Size &in = pipe->input; + Size gdc = calculateGDC(pipe); + + unsigned int ifWidth = utils::alignUp(in.width, IF_ALIGN_W); + unsigned int ifHeight = in.height; + unsigned int minIfWidth = in.width - IF_CROP_MAX_W; + float bdsSF = static_cast(in.width) / + static_cast(gdc.width); + float sf = findScaleFactor(bdsSF, bdsScalingFactors, true); + while (ifWidth >= minIfWidth) { + Size iif{ ifWidth, ifHeight }; + calculateBDS(pipe, iif, gdc, sf); + + ifWidth -= IF_ALIGN_W; + } + + if (pipeConfigs.size() == 0) { + LOG(IPU3, Error) << "Failed to calculate pipe configuration"; + return {}; + } + + FOV bestFov = calcFOV(pipe->input, pipeConfigs[0]); + unsigned int bestIndex = 0; + unsigned int p = 0; + for (auto pipeConfig : pipeConfigs) { + FOV fov = calcFOV(pipe->input, pipeConfig); + if (fov.isLarger(bestFov)) { + bestFov = fov; + bestIndex = p; + } + + ++p; + } + + LOG(IPU3, Debug) << "Computed pipe configuration: "; + LOG(IPU3, Debug) << "IF: " << pipeConfigs[bestIndex].iif.toString(); + LOG(IPU3, Debug) << "BDS: " << pipeConfigs[bestIndex].bds.toString(); + LOG(IPU3, Debug) << "GDC: " << pipeConfigs[bestIndex].gdc.toString(); + + return pipeConfigs[bestIndex]; +} + /** * \brief Configure the ImgU unit input * \param[in] size The ImgU input frame size diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h index 5c124af2e9fe..15ee9a7f5698 100644 --- a/src/libcamera/pipeline/ipu3/imgu.h +++ b/src/libcamera/pipeline/ipu3/imgu.h @@ -23,8 +23,28 @@ struct StreamConfiguration; class ImgUDevice { public: + struct PipeConfig { + float bds_sf; + Size iif; + Size bds; + Size gdc; + + bool isNull() const + { + return iif.isNull() || bds.isNull() || gdc.isNull(); + } + }; + + struct Pipe { + Size input; + Size output; + Size viewfinder; + }; + int init(MediaDevice *media, unsigned int index); + PipeConfig calculatePipeConfig(Pipe *pipe); + int configureInput(const Size &size, V4L2DeviceFormat *inputFormat); int configureOutput(const StreamConfiguration &cfg, From patchwork Tue Jul 14 10:42:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8793 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 46CECBD792 for ; Tue, 14 Jul 2020 10:39:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 232F46090F; Tue, 14 Jul 2020 12:39:06 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F2D396087E for ; Tue, 14 Jul 2020 12:39:00 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 3E0EC240011; Tue, 14 Jul 2020 10:39:00 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:10 +0200 Message-Id: <20200714104212.48683-19-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 18/20] libcamera: ipu3: Validate the pipe configuration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Collect the desired ImgU pipe configuration while assigning streams in the pipeline handler validate() function and ask the ImgUDevice class to calculate the pipe configuration parameters. If the requested pipe configuration results in a non-valid configuration, return an error from the validate() function. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 804d68d47c92..00aab2bdfc14 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -77,6 +77,7 @@ private: const IPU3CameraData *data_; StreamConfiguration cio2Configuration_; + ImgUDevice::PipeConfig pipeConfig_; }; class PipelineHandlerIPU3 : public PipelineHandler @@ -191,6 +192,9 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() LOG(IPU3, Debug) << "CIO2 configuration: " << cio2Configuration_.toString(); + ImgUDevice::Pipe pipe{}; + pipe.input = cio2Configuration_.size; + /* * Adjust the configurations if needed and assign streams while * iterating them. @@ -262,10 +266,15 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() cfg->setStream(const_cast(&data_->outStream_)); mainOutputAvailable = false; + pipe.output = cfg->size; + if (yuvCount == 1) + pipe.viewfinder = pipe.output; + LOG(IPU3, Debug) << "Assigned " << cfg->toString() << " to the main output"; } else { cfg->setStream(const_cast(&data_->vfStream_)); + pipe.viewfinder = cfg->size; LOG(IPU3, Debug) << "Assigned " << cfg->toString() << " to the viewfinder output"; @@ -281,6 +290,16 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() } } + /* Only compute the ImgU configuration if a YUV stream has been requested. */ + if (yuvCount) { + pipeConfig_ = data_->imgu_->calculatePipeConfig(&pipe); + if (pipeConfig_.isNull()) { + LOG(IPU3, Error) << "Failed to calculate pipe configuration: " + << "unsupported resolutions."; + return Invalid; + } + } + return status; } From patchwork Tue Jul 14 10:42:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8794 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id A2344BDB1C for ; Tue, 14 Jul 2020 10:39:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 481C86087E; Tue, 14 Jul 2020 12:39:06 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E383A60917 for ; Tue, 14 Jul 2020 12:39:01 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 2008C24000F; Tue, 14 Jul 2020 10:39:00 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:11 +0200 Message-Id: <20200714104212.48683-20-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 19/20] libcamera: ipu3: Configure ImgU with the computed parameters X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Instrument the ImgUDevice::configureInput() function to use the provided pipe configuration parameters to configure the IF, BDS and GDC rectangles. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/imgu. | 0 src/libcamera/pipeline/ipu3/imgu.cpp | 35 ++++++++++++++++------------ src/libcamera/pipeline/ipu3/imgu.h | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 11 ++++++++- 4 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 src/libcamera/pipeline/ipu3/imgu. diff --git a/src/libcamera/pipeline/ipu3/imgu. b/src/libcamera/pipeline/ipu3/imgu. new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index ff0062a0e95c..32e26c85807b 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -425,11 +425,11 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe) /** * \brief Configure the ImgU unit input - * \param[in] size The ImgU input frame size + * \param[in] config The ImgU pipe configuration parameters * \param[in] inputFormat The format to be applied to ImgU input * \return 0 on success or a negative error code otherwise */ -int ImgUDevice::configureInput(const Size &size, +int ImgUDevice::configureInput(const PipeConfig &pipeConfig, V4L2DeviceFormat *inputFormat) { /* Configure the ImgU input video device with the requested sizes. */ @@ -449,32 +449,37 @@ int ImgUDevice::configureInput(const Size &size, * to configure the crop/compose rectangles, contradicting the * V4L2 specification. */ - Rectangle rect = { + Rectangle iif = { .x = 0, .y = 0, - .width = inputFormat->size.width, - .height = inputFormat->size.height, + .width = pipeConfig.iif.width, + .height = pipeConfig.iif.height, }; - ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_CROP, &rect); + ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_CROP, &iif); if (ret) return ret; + LOG(IPU3, Debug) << "ImgU IF rectangle = " << iif.toString(); - ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_COMPOSE, &rect); + Rectangle bds = { + .x = 0, + .y = 0, + .width = pipeConfig.bds.width, + .height = pipeConfig.bds.height, + }; + ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_COMPOSE, &bds); if (ret) return ret; + LOG(IPU3, Debug) << "ImgU BDS rectangle = " << bds.toString(); - LOG(IPU3, Debug) << "ImgU input feeder and BDS rectangle = " - << rect.toString(); - - V4L2SubdeviceFormat imguFormat = {}; - imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED; - imguFormat.size = size; + V4L2SubdeviceFormat gdcFormat = {}; + gdcFormat.mbus_code = MEDIA_BUS_FMT_FIXED; + gdcFormat.size = pipeConfig.gdc; - ret = imgu_->setFormat(PAD_INPUT, &imguFormat); + ret = imgu_->setFormat(PAD_INPUT, &gdcFormat); if (ret) return ret; - LOG(IPU3, Debug) << "ImgU GDC format = " << imguFormat.toString(); + LOG(IPU3, Debug) << "ImgU GDC format = " << gdcFormat.toString(); return 0; } diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h index 15ee9a7f5698..6193c84bf35d 100644 --- a/src/libcamera/pipeline/ipu3/imgu.h +++ b/src/libcamera/pipeline/ipu3/imgu.h @@ -45,7 +45,7 @@ public: PipeConfig calculatePipeConfig(Pipe *pipe); - int configureInput(const Size &size, V4L2DeviceFormat *inputFormat); + int configureInput(const PipeConfig &pipeConfig, V4L2DeviceFormat *inputFormat); int configureOutput(const StreamConfiguration &cfg, V4L2DeviceFormat *outputFormat) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 00aab2bdfc14..9906de38021b 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -67,6 +67,7 @@ public: Status validate() override; const StreamConfiguration &cio2Format() const { return cio2Configuration_; }; + const ImgUDevice::PipeConfig imguConfig() const { return pipeConfig_; } private: /* @@ -457,7 +458,15 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) if (ret) return ret; - ret = imgu->configureInput(sensorSize, &cio2Format); + /* + * If no ImgU configuration has been computed, only RAW stream has + * been requested: return here and skip the ImgU configuration part. + */ + ImgUDevice::PipeConfig imguConfig = config->imguConfig(); + if (imguConfig.isNull()) + return 0; + + ret = imgu->configureInput(imguConfig, &cio2Format); if (ret) return ret; From patchwork Tue Jul 14 10:42:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8795 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E3AF5BD792 for ; Tue, 14 Jul 2020 10:39:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5FE226091C; Tue, 14 Jul 2020 12:39:06 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D32EC60901 for ; Tue, 14 Jul 2020 12:39:02 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 1CDEC24000C; Tue, 14 Jul 2020 10:39:01 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Jul 2020 12:42:12 +0200 Message-Id: <20200714104212.48683-21-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714104212.48683-1-jacopo@jmondi.org> References: <20200714104212.48683-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 20/20] libcamera: ipu3: imgu: Rename configureInput() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The ImgUDevice::configureInput() function does not only configure the input format but applies rectangles to the IF, BDS and GDC components. Rename it to ImgUDevice::configure(). Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/imgu.cpp | 5 ++--- src/libcamera/pipeline/ipu3/imgu.h | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index 32e26c85807b..608b8311c933 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -424,13 +424,12 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe) } /** - * \brief Configure the ImgU unit input + * \brief Configure the ImgU pipeline * \param[in] config The ImgU pipe configuration parameters * \param[in] inputFormat The format to be applied to ImgU input * \return 0 on success or a negative error code otherwise */ -int ImgUDevice::configureInput(const PipeConfig &pipeConfig, - V4L2DeviceFormat *inputFormat) +int ImgUDevice::configure(const PipeConfig &pipeConfig, V4L2DeviceFormat *inputFormat) { /* Configure the ImgU input video device with the requested sizes. */ int ret = input_->setFormat(inputFormat); diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h index 6193c84bf35d..16525c8dc6d1 100644 --- a/src/libcamera/pipeline/ipu3/imgu.h +++ b/src/libcamera/pipeline/ipu3/imgu.h @@ -45,7 +45,7 @@ public: PipeConfig calculatePipeConfig(Pipe *pipe); - int configureInput(const PipeConfig &pipeConfig, V4L2DeviceFormat *inputFormat); + int configure(const PipeConfig &pipeConfig, V4L2DeviceFormat *inputFormat); int configureOutput(const StreamConfiguration &cfg, V4L2DeviceFormat *outputFormat) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 9906de38021b..ef791f7e6f21 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -466,7 +466,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) if (imguConfig.isNull()) return 0; - ret = imgu->configureInput(imguConfig, &cio2Format); + ret = imgu->configure(imguConfig, &cio2Format); if (ret) return ret;