From patchwork Thu Jun 30 13:38:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16472 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 3D6DCC3275 for ; Thu, 30 Jun 2022 13:39:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DFA3E656AA; Thu, 30 Jun 2022 15:39:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656596382; bh=9E+htababTQRwiAXk97E3/6MTUzUihKkQXjRjDhKrec=; 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=AhMLkuOJPozAg16ySDICfLdpz1j/9MG8FkBmCDxwaXaqWCPfStL0DG1T6p6BZJHi9 D+5Cp2NOaT3MbJ9y02nypCBJex2l37b0AJEykPiD9DnK6VfCA+Zqd+tDj3D4ed+CEP XJRkZDYoPTDOl3jEINOocKCupCNLg8urAk1mldfd6aSj/sN3+6kmNAQTNvWPAcQoTd nUPTNhDlLflnW15IX7GL6oshrot6DPbbsuj4mjbFWQ0Ln2KMoocdxf3yjMhkMssiho sScFU1NibWlT13m/QW3wKlEhtwONwqz1sjLndh960FQFNp5JgDkYv4HvfOLNl1E1R5 yP4akI2OP8bTA== Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::221]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CB7BB65658 for ; Thu, 30 Jun 2022 15:39:35 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id CBFA2240010; Thu, 30 Jun 2022 13:39:34 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jun 2022 15:38:52 +0200 Message-Id: <20220630133902.321099-14-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220630133902.321099-1-jacopo@jmondi.org> References: <20220630133902.321099-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 13/23] libcamera: camera_sensor: Cache the sensor 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: , 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" The sensor configuration parameters, which include the output format the blanking lengths and the current pixel rate, are updated everytime a new format is set on the sensor. The sensor configuration parameters will be used in order to translate libcamera controls in the corresponding V4L2 control values (and vice-versa). The same parameters are also used to populate the CameraSensorInfo to pass it to IPA modules. In order to avoid re-querying the V4L2 subdevice for the control values and the output format everytime, cache the current sensor configuration in a class member field, updated when a new format is set on the sensor and at initialization time. As the function that updates the configuration was originally only meant to update the CameraSensor ControlInfoMap limits, rename it from updateControls() to updateConfiguration(). Signed-off-by: Jacopo Mondi --- include/libcamera/internal/camera_sensor.h | 9 ++- src/libcamera/camera_sensor/camera_sensor.cpp | 69 +++++++------------ 2 files changed, 32 insertions(+), 46 deletions(-) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index a606bc5d1cb5..bb9327646bc1 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -81,6 +81,13 @@ protected: private: LIBCAMERA_DISABLE_COPY(CameraSensor) + struct { + V4L2SubdeviceFormat outputFormat; + uint64_t pixelRate; + uint32_t hblank; + double lineDuration; + } config_; + int generateId(); int validateSensorDriver(); void initVimcDefaultProperties(); @@ -88,7 +95,7 @@ private: void initTestPatternModes(); int initProperties(); int initDelayedControls(); - int updateControls(); + int updateConfiguration(); int applyTestPatternMode(controls::draft::TestPatternModeEnum mode); int discoverAncillaryDevices(); diff --git a/src/libcamera/camera_sensor/camera_sensor.cpp b/src/libcamera/camera_sensor/camera_sensor.cpp index e1770e8fa130..cc4cbd4ad509 100644 --- a/src/libcamera/camera_sensor/camera_sensor.cpp +++ b/src/libcamera/camera_sensor/camera_sensor.cpp @@ -181,7 +181,7 @@ int CameraSensor::init() return -ENODEV; } - ret = updateControls(); + ret = updateConfiguration(); if (ret) return ret; @@ -501,7 +501,7 @@ int CameraSensor::initDelayedControls() return 0; } -int CameraSensor::updateControls() +int CameraSensor::updateConfiguration() { if (!bayerFormat_) return 0; @@ -511,12 +511,11 @@ int CameraSensor::updateControls() /* The subdev driver has been validate already, the controls are there! */ ControlList subdevControls = subdev_->getControls({ V4L2_CID_PIXEL_RATE, V4L2_CID_HBLANK }); - uint64_t pixelRate = subdevControls.get(V4L2_CID_PIXEL_RATE).get(); - uint32_t hblank = subdevControls.get(V4L2_CID_HBLANK).get(); + config_.pixelRate = subdevControls.get(V4L2_CID_PIXEL_RATE).get(); + config_.hblank = subdevControls.get(V4L2_CID_HBLANK).get(); /* Assume the sensor has a single source pad #0. */ - V4L2SubdeviceFormat subdevFormat; - subdev_->getFormat(0, &subdevFormat); + subdev_->getFormat(0, &config_.outputFormat); const ControlInfoMap &subdevControlsInfo = subdev_->controls(); @@ -526,12 +525,14 @@ int CameraSensor::updateControls() * get exposure min, max and default and convert it from lines to * microseconds. */ - uint32_t lineLength = subdevFormat.size.width + hblank; - double lineDuration = lineLength / (pixelRate / 1000000.0F); - const ControlInfo &v4l2Exposure = subdevControlsInfo.at(V4L2_CID_EXPOSURE); - int32_t minExposure = v4l2Exposure.min().get() * lineDuration; - int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; - int32_t defExposure = v4l2Exposure.def().get() * lineDuration; + const Size &outputSize = config_.outputFormat.size; + uint32_t lineLength = outputSize.width + config_.hblank; + config_.lineDuration = lineLength / (config_.pixelRate / 1000000.0F); + + ControlInfo v4l2Exposure = subdevControlsInfo.at(V4L2_CID_EXPOSURE); + int32_t minExposure = v4l2Exposure.min().get() * config_.lineDuration; + int32_t maxExposure = v4l2Exposure.max().get() * config_.lineDuration; + int32_t defExposure = v4l2Exposure.def().get() * config_.lineDuration; controlsMap[&controls::internal::ExposureTime] = ControlInfo(minExposure, maxExposure, defExposure); @@ -544,15 +545,15 @@ int CameraSensor::updateControls() */ const ControlInfo &v4l2VBlank = subdevControlsInfo.at(V4L2_CID_VBLANK); std::array frameHeights{ - v4l2VBlank.min().get() + subdevFormat.size.height, - v4l2VBlank.max().get() + subdevFormat.size.height, - v4l2VBlank.def().get() + subdevFormat.size.height, + v4l2VBlank.min().get() + outputSize.height, + v4l2VBlank.max().get() + outputSize.height, + v4l2VBlank.def().get() + outputSize.height, }; std::array frameDurations; for (unsigned int i = 0; i < frameHeights.size(); ++i) { uint64_t frameSize = lineLength * frameHeights[i]; - frameDurations[i] = frameSize / (pixelRate / 1000000.0F); + frameDurations[i] = frameSize / (config_.pixelRate / 1000000.0F); } controlsMap[&controls::internal::FrameDuration] = @@ -989,6 +990,8 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const << "The analogue crop rectangle has been defaulted to the active area size"; } + const ControlInfo vblank = subdev_->controls().at(V4L2_CID_VBLANK); + /* * IPACameraSensorInfo::analogCrop::x and IPACameraSensorInfo::analogCrop::y * are defined relatively to the active pixel area, while V4L2's @@ -998,34 +1001,10 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const */ info->analogCrop.x -= activeArea_.x; info->analogCrop.y -= activeArea_.y; - - /* The bit depth and image size depend on the currently applied format. */ - V4L2SubdeviceFormat format{}; - ret = subdev_->getFormat(pad_, &format); - if (ret) - return ret; - info->bitsPerPixel = format.bitsPerPixel(); - info->outputSize = format.size; - - /* - * Retrieve the pixel rate, line length and minimum/maximum frame - * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE, - * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory. - */ - ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE, - V4L2_CID_HBLANK, - V4L2_CID_VBLANK }); - if (ctrls.empty()) { - LOG(CameraSensor, Error) - << "Failed to retrieve camera info controls"; - return -EINVAL; - } - - int32_t hblank = ctrls.get(V4L2_CID_HBLANK).get(); - info->lineLength = info->outputSize.width + hblank; - info->pixelRate = ctrls.get(V4L2_CID_PIXEL_RATE).get(); - - const ControlInfo vblank = ctrls.infoMap()->at(V4L2_CID_VBLANK); + info->bitsPerPixel = config_.outputFormat.bitsPerPixel(); + info->outputSize = config_.outputFormat.size; + info->lineLength = info->outputSize.width + config_.hblank; + info->pixelRate = config_.pixelRate; info->minFrameLength = info->outputSize.height + vblank.min().get(); info->maxFrameLength = info->outputSize.height + vblank.max().get(); @@ -1040,7 +1019,7 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const void CameraSensor::updateControlInfo() { subdev_->updateControlInfo(); - updateControls(); + updateConfiguration(); } /**