From patchwork Tue Dec 29 16:03:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 10773 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se 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 17690C0F1A for ; Tue, 29 Dec 2020 16:04:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D9C57615D2; Tue, 29 Dec 2020 17:04:11 +0100 (CET) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 090AB615D5 for ; Tue, 29 Dec 2020 17:04:11 +0100 (CET) X-Halon-ID: 7c070017-49ef-11eb-a542-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de [79.202.36.88]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 7c070017-49ef-11eb-a542-005056917a89; Tue, 29 Dec 2020 17:04:09 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Dec 2020 17:03:14 +0100 Message-Id: <20201229160318.77536-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201229160318.77536-1-niklas.soderlund@ragnatech.se> References: <20201229160318.77536-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 07/11] libcamera: ipu3: Attach to an IPA and allow it to set sensor controls 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" Attach to the IPA and allow it to push V4L2 controls that applies on the camera sensor. The IPA is not fully integrated in the pipeline as statistics and parameters buffers are not yet allocated, processed by the IPA nor queued to the hardware. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- * Changes since v1 - Rewrite to not use CameraSensor. - Fix mistake where configuration sen to IPA was overwritten. - Check that IPA configuration was successful before starting. - Update commit message. --- src/libcamera/pipeline/ipu3/ipu3.cpp | 103 +++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index a87ce8f3378ba2fe..95f1b75dc8be5d40 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -14,11 +14,14 @@ #include #include #include +#include #include #include #include "libcamera/internal/camera_sensor.h" +#include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/log.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" @@ -53,6 +56,8 @@ public: { } + int loadIPA(); + void imguOutputBufferReady(FrameBuffer *buffer); void cio2BufferReady(FrameBuffer *buffer); @@ -62,6 +67,11 @@ public: Stream outStream_; Stream vfStream_; Stream rawStream_; + + std::unique_ptr delayedCtrls_; + +private: + void actOnIpa(unsigned int id, const IPAOperationData &op); }; class IPU3CameraConfiguration : public CameraConfiguration @@ -590,6 +600,13 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *con IPU3CameraData *data = cameraData(camera); CIO2Device *cio2 = &data->cio2_; ImgUDevice *imgu = data->imgu_; + + CameraSensorInfo sensorInfo = {}; + std::map streamConfig; + std::map entityControls; + IPAOperationData ipaConfig; + IPAOperationData result = {}; + int ret; /* Allocate buffers for internal pipeline usage. */ @@ -597,6 +614,11 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *con if (ret) return ret; + IPAOperationData ipaData = {}; + ret = data->ipa_->start(ipaData, nullptr); + if (ret) + goto error; + /* * Start the ImgU video devices, buffers will be queued to the * ImgU output and viewfinder when requests will be queued. @@ -612,9 +634,40 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *con goto error; } + /* Inform IPA of stream configuration and sensor controls. */ + ret = data->cio2_.sensor()->sensorInfo(&sensorInfo); + if (ret) { + /* \todo Turn to hard failure once sensors info is mandatory. */ + LOG(IPU3, Warning) << "Camera sensor information not available"; + sensorInfo = {}; + ret = 0; + } + + streamConfig[0] = { + .pixelFormat = data->outStream_.configuration().pixelFormat, + .size = data->outStream_.configuration().size, + }; + streamConfig[1] = { + .pixelFormat = data->vfStream_.configuration().pixelFormat, + .size = data->vfStream_.configuration().size, + }; + + entityControls.emplace(0, data->cio2_.sensor()->controls()); + + data->ipa_->configure(sensorInfo, streamConfig, entityControls, + ipaConfig, &result); + + if ((result.operation != IPU3_IPA_STATUS_CONFIGURATION) || + (result.data.size() != 1) || (result.data.at(0) != 1)) { + LOG(IPU3, Warning) << "Failed to configure IPA"; + ret = -EINVAL; + goto error; + } + return 0; error: + data->ipa_->stop(); freeBuffers(camera); LOG(IPU3, Error) << "Failed to start camera " << camera->id(); @@ -631,6 +684,8 @@ void PipelineHandlerIPU3::stop(Camera *camera) if (ret) LOG(IPU3, Warning) << "Failed to stop camera " << camera->id(); + data->ipa_->stop(); + freeBuffers(camera); } @@ -762,12 +817,32 @@ int PipelineHandlerIPU3::registerCameras() if (ret) continue; + ret = data->loadIPA(); + if (ret) + continue; + /* Initialize the camera properties. */ data->properties_ = cio2->sensor()->properties(); /* Initialze the camera controls. */ data->controlInfo_ = IPU3Controls; + /* + * \todo Read dealy values from the sensor itself or from a + * a sensor database. For now use generic values taken from + * the Raspberry Pi and listed as generic values. + */ + std::unordered_map delays = { + { V4L2_CID_ANALOGUE_GAIN, 1 }, + { V4L2_CID_EXPOSURE, 2 }, + }; + + data->delayedCtrls_ = + std::make_unique(cio2->sensor()->device(), + delays); + data->cio2_.frameStart().connect(data->delayedCtrls_.get(), + &DelayedControls::applyControls); + /** * \todo Dynamically assign ImgU and output devices to each * stream and camera; as of now, limit support to two cameras @@ -811,6 +886,34 @@ int PipelineHandlerIPU3::registerCameras() return numCameras ? 0 : -ENODEV; } +int IPU3CameraData::loadIPA() +{ + ipa_ = IPAManager::createIPA(pipe_, 1, 1); + if (!ipa_) + return -ENOENT; + + ipa_->queueFrameAction.connect(this, &IPU3CameraData::actOnIpa); + + ipa_->init(IPASettings{}); + + return 0; +} + +void IPU3CameraData::actOnIpa([[maybe_unused]] unsigned int id, + const IPAOperationData &action) +{ + switch (action.operation) { + case IPU3_IPA_ACTION_SET_SENSOR_CONTROLS: { + const ControlList &controls = action.controls[0]; + delayedCtrls_->push(controls); + break; + } + default: + LOG(IPU3, Error) << "Unknown action " << action.operation; + break; + } +} + /* ----------------------------------------------------------------------------- * Buffer Ready slots */