From patchwork Wed Jun 21 12:37:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18756 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 20B7CBD87C for ; Wed, 21 Jun 2023 12:37:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 34643628C0; Wed, 21 Jun 2023 14:37:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1687351043; bh=GCpAKYKVRCKRJL6HdWe2Tj29uLV0jpW2p1Tn2+x5Ib8=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=r2vjlAPoAy6tW+Itue1LRT5INKHqmoonKT3MEupGgnEn1HDajs4GyQgXeePfJ53ge O0Qq2Gx4XUDpk2FNt1vxJze1/s+DsmhMEcKPjIflBYNdN2p2YUbpg0UwbUL0PhAef5 RFQDDa8g67n0tsKsqIss4x5L+QfJbWQVuMbFP53KmIJ+81Rr8GtjZ3GeWtmrdyBOnX cBUt2bpSDa+8l46R/cgEk+aiV5UWkZz6oDWMUdVgNQyUPi4a7U9M9jCE19lOyqr9jI UCOFQ+Lkt0jfYtqyd8W0TUmSKGjZ2rSRAetdn8luy3atdCs0JHMZySQi/ipoYp4902 p16o+EQUClfDg== Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 47DBA61E41 for ; Wed, 21 Jun 2023 14:37:21 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="hG9npHEC"; dkim-atps=neutral Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-3f901f87195so37551325e9.1 for ; Wed, 21 Jun 2023 05:37:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1687351040; x=1689943040; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=YKI3ZckpxYyi6v/yb1y8SshgwKDM0rJrEComuJNIimI=; b=hG9npHECea8gusYtD6PwDNzTEel4FKgYEIfAr97Q56SRhhaeHTW059iq9zUSLqtDff 9wjLpDUW51mXtTok9j6S8GDCpubuZawxlvqY5zRfDzbQZPMcGQKVjpBnzHkfnmIh3qn8 +VJXlsKac2GMQcH2h9bWS/Yv2dH1pmCv9fDngWE267g/ka6/BCp58FpFCBUUcVhmFCsI 5vEbLfQRcimx02mHy8WVz9ktXa/FTQDQMX7ZIPheijG7aCfW0vQ8zbGc/wJZYjm3lGbf iTaysZrz2kdC94wzUR9an9fOTM7c0TLtEIbXpBod5XVu+bPSH5ajWQQb4f7iq89sRW+Y VrLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687351040; x=1689943040; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=YKI3ZckpxYyi6v/yb1y8SshgwKDM0rJrEComuJNIimI=; b=UlaAtwrBmav2FEfiETcUHFl/604vl6EH57+U/nma+2WtaU4juCUOwuRMCUFX6zXlRI nrNYW7Lk9a42CSUbbafJtQxFkfYZ5SANYgxq34nHyGh89omADhlQsXiEOMbP9a3r90VD nhnic9KKief+6sy62oGFvPK01i6kJ6G5WPm7HKYOanOR3yW2KzpiBeSu0IMbp0zPdXGx sv2SADaya+MD0M4mNb+A1JsfW/SOmiigDq7FhsJj/Ku6fohvOBiS0M7U3yak7yi5EStT ZPUysCI2A8WfIbqagGqiBa3RbbzdI0Fy0vkCTrjP330zBIDZzcRlZSpGznsAuGSr4dmx 3KaA== X-Gm-Message-State: AC+VfDzoarGZ02F87MBeSMjwxMUFqC6TlNEKE+asWD1DhvurbQoIbc81 3/K5AVn0bylyieKXW4A77D8WflfPXb7ki1FXOOqX4A== X-Google-Smtp-Source: ACHHUZ5pP43A8QMSEZP+5wGjcBSmRQPL6d6WwVe5ftjRDaFpgsFZpKTq7/zj5M20h4WmPewJFztPrg== X-Received: by 2002:a1c:f616:0:b0:3f6:d90:3db with SMTP id w22-20020a1cf616000000b003f60d9003dbmr13351892wmc.3.1687351040548; Wed, 21 Jun 2023 05:37:20 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id s10-20020a1cf20a000000b003f9b0cfbe30sm4868011wmc.36.2023.06.21.05.37.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 05:37:20 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 21 Jun 2023 13:37:12 +0100 Message-Id: <20230621123712.7787-1-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] ipa: rpi: imx296: Enable embedded data 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Enable embedded data parising for the imx296 sensor. However, the imx296 has a quirk where the embedded data is ahead by a single frame, i.e. embedded data in frame N corresponds to the image data in frame N+1. So make a copy of the embedded data buffer stored in the camera helper state, and use that copy in the next frame. Signed-off-by: Naushir Patuck --- src/ipa/rpi/cam_helper/cam_helper_imx296.cpp | 61 +++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp index ecb845e76e12..8f06981b500e 100644 --- a/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp +++ b/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include "cam_helper.h" @@ -15,6 +16,17 @@ using namespace RPiController; using libcamera::utils::Duration; using namespace std::literals::chrono_literals; +constexpr uint32_t gainReg = 0x41ba; +constexpr uint32_t shsLoReg = 0x41b4; +constexpr uint32_t shsMidReg = 0x41b5; +constexpr uint32_t shsHiReg = 0x41b6; +constexpr uint32_t vmaxLoReg = 0x41cc; +constexpr uint32_t vmaxMidReg = 0x41cd; +constexpr uint32_t vmaxHiReg = 0x41ce; +constexpr uint32_t tempReg = 0x41da; +constexpr std::initializer_list registerList = + { gainReg, shsLoReg, shsMidReg, shsHiReg, vmaxLoReg, vmaxMidReg, vmaxHiReg, tempReg }; + class CamHelperImx296 : public CamHelper { public: @@ -23,8 +35,12 @@ public: double gain(uint32_t gainCode) const override; uint32_t exposureLines(const Duration exposure, const Duration lineLength) const override; Duration exposure(uint32_t exposureLines, const Duration lineLength) const override; + void prepare(libcamera::Span buffer, Metadata &metadata) override; void getDelays(int &exposureDelay, int &gainDelay, int &vblankDelay, int &hblankDelay) const override; + bool sensorEmbeddedDataPresent() const override; + void populateMetadata(const MdParser::RegisterMap ®isters, + Metadata &metadata) const override; private: static constexpr uint32_t minExposureLines = 1; @@ -36,10 +52,13 @@ private: * in units of lines. */ static constexpr int frameIntegrationDiff = 4; + + std::unique_ptr lastEmbeddedBuffer_; + libcamera::Span embeddedBufferSpan_; }; CamHelperImx296::CamHelperImx296() - : CamHelper(nullptr, frameIntegrationDiff) + : CamHelper(std::make_unique(registerList), frameIntegrationDiff) { } @@ -66,6 +85,24 @@ Duration CamHelperImx296::exposure(uint32_t exposureLines, return std::max(minExposureLines, exposureLines) * timePerLine + 14.26us; } +void CamHelperImx296::prepare(libcamera::Span buffer, Metadata &metadata) +{ + /* + * The imx296 embedded data is ahead by a single frame, i.e. embedded + * data in frame N corresponds to the image data in frame N+1. So make + * a copy of the embedded data buffer and use it as normal for the next + * frame. + */ + CamHelper::prepare(embeddedBufferSpan_, metadata); + + if (embeddedBufferSpan_.size() != buffer.size()) { + lastEmbeddedBuffer_ = std::make_unique(buffer.size()); + embeddedBufferSpan_ = libcamera::Span(lastEmbeddedBuffer_.get(), buffer.size()); + } + + memcpy(embeddedBufferSpan_.data(), buffer.data(), embeddedBufferSpan_.size()); +} + void CamHelperImx296::getDelays(int &exposureDelay, int &gainDelay, int &vblankDelay, int &hblankDelay) const { @@ -75,6 +112,28 @@ void CamHelperImx296::getDelays(int &exposureDelay, int &gainDelay, hblankDelay = 2; } +bool CamHelperImx296::sensorEmbeddedDataPresent() const +{ + return true; +} + +void CamHelperImx296::populateMetadata(const MdParser::RegisterMap ®isters, + Metadata &metadata) const +{ + uint32_t shs = registers.at(shsLoReg) + (registers.at(shsMidReg) << 8) + + (registers.at(shsHiReg) << 16); + uint32_t vmax = registers.at(vmaxLoReg) + (registers.at(vmaxMidReg) << 8) + + (registers.at(vmaxHiReg) << 16); + + DeviceStatus deviceStatus; + deviceStatus.lineLength = timePerLine; + deviceStatus.frameLength = vmax; + deviceStatus.shutterSpeed = exposure(vmax - shs, timePerLine); + deviceStatus.analogueGain = gain(registers.at(gainReg)); + + metadata.set("device.status", deviceStatus); +} + static CamHelper *create() { return new CamHelperImx296();