From patchwork Fri May 7 11:37:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 12229 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 A5E30BF831 for ; Fri, 7 May 2021 11:37:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4CF606891E; Fri, 7 May 2021 13:37:35 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="E7lgAUHB"; dkim-atps=neutral Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 93D53602BB for ; Fri, 7 May 2021 13:37:32 +0200 (CEST) Received: by mail-wr1-x435.google.com with SMTP id a4so8888261wrr.2 for ; Fri, 07 May 2021 04:37:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OK8QXok1w8+H9bvA1Y5X2DEO0Zo2BqKFQiJ4Rdn9HkI=; b=E7lgAUHBvKZBRC5ZOAj7o+LKqLWoj4SAwGJma4tsrggUZb/kKS0lF+ikxOcSeWAKLi npQmoBouKlBv/4c+BpyZ9wQIYMROSstC67Zp6b5e9APBwA4/N+1921eAeU1kmSHdfGiZ HT91T4BnJhWkm+2CWGrx9wdeGF4mTk8ihpY/7pP6pOyNy2xiGKKROzxz7lt19iglBZ3c nPOsKPDRLWs7aGBYf/D9cq3VfYwfRs9+Iyro65dWyha28wrhjma9qWTQteHn4aqjxgFE 0//1jG6LtsOvfG691gGR3iE5GetDp/UnR7eHB3qMtcQwb8JyyQpadpS4SJ3KnYYUyh1z zazg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OK8QXok1w8+H9bvA1Y5X2DEO0Zo2BqKFQiJ4Rdn9HkI=; b=RiQXe0eDKj8YgruogXGRPNX5Fe2eUqsOLC43M7DEbcLyF16fP4gqfg+zM2Rdxs+2SV PjCh4rlymoeSPu7z2xfspA1e+OUYDUnHezc+xXlxxvj0/JS2rrli1Uo69CDaUTWOQ2xx 38sSTtnGlpLSRrY/CzPh9nRW/fPNhgsQko8+9idqVyrC5QZJiU9KKdTd/Jyl10ktvMDl BzjnUZEzSaLlr8oOLXi2fiRAfcYTRvnX/lbXueXVLyOUfnf718w+55PGZsERNztQfwJG ZDVxhQxA9fffZYrf6a/dDzp5nkjw/hCov5bubVaNcHnjB4AQAhinQHuBG64JdLNYrOx6 /MbQ== X-Gm-Message-State: AOAM532TyxF4/q1CRgJGJkm4aCB/8mqiiFS/39z+MbLPgJfUDmAFeWKG Ulo143bsDKKC/PtX42EPTbIbzM5TkzrJuA== X-Google-Smtp-Source: ABdhPJxc5AUwz0YOnI5LieWa3O8ShnKcrfveiZ4WW7cjn7x1pRKmwfkDytfVEzjHDIHsq0kM25FXVw== X-Received: by 2002:a05:6000:18a:: with SMTP id p10mr11909263wrx.345.1620387452051; Fri, 07 May 2021 04:37:32 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id w22sm13739009wmc.13.2021.05.07.04.37.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 May 2021 04:37:31 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 7 May 2021 12:37:27 +0100 Message-Id: <20210507113728.14037-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210507113728.14037-1-david.plowman@raspberrypi.com> References: <20210507113728.14037-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/2] ipa: raspberrypi: Make sensor embedded data parser use Span class 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Improve MdParser::Parse() by taking a Span, pointing to const data that it should not change, as its input buffer. Signed-off-by: David Plowman Reviewed-by: Laurent Pinchart --- src/ipa/raspberrypi/cam_helper_imx219.cpp | 8 ++++---- src/ipa/raspberrypi/cam_helper_imx477.cpp | 8 ++++---- src/ipa/raspberrypi/md_parser.cpp | 23 ++++++++++++----------- src/ipa/raspberrypi/md_parser.hpp | 20 ++++++++------------ 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/ipa/raspberrypi/cam_helper_imx219.cpp b/src/ipa/raspberrypi/cam_helper_imx219.cpp index 566ecbca..e550fba6 100644 --- a/src/ipa/raspberrypi/cam_helper_imx219.cpp +++ b/src/ipa/raspberrypi/cam_helper_imx219.cpp @@ -29,7 +29,7 @@ class MdParserImx219 : public MdParserSmia { public: MdParserImx219(); - Status Parse(void *data) override; + Status Parse(libcamera::Span buffer) override; Status GetExposureLines(unsigned int &lines) override; Status GetGainCode(unsigned int &gain_code) override; private: @@ -118,7 +118,7 @@ MdParserImx219::MdParserImx219() reg_offsets_[0] = reg_offsets_[1] = reg_offsets_[2] = -1; } -MdParser::Status MdParserImx219::Parse(void *data) +MdParser::Status MdParserImx219::Parse(libcamera::Span buffer) { bool try_again = false; @@ -132,7 +132,7 @@ MdParser::Status MdParserImx219::Parse(void *data) /* Need to be ordered */ uint32_t regs[3] = { GAIN_REG, EXPHI_REG, EXPLO_REG }; reg_offsets_[0] = reg_offsets_[1] = reg_offsets_[2] = -1; - int ret = static_cast(findRegs(static_cast(data), + int ret = static_cast(findRegs(buffer, regs, reg_offsets_, 3)); /* * > 0 means "worked partially but parse again next time", @@ -148,7 +148,7 @@ MdParser::Status MdParserImx219::Parse(void *data) if (reg_offsets_[i] == -1) continue; - reg_values_[i] = static_cast(data)[reg_offsets_[i]]; + reg_values_[i] = buffer[reg_offsets_[i]]; } /* Re-parse next time if we were unhappy in some way. */ diff --git a/src/ipa/raspberrypi/cam_helper_imx477.cpp b/src/ipa/raspberrypi/cam_helper_imx477.cpp index 73a5ca7d..a4a58c15 100644 --- a/src/ipa/raspberrypi/cam_helper_imx477.cpp +++ b/src/ipa/raspberrypi/cam_helper_imx477.cpp @@ -21,7 +21,7 @@ class MdParserImx477 : public MdParserSmia { public: MdParserImx477(); - Status Parse(void *data) override; + Status Parse(libcamera::Span buffer) override; Status GetExposureLines(unsigned int &lines) override; Status GetGainCode(unsigned int &gain_code) override; private: @@ -107,7 +107,7 @@ MdParserImx477::MdParserImx477() reg_offsets_[0] = reg_offsets_[1] = reg_offsets_[2] = reg_offsets_[3] = -1; } -MdParser::Status MdParserImx477::Parse(void *data) +MdParser::Status MdParserImx477::Parse(libcamera::Span buffer) { bool try_again = false; @@ -126,7 +126,7 @@ MdParser::Status MdParserImx477::Parse(void *data) GAINLO_REG }; reg_offsets_[0] = reg_offsets_[1] = reg_offsets_[2] = reg_offsets_[3] = -1; - int ret = static_cast(findRegs(static_cast(data), + int ret = static_cast(findRegs(buffer, regs, reg_offsets_, 4)); /* * > 0 means "worked partially but parse again next time", @@ -142,7 +142,7 @@ MdParser::Status MdParserImx477::Parse(void *data) if (reg_offsets_[i] == -1) continue; - reg_values_[i] = static_cast(data)[reg_offsets_[i]]; + reg_values_[i] = buffer[reg_offsets_[i]]; } /* Re-parse next time if we were unhappy in some way. */ diff --git a/src/ipa/raspberrypi/md_parser.cpp b/src/ipa/raspberrypi/md_parser.cpp index d82c102c..852a1d34 100644 --- a/src/ipa/raspberrypi/md_parser.cpp +++ b/src/ipa/raspberrypi/md_parser.cpp @@ -27,12 +27,13 @@ using namespace RPiController; #define REG_VALUE 0x5a #define REG_SKIP 0x55 -MdParserSmia::ParseStatus MdParserSmia::findRegs(unsigned char *data, +MdParserSmia::ParseStatus MdParserSmia::findRegs(libcamera::Span buffer, uint32_t regs[], int offsets[], unsigned int num_regs) { assert(num_regs > 0); - if (data[0] != LINE_START) + + if (buffer[0] != LINE_START) return NO_LINE_START; unsigned int current_offset = 1; // after the LINE_START @@ -40,15 +41,15 @@ MdParserSmia::ParseStatus MdParserSmia::findRegs(unsigned char *data, unsigned int reg_num = 0, first_reg = 0; ParseStatus retcode = PARSE_OK; while (1) { - int tag = data[current_offset++]; + int tag = buffer[current_offset++]; if ((bits_per_pixel_ == 10 && (current_offset + 1 - current_line_start) % 5 == 0) || (bits_per_pixel_ == 12 && (current_offset + 1 - current_line_start) % 3 == 0)) { - if (data[current_offset++] != REG_SKIP) + if (buffer[current_offset++] != REG_SKIP) return BAD_DUMMY; } - int data_byte = data[current_offset++]; + int data_byte = buffer[current_offset++]; //printf("Offset %u, tag 0x%02x data_byte 0x%02x\n", current_offset-1, tag, data_byte); if (tag == LINE_END_TAG) { if (data_byte != LINE_END_TAG) @@ -59,18 +60,18 @@ MdParserSmia::ParseStatus MdParserSmia::findRegs(unsigned char *data, current_offset = current_line_start + line_length_bytes_; // Require whole line to be in the buffer (if buffer size set). - if (buffer_size_bytes_ && + if (buffer.size() && current_offset + line_length_bytes_ > - buffer_size_bytes_) + buffer.size()) return MISSING_REGS; - if (data[current_offset] != LINE_START) + if (buffer[current_offset] != LINE_START) return NO_LINE_START; } else { // allow a zero line length to mean "hunt for the next line" - while (data[current_offset] != LINE_START && - current_offset < buffer_size_bytes_) + while (buffer[current_offset] != LINE_START && + current_offset < buffer.size()) current_offset++; - if (current_offset == buffer_size_bytes_) + if (current_offset == buffer.size()) return NO_LINE_START; } // inc current_offset to after LINE_START diff --git a/src/ipa/raspberrypi/md_parser.hpp b/src/ipa/raspberrypi/md_parser.hpp index 926f676e..8e22b1d7 100644 --- a/src/ipa/raspberrypi/md_parser.hpp +++ b/src/ipa/raspberrypi/md_parser.hpp @@ -8,6 +8,8 @@ #include +#include + /* Camera metadata parser class. Usage as shown below. Setup: @@ -21,17 +23,15 @@ parser->SetBitsPerPixel(bpp); parser->SetLineLengthBytes(pitch); parser->SetNumLines(2); -Note 1: if you don't know how many lines there are, you can use SetBufferSize -instead to limit the total buffer size. +Note 1: if you don't know how many lines there are, the size of the input +buffer is used as a limit instead. Note 2: if you don't know the line length, you can leave the line length unset -(or set to zero) and the parser will hunt for the line start instead. In this -case SetBufferSize *must* be used so that the parser won't run off the end of -the buffer. +(or set to zero) and the parser will hunt for the line start instead. Then on every frame: -if (parser->Parse(data) != MdParser::OK) +if (parser->Parse(buffer) != MdParser::OK) much badness; unsigned int exposure_lines, gain_code if (parser->GetExposureLines(exposure_lines) != MdParser::OK) @@ -75,11 +75,7 @@ public: { line_length_bytes_ = num_bytes; } - void SetBufferSize(unsigned int num_bytes) - { - buffer_size_bytes_ = num_bytes; - } - virtual Status Parse(void *data) = 0; + virtual Status Parse(libcamera::Span buffer) = 0; virtual Status GetExposureLines(unsigned int &lines) = 0; virtual Status GetGainCode(unsigned int &gain_code) = 0; @@ -116,7 +112,7 @@ protected: BAD_LINE_END = -4, BAD_PADDING = -5 }; - ParseStatus findRegs(unsigned char *data, uint32_t regs[], + ParseStatus findRegs(libcamera::Span buffer, uint32_t regs[], int offsets[], unsigned int num_regs); }; From patchwork Fri May 7 11:37:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 12230 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 C4146BF831 for ; Fri, 7 May 2021 11:37:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B8EC868918; Fri, 7 May 2021 13:37:35 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="OOHInNgZ"; dkim-atps=neutral Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5FE52602BB for ; Fri, 7 May 2021 13:37:33 +0200 (CEST) Received: by mail-wr1-x434.google.com with SMTP id d11so8878810wrw.8 for ; Fri, 07 May 2021 04:37:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=H5tXhgNnZvpT7uH55DnBMeopzIT6bN1cjg1nDK+SYTc=; b=OOHInNgZKXQGLZERT847qUZamUyv5x1LyqLfR8Glo3zF+SitENJfeKpxx7M0U7i3i7 DL/I/JILrcOTW9iyme/3c86cwNbLoq9Mf7R2ZlbXx1JiZlekhaScVOGPoxpKCmn4FOsv JpTkgk/Kx/p+2DUw4eDxof1/rduk9LjzcfEWg29zoMwho3PJkv4SWL43dnOMcFAUQpG8 tTKCPF68MlIbwqEJH9UB7W2lvnBKwUE1cREFtwKYTesWA+b3P7PpxKI+QYSA/iIZhDwf GBmOuschYlMqJBUj376A0ZZ4swlM6e4hvKn9zyXLafGMDQ2U6lK8M8yScfoaJPdnUOA/ U7Ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H5tXhgNnZvpT7uH55DnBMeopzIT6bN1cjg1nDK+SYTc=; b=qvAcSSWMAo6uh1vnw/jPBMe+/H7U9JcQx6/KDscPYr4HsCnTZvLAq1/Gzduxjz8NAq dmeObcnNtFutgJE7PCMQn3FHd0WUfRBxnRJucA1gcWTiGNDD2+35WroCvqPg154N6CgJ BU+4+0iIe2ozwlI72eE8j5lgMyL9XviqWZC532XkmsTb7mqCqfNY8j+dmvsVNqEt9QH8 AABUTDlePGR8V8baVil+xf+2o3/wuqcE04ltEnuhRNo69iGMi9fGJJ93GeKTZyC5Gzfo zcDzKqKXmoFn/Vytb7fuUfa9pmA7BiaUNw+FU1nh5e4DCm1Sfdasd8TiwgHEmeFd28MA EPKA== X-Gm-Message-State: AOAM532y2qANO11Nn9Bpjq+7+lnP55Du+EyYqPqWtPQi07zV5bOV8Iz7 Gyt/rc9O/oCmxpQtoBPEZGTAfU16RghksA== X-Google-Smtp-Source: ABdhPJxx1Xb9BNa7pP4bDOP7aLHOjapr3XCJdEwt4UinouZ6bylCrcME0d0C0ycBtpfmkFLmrzsFxA== X-Received: by 2002:a05:6000:108f:: with SMTP id y15mr12168538wrw.115.1620387452809; Fri, 07 May 2021 04:37:32 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id w22sm13739009wmc.13.2021.05.07.04.37.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 May 2021 04:37:32 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 7 May 2021 12:37:28 +0100 Message-Id: <20210507113728.14037-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210507113728.14037-1-david.plowman@raspberrypi.com> References: <20210507113728.14037-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/2] ipa: raspberrypi: Use CamHelpers to generalise sensor embedded data parsing 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" CamHelpers get virtual Prepare() and Process() methods, running just before and just after the ISP, just like Raspberry Pi Algorithms. The Prepare() method is able to parse the register dumps in embedded data buffers, and can be specialised to perform custom processing when necessary. The IPA itself only needs to call the new Prepare() and Process() methods. It must fill in the DeviceStatus from the controls first, in case the Prepare() method does not supply its own values. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck Reviewed-by: Laurent Pinchart --- src/ipa/raspberrypi/cam_helper.cpp | 54 +++++++++++++++++++ src/ipa/raspberrypi/cam_helper.hpp | 11 +++- src/ipa/raspberrypi/raspberrypi.cpp | 80 ++++++++++------------------- 3 files changed, 90 insertions(+), 55 deletions(-) diff --git a/src/ipa/raspberrypi/cam_helper.cpp b/src/ipa/raspberrypi/cam_helper.cpp index 0ae0baa0..09917f3c 100644 --- a/src/ipa/raspberrypi/cam_helper.cpp +++ b/src/ipa/raspberrypi/cam_helper.cpp @@ -17,6 +17,11 @@ #include "md_parser.hpp" using namespace RPiController; +using namespace libcamera; + +namespace libcamera { +LOG_DECLARE_CATEGORY(IPARPI) +} static std::map cam_helpers; @@ -45,6 +50,17 @@ CamHelper::~CamHelper() delete parser_; } +void CamHelper::Prepare(Span buffer, + Metadata &metadata) +{ + parseEmbeddedData(buffer, metadata); +} + +void CamHelper::Process([[maybe_unused]] StatisticsPtr &stats, + [[maybe_unused]] Metadata &metadata) +{ +} + uint32_t CamHelper::ExposureLines(double exposure_us) const { assert(initialized_); @@ -139,6 +155,44 @@ unsigned int CamHelper::MistrustFramesModeSwitch() const return 0; } +void CamHelper::parseEmbeddedData(Span buffer, + Metadata &metadata) +{ + if (buffer.empty()) + return; + + uint32_t exposureLines, gainCode; + + if (parser_->Parse(buffer) != MdParser::Status::OK || + parser_->GetExposureLines(exposureLines) != MdParser::Status::OK || + parser_->GetGainCode(gainCode) != MdParser::Status::OK) { + LOG(IPARPI, Error) << "Embedded data buffer parsing failed"; + return; + } + + /* + * Overwrite the exposure/gain values in the DeviceStatus, as + * we know better. Fetch it first in case any other fields were + * set meaningfully. + */ + DeviceStatus deviceStatus; + + if (metadata.Get("device.status", deviceStatus) != 0) { + LOG(IPARPI, Error) << "DeviceStatus not found"; + return; + } + + deviceStatus.shutter_speed = Exposure(exposureLines); + deviceStatus.analogue_gain = Gain(gainCode); + + LOG(IPARPI, Debug) << "Metadata updated - Exposure : " + << deviceStatus.shutter_speed + << " Gain : " + << deviceStatus.analogue_gain; + + metadata.Set("device.status", deviceStatus); +} + RegisterCamHelper::RegisterCamHelper(char const *cam_name, CamHelperCreateFunc create_func) { diff --git a/src/ipa/raspberrypi/cam_helper.hpp b/src/ipa/raspberrypi/cam_helper.hpp index c3ed5362..a52f3f0b 100644 --- a/src/ipa/raspberrypi/cam_helper.hpp +++ b/src/ipa/raspberrypi/cam_helper.hpp @@ -8,7 +8,11 @@ #include +#include + #include "camera_mode.h" +#include "controller/controller.hpp" +#include "controller/metadata.hpp" #include "md_parser.hpp" #include "libcamera/internal/v4l2_videodevice.h" @@ -65,7 +69,9 @@ public: CamHelper(MdParser *parser, unsigned int frameIntegrationDiff); virtual ~CamHelper(); void SetCameraMode(const CameraMode &mode); - MdParser &Parser() const { return *parser_; } + virtual void Prepare(libcamera::Span buffer, + Metadata &metadata); + virtual void Process(StatisticsPtr &stats, Metadata &metadata); uint32_t ExposureLines(double exposure_us) const; double Exposure(uint32_t exposure_lines) const; // in us virtual uint32_t GetVBlanking(double &exposure_us, double minFrameDuration, @@ -81,6 +87,9 @@ public: virtual unsigned int MistrustFramesModeSwitch() const; protected: + void parseEmbeddedData(libcamera::Span buffer, + Metadata &metadata); + MdParser *parser_; CameraMode mode_; diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index dad6395f..bb55f931 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -101,9 +101,7 @@ private: void returnEmbeddedBuffer(unsigned int bufferId); void prepareISP(const ipa::RPi::ISPConfig &data); void reportMetadata(); - bool parseEmbeddedData(unsigned int bufferId, struct DeviceStatus &deviceStatus); - void fillDeviceStatus(uint32_t exposureLines, uint32_t gainCode, - struct DeviceStatus &deviceStatus); + void fillDeviceStatus(const ControlList &sensorControls); void processStats(unsigned int bufferId); void applyFrameDurations(double minFrameDuration, double maxFrameDuration); void applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls); @@ -894,35 +892,34 @@ void IPARPi::returnEmbeddedBuffer(unsigned int bufferId) void IPARPi::prepareISP(const ipa::RPi::ISPConfig &data) { - struct DeviceStatus deviceStatus = {}; - bool success = false; + Span embeddedBuffer; + + rpiMetadata_.Clear(); + + fillDeviceStatus(data.controls); if (data.embeddedBufferPresent) { /* * Pipeline handler has supplied us with an embedded data buffer, - * so parse it and extract the exposure and gain. + * we must pass it to the CamHelper for parsing. */ - success = parseEmbeddedData(data.embeddedBufferId, deviceStatus); - - /* Done with embedded data now, return to pipeline handler asap. */ - returnEmbeddedBuffer(data.embeddedBufferId); + auto it = buffers_.find(data.embeddedBufferId); + ASSERT(it != buffers_.end()); + embeddedBuffer = it->second.maps()[0]; } - if (!success) { - /* - * Pipeline handler has not supplied an embedded data buffer, - * or embedded data buffer parsing has failed for some reason, - * so pull the exposure and gain values from the control list. - */ - int32_t exposureLines = data.controls.get(V4L2_CID_EXPOSURE).get(); - int32_t gainCode = data.controls.get(V4L2_CID_ANALOGUE_GAIN).get(); - fillDeviceStatus(exposureLines, gainCode, deviceStatus); - } + /* + * This may overwrite the DeviceStatus using values from the sensor + * metadata, and may also do additional custom processing. + */ + helper_->Prepare(embeddedBuffer, rpiMetadata_); + + /* Done with embedded data now, return to pipeline handler asap. */ + if (data.embeddedBufferPresent) + returnEmbeddedBuffer(data.embeddedBufferId); ControlList ctrls(ispCtrls_); - rpiMetadata_.Clear(); - rpiMetadata_.Set("device.status", deviceStatus); controller_.Prepare(&rpiMetadata_); /* Lock the metadata buffer to avoid constant locks/unlocks. */ @@ -972,41 +969,13 @@ void IPARPi::prepareISP(const ipa::RPi::ISPConfig &data) setIspControls.emit(ctrls); } -bool IPARPi::parseEmbeddedData(unsigned int bufferId, struct DeviceStatus &deviceStatus) +void IPARPi::fillDeviceStatus(const ControlList &sensorControls) { - auto it = buffers_.find(bufferId); - if (it == buffers_.end()) { - LOG(IPARPI, Error) << "Could not find embedded buffer!"; - return false; - } - - Span mem = it->second.maps()[0]; - helper_->Parser().SetBufferSize(mem.size()); - RPiController::MdParser::Status status = helper_->Parser().Parse(mem.data()); - if (status != RPiController::MdParser::Status::OK) { - LOG(IPARPI, Error) << "Embedded Buffer parsing failed, error " << status; - return false; - } else { - uint32_t exposureLines, gainCode; - if (helper_->Parser().GetExposureLines(exposureLines) != RPiController::MdParser::Status::OK) { - LOG(IPARPI, Error) << "Exposure time failed"; - return false; - } - - if (helper_->Parser().GetGainCode(gainCode) != RPiController::MdParser::Status::OK) { - LOG(IPARPI, Error) << "Gain failed"; - return false; - } - - fillDeviceStatus(exposureLines, gainCode, deviceStatus); - } + DeviceStatus deviceStatus = {}; - return true; -} + int32_t exposureLines = sensorControls.get(V4L2_CID_EXPOSURE).get(); + int32_t gainCode = sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get(); -void IPARPi::fillDeviceStatus(uint32_t exposureLines, uint32_t gainCode, - struct DeviceStatus &deviceStatus) -{ deviceStatus.shutter_speed = helper_->Exposure(exposureLines); deviceStatus.analogue_gain = helper_->Gain(gainCode); @@ -1014,6 +983,8 @@ void IPARPi::fillDeviceStatus(uint32_t exposureLines, uint32_t gainCode, << deviceStatus.shutter_speed << " Gain : " << deviceStatus.analogue_gain; + + rpiMetadata_.Set("device.status", deviceStatus); } void IPARPi::processStats(unsigned int bufferId) @@ -1027,6 +998,7 @@ void IPARPi::processStats(unsigned int bufferId) Span mem = it->second.maps()[0]; bcm2835_isp_stats *stats = reinterpret_cast(mem.data()); RPiController::StatisticsPtr statistics = std::make_shared(*stats); + helper_->Process(statistics, rpiMetadata_); controller_.Process(statistics, &rpiMetadata_); struct AgcStatus agcStatus;