From patchwork Tue Aug 3 13:32:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13179 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 709CBC3235 for ; Tue, 3 Aug 2021 13:32:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 287C1687BC; Tue, 3 Aug 2021 15:32:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cS0Pgq0/"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CFF056026A for ; Tue, 3 Aug 2021 15:32:29 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.238.109.12]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7281E3F0; Tue, 3 Aug 2021 15:32:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1627997549; bh=XI2fwNT/vRzreI/MHOIyCO6zOrg+qzwqMxOr0NiIQ70=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cS0Pgq0/3VT4lktHkcXNSJKonKsHJ+pVuUIlPoRTVc5UO1LVypDlpKDYxySkyjVdn afsIkocJKTJVD8WEPDozoyyGNFOwP+SZt8toGL5ryJgXrCKyEIWX4+/fYJB2/NLbmc RyqBOh+3njgcIDFf32DNzsu5AV6I+CyjOTG9x9kg= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Tue, 3 Aug 2021 19:02:03 +0530 Message-Id: <20210803133205.6599-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210803133205.6599-1-umang.jain@ideasonboard.com> References: <20210803133205.6599-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/4] ipu3: cio2: Replicate CameraSensor::getFormats() to a member function 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" This prepares a base to introduce custom selection of sensor format based on platform(soraka or nautilus) constraints. The changes in selection policy will be introduced in a subsequent patch. The replication of the function is not verbatim and has small changes. CameraSensor::getFormats() has accesss to all the supported sensor formats via a V4L2Subdevice::Formats internally and use it directly. We do not want to expose V4L2Subdevice::Formats directly to the pipeline-handler hence, the patch is adapted to use the CameraSensor::sizes(mbusCode) instead, to get the range of sensor sizes supported for desired media bus codes. No functional changes in this patch. Signed-off-by: Umang Jain Reviewed-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/cio2.cpp | 91 +++++++++++++++++++++++++++- src/libcamera/pipeline/ipu3/cio2.h | 3 + 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 6f2ef321..be063613 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -7,6 +7,8 @@ #include "cio2.h" +#include + #include #include @@ -170,7 +172,7 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat) * the CIO2 output device. */ std::vector mbusCodes = utils::map_keys(mbusCodesToPixelFormat); - sensorFormat = sensor_->getFormat(mbusCodes, size); + sensorFormat = getSensorFormat(mbusCodes, size); ret = sensor_->setFormat(&sensorFormat); if (ret) return ret; @@ -208,7 +210,7 @@ StreamConfiguration CIO2Device::generateConfiguration(Size size) const /* Query the sensor static information for closest match. */ std::vector mbusCodes = utils::map_keys(mbusCodesToPixelFormat); - V4L2SubdeviceFormat sensorFormat = sensor_->getFormat(mbusCodes, size); + V4L2SubdeviceFormat sensorFormat = getSensorFormat(mbusCodes, size); if (!sensorFormat.mbus_code) { LOG(IPU3, Error) << "Sensor does not support mbus code"; return {}; @@ -221,6 +223,91 @@ StreamConfiguration CIO2Device::generateConfiguration(Size size) const return cfg; } +/** + * \brief Retrieve the best sensor format for a desired output + * \param[in] mbusCodes The list of acceptable media bus codes + * \param[in] size The desired size + * + * Media bus codes are selected from \a mbusCodes, which lists all acceptable + * codes in decreasing order of preference. Media bus codes supported by the + * sensor but not listed in \a mbusCodes are ignored. If none of the desired + * codes is supported, it returns an error. + * + * \a size indicates the desired size at the output of the sensor. This method + * selects the best media bus code and size supported by the sensor according + * to the following criteria. + * + * - The desired \a size shall fit in the sensor output size to avoid the need + * to up-scale. + * - The sensor output size shall match the desired aspect ratio to avoid the + * need to crop the field of view. + * - The sensor output size shall be as small as possible to lower the required + * bandwidth. + * - The desired \a size shall be supported by one of the media bus code listed + * in \a mbusCodes. + * + * When multiple media bus codes can produce the same size, the code at the + * lowest position in \a mbusCodes is selected. + * + * The use of this method is optional, as the above criteria may not match the + * needs of all pipeline handlers. Pipeline handlers may implement custom + * sensor format selection when needed. + * + * The returned sensor output format is guaranteed to be acceptable by the + * setFormat() method without any modification. + * + * \return The best sensor output format matching the desired media bus codes + * and size on success, or an empty format otherwise. + */ +V4L2SubdeviceFormat CIO2Device::getSensorFormat(const std::vector &mbusCodes, + const Size &size) const +{ + unsigned int desiredArea = size.width * size.height; + unsigned int bestArea = UINT_MAX; + float desiredRatio = static_cast(size.width) / size.height; + float bestRatio = FLT_MAX; + Size bestSize; + uint32_t bestCode = 0; + + for (unsigned int code : mbusCodes) { + const auto sizes = sensor_->sizes(code); + if (!sizes.size()) + continue; + + for (const Size &sz : sizes) { + if (sz.width < size.width || sz.height < size.height) + continue; + + float ratio = static_cast(sz.width) / sz.height; + float ratioDiff = fabsf(ratio - desiredRatio); + unsigned int area = sz.width * sz.height; + unsigned int areaDiff = area - desiredArea; + + if (ratioDiff > bestRatio) + continue; + + if (ratioDiff < bestRatio || areaDiff < bestArea) { + bestRatio = ratioDiff; + bestArea = areaDiff; + bestSize = sz; + bestCode = code; + } + } + } + + if (bestSize.isNull()) { + LOG(IPU3, Debug) << "No supported format or size found"; + return {}; + } + + V4L2SubdeviceFormat format{ + .mbus_code = bestCode, + .size = bestSize, + }; + + return format; +} + int CIO2Device::exportBuffers(unsigned int count, std::vector> *buffers) { diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h index f28e9f1d..da024d45 100644 --- a/src/libcamera/pipeline/ipu3/cio2.h +++ b/src/libcamera/pipeline/ipu3/cio2.h @@ -45,6 +45,9 @@ public: int exportBuffers(unsigned int count, std::vector> *buffers); + V4L2SubdeviceFormat getSensorFormat(const std::vector &mbusCodes, + const Size &size) const; + int start(); int stop();