From patchwork Thu Jul 9 08:41: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: 8692 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 1D5BCBD790 for ; Thu, 9 Jul 2020 08:38:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EB47F6118A; Thu, 9 Jul 2020 10:38:03 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 450F961184 for ; Thu, 9 Jul 2020 10:38:02 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 6D41C100015; Thu, 9 Jul 2020 08:38:00 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:09 +0200 Message-Id: <20200709084128.5316-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 01/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. Reviewed-by: Niklas Söderlund Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/cio2.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 97a434a73b28..f5a01dd3ec1f 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 = { +static 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 }, @@ -95,8 +95,8 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index) * cio2Codes vector sorted in ascending order. */ std::vector cio2Codes; - cio2Codes.reserve(mbusCodesToInfo.size()); - std::transform(mbusCodesToInfo.begin(), mbusCodesToInfo.end(), + cio2Codes.reserve(mbusCodesToPixelFormat.size()); + std::transform(mbusCodesToPixelFormat.begin(), mbusCodesToPixelFormat.end(), std::back_inserter(cio2Codes), [](auto &pair) { return pair.first; }); const std::vector &sensorCodes = sensor_->mbusCodes(); @@ -139,8 +139,8 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat) * the CIO2 output device. */ std::vector mbusCodes; - mbusCodes.reserve(mbusCodesToInfo.size()); - std::transform(mbusCodesToInfo.begin(), mbusCodesToInfo.end(), + mbusCodes.reserve(mbusCodesToPixelFormat.size()); + std::transform(mbusCodesToPixelFormat.begin(), mbusCodesToPixelFormat.end(), std::back_inserter(mbusCodes), [](auto &pair) { return pair.first; }); @@ -153,8 +153,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); @@ -183,7 +183,7 @@ CIO2Device::generateConfiguration(Size size) const /* Query the sensor static information for closest match. */ std::vector mbusCodes; - std::transform(mbusCodesToInfo.begin(), mbusCodesToInfo.end(), + std::transform(mbusCodesToPixelFormat.begin(), mbusCodesToPixelFormat.end(), std::back_inserter(mbusCodes), [](auto &pair) { return pair.first; }); @@ -194,7 +194,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 Thu Jul 9 08:41:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8693 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 6D35EBD790 for ; Thu, 9 Jul 2020 08:38:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2AD916118C; Thu, 9 Jul 2020 10:38:07 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3570161158 for ; Thu, 9 Jul 2020 10:38:05 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 4CA1D10000B; Thu, 9 Jul 2020 08:38:02 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:10 +0200 Message-Id: <20200709084128.5316-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 02/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: Kieran Bingham Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 104 ++++++++------------------- 1 file changed, 30 insertions(+), 74 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index af51fb2d1718..85d21b4db046 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -31,6 +31,14 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPU3) +static constexpr unsigned int IPU3_BUFFER_COUNT = 4; +static constexpr unsigned int IPU3_MAX_STREAMS = 3; +static constexpr unsigned int IPU3_OUTPUT_MAX_WIDTH = 4480; +static constexpr unsigned int IPU3_OUTPUT_MAX_HEIGHT = 34004; +static const Size minIPU3OutputSize = { 2, 2 }; +static constexpr unsigned int IPU3_OUTPUT_WIDTH_ALIGN = 0x3f; +static constexpr unsigned int IPU3_OUTPUT_HEIGHT_ALIGN = 0x3; + class IPU3CameraData : public CameraData { public: @@ -61,9 +69,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); @@ -293,94 +298,51 @@ 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. */ - cfg.size = { 2560, 1920 }; + cfg.size.width = std::min(sensorResolution.width, + IPU3_OUTPUT_MAX_WIDTH); + cfg.size.height = std::min(sensorResolution.height, + IPU3_OUTPUT_MAX_HEIGHT); + cfg.size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; + cfg.size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; + 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.bufferCount = 1; - 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 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.width = std::min(1280U, sensorResolution.width); + cfg.size.height = std::min(720U, sensorResolution.height); + cfg.size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; + cfg.size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; + cfg.pixelFormat = formats::NV12; + cfg.bufferCount = IPU3_BUFFER_COUNT; break; } @@ -388,16 +350,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 Thu Jul 9 08:41: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: 8694 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 B79AABD790 for ; Thu, 9 Jul 2020 08:38:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 927C26118C; Thu, 9 Jul 2020 10:38:09 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 53C7D61158 for ; Thu, 9 Jul 2020 10:38:06 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 83C02100004; Thu, 9 Jul 2020 08:38:05 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:11 +0200 Message-Id: <20200709084128.5316-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 03/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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- 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 85d21b4db046..e62a5d5b3517 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -357,7 +357,8 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, config->addConfiguration(cfg); } - config->validate(); + if (CameraConfiguration::Invalid == config->validate()) + return {}; return config; } From patchwork Thu Jul 9 08:41:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8695 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 2527FBDB1C for ; Thu, 9 Jul 2020 08:38:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D60C061191; Thu, 9 Jul 2020 10:38:09 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 272DA61169 for ; Thu, 9 Jul 2020 10:38:07 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 9AD4810000B; Thu, 9 Jul 2020 08:38:06 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:12 +0200 Message-Id: <20200709084128.5316-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 04/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 --- 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 f5a01dd3ec1f..525513317604 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 Thu Jul 9 08:41:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8696 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 6830FBD790 for ; Thu, 9 Jul 2020 08:38:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 454F4611A7; Thu, 9 Jul 2020 10:38:12 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CE26D61186 for ; Thu, 9 Jul 2020 10:38:08 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 6EC96100002; Thu, 9 Jul 2020 08:38:07 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:13 +0200 Message-Id: <20200709084128.5316-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 05/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: Niklas Söderlund Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- 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 e62a5d5b3517..978a6e58c72f 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -269,7 +269,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 Thu Jul 9 08:41:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8697 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 BEF8BBDB1C for ; Thu, 9 Jul 2020 08:38:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 66DCD611AA; Thu, 9 Jul 2020 10:38:12 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5096B61169 for ; Thu, 9 Jul 2020 10:38:10 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 6F205100015; Thu, 9 Jul 2020 08:38:08 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:14 +0200 Message-Id: <20200709084128.5316-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 06/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 --- src/libcamera/pipeline/ipu3/ipu3.cpp | 50 ++++++++++++++++++---------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 978a6e58c72f..d27acb405a1d 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -306,7 +306,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: @@ -314,20 +317,27 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, * Use the sensor resolution aligned to the ImgU * output constraints. */ - cfg.size.width = std::min(sensorResolution.width, - IPU3_OUTPUT_MAX_WIDTH); - cfg.size.height = std::min(sensorResolution.height, - IPU3_OUTPUT_MAX_HEIGHT); - cfg.size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; - cfg.size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; - cfg.pixelFormat = formats::NV12; - cfg.bufferCount = IPU3_BUFFER_COUNT; + size.width = std::min(sensorResolution.width, + IPU3_OUTPUT_MAX_WIDTH); + size.height = std::min(sensorResolution.height, + IPU3_OUTPUT_MAX_HEIGHT); + size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; + size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; + pixelFormat = formats::NV12; + bufferCount = IPU3_BUFFER_COUNT; + streamFormats[pixelFormat] = { { minIPU3OutputSize, size } }; break; case StreamRole::StillCaptureRaw: { - cfg = data->cio2_.generateConfiguration(sensorResolution); - cfg.bufferCount = 1; + 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; } @@ -339,12 +349,13 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, * sensor resolution and aligned to the ImgU output * constraints. */ - cfg.size.width = std::min(1280U, sensorResolution.width); - cfg.size.height = std::min(720U, sensorResolution.height); - cfg.size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; - cfg.size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; - cfg.pixelFormat = formats::NV12; - cfg.bufferCount = IPU3_BUFFER_COUNT; + size.width = std::min(1280U, sensorResolution.width); + size.height = std::min(720U, sensorResolution.height); + size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; + size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; + pixelFormat = formats::NV12; + bufferCount = IPU3_BUFFER_COUNT; + streamFormats[pixelFormat] = { { minIPU3OutputSize, size } }; break; } @@ -356,6 +367,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 Thu Jul 9 08:41:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8698 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 18166BD790 for ; Thu, 9 Jul 2020 08:38:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C1BC46118C; Thu, 9 Jul 2020 10:38:12 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F31CB61169 for ; Thu, 9 Jul 2020 10:38:10 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 7991310001A; Thu, 9 Jul 2020 08:38:10 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:15 +0200 Message-Id: <20200709084128.5316-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 07/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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- 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 d27acb405a1d..05e10ebb1a7d 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -245,7 +245,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 Thu Jul 9 08:41:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8699 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 AC74CBD790 for ; Thu, 9 Jul 2020 08:38:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 854E9611A7; Thu, 9 Jul 2020 10:38:14 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F202661189 for ; Thu, 9 Jul 2020 10:38:11 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 31A36100015; Thu, 9 Jul 2020 08:38:10 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:16 +0200 Message-Id: <20200709084128.5316-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 08/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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 05e10ebb1a7d..9128e42d42ed 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -240,19 +240,37 @@ 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 outCount = 0; Size size; for (const StreamConfiguration &cfg : config_) { + const PixelFormatInfo &info = + PixelFormatInfo::info(cfg.pixelFormat); + + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + rawCount++; + else + outCount++; + 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 || outCount > 2) { + LOG(IPU3, Error) + << "Camera configuration not supported: " + << "the platform supports up to one raw stream and " + << "two processed ones."; + return Invalid; + } /* Generate raw configuration from CIO2. */ cio2Configuration_ = data_->cio2_.generateConfiguration(size); From patchwork Thu Jul 9 08:41:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8700 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 14807BDB1C for ; Thu, 9 Jul 2020 08:38:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B9B86611B3; Thu, 9 Jul 2020 10:38:14 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 069F3611AF for ; Thu, 9 Jul 2020 10:38:13 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 4A3C5100011; Thu, 9 Jul 2020 08:38:11 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:17 +0200 Message-Id: <20200709084128.5316-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 09/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(). Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- 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 Thu Jul 9 08:41:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8701 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 1262CBD790 for ; Thu, 9 Jul 2020 08:38:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DDFC661189; Thu, 9 Jul 2020 10:38:16 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CC6806118E for ; Thu, 9 Jul 2020 10:38:13 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 353CD10000B; Thu, 9 Jul 2020 08:38:12 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:18 +0200 Message-Id: <20200709084128.5316-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 10/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 assume 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 Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 204 ++++++++++++--------------- 1 file changed, 91 insertions(+), 113 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 9128e42d42ed..18f4a02cc270 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -69,9 +69,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 @@ -136,96 +133,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; @@ -248,17 +155,26 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() */ unsigned int rawCount = 0; unsigned int outCount = 0; + Size yuvSize; Size size; for (const StreamConfiguration &cfg : config_) { const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { rawCount++; - else + } else { outCount++; + /* + * Collect the maximum processed size to later assign + * streams to configurations. + */ + if (cfg.size > yuvSize) + yuvSize = cfg.size; + } + if (cfg.size.width > size.width) size.width = cfg.size.width; if (cfg.size.height > size.height) @@ -277,24 +193,94 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() if (!cio2Configuration_.pixelFormat.isValid()) return Invalid; - /* Assign streams to each configuration entry. */ - assignStreams(); - - /* 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]; + const PixelFormatInfo &info = + PixelFormatInfo::info(cfg.pixelFormat); - if (stream == &data_->rawStream_) { + LOG(IPU3, Debug) << "Validating configuration: " << cfg.toString(); + + /* Initialize the RAW stream with the CIO2 configuration. */ + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { cfg.size = cio2Configuration_.size; cfg.pixelFormat = cio2Configuration_.pixelFormat; cfg.bufferCount = cio2Configuration_.bufferCount; + cfg.setStream(const_cast(&data_->rawStream_)); + + LOG(IPU3, Debug) << "Assigned " << cfg.toString() + << " to the raw stream"; + continue; + } + + /* + * Assign and configure the main and viewfinder outputs. + */ + + /* Clamp the size to match the ImgU size limits. */ + cfg.size.width = utils::clamp(cfg.size.width, + minIPU3OutputSize.width, + IPU3_OUTPUT_MAX_WIDTH); + cfg.size.height = utils::clamp(cfg.size.height, + minIPU3OutputSize.height, + IPU3_OUTPUT_MAX_HEIGHT); + + /* + * All the ImgU output stream should be smaller than the ImgU + * input frame, to give space to the IF and BDS to crop the + * image. + * + * \todo Give the BDS rectangle at least 32 pixels from the + * input frame size. This is an assumption deduced + * from inspecting the pipe configuration tool output + * and the platform configuration files shipped for the + * Soraka device by ChromeOS. + */ + if (cfg.size.width >= (cio2Configuration_.size.width - 31)) + cfg.size.width = cio2Configuration_.size.width - 32; + + if (cfg.size.height >= (cio2Configuration_.size.height - 31)) + cfg.size.height = cio2Configuration_.size.height - 32; + + /* + * Adjust to match the main output or the viewfinder + * output constraints and assign streams. + * + * Use the main output stream in case only one stream is + * requested or if the current configuration is the one with + * the maximum RGB/YUV output size. + */ + cfg.size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; + cfg.size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; + cfg.bufferCount = IPU3_BUFFER_COUNT; + cfg.pixelFormat = formats::NV12; + + /* + * 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; + if (mainOutputAvailable && + (oldCfg.size == yuvSize || outCount == 1)) { + stream = const_cast(&data_->outStream_); + mainOutputAvailable = false; + + LOG(IPU3, Debug) << "Assigned " << cfg.toString() + << " to the main output"; } else { - bool scale = stream == &data_->vfStream_; - adjustStream(config_[i], scale); - cfg.bufferCount = IPU3_BUFFER_COUNT; + stream = const_cast(&data_->vfStream_); + + LOG(IPU3, Debug) << "Assigned " << cfg.toString() + << " to the viewfinder output"; } + cfg.setStream(stream); if (cfg.pixelFormat != oldCfg.pixelFormat || cfg.size != oldCfg.size) { @@ -472,16 +458,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 Thu Jul 9 08:41:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8702 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 63017BDB1C for ; Thu, 9 Jul 2020 08:38:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3892B611B7; Thu, 9 Jul 2020 10:38:17 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 94DD6611B1 for ; Thu, 9 Jul 2020 10:38:14 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 0C8F010000B; Thu, 9 Jul 2020 08:38:13 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:19 +0200 Message-Id: <20200709084128.5316-12-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 11/20] libcamera: ipu3: Adjust full frame picture to 32 pixels 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" To respect the same constraint introduced in validate() that the maximum ImgU output size shall be at least 32 pixels smaller than the full frame size, adjust the sizes assigned to the StillCapture role in generateConfiguration(). Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 18f4a02cc270..d07f1a7b5ae8 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -320,10 +320,14 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, /* * Use the sensor resolution aligned to the ImgU * output constraints. + * + * \todo Give 32 pixels from the sensor frame size + * for the IF and BDS rectangles to scale. See + * the todo note for te same operation in validate(). */ - size.width = std::min(sensorResolution.width, + size.width = std::min(sensorResolution.width - 32, IPU3_OUTPUT_MAX_WIDTH); - size.height = std::min(sensorResolution.height, + size.height = std::min(sensorResolution.height - 32, IPU3_OUTPUT_MAX_HEIGHT); size.width &= ~IPU3_OUTPUT_WIDTH_ALIGN; size.height &= ~IPU3_OUTPUT_HEIGHT_ALIGN; From patchwork Thu Jul 9 08:41:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8703 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 F048CBD790 for ; Thu, 9 Jul 2020 08:38:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 90C70611A9; Thu, 9 Jul 2020 10:38:17 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7C29061158 for ; Thu, 9 Jul 2020 10:38:15 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id E2996100015; Thu, 9 Jul 2020 08:38:14 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:20 +0200 Message-Id: <20200709084128.5316-13-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 12/20] libcamera: ipu3: Always use the maximum frame 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 requirement of having the ImgU output height 32 pixels smaller than the input frame produced by the CIO2 makes it complicated to re-adjust the sensor produced size after the alignement has been applied. To simplify the procedure, always ask for the full frame size from the CIO2 unit. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index d07f1a7b5ae8..feabffe641e1 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -156,8 +156,6 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() unsigned int rawCount = 0; unsigned int outCount = 0; Size yuvSize; - Size size; - for (const StreamConfiguration &cfg : config_) { const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); @@ -174,11 +172,6 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() if (cfg.size > yuvSize) yuvSize = cfg.size; } - - 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 || outCount > 2) { LOG(IPU3, Error) @@ -189,10 +182,13 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() } /* Generate raw configuration from CIO2. */ - cio2Configuration_ = data_->cio2_.generateConfiguration(size); + Size sensorSize = data_->cio2_.sensor()->resolution(); + cio2Configuration_ = data_->cio2_.generateConfiguration(sensorSize); if (!cio2Configuration_.pixelFormat.isValid()) return Invalid; + LOG(IPU3, Debug) << "CIO2 configuration: " << cio2Configuration_.toString(); + /* * Adjust the configurations if needed and assign streams while * iterating them. From patchwork Thu Jul 9 08:41:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8704 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 740BBBD790 for ; Thu, 9 Jul 2020 08:38:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3AC04611AE; Thu, 9 Jul 2020 10:38:18 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6165561158 for ; Thu, 9 Jul 2020 10:38:16 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id ADE34100004; Thu, 9 Jul 2020 08:38:15 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:21 +0200 Message-Id: <20200709084128.5316-14-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 13/20] libcamera: ipu3: Store CameraData as mutable in CameraConfiguration 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" A reference to the CameraData sub-class is stored in the IPU3CameraConfiguration as a const pointer, as the now removed comment reports "to allow the compiler catch un-wanted modifications during validate()". As the CameraData contains pointers to the available streams, which are actually assigned during validate, the comment and the rationale behind that choice seems now moot. Store CameraData as a mutable pointer and remove the comment and the const_cast<> required to assign streams. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/libcamera/pipeline/ipu3/ipu3.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index feabffe641e1..9fed6c1e5aa7 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -75,7 +75,7 @@ private: * reference to the camera data, store a new reference to the camera. */ std::shared_ptr camera_; - const IPU3CameraData *data_; + IPU3CameraData *data_; StreamConfiguration cio2Configuration_; std::vector streams_; @@ -207,7 +207,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() cfg.size = cio2Configuration_.size; cfg.pixelFormat = cio2Configuration_.pixelFormat; cfg.bufferCount = cio2Configuration_.bufferCount; - cfg.setStream(const_cast(&data_->rawStream_)); + cfg.setStream(&data_->rawStream_); LOG(IPU3, Debug) << "Assigned " << cfg.toString() << " to the raw stream"; @@ -256,27 +256,19 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() cfg.bufferCount = IPU3_BUFFER_COUNT; cfg.pixelFormat = formats::NV12; - /* - * 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; if (mainOutputAvailable && (oldCfg.size == yuvSize || outCount == 1)) { - stream = const_cast(&data_->outStream_); + cfg.setStream(&data_->outStream_); mainOutputAvailable = false; LOG(IPU3, Debug) << "Assigned " << cfg.toString() << " to the main output"; } else { - stream = const_cast(&data_->vfStream_); + cfg.setStream(&data_->vfStream_); LOG(IPU3, Debug) << "Assigned " << cfg.toString() << " to the viewfinder output"; } - cfg.setStream(stream); if (cfg.pixelFormat != oldCfg.pixelFormat || cfg.size != oldCfg.size) { From patchwork Thu Jul 9 08:41:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8705 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 09667BD790 for ; Thu, 9 Jul 2020 08:38:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D5659611B2; Thu, 9 Jul 2020 10:38:19 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 709B6611B9 for ; Thu, 9 Jul 2020 10:38:17 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 91AFF100004; Thu, 9 Jul 2020 08:38:16 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:22 +0200 Message-Id: <20200709084128.5316-15-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 14/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 9fed6c1e5aa7..1c6627e561c4 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -66,7 +66,6 @@ public: Status validate() override; const StreamConfiguration &cio2Format() const { return cio2Configuration_; }; - const std::vector &streams() { return streams_; } private: /* @@ -78,7 +77,6 @@ private: IPU3CameraData *data_; StreamConfiguration cio2Configuration_; - std::vector streams_; }; class PipelineHandlerIPU3 : public PipelineHandler From patchwork Thu Jul 9 08:41:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8706 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 7AC6FBDB1C for ; Thu, 9 Jul 2020 08:38:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3AC4361197; Thu, 9 Jul 2020 10:38:20 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7954C611AA for ; Thu, 9 Jul 2020 10:38:18 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 93895100002; Thu, 9 Jul 2020 08:38:17 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:23 +0200 Message-Id: <20200709084128.5316-16-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 15/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 | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 1c6627e561c4..9a6e71514c90 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -61,19 +61,13 @@ public: class IPU3CameraConfiguration : public CameraConfiguration { public: - IPU3CameraConfiguration(Camera *camera, IPU3CameraData *data); + IPU3CameraConfiguration(IPU3CameraData *data); Status validate() override; const StreamConfiguration &cio2Format() const { return cio2Configuration_; }; private: - /* - * The IPU3CameraData instance is guaranteed to be valid as long as the - * 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_; IPU3CameraData *data_; StreamConfiguration cio2Configuration_; @@ -123,11 +117,9 @@ private: MediaDevice *imguMediaDev_; }; -IPU3CameraConfiguration::IPU3CameraConfiguration(Camera *camera, - IPU3CameraData *data) +IPU3CameraConfiguration::IPU3CameraConfiguration(IPU3CameraData *data) : CameraConfiguration() { - camera_ = camera->shared_from_this(); data_ = data; } @@ -289,7 +281,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 Thu Jul 9 08:41:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8707 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 BEDFDBD790 for ; Thu, 9 Jul 2020 08:38:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8ABCE6120A; Thu, 9 Jul 2020 10:38:22 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A9077611A2 for ; Thu, 9 Jul 2020 10:38:19 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id B25C7100002; Thu, 9 Jul 2020 08:38:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:24 +0200 Message-Id: <20200709084128.5316-17-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 16/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. Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- include/libcamera/geometry.h | 1 + src/libcamera/geometry.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 7d4b8bcfe3d8..44561d9cc5a4 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -18,6 +18,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 24c44fb43acf..af29ed1119fe 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 From patchwork Thu Jul 9 08:41:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8708 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 F37F6BDB1C for ; Thu, 9 Jul 2020 08:38:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BF8BF611B6; Thu, 9 Jul 2020 10:38:22 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A6A4161184 for ; Thu, 9 Jul 2020 10:38:20 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id F25E7100002; Thu, 9 Jul 2020 08:38:19 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:25 +0200 Message-Id: <20200709084128.5316-18-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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 unit. Finally, add a new operation to the ImgUDdevice that calculates the pipe configuration parameters based on the requested input and output sizes. Signed-off-by: Jacopo Mondi Acked-by: Niklas Söderlund --- src/libcamera/pipeline/ipu3/imgu.cpp | 365 +++++++++++++++++++++++++++ src/libcamera/pipeline/ipu3/imgu.h | 20 ++ 2 files changed, 385 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index d7f4173d3607..d1addb7d84d1 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 @@ -19,6 +22,311 @@ 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; +} + +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; + float bdsHeight; + + if (!isSameRatio(pipe->input, gdc)) { + bool found = false; + float estIFHeight = static_cast(iif.width) * + static_cast(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; + 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 = static_cast( + alignIncrease(static_cast(estIFHeight), + IF_ALIGN_H)); + + while (ifHeight <= iif.height && ifHeight / bdsSF >= minBDSHeight) { + bdsHeight = 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 ifIntHeight = static_cast(ifHeight); + unsigned int bdsIntHeight = static_cast(bdsHeight); + pipeConfigs.push_back({ bdsSF, { iif.width, ifIntHeight }, + { bdsWidth, bdsIntHeight }, gdc }); + return; + } + } else { + float ifHeight = static_cast(alignIncrease(iif.height, IF_ALIGN_H)); + while (ifHeight > minIFHeight && (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) && + !(bdsIntHeight % BDS_ALIGN_H)) { + pipeConfigs.push_back({ bdsSF, { iif.width, ifIntHeight }, + { 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) * + static_cast(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) - static_cast(pipe.iif.width); + float ifCropH = static_cast(in.height) - static_cast(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 +382,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 = alignIncrease(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 Thu Jul 9 08:41:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8709 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 5977ABDB1D for ; Thu, 9 Jul 2020 08:38:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 179FC61211; Thu, 9 Jul 2020 10:38:23 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 664B261184 for ; Thu, 9 Jul 2020 10:38:21 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id D7C60100002; Thu, 9 Jul 2020 08:38:20 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:26 +0200 Message-Id: <20200709084128.5316-19-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 18/20] libcamera: ipu3: 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" Collect the ImgU device desired 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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 9a6e71514c90..72261d16e9f8 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -71,6 +71,7 @@ private: IPU3CameraData *data_; StreamConfiguration cio2Configuration_; + ImgUDevice::PipeConfig pipeConfig_; }; class PipelineHandlerIPU3 : public PipelineHandler @@ -179,6 +180,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. @@ -250,11 +254,13 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() (oldCfg.size == yuvSize || outCount == 1)) { cfg.setStream(&data_->outStream_); mainOutputAvailable = false; + pipe.output = cfg.size; LOG(IPU3, Debug) << "Assigned " << cfg.toString() << " to the main output"; } else { cfg.setStream(&data_->vfStream_); + pipe.viewfinder = cfg.size; LOG(IPU3, Debug) << "Assigned " << cfg.toString() << " to the viewfinder output"; @@ -269,6 +275,13 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() } } + pipeConfig_ = data_->imgu_->calculatePipeConfig(&pipe); + if (pipeConfig_.isNull()) { + LOG(IPU3, Error) << "Failed to calculate pipe configuration: " + << "unsupported resolutions."; + return Invalid; + } + return status; } From patchwork Thu Jul 9 08:41:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8710 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 0E2F3BD790 for ; Thu, 9 Jul 2020 08:38:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DEAED611BA; Thu, 9 Jul 2020 10:38:25 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 897E5611A2 for ; Thu, 9 Jul 2020 10:38:22 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id B91F2100002; Thu, 9 Jul 2020 08:38:21 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:27 +0200 Message-Id: <20200709084128.5316-20-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 19/20] lbcamera: 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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- 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 | 3 ++- 4 files changed, 23 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 d1addb7d84d1..69bcc4f30962 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -441,11 +441,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. */ @@ -465,32 +465,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 input feeder 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 72261d16e9f8..d33aa7aee5e5 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -66,6 +66,7 @@ public: Status validate() override; const StreamConfiguration &cio2Format() const { return cio2Configuration_; }; + const ImgUDevice::PipeConfig imguConfig() const { return pipeConfig_; } private: IPU3CameraData *data_; @@ -444,7 +445,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) if (ret) return ret; - ret = imgu->configureInput(sensorSize, &cio2Format); + ret = imgu->configureInput(config->imguConfig(), &cio2Format); if (ret) return ret; From patchwork Thu Jul 9 08:41:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8711 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 32419BDB1C for ; Thu, 9 Jul 2020 08:38:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0B96E61212; Thu, 9 Jul 2020 10:38:26 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 43FD461212 for ; Thu, 9 Jul 2020 10:38:23 +0200 (CEST) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id BC360100002; Thu, 9 Jul 2020 08:38:22 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 10:41:28 +0200 Message-Id: <20200709084128.5316-21-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709084128.5316-1-jacopo@jmondi.org> References: <20200709084128.5316-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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(). Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/imgu.cpp | 3 +-- src/libcamera/pipeline/ipu3/imgu.h | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index 69bcc4f30962..a9fd2f6d2aa6 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -445,8 +445,7 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe) * \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 d33aa7aee5e5..eb4c72b90f3a 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -445,7 +445,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) if (ret) return ret; - ret = imgu->configureInput(config->imguConfig(), &cio2Format); + ret = imgu->configure(config->imguConfig(), &cio2Format); if (ret) return ret;