From patchwork Thu Aug 18 09:44:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 17168 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 B0D4AC3272 for ; Thu, 18 Aug 2022 09:44:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 668F861FCF; Thu, 18 Aug 2022 11:44:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660815880; bh=l89hiHPM7YlhUtC+fO+aFPQBN+t7zcaY+iz3xUnQJnk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=2Jc22eWiN8hi7UhxzgiN90AXOZAyHv5rl0jfr3WghOvKAWXasjum15ahwww/mP0wZ mWEqI33xd17LViR8ZOnzjYJuN2dUHCBAXbZpFZ7v6RCRYb/BOLBoZI0AgIvuOeMIxy 04ZRu/mh2GRom3mP45E4KvkbeUB5wjXvEz2JqGdweEno3lDz1gSgvSc6/TFgKKcO3+ H9WEbYVUfnnoetAAZfzDi3R4vXEXual6h91/yUs7aYSln4umg76V13/6sOW3VtTZU+ m1g4mTFB98TfvKTvCGn27wpwlwUEM9rVZ8cFwrs+MOJYCMLTmPoldNv8AVhzH/MH2A p9rDdunJRJrPg== Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4349361FD1 for ; Thu, 18 Aug 2022 11:44:36 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 42517FF80D; Thu, 18 Aug 2022 09:44:35 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Thu, 18 Aug 2022 11:44:06 +0200 Message-Id: <20220818094410.1671-14-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220818094410.1671-1-jacopo@jmondi.org> References: <20220818094410.1671-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 13/17] ipa: ipu3: Re-sort methods implementation 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Move the updateSessionConfiguration(), updateControls() and validateControls() function implementations before their unique caller (configure()) and re-sort them in orders they are called. For consistency, enforce the same ordering in the RkIPS1 module. Signed-off-by: Jacopo Mondi --- src/ipa/ipu3/ipu3.cpp | 250 +++++++++++++++++++------------------- src/ipa/rkisp1/rkisp1.cpp | 39 +++--- 2 files changed, 144 insertions(+), 145 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 077cf8050508..072d6cc28f33 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -161,13 +161,12 @@ protected: std::string logPrefix() const override; private: + bool validateSensorControls(); void updateControls(const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls); void updateSessionConfiguration(const IPAConfigInfo &configInfo); - bool validateSensorControls(); - void setControls(unsigned int frame); void calculateBdsGrid(const Size &bdsOutputSize); @@ -190,129 +189,6 @@ std::string IPAIPU3::logPrefix() const return "ipu3"; } -/** - * \brief Compute IPASessionConfiguration using the sensor information and the - * sensor V4L2 controls - */ -void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &configInfo) -{ - const IPACameraSensorInfo &sensorInfo = configInfo.sensorInfo; - const ControlInfoMap &sensorControls = configInfo.sensorControls; - - const ControlInfo vBlank = sensorControls.find(V4L2_CID_VBLANK)->second; - context_.configuration.sensor.defVBlank = vBlank.def().get(); - - const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; - int32_t minExposure = v4l2Exposure.min().get(); - int32_t maxExposure = v4l2Exposure.max().get(); - - const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second; - int32_t minGain = v4l2Gain.min().get(); - int32_t maxGain = v4l2Gain.max().get(); - - /* Clear the IPA context before the streaming session. */ - context_.frameContexts.clear(); - context_ = {}; - - /* - * When the AGC computes the new exposure values for a frame, it needs - * to know the limits for shutter speed and analogue gain. - * As it depends on the sensor, update it with the controls. - * - * \todo take VBLANK into account for maximum shutter speed - */ - context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s - / sensorInfo.pixelRate; - context_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration; - context_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration; - context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain); - context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); -} - -/** - * \brief Compute camera controls using the sensor information and the sensor - * V4L2 controls - * - * Some of the camera controls are computed by the pipeline handler, some others - * by the IPA module which is in charge of handling, for example, the exposure - * time and the frame duration. - * - * This function computes: - * - controls::ExposureTime - * - controls::FrameDurationLimits - */ -void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo, - const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) -{ - ControlInfoMap::Map controls{}; - double lineDuration = context_.configuration.sensor.lineDuration.get(); - - /* - * Compute exposure time limits by using line length and pixel rate - * converted to microseconds. Use the V4L2_CID_EXPOSURE control to get - * exposure min, max and default and convert it from lines to - * microseconds. - */ - const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; - int32_t minExposure = v4l2Exposure.min().get() * lineDuration; - int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; - int32_t defExposure = v4l2Exposure.def().get() * lineDuration; - controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure, - defExposure); - - /* - * Compute the frame duration limits. - * - * The frame length is computed assuming a fixed line length combined - * with the vertical frame sizes. - */ - const ControlInfo &v4l2HBlank = sensorControls.find(V4L2_CID_HBLANK)->second; - uint32_t hblank = v4l2HBlank.def().get(); - uint32_t lineLength = sensorInfo.outputSize.width + hblank; - - const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second; - std::array frameHeights{ - v4l2VBlank.min().get() + sensorInfo.outputSize.height, - v4l2VBlank.max().get() + sensorInfo.outputSize.height, - v4l2VBlank.def().get() + sensorInfo.outputSize.height, - }; - - std::array frameDurations; - for (unsigned int i = 0; i < frameHeights.size(); ++i) { - uint64_t frameSize = lineLength * frameHeights[i]; - frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); - } - - controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0], - frameDurations[1], - frameDurations[2]); - - *ipaControls = ControlInfoMap(std::move(controls), controls::controls); -} - -/** - * \brief Validate that the sensor controls mandatory for the IPA exists - */ -bool IPAIPU3::validateSensorControls() -{ - static const uint32_t ctrls[] = { - V4L2_CID_ANALOGUE_GAIN, - V4L2_CID_EXPOSURE, - V4L2_CID_VBLANK, - }; - - for (auto c : ctrls) { - if (sensorCtrls_.find(c) == sensorCtrls_.end()) { - LOG(IPAIPU3, Error) << "Unable to find sensor control " - << utils::hex(c); - return false; - } - } - - return true; -} - /** * \brief Initialize the IPA module and its controls * @@ -464,6 +340,130 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) << (int)bdsGrid.height << " << " << (int)bdsGrid.block_height_log2 << ")"; } +/** + * \brief Validate that the sensor controls mandatory for the IPA exists + */ +bool IPAIPU3::validateSensorControls() +{ + static const uint32_t ctrls[] = { + V4L2_CID_ANALOGUE_GAIN, + V4L2_CID_EXPOSURE, + V4L2_CID_VBLANK, + }; + + for (auto c : ctrls) { + if (sensorCtrls_.find(c) == sensorCtrls_.end()) { + LOG(IPAIPU3, Error) << "Unable to find sensor control " + << utils::hex(c); + return false; + } + } + + return true; +} + +/** + * \brief Compute camera controls using the sensor information and the sensor + * V4L2 controls + * + * Some of the camera controls are computed by the pipeline handler, some others + * by the IPA module which is in charge of handling, for example, the exposure + * time and the frame duration. + * + * This function computes: + * - controls::ExposureTime + * - controls::FrameDurationLimits + */ +void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo, + const ControlInfoMap &sensorControls, + ControlInfoMap *ipaControls) +{ + ControlInfoMap::Map controls{}; + double lineDuration = context_.configuration.sensor.lineDuration.get(); + + /* + * Compute exposure time limits by using line length and pixel rate + * converted to microseconds. Use the V4L2_CID_EXPOSURE control to get + * exposure min, max and default and convert it from lines to + * microseconds. + */ + const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; + int32_t minExposure = v4l2Exposure.min().get() * lineDuration; + int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; + int32_t defExposure = v4l2Exposure.def().get() * lineDuration; + controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure, + defExposure); + + /* + * Compute the frame duration limits. + * + * The frame length is computed assuming a fixed line length combined + * with the vertical frame sizes. + */ + const ControlInfo &v4l2HBlank = sensorControls.find(V4L2_CID_HBLANK)->second; + uint32_t hblank = v4l2HBlank.def().get(); + uint32_t lineLength = sensorInfo.outputSize.width + hblank; + + const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second; + std::array frameHeights{ + v4l2VBlank.min().get() + sensorInfo.outputSize.height, + v4l2VBlank.max().get() + sensorInfo.outputSize.height, + v4l2VBlank.def().get() + sensorInfo.outputSize.height, + }; + + std::array frameDurations; + for (unsigned int i = 0; i < frameHeights.size(); ++i) { + uint64_t frameSize = lineLength * frameHeights[i]; + frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); + } + + controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0], + frameDurations[1], + frameDurations[2]); + + *ipaControls = ControlInfoMap(std::move(controls), controls::controls); +} + + +/** + * \brief Compute IPASessionConfiguration using the sensor information and the + * sensor V4L2 controls + */ +void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &configInfo) +{ + const IPACameraSensorInfo &sensorInfo = configInfo.sensorInfo; + const ControlInfoMap &sensorControls = configInfo.sensorControls; + + const ControlInfo vBlank = sensorControls.find(V4L2_CID_VBLANK)->second; + context_.configuration.sensor.defVBlank = vBlank.def().get(); + + const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; + int32_t minExposure = v4l2Exposure.min().get(); + int32_t maxExposure = v4l2Exposure.max().get(); + + const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second; + int32_t minGain = v4l2Gain.min().get(); + int32_t maxGain = v4l2Gain.max().get(); + + /* Clear the IPA context before the streaming session. */ + context_.frameContexts.clear(); + context_ = {}; + + /* + * When the AGC computes the new exposure values for a frame, it needs + * to know the limits for shutter speed and analogue gain. + * As it depends on the sensor, update it with the controls. + * + * \todo take VBLANK into account for maximum shutter speed + */ + context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s + / sensorInfo.pixelRate; + context_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration; + context_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration; + context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain); + context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain); +} + /** * \brief Configure the IPU3 IPA * \param[in] configInfo The IPA configuration data, received from the pipeline diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 9f97c776016e..da7374815c99 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -62,8 +62,8 @@ protected: std::string logPrefix() const override; private: - void updateSessionConfiguration(const IPAConfigInfo &configInfo); bool validateSensorControls(const ControlInfoMap &sensorControls); + void updateSessionConfiguration(const IPAConfigInfo &configInfo); void setControls(unsigned int frame); void prepareMetadata(unsigned int frame, unsigned int aeState); @@ -194,6 +194,24 @@ void IPARkISP1::stop() context_.frameContexts.clear(); } +bool IPARkISP1::validateSensorControls(const ControlInfoMap &sensorControls) +{ + static const uint32_t ctrls[] = { + V4L2_CID_ANALOGUE_GAIN, + V4L2_CID_EXPOSURE, + }; + + for (auto c : ctrls) { + if (sensorControls.find(c) == sensorControls.end()) { + LOG(IPARkISP1, Error) << "Unable to find sensor control " + << utils::hex(c); + return false; + } + } + + return true; +} + void IPARkISP1::updateSessionConfiguration(const IPAConfigInfo &configInfo) { const IPACameraSensorInfo &sensorInfo = configInfo.sensorInfo; @@ -237,25 +255,6 @@ void IPARkISP1::updateSessionConfiguration(const IPAConfigInfo &configInfo) context_.activeState.frameCount = 0; } -bool IPARkISP1::validateSensorControls(const ControlInfoMap &sensorControls) -{ - static const uint32_t ctrls[] = { - V4L2_CID_ANALOGUE_GAIN, - V4L2_CID_EXPOSURE, - }; - - for (auto c : ctrls) { - if (sensorControls.find(c) == sensorControls.end()) { - LOG(IPARkISP1, Error) << "Unable to find sensor control " - << utils::hex(c); - return false; - } - } - - return true; - -} - int IPARkISP1::configure(const IPAConfigInfo &configInfo) { if (!validateSensorControls(configInfo.sensorControls)) {