From patchwork Mon Jun 26 14:39:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18760 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 7AF87BE175 for ; Mon, 26 Jun 2023 14:39:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C76D7628BC; Mon, 26 Jun 2023 16:39:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1687790382; bh=hXH/4526E4HB6etrfFtjgr1Bamw2gVBNCsVSBBiiI1Q=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=SkxW/iu8npPasp+OTFvcIUb8TF9kD1QaoBWzWqXFzG8fFj+y7MjiMYPenTdi8Fymp 8M2ZVopOeg6QCz+IMbizdhaPPtS4cqUmK+dLcAVsMAxBo3fZJx8KI4cGMEwvLbM4Jf 9BmO5CrXdnbrO49mGnanefN+YG0EAZW642UxpPcqapSkTMXgMP9sVQHQXwsfCZ+UGx AJzL/AeJNevWRbuWCep8xnVs1ppSgY6dnSneG0ScOqvr3nUaTNxvW4jLWx2XGBttY0 rDEeEmZU2OL+3lQJg6DpnqqmlJYDQq7+Cz4uTEcznDEaa3EXIWtG93683wpTLrCoZS jc7B2McNQfULQ== Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 216D5628BB for ; Mon, 26 Jun 2023 16:39:41 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="nnQGh+nT"; dkim-atps=neutral Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-3fa7512e599so42734965e9.2 for ; Mon, 26 Jun 2023 07:39:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1687790380; x=1690382380; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=srQSobLNFp4tpaFsvUikh1UEgwOsk04nj32HAQ8HttA=; b=nnQGh+nT7BmzeFl/fkC1z0y4VQcj4wJvCfLK3auDjXp5SDm7HhGsgAa+jxv+BdZLK9 6MjH+aAVEOL8v9UMav62MC5VwgKm1M/ER8JAIFlNYlmGIhSLVUuN37GAY3zy4LohPV2h BNRzd/oIT3OC4ude5q1XrLZmNP5OJNXVj3655pgZ1Db/EarhU9znf5wBArFFaGDA4cqG VamdkbEqDFcqUngf88JhPnxeyyVaTiPMaXuOgTjwrXzQbLbUgKkK+x2jGTrN10R9WpE0 Va7ekcJUaDau4jsBCB5FK7QndfUmU8HPzEnX2ElM+4Hl/tBS8iP5lZSxnVqztDDSuiUB kB5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687790380; x=1690382380; 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=srQSobLNFp4tpaFsvUikh1UEgwOsk04nj32HAQ8HttA=; b=jf+UBbEEA7H3AEUqMWEjwItwsuvRL52sq0OYz0hn0wCoaoOqV/KPwRaQmHfz38qeIt qzRQFLsZLbpldLeSB+mLjsmqUCkNRGlN7XfeEzkT4hRg3nerOmXEpDtlVsl4r+2me150 ipHITQ4HSYrpcIdv4pNC8dnEad7orjP63VS4RILi0z+80+ajCr8j71yHVW5/3vhUCyNV OK3BVf2BP9WMyD3YiKPckAPZ7wdAaiP2Y1tlOSMG/t81pqjqkwHGQaMLGmcKfjmnj27J Gz6Of22N5E6HQB1eb0dCUZmexfx5PN7iya5o4MKc5At6y7s5kHeT85wDbjql5mKVG5eo G1fg== X-Gm-Message-State: AC+VfDzLjDsTKdvpYw2CdjZV+3e4VBnizq22iIIjQ3cFFLIKQDPARVyy QlXjXIkP17L0n3ASBV2JA+jfSntzZda+nOugj8zefA== X-Google-Smtp-Source: ACHHUZ5toog0PpIGSO0mK/6FVxpT14AKz6jPHesr2hYLDjviuvtid0yKjLMNBINYjlsAj7ifvz18xw== X-Received: by 2002:a7b:ca57:0:b0:3f9:b4a0:6062 with SMTP id m23-20020a7bca57000000b003f9b4a06062mr15467162wml.24.1687790380237; Mon, 26 Jun 2023 07:39:40 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id a10-20020a05600c224a00b003faef96ee78sm1740539wmm.33.2023.06.26.07.39.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jun 2023 07:39:39 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 26 Jun 2023 15:39:32 +0100 Message-Id: <20230626143932.18888-1-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2] 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 parsing 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 Reviewed-by: Kieran Bingham --- Changes since v1: - Replace the use of std::unique_ptr with std::vector --- src/ipa/rpi/cam_helper/cam_helper_imx296.cpp | 60 +++++++++++++++++++- 1 file changed, 59 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..e84243704e5a 100644 --- a/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp +++ b/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp @@ -7,7 +7,9 @@ #include #include +#include #include +#include #include "cam_helper.h" @@ -15,6 +17,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 +36,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 +53,12 @@ private: * in units of lines. */ static constexpr int frameIntegrationDiff = 4; + + std::vector lastEmbeddedBuffer_; }; CamHelperImx296::CamHelperImx296() - : CamHelper(nullptr, frameIntegrationDiff) + : CamHelper(std::make_unique(registerList), frameIntegrationDiff) { } @@ -66,6 +85,23 @@ 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({ lastEmbeddedBuffer_.data(), lastEmbeddedBuffer_.size() }, + metadata); + + if (lastEmbeddedBuffer_.size() != buffer.size()) + lastEmbeddedBuffer_.resize(buffer.size()); + + memcpy(lastEmbeddedBuffer_.data(), buffer.data(), buffer.size()); +} + void CamHelperImx296::getDelays(int &exposureDelay, int &gainDelay, int &vblankDelay, int &hblankDelay) const { @@ -75,6 +111,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();