From patchwork Mon Jun 27 16:27:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16389 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 F2F64BD808 for ; Mon, 27 Jun 2022 16:27:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 73DEF6563E; Mon, 27 Jun 2022 18:27:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656347275; bh=y2h0WznafB5q+/INu0P7L8XWOVslu0KaZmIrAPC07d8=; 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=uae3sTqwbQTLni+zWNlJhbNGGs/8xRa6Q+9w5EjoFw4ZOE9w5Ks6X1oJssXUNGeLz 4q2khufbN8WsEY+fUDbykp29ElCzld2iyhKp9nOiElD3IjQ251GTHGTX6Tc2hQezHd 5ZNoJlyJozkv87GIJKWhI1q3onki2qpjuJVj2l5/nVukFrGjszfvnzcFuFQ4GIAoul 4rRGxHbZdas3azcbFWJoOgh1rdvvKQRncWkAIyABNeC7LET5mYTY7NZpR8CuFWAVG4 rWZEpsTD9ZiHiUzKbKn5HnC5zT80Mw9sWXWPlwF51JrgVslxBQtLVZYnRynW2lMszW 8XmlfDuXujAzA== Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 392B465636 for ; Mon, 27 Jun 2022 18:27:48 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 6E62420009; Mon, 27 Jun 2022 16:27:47 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Jun 2022 18:27:25 +0200 Message-Id: <20220627162732.33160-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220627162732.33160-1-jacopo@jmondi.org> References: <20220627162732.33160-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/15] libcamera: camera_sensor: Initialize controls 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" Initialize the control interface of the CameraSensor class by registering the control limits for controls::internal::ExposureTime, controls::internal::FrameDuration and controls::internal::draft::SensorAnalogueGain. Update the CameraSensor controls in the CameraSensor::updateControlInfo() function after having updated the subdevice V4L2 controls. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/camera_sensor.h | 3 + src/libcamera/camera_sensor.cpp | 89 ++++++++++++++++++++++ src/libcamera/internal_control_ids.yaml | 10 +++ 3 files changed, 102 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 0bed6e679840..c71f93f230d1 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -66,6 +66,7 @@ public: V4L2Subdevice *device() { return subdev_.get(); } const ControlList &properties() const { return properties_; } + const ControlInfoMap &controls() const { return controls_; } int sensorInfo(IPACameraSensorInfo *info) const; void updateControlInfo(); @@ -84,6 +85,7 @@ private: void initStaticProperties(); void initTestPatternModes(); int initProperties(); + int updateControls(); int applyTestPatternMode(controls::draft::TestPatternModeEnum mode); int discoverAncillaryDevices(); @@ -107,6 +109,7 @@ private: const BayerFormat *bayerFormat_; ControlList properties_; + ControlInfoMap controls_; std::unique_ptr focusLens_; }; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index e3354530380c..82e51272cccc 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -22,6 +22,7 @@ #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/camera_lens.h" #include "libcamera/internal/camera_sensor_properties.h" +#include "libcamera/internal/control_ids.h" #include "libcamera/internal/formats.h" #include "libcamera/internal/sysfs.h" @@ -180,6 +181,10 @@ int CameraSensor::init() if (ret) return ret; + ret = updateControls(); + if (ret) + return ret; + ret = discoverAncillaryDevices(); if (ret) return ret; @@ -455,6 +460,83 @@ int CameraSensor::initProperties() return 0; } +int CameraSensor::updateControls() +{ + if (!bayerFormat_) + return 0; + + ControlInfoMap::Map controlsMap; + + /* The subdev driver has been validate already, the controls are there! */ + ControlList subdevControls = subdev_->getControls({ V4L2_CID_PIXEL_RATE, + V4L2_CID_HBLANK, + V4L2_CID_VBLANK }); + uint64_t pixelRate = subdevControls.get(V4L2_CID_PIXEL_RATE).get(); + uint32_t hblank = subdevControls.get(V4L2_CID_HBLANK).get(); + + /* Assume the sensor has a single source pad #0. */ + V4L2SubdeviceFormat subdevFormat; + subdev_->getFormat(0, &subdevFormat); + + const ControlInfoMap &subdevControlsInfo = subdev_->controls(); + + /* + * Compute controls::ExposureTime 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. + */ + uint32_t lineLength = subdevFormat.size.width + hblank; + double lineDuration = lineLength / (pixelRate / 1000000.0F); + auto &[expId, v4l2Exposure] = *subdevControlsInfo.find(V4L2_CID_EXPOSURE); + int32_t minExposure = v4l2Exposure.min().get() * lineDuration; + int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; + int32_t defExposure = v4l2Exposure.def().get() * lineDuration; + + controlsMap[&controls::internal::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. + */ + auto &[vblankId, v4l2VBlank] = *subdevControlsInfo.find(V4L2_CID_VBLANK); + std::array frameHeights{ + v4l2VBlank.min().get() + subdevFormat.size.height, + v4l2VBlank.max().get() + subdevFormat.size.height, + v4l2VBlank.def().get() + subdevFormat.size.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); + } + + controlsMap[&controls::internal::FrameDuration] = + ControlInfo(frameDurations[0], frameDurations[1], frameDurations[2]); + + /* + * For analogue gain collect the raw V4L2 control values which express + * the gain codes as seen from the sensor and need to be translated + * on the IPA side. + * + * \todo Translate it by using a CameraSensorHelper. + */ + auto &[gainId, v4l2AGain] = *subdevControlsInfo.find(V4L2_CID_ANALOGUE_GAIN); + controlsMap[&controls::internal::draft::SensorAnalogueGain] = + ControlInfo(v4l2AGain.min().get(), + v4l2AGain.max().get(), + v4l2AGain.def().get()); + + controls_ = ControlInfoMap(std::move(controlsMap), + controls::internal::controls); + + return 0; +} + /** * \brief Check for and initialise any ancillary devices * @@ -837,6 +919,12 @@ int CameraSensor::setV4L2Controls(ControlList *ctrls) * \return The list of camera sensor properties */ +/** + * \fn CameraSensor::controls() + * \brief Retrieve the map of the camera sensor controls limits + * \return The map of camera sensor control information + */ + /** * \brief Assemble and return the camera sensor info * \param[out] info The camera sensor info @@ -932,6 +1020,7 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const void CameraSensor::updateControlInfo() { subdev_->updateControlInfo(); + updateControls(); } /** diff --git a/src/libcamera/internal_control_ids.yaml b/src/libcamera/internal_control_ids.yaml index e69e0d30657c..c6e6bd111cf7 100644 --- a/src/libcamera/internal_control_ids.yaml +++ b/src/libcamera/internal_control_ids.yaml @@ -9,6 +9,16 @@ controls: + - ExposureTime: + type: int32_t + description: | + The sensor exposure time in milliseconds. + + - FrameDuration: + type: int64_t + description: | + The sensor frame duration time in milliseconds. + # ---------------------------------------------------------------------------- # Draft controls section