From patchwork Wed Dec 9 09:53:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10623 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 BA9F7BDE19 for ; Wed, 9 Dec 2020 09:53:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2052067E4D; Wed, 9 Dec 2020 10:53:46 +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="rgp0yHy9"; dkim-atps=neutral Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 27A4D635C4 for ; Wed, 9 Dec 2020 10:53:45 +0100 (CET) Received: by mail-wr1-x42b.google.com with SMTP id r7so1022198wrc.5 for ; Wed, 09 Dec 2020 01:53:45 -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:mime-version :content-transfer-encoding; bh=qWoZ5CpjT3w9n26TV/VtaSkHi37FTRfo/PrryIzxKfk=; b=rgp0yHy92rmvzgdOL6A+fd1EDYOPPk/qRw2s5lm4Vn3KzOhdjdfkFeKL1tWWl+Y+yq ZfxidbQBZ8RyrNaIBGIhQBhOOwCc56zM6qxu/aswjQO/kPlEqB77FWWWsd4LXMU2m/4W KmaqCHcXkpLgyTDTnBJ16+wWShsIV6dIk1Fz1vF1MbEh7bXF1EckjWyW8q/4hbwZKJQR r2PJkf/n0PkbHFUfRWu3FmbKjkmvaThQYkK71dIPlO6xjPxGw6HQ+rlcuNlaIMgzlKcD jcEcSjZH1h6mddTlQJE+fMwyQd6S2JIm4d8d6CJbt9WDcPGi6cUVKb89mtNkjOphr1Q2 1TWQ== 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:mime-version :content-transfer-encoding; bh=qWoZ5CpjT3w9n26TV/VtaSkHi37FTRfo/PrryIzxKfk=; b=Hs1QISA6G1MtNVrqv8V0i6wxd0dbM3+46rbE/xORsB2BKeN5vX3pTDyW3aEwKmxIf9 pOdINPkDnWX4vsA3Y0UVmG4lceaQcbF1+DBnXtLbwbY1MpBHIstrbW8C6dcuTDvnGxfd JLHoKsMZflPQern6xCCZLE+XkZVd2tuq9aMzMKIoarLit5pSqItmZqYs2OuKt8nf2Kmc /4LjmmcAyFI+X6YJs2XU3yJYEzVW+2satwk2TU3iF8iaonRJus/OLcy+H5I/dX7m1rXF QYjYOov8W1TWpQQrmTJLfSc/qdbhZkJKNF+jIFO0WrrM+3P9ia4IAO0wdbG8GF+BYSNW qaKw== X-Gm-Message-State: AOAM531O+aarHBGrVmWghxj9sMBs68JrEaQgmjEnmQYO9fOOTE0QOzUw d3Fhw13gjeA4wxF5VWhQ2lOw5GVg/4FOKg== X-Google-Smtp-Source: ABdhPJxJjC+3ITwMngu7eahrVBotTOQr/rC0uwzoMpu/owtlIC7+l4nADNA3hUa9jYuaagji/ccf3A== X-Received: by 2002:a5d:6386:: with SMTP id p6mr1723970wru.261.1607507624398; Wed, 09 Dec 2020 01:53:44 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id w12sm2635015wre.57.2020.12.09.01.53.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Dec 2020 01:53:43 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Wed, 9 Dec 2020 09:53:39 +0000 Message-Id: <20201209095339.4107-1-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] ipa: raspberrypi: Only validate ISP and Unicam controls 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 Unicam V4L2 controls on every frame. Simply validate them once during the IPA configuration, and fail if a required control is not available. Also add some whitespace for readability. Signed-off-by: Naushir Patuck --- src/ipa/raspberrypi/raspberrypi.cpp | 131 ++++++++++++++-------------- 1 file changed, 64 insertions(+), 67 deletions(-) diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 60cfdc27..e5d2b41e 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 validateUnicamControls(); + bool validateIspControls(); void queueRequest(const ControlList &controls); void returnEmbeddedBuffer(unsigned int bufferId); void prepareISP(unsigned int bufferId); @@ -238,6 +240,16 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, unicamCtrls_ = entityControls.at(0); ispCtrls_ = entityControls.at(1); + if (!validateUnicamControls()) { + LOG(IPARPI, Error) << "Unicam control validation failed."; + return -EINVAL; + } + + if (!validateIspControls()) { + LOG(IPARPI, Error) << "ISP control validation failed."; + return -EINVAL; + } + /* Setup a metadata ControlList to output metadata. */ libcameraMetadata_ = ControlList(controls::controls); @@ -473,6 +485,51 @@ void IPARPi::reportMetadata() } } +bool IPARPi::validateUnicamControls() +{ + const uint32_t ctrls[] = { + V4L2_CID_ANALOGUE_GAIN, + V4L2_CID_EXPOSURE + }; + + for (auto c : ctrls) { + if (unicamCtrls_.find(c) == unicamCtrls_.end()) { + LOG(IPARPI, Error) << "Unable to find Unicam control " + << c; + return false; + } + } + + return true; +} + +bool IPARPi::validateIspControls() +{ + 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 " + << 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 @@ -858,18 +915,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; @@ -884,16 +929,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 (unicamCtrls_.find(V4L2_CID_ANALOGUE_GAIN) == unicamCtrls_.end()) { - LOG(IPARPI, Error) << "Can't find analogue gain control"; - return; - } - - if (unicamCtrls_.find(V4L2_CID_EXPOSURE) == unicamCtrls_.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: " @@ -905,23 +940,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]; @@ -937,12 +963,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; @@ -956,12 +978,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; @@ -974,12 +992,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; @@ -992,12 +1006,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; @@ -1012,12 +1022,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; @@ -1033,12 +1039,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; @@ -1049,11 +1051,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.