From patchwork Fri Dec 4 15:31:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10561 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 A1362BE177 for ; Fri, 4 Dec 2020 15:31:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1BD3E635F8; Fri, 4 Dec 2020 16:31:30 +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="cw2hQg02"; dkim-atps=neutral Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 948BC635D6 for ; Fri, 4 Dec 2020 16:31:28 +0100 (CET) Received: by mail-wm1-x335.google.com with SMTP id g185so7404293wmf.3 for ; Fri, 04 Dec 2020 07:31:28 -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=0PV2Y5oXqUFKFkSmsjE6h2mwWzE30CUw3vNPsXz+F/M=; b=cw2hQg025wombO8odwyKU7iDFApHYVLjhosBLHNH9kUfqzDFtUetlxq41L1PxjhGnx tLwoxLKjiHHifIWb0cLbeB3zbVi5DUa/Ad++bflZ43hw4EsjtYFMJAYNfoPLvx4cnRA6 L1rtobsztDQLC7EeWO/YRb0UvJpJmE9Ossbf3lfEhanvAKfoBkQDtq8mWXYGEjoJsgF+ FQ0p9/r5foNaW/ug/a14kOB558l34klpkEGvnqil3YaNTE1YzAjjNoqcBUoiqtsTf3EC Wb8OPyRoKqDrjrlTSaN2MTm2+QJEISk30GQ1sjiqmylFnhGadXvh5s3TMo/zRyNeYWXM zotQ== 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=0PV2Y5oXqUFKFkSmsjE6h2mwWzE30CUw3vNPsXz+F/M=; b=KTgc+yEK9Ok5ngLw5LmVBDx1BPKJVujgblQjFLA+8MUd9GWmcoSATAuNhv+3f76esU yAUdkPHylpWBI6tMfNoIbNqiOUHqwuIYQAlTowgtn21xtsy9MaJkg3Gce/7HVR7lnTi2 fPAy7yqAWbO/liK+M1up91qe6OFjNMY6phLrV/9aluuvH4fOxVA/c06J7+E5PH2BVTO1 LDIE3b8lACZ/7ADjJLpBdS9H9aRFejkKxA4w95Rdr2NKUADNZUvbo6gycBGx3QVUMGqD oAir3OFTtLm8XoKofjdw46wZuP/kld8mwgGP8i8N7Y5bduNUgp+IPelcBFVNOIAtYaw6 WSAw== X-Gm-Message-State: AOAM530N7Um/tJW5wj6hStBcdOUjZ6xMQvpbZ/iT3sMy+OPluGw+ubUK Uf2uD6RmEHpztP3wCmGflVvvEWoI3kmhvA== X-Google-Smtp-Source: ABdhPJx9YLoE0u8f2RA1uZAZrKzTxdQt6qAkfXsiEOUImXZpB+oM3+V5g9tzBdn8qo19cu2XOsZIQQ== X-Received: by 2002:a1c:5f83:: with SMTP id t125mr4944212wmb.82.1607095887960; Fri, 04 Dec 2020 07:31:27 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id x66sm3465426wmg.26.2020.12.04.07.31.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Dec 2020 07:31:27 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Fri, 4 Dec 2020 15:31:21 +0000 Message-Id: <20201204153121.66136-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201204153121.66136-1-naush@raspberrypi.com> References: <20201204153121.66136-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/3] pipeline: ipa: raspberrypi: Pass controls to IPA on start 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" Forward any controls passed into the pipeline handler to the IPA. The IPA then sets up the Raspberry Pi controller with these settings appropriately, and passes back any V4L2 sensor controls that need to be applied. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman Reviewed-by: Jacopo Mondi --- include/libcamera/ipa/raspberrypi.h | 1 + src/ipa/raspberrypi/raspberrypi.cpp | 54 ++++++++++++------- .../pipeline/raspberrypi/raspberrypi.cpp | 13 ++++- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 2b55dbfc..c91a14bd 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -21,6 +21,7 @@ enum ConfigParameters { IPA_CONFIG_STAGGERED_WRITE = (1 << 1), IPA_CONFIG_SENSOR = (1 << 2), IPA_CONFIG_DROP_FRAMES = (1 << 3), + IPA_CONFIG_STARTUP = (1 << 4) }; enum Operations { diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index b8c0f955..ff95580e 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -78,8 +78,7 @@ public: } int init(const IPASettings &settings) override; - int start([[maybe_unused]] const IPAOperationData &data, - [[maybe_unused]] IPAOperationData *result) override { return 0; } + int start(const IPAOperationData &data, IPAOperationData *result) override; void stop() override {} void configure(const CameraSensorInfo &sensorInfo, @@ -154,6 +153,36 @@ int IPARPi::init(const IPASettings &settings) return 0; } +int IPARPi::start(const IPAOperationData &data, IPAOperationData *result) +{ + RPiController::Metadata metadata; + + ASSERT(result); + result->operation = 0; + if (data.operation & RPi::IPA_CONFIG_STARTUP) { + /* We have been given some controls to action before start. */ + queueRequest(data.controls[0]); + } + + controller_.SwitchMode(mode_, &metadata); + + /* SwitchMode may supply updated exposure/gain values to use. */ + AgcStatus agcStatus; + agcStatus.shutter_time = 0.0; + agcStatus.analogue_gain = 0.0; + + /* SwitchMode may supply updated exposure/gain values to use. */ + metadata.Get("agc.status", agcStatus); + if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) { + ControlList ctrls(unicamCtrls_); + applyAGC(&agcStatus, ctrls); + result->controls.emplace_back(ctrls); + result->operation |= RPi::IPA_CONFIG_SENSOR; + } + + return 0; +} + void IPARPi::setMode(const CameraSensorInfo &sensorInfo) { mode_.bitdepth = sensorInfo.bitsPerPixel; @@ -229,7 +258,6 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, result->data.push_back(gainDelay); result->data.push_back(exposureDelay); result->data.push_back(sensorMetadata); - result->operation |= RPi::IPA_CONFIG_STAGGERED_WRITE; } @@ -285,11 +313,6 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, result->data.push_back(dropFrame); result->operation |= RPi::IPA_CONFIG_DROP_FRAMES; - /* These zero values mean not program anything (unless overwritten). */ - struct AgcStatus agcStatus; - agcStatus.shutter_time = 0.0; - agcStatus.analogue_gain = 0.0; - if (!controllerInit_) { /* Load the tuning file for this sensor. */ controller_.Read(tuningFile_.c_str()); @@ -297,20 +320,13 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, controllerInit_ = true; /* Supply initial values for gain and exposure. */ + ControlList ctrls(unicamCtrls_); + AgcStatus agcStatus; agcStatus.shutter_time = DefaultExposureTime; agcStatus.analogue_gain = DefaultAnalogueGain; - } - - RPiController::Metadata metadata; - controller_.SwitchMode(mode_, &metadata); - - /* SwitchMode may supply updated exposure/gain values to use. */ - metadata.Get("agc.status", agcStatus); - if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) { - ControlList ctrls(unicamCtrls_); applyAGC(&agcStatus, ctrls); - result->controls.push_back(ctrls); + result->controls.emplace_back(ctrls); result->operation |= RPi::IPA_CONFIG_SENSOR; } @@ -824,7 +840,7 @@ void IPARPi::processStats(unsigned int bufferId) IPAOperationData op; op.operation = RPi::IPA_ACTION_V4L2_SET_STAGGERED; - op.controls.push_back(ctrls); + op.controls.emplace_back(ctrls); queueFrameAction.emit(0, op); } } diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index bafd0b2d..bc7c56f8 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -753,8 +753,10 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont /* Start the IPA. */ IPAOperationData ipaData = {}, result = {}; - if (controls) + if (controls) { + ipaData.operation = RPi::IPA_CONFIG_STARTUP; ipaData.controls.emplace_back(*controls); + } ret = data->ipa_->start(ipaData, &result); if (ret) { LOG(RPI, Error) @@ -763,6 +765,14 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont return ret; } + /* Apply any gain/exposure settings that the IPA may have passed back. */ + ASSERT(data->staggeredCtrl_); + if (result.operation & RPi::IPA_CONFIG_SENSOR) { + const ControlList &ctrls = result.controls[0]; + if (!data->staggeredCtrl_.set(ctrls)) + LOG(RPI, Error) << "V4L2 staggered set failed"; + } + /* * IPA configure may have changed the sensor flips - hence the bayer * order. Get the sensor format and set the ISP input now. @@ -783,7 +793,6 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont * starting. First check that the staggered ctrl has been initialised * by configure(). */ - ASSERT(data->staggeredCtrl_); data->staggeredCtrl_.reset(); data->staggeredCtrl_.write(); data->expectedSequence_ = 0;