From patchwork Tue Dec 15 10:16:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10669 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 DD8D8BD80A for ; Tue, 15 Dec 2020 10:16:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EE1C461594; Tue, 15 Dec 2020 11:16:39 +0100 (CET) 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="mRQYluoY"; dkim-atps=neutral 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 4B694600FD for ; Tue, 15 Dec 2020 11:16:38 +0100 (CET) Received: by mail-wm1-x32b.google.com with SMTP id q75so17938857wme.2 for ; Tue, 15 Dec 2020 02:16:38 -0800 (PST) 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=lXMmv1RSkTY6TxW3gM14i/0ixKRskwN7lmq08a9CYME=; b=mRQYluoYckrz29as1PSYgXBNB+0Dvz799xe8FBSjO77vYDNY1oDKNEXPNWGL7kcNOm 4ZgVdwJrCouxJi174cJ5TM5awhMvKhWlG1X9nOLQSuW3fPhgJjnHW2t1odDjHNrm561E T6Onixv6/Jy1qXlD/stWGcWVu19TFESz8zKUBCLreKfRRaSHF5mvKq830VZuef330TFV PhTQMISznQrqiTwTqny6K4AVXL3hO8N3r5/ADDU6jtl/mB5QNFTYQquAPskl5B6nGvD9 pnjr1Hg+f9TuO2cRKbJkA2xOeN9mUs2AxurhJIVI8EbsBgTDllr88N787iLKtGX7f4rv G9JA== 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=lXMmv1RSkTY6TxW3gM14i/0ixKRskwN7lmq08a9CYME=; b=AaP/1iCN/VUQyndwV0DqjrgToxnj16RO4kgpQLAz9c1pueuNLX+uepAXJ8ttDGo/Du Cb+3CqbWSc71DGIxJ27LZlTANVN567WeA7NeBK89AG9fPSmEbapT56BzTJYp94Aq5ynr gAYhU5R+ddYsdVSPv4mXVikCpRobGoQexmEYNoc8cMLulgw9VG6wDSpRRA77yKofJEU3 8YEL/Ptovsx3IhJYjfw85HkcgWk7WNffwcjo48cRcciGIHu+mUQmnVYOX6Y173BZV1NE 8V6QkDnIxM0f/Q+lWWTAPXCZFEr7IhxOfpULVN9yX/V7c4zuGAUV2Ef1CtfKrT4Vl1Bd cdeg== X-Gm-Message-State: AOAM530eJeScx30uXMlRrLotlE5JXPXpD2lCTmGtu9vfi8vlY50Sed+E xn0FchToTr21bfP9IqJwoE7/joVzD2i10Q== X-Google-Smtp-Source: ABdhPJyoSbY2jnNr4811021060pdQzO4fdbh5k0FQnDoiWv2Ehe/q6lo5Y1rQBy4w/lZKG5GWC/WTg== X-Received: by 2002:a7b:c24d:: with SMTP id b13mr25442973wmj.151.1608027397669; Tue, 15 Dec 2020 02:16:37 -0800 (PST) Received: from localhost.localdomain ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id s63sm39801117wms.18.2020.12.15.02.16.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 02:16:36 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Tue, 15 Dec 2020 10:16:33 +0000 Message-Id: <20201215101633.21546-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201215101633.21546-1-naush@raspberrypi.com> References: <20201215101633.21546-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/2] ipa: raspberrypi: Only validate ISP and sensor control during configure 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" There is no need to validate all the ISP and sensor V4L2 control on every use. Simply validate them once during the IPA configuration, and fail if a required control is not available. Signed-off-by: Naushir Patuck Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/raspberrypi/raspberrypi.cpp | 133 ++++++++++++++-------------- 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 5f2e07fd..bf544553 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -92,6 +92,8 @@ public: private: void setMode(const CameraSensorInfo &sensorInfo); + bool validateSensorControls(); + bool validateIspControls(); void queueRequest(const ControlList &controls); void returnEmbeddedBuffer(unsigned int bufferId); void prepareISP(unsigned int bufferId); @@ -290,6 +292,18 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, sensorCtrls_ = entityControls.at(0); ispCtrls_ = entityControls.at(1); + if (!validateSensorControls()) { + LOG(IPARPI, Error) << "Sensor control validation failed."; + result->operation = RPi::IPA_CONFIG_FAILED; + return; + } + + if (!validateIspControls()) { + LOG(IPARPI, Error) << "ISP control validation failed."; + result->operation = RPi::IPA_CONFIG_FAILED; + return; + } + /* Setup a metadata ControlList to output metadata. */ libcameraMetadata_ = ControlList(controls::controls); @@ -506,6 +520,51 @@ void IPARPi::reportMetadata() } } +bool IPARPi::validateSensorControls() +{ + static const uint32_t ctrls[] = { + V4L2_CID_ANALOGUE_GAIN, + V4L2_CID_EXPOSURE + }; + + for (auto c : ctrls) { + if (sensorCtrls_.find(c) == sensorCtrls_.end()) { + LOG(IPARPI, Error) << "Unable to find Unicam control " + << utils::hex(c); + return false; + } + } + + return true; +} + +bool IPARPi::validateIspControls() +{ + static const uint32_t ctrls[] = { + V4L2_CID_RED_BALANCE, + V4L2_CID_BLUE_BALANCE, + V4L2_CID_DIGITAL_GAIN, + V4L2_CID_USER_BCM2835_ISP_CC_MATRIX, + V4L2_CID_USER_BCM2835_ISP_GAMMA, + V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL, + V4L2_CID_USER_BCM2835_ISP_GEQ, + V4L2_CID_USER_BCM2835_ISP_DENOISE, + V4L2_CID_USER_BCM2835_ISP_SHARPEN, + V4L2_CID_USER_BCM2835_ISP_DPC, + V4L2_CID_USER_BCM2835_ISP_LENS_SHADING + }; + + for (auto c : ctrls) { + if (ispCtrls_.find(c) == ispCtrls_.end()) { + LOG(IPARPI, Error) << "Unable to find ISP control " + << utils::hex(c); + return false; + } + } + + return true; +} + /* * Converting between enums (used in the libcamera API) and the names that * we use to identify different modes. Unfortunately, the conversion tables @@ -891,18 +950,6 @@ void IPARPi::processStats(unsigned int bufferId) void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) { - const auto gainR = ispCtrls_.find(V4L2_CID_RED_BALANCE); - if (gainR == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find red gain control"; - return; - } - - const auto gainB = ispCtrls_.find(V4L2_CID_BLUE_BALANCE); - if (gainB == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find blue gain control"; - return; - } - LOG(IPARPI, Debug) << "Applying WB R: " << awbStatus->gain_r << " B: " << awbStatus->gain_b; @@ -917,16 +964,6 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls) int32_t gainCode = helper_->GainCode(agcStatus->analogue_gain); int32_t exposureLines = helper_->ExposureLines(agcStatus->shutter_time); - if (sensorCtrls_.find(V4L2_CID_ANALOGUE_GAIN) == sensorCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find analogue gain control"; - return; - } - - if (sensorCtrls_.find(V4L2_CID_EXPOSURE) == sensorCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find exposure control"; - return; - } - LOG(IPARPI, Debug) << "Applying AGC Exposure: " << agcStatus->shutter_time << " (Shutter lines: " << exposureLines << ") Gain: " << agcStatus->analogue_gain << " (Gain Code: " @@ -938,23 +975,14 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls) void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_DIGITAL_GAIN) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find digital gain control"; - return; - } - ctrls.set(V4L2_CID_DIGITAL_GAIN, static_cast(dgStatus->digital_gain * 1000)); } void IPARPi::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_CC_MATRIX) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find CCM control"; - return; - } - bcm2835_isp_custom_ccm ccm; + for (int i = 0; i < 9; i++) { ccm.ccm.ccm[i / 3][i % 3].den = 1000; ccm.ccm.ccm[i / 3][i % 3].num = 1000 * ccmStatus->matrix[i]; @@ -970,12 +998,8 @@ void IPARPi::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls) void IPARPi::applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_GAMMA) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find Gamma control"; - return; - } - struct bcm2835_isp_gamma gamma; + gamma.enabled = 1; for (int i = 0; i < CONTRAST_NUM_POINTS; i++) { gamma.x[i] = contrastStatus->points[i].x; @@ -989,12 +1013,8 @@ void IPARPi::applyGamma(const struct ContrastStatus *contrastStatus, ControlList void IPARPi::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find black level control"; - return; - } - bcm2835_isp_black_level blackLevel; + blackLevel.enabled = 1; blackLevel.black_level_r = blackLevelStatus->black_level_r; blackLevel.black_level_g = blackLevelStatus->black_level_g; @@ -1007,12 +1027,8 @@ void IPARPi::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, Co void IPARPi::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_GEQ) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find geq control"; - return; - } - bcm2835_isp_geq geq; + geq.enabled = 1; geq.offset = geqStatus->offset; geq.slope.den = 1000; @@ -1025,12 +1041,8 @@ void IPARPi::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls) void IPARPi::applyDenoise(const struct SdnStatus *denoiseStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_DENOISE) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find denoise control"; - return; - } - bcm2835_isp_denoise denoise; + denoise.enabled = 1; denoise.constant = denoiseStatus->noise_constant; denoise.slope.num = 1000 * denoiseStatus->noise_slope; @@ -1045,12 +1057,8 @@ void IPARPi::applyDenoise(const struct SdnStatus *denoiseStatus, ControlList &ct void IPARPi::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_SHARPEN) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find sharpen control"; - return; - } - bcm2835_isp_sharpen sharpen; + sharpen.enabled = 1; sharpen.threshold.num = 1000 * sharpenStatus->threshold; sharpen.threshold.den = 1000; @@ -1066,12 +1074,8 @@ void IPARPi::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList void IPARPi::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_DPC) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find DPC control"; - return; - } - bcm2835_isp_dpc dpc; + dpc.enabled = 1; dpc.strength = dpcStatus->strength; @@ -1082,11 +1086,6 @@ void IPARPi::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls) void IPARPi::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) { - if (ispCtrls_.find(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING) == ispCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find LS control"; - return; - } - /* * Program lens shading tables into pipeline. * Choose smallest cell size that won't exceed 63x48 cells.