From patchwork Thu Nov 26 09:51:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10500 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 02067BE08A for ; Thu, 26 Nov 2020 09:51:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C0D2C63449; Thu, 26 Nov 2020 10:51:34 +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="mN8sFW+Z"; dkim-atps=neutral Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4C0A863445 for ; Thu, 26 Nov 2020 10:51:33 +0100 (CET) Received: by mail-wr1-x429.google.com with SMTP id s8so1417014wrw.10 for ; Thu, 26 Nov 2020 01:51:33 -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=LgcW+QiPUg9btLTFemG0qL47tIsFP5c/CIoGpSHdOog=; b=mN8sFW+ZNhEWMiDzWYaygIPRsrSfEesFvPe06SChU30SLCM8o1nbT8oIXoBoSLZzpm Aft6n/9GXET3Eq3/q9X8Ny0yfCWojyTOJQNVNi99hsqS6VCRi3CQG9lrJJ4ln0LXNDuA cp5FW/wRkWw/wf6uLQpG/VBZ/PG/U1YXhtSGZ4B48VYCjm0/9qF+f79clkxkSq8CTstR 1pIoFeJciYDLVEDsW8x3/sw7n1xdpsOvdhgnmmA3f7fcG9yhWpYlwySZV4SIwFNoz0c3 NWogZVpzFM3F7IU43UFBXsApcRCeJiXdnC7p9XsvgdyhP+E7z73L76NDC7cH0Y6bXsNW iuuw== 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=LgcW+QiPUg9btLTFemG0qL47tIsFP5c/CIoGpSHdOog=; b=cryAo9URzgueAb9oSdx5yUOUmc9kygN5zQlQeDAefLOaRODI0qbjevGmFbwM0cUjzK DkNIVY/almB98n9uN8EgQdVEGdJIkLvR7lT3VwlCTPLfWKSa8oVc2N9ksRtjhdobFVb1 zSqfkZROYb0ZV/76eLuwkSISeo+fQwZUETiJntts/IR0tWhFox8X6asKu6XmAPwIT1CC BE7E/OsmaBuJWpIIrd4OPlXVm9I6jjMXwwrNdlhNMpFORe0xt4TQSliSDCxcQ5mjIBUq UoUEVROJkG23cDJgw3pkX6m6JBdYZkHgK3cIrQpAxMFJ0xccGgumB3n18PjeX/dtFOwQ o7wg== X-Gm-Message-State: AOAM530FIgtwe0/5xNvislupogm77EbDx96iwDihlpd1Y5u5ZOduBHm2 suIUyddDUM4f9gLcGeuqS1GB/V2JzJEvSg== X-Google-Smtp-Source: ABdhPJzoNJ1tS1OhwQqpwCbrj/L4LWTjccMw8gtLA4H/UxTXRKIpyPTAUOnz/0Qo7rWgrrPgGgSDQA== X-Received: by 2002:a5d:60cb:: with SMTP id x11mr2861625wrt.0.1606384292579; Thu, 26 Nov 2020 01:51:32 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id i11sm8176827wrm.1.2020.11.26.01.51.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Nov 2020 01:51:32 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 26 Nov 2020 09:51:26 +0000 Message-Id: <20201126095126.997055-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201126095126.997055-1-naush@raspberrypi.com> References: <20201126095126.997055-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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 --- include/libcamera/ipa/raspberrypi.h | 1 + src/ipa/raspberrypi/raspberrypi.cpp | 53 ++++++++++++------- .../pipeline/raspberrypi/raspberrypi.cpp | 14 ++++- 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 7a07b477..c09b3d07 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -77,8 +77,7 @@ public: } int init(const IPASettings &settings) override; - int start([[maybe_unused]] const IPAOperationData &ipaConfig, - [[maybe_unused]] IPAOperationData *result) override { return 0; } + int start(const IPAOperationData &ipaConfig, IPAOperationData *result) override; void stop() override {} void configure(const CameraSensorInfo &sensorInfo, @@ -154,6 +153,35 @@ int IPARPi::init(const IPASettings &settings) return 0; } +int IPARPi::start(const IPAOperationData &ipaConfig, IPAOperationData *result) +{ + RPiController::Metadata metadata; + + result->operation = 0; + if (ipaConfig.operation & RPi::IPA_CONFIG_STARTUP) { + /* We have been given some controls to action before start. */ + queueRequest(ipaConfig.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 +257,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 +312,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 +319,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; } @@ -843,7 +858,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 29bcef07..3eb8c190 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -748,7 +748,10 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont /* Start the IPA. */ IPAOperationData ipaConfig = {}, result = {}; - ipaConfig.controls.emplace_back(*controls); + if (controls) { + ipaConfig.operation = RPi::IPA_CONFIG_STARTUP; + ipaConfig.controls.emplace_back(*controls); + } ret = data->ipa_->start(ipaConfig, &result); if (ret) { LOG(RPI, Error) @@ -757,6 +760,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. @@ -777,7 +788,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;