From patchwork Wed Jun 2 10:23:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 12484 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 2269BC3208 for ; Wed, 2 Jun 2021 10:23:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AE3356892A; Wed, 2 Jun 2021 12:23:39 +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="d33xO9b+"; 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 93108602AF for ; Wed, 2 Jun 2021 12:23:38 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.189]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 851104A5; Wed, 2 Jun 2021 12:23:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1622629418; bh=FNVQk+nrjoofngYNP1XSueEI/WKdzeRlImzEQmum3QE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d33xO9b+7V99JQOPLORtvO/m+sqiJvBrFpQ/WaNer1+06InQUnzNxdZF4p33fWt+h ue4SQ4VNxrCUPNzyxoYaC3E0bQF3CHH8Uk/L/zb10oKE4OL62gRodfahSGxsGHv0ar RQwhmlHMFkPmPe/gfhvhrp9tFWWFfQi+CNmE/CTM= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Jun 2021 15:53:23 +0530 Message-Id: <20210602102326.106549-2-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210602102326.106549-1-umang.jain@ideasonboard.com> References: <20210602102326.106549-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/4] android: Make FRAME_DURATION result key available in static metadata 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 ANDROID_SENSOR_FRAME_DURATION as an available result key for CTS to read out the value of frame duration we set in getResult in CameraDevice::getResultMetadata(). Failing to do so might fail the CTS test: android.hardware.camera2.cts.CaptureRequestTest#testNoiseReductionModeControl Fixes: 3beb1accac1d ("android: camera_device: Fix sensor frame duration") Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index fddc07ff..fe332ec3 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1422,6 +1422,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() ANDROID_REQUEST_PIPELINE_DEPTH, ANDROID_SCALER_CROP_REGION, ANDROID_SENSOR_EXPOSURE_TIME, + ANDROID_SENSOR_FRAME_DURATION, ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, ANDROID_SENSOR_TEST_PATTERN_MODE, ANDROID_SENSOR_TIMESTAMP, From patchwork Wed Jun 2 10:23:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 12485 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 6D9CDC3208 for ; Wed, 2 Jun 2021 10:23:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2BC86602AF; Wed, 2 Jun 2021 12:23:42 +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="UtLH6N0U"; 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 B7ACD68929 for ; Wed, 2 Jun 2021 12:23:40 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.189]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B0E9D4A5; Wed, 2 Jun 2021 12:23:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1622629420; bh=to6cSYtIicTZXif4Qk/X4aVwAAdccqAhk7IL9SAGETY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UtLH6N0UkvxzvMn+b7HayF1/7RTv8VF0Dgb0UCLXEaSlmZnFP7IyxPMFwV0HbCIPe fY4kIvrQG7HXLxxssHCloBrIWr4ElWmUrit3LjCAnsIrWjHEYoqj3pN6xo2+6IN1dM 8Br44+/FqgYpffN72hhxnz/QHDQgum2TeEdIGzMk= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Jun 2021 15:53:24 +0530 Message-Id: <20210602102326.106549-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210602102326.106549-1-umang.jain@ideasonboard.com> References: <20210602102326.106549-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/4] ipa: ipu3: Calculate line duration from IPACameraSensorInfo 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" Squash \todo by calculating line duration from IPACameraSensorInfo, now passed in, to IPU3Agc::initialise(). Since line duration is now calculated from real values, store it as a private member in IPU3Agc class. As a further step, replace the associated global constant, kMaxExposureTime, with a private IPU3Agc class member as well, and assign its value correspondingly in IPU3Agc::initialise(), similar to previous precedence. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham --- src/ipa/ipu3/ipu3.cpp | 2 +- src/ipa/ipu3/ipu3_agc.cpp | 22 +++++++++++----------- src/ipa/ipu3/ipu3_agc.h | 7 ++++++- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 700a5660..2496b0a0 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -174,7 +174,7 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo) awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_); agcAlgo_ = std::make_unique(); - agcAlgo_->initialise(bdsGrid_); + agcAlgo_->initialise(bdsGrid_, configInfo.sensorInfo); } void IPAIPU3::mapBuffers(const std::vector &buffers) diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp index 8bae423f..ccd01371 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/ipu3_agc.cpp @@ -39,11 +39,6 @@ static constexpr uint32_t kMaxGain = kMaxISO / 100; static constexpr uint32_t kMinExposure = 1; static constexpr uint32_t kMaxExposure = 1976; -/* \todo those should be got from IPACameraSensorInfo ! */ -/* line duration in microseconds */ -static constexpr double kLineDuration = 16.8; -static constexpr double kMaxExposureTime = kMaxExposure * kLineDuration; - /* Histogram constants */ static constexpr uint32_t knumHistogramBins = 256; static constexpr double kEvGainTarget = 0.5; @@ -54,14 +49,19 @@ static constexpr uint8_t kCellSize = 8; IPU3Agc::IPU3Agc() : frameCount_(0), lastFrame_(0), converged_(false), updateControls_(false), iqMean_(0.0), gamma_(1.0), + lineDuration_(0.0), maxExposureTime_(0.0), prevExposure_(0.0), prevExposureNoDg_(0.0), currentExposure_(0.0), currentExposureNoDg_(0.0) { } -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid) +void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo) { aeGrid_ = bdsGrid; + + /* line duration in microseconds */ + lineDuration_ = sensorInfo.lineLength / static_cast(sensorInfo.pixelRate / 1000000); + maxExposureTime_ = kMaxExposure * lineDuration_; } void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) @@ -160,13 +160,13 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain) double newGain = kEvGainTarget * knumHistogramBins / iqMean_; /* extracted from Rpi::Agc::computeTargetExposure */ - double currentShutter = exposure * kLineDuration; + double currentShutter = exposure * lineDuration_; currentExposureNoDg_ = currentShutter * gain; LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ << " Shutter speed " << currentShutter << " Gain " << gain; currentExposure_ = currentExposureNoDg_ * newGain; - double maxTotalExposure = kMaxExposureTime * kMaxGain; + double maxTotalExposure = maxExposureTime_ * kMaxGain; currentExposure_ = std::min(currentExposure_, maxTotalExposure); LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_; @@ -174,18 +174,18 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain) filterExposure(); double newExposure = 0.0; - if (currentShutter < kMaxExposureTime) { + if (currentShutter < maxExposureTime_) { exposure = std::clamp(static_cast(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure); newExposure = currentExposure_ / exposure; gain = std::clamp(static_cast(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); updateControls_ = true; - } else if (currentShutter >= kMaxExposureTime) { + } else if (currentShutter >= maxExposureTime_) { gain = std::clamp(static_cast(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); newExposure = currentExposure_ / gain; exposure = std::clamp(static_cast(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure); updateControls_ = true; } - LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * kLineDuration << " and gain " << gain; + LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; } lastFrame_ = frameCount_; } diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h index bfdf45d1..ae557bdd 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/ipu3_agc.h @@ -12,6 +12,8 @@ #include +#include + #include #include "libipa/algorithm.h" @@ -26,7 +28,7 @@ public: IPU3Agc(); ~IPU3Agc() = default; - void initialise(struct ipu3_uapi_grid_config &bdsGrid); + void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo); void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, uint32_t &gain); bool converged() { return converged_; } bool updateControls() { return updateControls_; } @@ -49,6 +51,9 @@ private: double iqMean_; double gamma_; + double lineDuration_; + double maxExposureTime_; + double prevExposure_; double prevExposureNoDg_; double currentExposure_; From patchwork Wed Jun 2 10:23:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 12486 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 BE2C2C3208 for ; Wed, 2 Jun 2021 10:23:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 831EC602AF; Wed, 2 Jun 2021 12:23:44 +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="BRYFzvn6"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D89B16050E for ; Wed, 2 Jun 2021 12:23:42 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.189]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A42784A5; Wed, 2 Jun 2021 12:23:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1622629422; bh=e8oBXTN623xZPGO/xDSa8+LGPhWI+SbMGHcd707iDa0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BRYFzvn6mJYW7suY0cHsTNZ1ZyhVkCRvZeBcBW89DOXd3N/F2wrLijrbtH97ilbZ1 SUjsBcx4fkQ8Qcnz0k7xKD7bXyQ0REtBjzOy1+BKBOn5f61WDAifTAKydAcqdHwAG5 Mu4rIiHZZwwlHPey1Ht3i/DtHGVwmuwnL/cxmBz4= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Jun 2021 15:53:25 +0530 Message-Id: <20210602102326.106549-4-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210602102326.106549-1-umang.jain@ideasonboard.com> References: <20210602102326.106549-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/4] ipa: ipu3: Copy IPACameraSensorInfo for future usage 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" IPACameraSensorInfo members will be needed at various places in the IPAIPU3 class, in subsequent commits. Hence, it seems trivial to copy this structure for wider availability throughout the class. This commit does not introduce any functional changes. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- src/ipa/ipu3/ipu3.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 2496b0a0..97ddb863 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -63,6 +63,8 @@ private: ControlInfoMap ctrls_; + IPACameraSensorInfo sensorInfo_; + /* Camera sensor controls. */ uint32_t exposure_; uint32_t minExposure_; @@ -144,6 +146,8 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo) if (configInfo.entityControls.empty()) return; + sensorInfo_ = configInfo.sensorInfo; + ctrls_ = configInfo.entityControls.at(0); const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE); @@ -174,7 +178,7 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo) awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_); agcAlgo_ = std::make_unique(); - agcAlgo_->initialise(bdsGrid_, configInfo.sensorInfo); + agcAlgo_->initialise(bdsGrid_, sensorInfo_); } void IPAIPU3::mapBuffers(const std::vector &buffers) From patchwork Wed Jun 2 10:23:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 12487 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 1F170C3208 for ; Wed, 2 Jun 2021 10:23:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D81586892B; Wed, 2 Jun 2021 12:23:45 +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="nfFLhFGI"; 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 08A746050E for ; Wed, 2 Jun 2021 12:23:45 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.189]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B99A84A5; Wed, 2 Jun 2021 12:23:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1622629424; bh=3bodz/Xb60Bp4G5y8TSCgkIFH0+0FqaPBMaUFAl8tw0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nfFLhFGIq9uUa/+ge7xIVh2vK5MYJfivVPcaoRCTR7lAXuAcqB6ZHosz+u84cSIxB JVSFdyIhyYDzCIGJdhUZQZjAIM6z3/mcnH4AZa7gBE3kVIqdUcuQbTVlDU2TOYH5Xm PaQeyhWMQJYggb0exA6/NC9/opg7BWgjpTNM0IMo= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Jun 2021 15:53:26 +0530 Message-Id: <20210602102326.106549-5-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210602102326.106549-1-umang.jain@ideasonboard.com> References: <20210602102326.106549-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/4] ipa: ipu3: Calculate frame duration from minimum VBLANK value 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" Frame duration is hard-coded for CTS as per [1]. Ideally, to accurately calculate the frame duration, it needs the VBLANK value from every frame's exposure. However, this particular bit is yet to be implemented in IPAIPU3. Meanwhile, we can atleast head in the right direction by not hard coding the value, instead using the minimum VBLANK value as reported the sensor. Update the existing \todo, to use the derived VBLANK value as and when it's available from each frame exposure. [1] 6c5f3fe6ced7 ("ipa: ipu3: Set output frame duration metadata") Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Jean-Michel Hautbois Tested-by: Jean-Michel Hautbois --- For reference, on `nautilus`: - minVBlank_ was reported as '104' - Calculating frame-duration using minVBlank_ came out to be: 34041 --- src/ipa/ipu3/ipu3.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 97ddb863..db4ec684 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -72,6 +72,7 @@ private: uint32_t gain_; uint32_t minGain_; uint32_t maxGain_; + uint32_t minVBlank_; /* Interface to the AWB algorithm */ std::unique_ptr awbAlgo_; @@ -162,6 +163,12 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo) return; } + const auto itVBlank = ctrls_.find(V4L2_CID_VBLANK); + if (itVBlank == ctrls_.end()) { + LOG(IPAIPU3, Error) << "Can't find VBLANK control"; + return; + } + minExposure_ = std::max(itExp->second.min().get(), 1); maxExposure_ = itExp->second.max().get(); exposure_ = minExposure_; @@ -170,6 +177,8 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo) maxGain_ = itGain->second.max().get(); gain_ = minGain_; + minVBlank_ = itVBlank->second.min().get(); + params_ = {}; calculateBdsGrid(configInfo.bdsOutputSize); @@ -273,9 +282,10 @@ void IPAIPU3::parseStatistics(unsigned int frame, if (agcAlgo_->updateControls()) setControls(frame); - /* \todo Populate this with real values */ - ctrls.set(controls::FrameDuration, - static_cast(33334)); + /* \todo Use VBlank value calculated from each frame exposure. */ + int64_t frameDuration = sensorInfo_.lineLength * (minVBlank_ + sensorInfo_.outputSize.height) / + (sensorInfo_.pixelRate / 1e6); + ctrls.set(controls::FrameDuration, frameDuration); IPU3Action op; op.op = ActionMetadataReady;