From patchwork Thu Jun 30 13:38:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16471 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 38F72C3274 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 650EB6564E; Thu, 30 Jun 2022 15:39:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656596383; bh=9ySY97JDsTSmnDSL7AIXOmHeC6+kW/Mb73b7umzzwqs=; 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=pkAn96Ad3BRrJDKlRqIPqbBlIE8hSVfXoghd4FxVk71+QECN0KN4Gl0/7W2f1kbhp J6rcUH8w8yvr/l+kV/jPiuJ/xd5DU+/wqPEdQ8Mx7ffs2VEWqf5azLQxXM3oAiphep cY4GNuP/Dj4X/lXaDdWLzLWM4qARvfHd4qEIP6+j/WMJnO8QNqmdMS4ory9VnwReeR SSmlZuwlR8kZzNkUW0Y0Fp5ERi3mmspvr/lH4mn/U2UuPWGCTO2UohmhAtPQkxSGsL 8RHxOIaEYwBSKHf3VvsFjg7jC84KE9Yg22o1cf73Ia6zROoKwRdtKmra31sQxnfxFo m5UwliY40KbcA== Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BDA4665699 for ; Thu, 30 Jun 2022 15:39:36 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 074B8240007; Thu, 30 Jun 2022 13:39:35 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jun 2022 15:38:53 +0200 Message-Id: <20220630133902.321099-15-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 14/23] libcamera: camera_sensor: Translate libcamera/V4L2 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" In the process of moving the CameraSensor class control interface to use libcamera::internal controls modify the CameraSensor::pushControls() and CameraSensor::getControls() to use lists of libcamera controls and translate to and from V4L2 controls to interface with DelayedControls, which will actually take care of applying controls to the V4L2 subdevice. Signed-off-by: Jacopo Mondi --- src/libcamera/camera_sensor/camera_sensor.cpp | 67 ++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/libcamera/camera_sensor/camera_sensor.cpp b/src/libcamera/camera_sensor/camera_sensor.cpp index cc4cbd4ad509..02810c7c5ad0 100644 --- a/src/libcamera/camera_sensor/camera_sensor.cpp +++ b/src/libcamera/camera_sensor/camera_sensor.cpp @@ -1038,19 +1038,82 @@ void CameraSensor::frameStart(uint32_t sequence) /** * \brief Push a new set of controls to the CameraSensor * \param[in] ctrls The list of controls to push to the sensor + * + * \a ctrls contains a list of libcamera::controls::internal controls */ void CameraSensor::pushControls(const ControlList &ctrls) { - delayedCtrls_->push(ctrls); + ControlList v4l2Ctrls(subdev_->controls()); + + /* + * DelayedControls applies V4L2 controls for us to the subdevice. + * Translate here between libcamera controls and V4L2 controls. + * + * The currently supported controls are V4L2_CID_VBLANK, + * V4L2_CID_EXPOSURE and V4L2_CID_ANALOGUE_GAIN. + */ + + if (ctrls.contains(controls::internal::AnalogueGain)) { + float gain = ctrls.get(controls::internal::AnalogueGain); + int32_t gainCode = helper_->gainCode(gain); + + v4l2Ctrls.set(V4L2_CID_ANALOGUE_GAIN, ControlValue(gainCode)); + } + + if (ctrls.contains(controls::internal::ExposureTime)) { + uint32_t exposureTime = ctrls.get(controls::internal::ExposureTime); + int32_t exposure = exposureTime / config_.lineDuration; + + v4l2Ctrls.set(V4L2_CID_EXPOSURE, ControlValue(exposure)); + } + + if (ctrls.contains(controls::internal::FrameDuration)) { + uint64_t duration = ctrls.get(controls::internal::FrameDuration); + uint32_t frameSize = duration / (1000000.0F / config_.pixelRate); + uint32_t lineLength = config_.outputFormat.size.width + config_.hblank; + int32_t vblank = frameSize / lineLength - config_.outputFormat.size.height; + + v4l2Ctrls.set(V4L2_CID_VBLANK, vblank); + } + + delayedCtrls_->push(v4l2Ctrls); } /** * \brief Get the list of controls applied at frame \a sequence * \param[in] sequence The frame sequence number + * + * The returned controls list contains libcamera::controls::internal controls */ ControlList CameraSensor::getControls(uint32_t sequence) { - return delayedCtrls_->get(sequence); + ControlList ctrls(controls::internal::controls); + ControlList v4l2Ctrls = delayedCtrls_->get(sequence); + + if (v4l2Ctrls.contains(V4L2_CID_ANALOGUE_GAIN)) { + uint32_t gainCode = v4l2Ctrls.get(V4L2_CID_ANALOGUE_GAIN).get(); + float gain = static_cast(helper_->gain(gainCode)); + + ctrls.set(controls::internal::AnalogueGain, gain); + } + + if (v4l2Ctrls.contains(V4L2_CID_EXPOSURE)) { + uint32_t exposure = v4l2Ctrls.get(V4L2_CID_EXPOSURE).get(); + uint32_t exposureTime = exposure * config_.lineDuration; + + ctrls.set(controls::internal::ExposureTime, exposureTime); + } + + if (v4l2Ctrls.contains(V4L2_CID_VBLANK)) { + uint32_t vblank = v4l2Ctrls.get(V4L2_CID_VBLANK).get(); + uint32_t frameSize = (config_.outputFormat.size.width + config_.hblank) + * (config_.outputFormat.size.height + vblank); + uint64_t duration = frameSize / (config_.pixelRate / 1000000.0F); + + ctrls.set(controls::internal::FrameDuration, duration); + } + + return ctrls; } /**