From patchwork Wed Aug 28 01:16:58 2019 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: 1866 Return-Path: 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 1FDD060C10 for ; Wed, 28 Aug 2019 03:17:35 +0200 (CEST) X-Halon-ID: 94214421-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 94214421-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:19 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:16:58 +0200 Message-Id: <20190828011710.32128-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 01/13] libcamera: pipeline: vimc: Increase version of dummy IPA X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:35 -0000 An IPA version number of 0 will be redefined as No IPA support. Increase the VIMC dummy IPA version to 1 to allow it to keep loading. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- src/ipa/ipa_dummy.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ipa/ipa_dummy.cpp b/src/ipa/ipa_dummy.cpp index 4c8b6657689d0c9f..b0e944a17fc5cffb 100644 --- a/src/ipa/ipa_dummy.cpp +++ b/src/ipa/ipa_dummy.cpp @@ -31,7 +31,7 @@ int IPADummy::init() extern "C" { const struct IPAModuleInfo ipaModuleInfo = { IPA_MODULE_API_VERSION, - 0, + 1, "PipelineHandlerVimc", "Dummy IPA for Vimc", "LGPL-2.1-or-later", diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index f8f91d6219b1aee4..e5c4890501db71c8 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -361,7 +361,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) if (!media) return false; - ipa_ = IPAManager::instance()->createIPA(this, 0, 0); + ipa_ = IPAManager::instance()->createIPA(this, 1, 1); if (ipa_ == nullptr) LOG(VIMC, Warning) << "no matching IPA found"; else From patchwork Wed Aug 28 01:16:59 2019 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: 1867 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 677AF60C10 for ; Wed, 28 Aug 2019 03:17:37 +0200 (CEST) X-Halon-ID: 953a03c8-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 953a03c8-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:21 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:16:59 +0200 Message-Id: <20190828011710.32128-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 02/13] libcamera: pipeline: Move IPA from pipeline to camera data X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:37 -0000 The IPA acts on a camera and not on a pipeline which can expose more then once camera. Move the IPA reference to the CameraData and move the loading of an IPA from the specific pipeline handler implementation to base PipelineHandler. It's still possible to expose a camera without an IPA but if an IPA is request the camera is not valid and will not be registered in the system if a suiting IPA module can't be found. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- src/libcamera/include/pipeline_handler.h | 12 ++++++-- src/libcamera/pipeline/vimc.cpp | 10 +----- src/libcamera/pipeline_handler.cpp | 39 +++++++++++++++++++++++- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index 1fdef9cea40f1f0a..ffc7adb802215313 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -15,6 +15,7 @@ #include #include +#include #include namespace libcamera { @@ -33,8 +34,11 @@ class Request; class CameraData { public: - explicit CameraData(PipelineHandler *pipe) - : pipe_(pipe) + explicit CameraData(PipelineHandler *pipe, + uint32_t minIPAVersion = 0, + uint32_t maxIPAVersion = 0) + : pipe_(pipe), ipa_(nullptr), minIPAVersion_(minIPAVersion), + maxIPAVersion_(maxIPAVersion) { } virtual ~CameraData() {} @@ -44,6 +48,10 @@ public: std::list queuedRequests_; ControlInfoMap controlInfo_; + std::unique_ptr ipa_; + const uint32_t minIPAVersion_; + const uint32_t maxIPAVersion_; + private: CameraData(const CameraData &) = delete; CameraData &operator=(const CameraData &) = delete; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index e5c4890501db71c8..be6507cd4bc0d1b9 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -38,7 +38,7 @@ class VimcCameraData : public CameraData { public: VimcCameraData(PipelineHandler *pipe) - : CameraData(pipe), sensor_(nullptr), debayer_(nullptr), + : CameraData(pipe, 1, 1), sensor_(nullptr), debayer_(nullptr), scaler_(nullptr), video_(nullptr), raw_(nullptr) { } @@ -100,8 +100,6 @@ private: return static_cast( PipelineHandler::cameraData(camera)); } - - std::unique_ptr ipa_; }; VimcCameraConfiguration::VimcCameraConfiguration() @@ -361,12 +359,6 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) if (!media) return false; - ipa_ = IPAManager::instance()->createIPA(this, 1, 1); - if (ipa_ == nullptr) - LOG(VIMC, Warning) << "no matching IPA found"; - else - ipa_->init(); - std::unique_ptr data = utils::make_unique(this); /* Locate and open the capture video node. */ diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 3e54aa23d92b9a36..89b67806597728f9 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -12,6 +12,7 @@ #include #include "device_enumerator.h" +#include "ipa_manager.h" #include "log.h" #include "media_device.h" #include "utils.h" @@ -49,13 +50,20 @@ LOG_DEFINE_CATEGORY(Pipeline) */ /** - * \fn CameraData::CameraData(PipelineHandler *pipe) + * \fn CameraData::CameraData(PipelineHandler *pipe, uint32_t minIPAVersion, + * uint32_t maxIPAVersion) * \brief Construct a CameraData instance for the given pipeline handler * \param[in] pipe The pipeline handler + * \param[in] minIPAVersion Minimum acceptable version of IPA module + * \param[in] maxIPAVersion Maximum acceptable version of IPA module * * The reference to the pipeline handler is stored internally, the caller shall * guarantee that the pointer remains valid as long as the CameraData instance * exists. + * + * The IPA maximum and minimum version numbers are used to match with an IPA + * interface that would be compatible with the Camera. If no IPA interface + * is needed for the camera both parameters should be set to 0. */ /** @@ -96,6 +104,24 @@ LOG_DEFINE_CATEGORY(Pipeline) * creating the camera, and shall not be modified afterwards. */ +/** + * \var CameraData::ipa_ + * \brief The IPA module used by the camera + * + * Reference to the Image Processing Algorithms (IPA) operating on the camera's + * stream(s). If no IPA are in operation this should be set to nullptr. + */ + +/** + * \var CameraData::minIPAVersion_ + * \brief Minimum acceptable version of IPA module + */ + +/** + * \var CameraData::maxIPAVersion_ + * \brief Maximum acceptable version of IPA module + */ + /** * \class PipelineHandler * \brief Create and manage cameras based on a set of media devices @@ -424,6 +450,17 @@ void PipelineHandler::completeRequest(Camera *camera, Request *request) void PipelineHandler::registerCamera(std::shared_ptr camera, std::unique_ptr data) { + if (data->minIPAVersion_ || data->maxIPAVersion_) { + data->ipa_ = IPAManager::instance()->createIPA(this, + data->minIPAVersion_, + data->maxIPAVersion_); + if (!data->ipa_) { + LOG(Pipeline, Warning) << "Skipping " << camera->name() + << " no IPA found"; + return; + } + } + data->camera_ = camera.get(); cameraData_[camera.get()] = std::move(data); cameras_.push_back(camera); From patchwork Wed Aug 28 01:17:00 2019 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: 1868 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9D53760C42 for ; Wed, 28 Aug 2019 03:17:39 +0200 (CEST) X-Halon-ID: 96621487-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 96621487-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:23 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:00 +0200 Message-Id: <20190828011710.32128-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 03/13] libcamera: pipeline: Add method to prepare buffer for IPA X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:39 -0000 The pipeline handlers dealing with buffers outside the request coming from an application needs to prepare Buffer objects before they can be used by other the libcamera functions. For objects coming from the user this is done by the Camera before the Buffers reach the pipeline handler. Add a new method prepareInternalBuffer() to aid with this preparation. Signed-off-by: Niklas Söderlund --- src/libcamera/include/pipeline_handler.h | 2 ++ src/libcamera/pipeline_handler.cpp | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index ffc7adb802215313..91d40ef40a465c4e 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -98,6 +98,8 @@ protected: CameraData *cameraData(const Camera *camera); + void prepareInternalBuffer(Buffer *buffer, Request *request, + BufferMemory *mem); CameraManager *manager_; private: diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 89b67806597728f9..766fd496306ece9c 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -484,6 +484,24 @@ void PipelineHandler::hotplugMediaDevice(MediaDevice *media) media->disconnected.connect(this, &PipelineHandler::mediaDeviceDisconnected); } +/** + * \brief Prepare buffer for internal usage by a pipeline handler + * \param[in,out] buffer The buffer to prepare + * \param[in] request The request to associate the \a buffer with + * \param[in] mem The memory to associate the \a buffer with + * + * Pipeline handlers creating internal buffers to facilitate data flow in the + * pipeline need to prepare the buffers by setting up the buffer object state. + * This function help pipeline handler implementations to perform this + * preparation. + */ +void PipelineHandler::prepareInternalBuffer(Buffer *buffer, Request *request, + BufferMemory *mem) +{ + buffer->request_ = request; + buffer->mem_ = mem; +} + /** * \brief Slot for the MediaDevice disconnected signal */ From patchwork Wed Aug 28 01:17:01 2019 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: 1869 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 44D5D60C42 for ; Wed, 28 Aug 2019 03:17:41 +0200 (CEST) X-Halon-ID: 979ada08-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 979ada08-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:25 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:01 +0200 Message-Id: <20190828011710.32128-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 04/13] libcamera: pipeline: Add initialization hook for CameraData X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:41 -0000 Add a hook so CameraData can be initialized before a camera is exposed to an application but after all resources and possibly an IPA have been found. Signed-off-by: Niklas Söderlund --- src/libcamera/include/pipeline_handler.h | 2 ++ src/libcamera/pipeline_handler.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index 91d40ef40a465c4e..45f9457879c64363 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -43,6 +43,8 @@ public: } virtual ~CameraData() {} + virtual int initCameraData() { return 0; }; + Camera *camera_; PipelineHandler *pipe_; std::list queuedRequests_; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 766fd496306ece9c..6b3ee0ed8f39676a 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -66,6 +66,12 @@ LOG_DEFINE_CATEGORY(Pipeline) * is needed for the camera both parameters should be set to 0. */ +/** + * \fn CameraData::initCameraData() + * \brief Hook to initialize the camera data + * \return 0 on success or a negative error code otherwise + */ + /** * \var CameraData::camera_ * \brief The camera related to this CameraData instance @@ -462,6 +468,12 @@ void PipelineHandler::registerCamera(std::shared_ptr camera, } data->camera_ = camera.get(); + if (data->initCameraData()) { + LOG(Pipeline, Warning) << "Skipping " << camera->name() + << " initialization camera data failed"; + return; + } + cameraData_[camera.get()] = std::move(data); cameras_.push_back(camera); manager_->addCamera(std::move(camera)); From patchwork Wed Aug 28 01:17:02 2019 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: 1870 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EC5AC60C18 for ; Wed, 28 Aug 2019 03:17:42 +0200 (CEST) X-Halon-ID: 98ad8a65-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 98ad8a65-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:27 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:02 +0200 Message-Id: <20190828011710.32128-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/13] libcamera: controls: Add AeEnable X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:43 -0000 Add a control to turn Auto Exposure on or off. Signed-off-by: Niklas Söderlund --- include/libcamera/control_ids.h | 1 + src/libcamera/controls.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/libcamera/control_ids.h b/include/libcamera/control_ids.h index 75b6a2d5cafeca72..8cd44e571f705ac5 100644 --- a/include/libcamera/control_ids.h +++ b/include/libcamera/control_ids.h @@ -13,6 +13,7 @@ namespace libcamera { enum ControlId { + AeEnable, AwbEnable, Brightness, Contrast, diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 727fdbd9450d2f40..54efef1bb337e945 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -186,6 +186,13 @@ std::string ControlValue::toString() const * \brief Numerical control ID */ +/** + * \var AeEnable + * ControlType: Bool + * + * Enables or disables the AE. See also \a libcamera::ControlId::ManualExposure. + */ + /** * \var AwbEnable * ControlType: Bool From patchwork Wed Aug 28 01:17:03 2019 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: 1871 Return-Path: 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 8A15D60C18 for ; Wed, 28 Aug 2019 03:17:44 +0200 (CEST) X-Halon-ID: 99af6639-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 99af6639-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:28 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:03 +0200 Message-Id: <20190828011710.32128-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/13] libcamera: controls: Allow read only access to control values X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:44 -0000 Allow the control values in a ControlList to be examined from a const environment. Signed-off-by: Niklas Söderlund --- include/libcamera/controls.h | 1 + src/libcamera/controls.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index fbb3a62274c64259..eee5ef87b8fd2633 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -124,6 +124,7 @@ public: void clear() { controls_.clear(); } ControlValue &operator[](ControlId id); + const ControlValue &operator[](ControlId id) const; ControlValue &operator[](const ControlInfo *info) { return controls_[info]; } void update(const ControlList &list); diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 54efef1bb337e945..424fe515fa69f8d8 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -517,6 +517,40 @@ ControlValue &ControlList::operator[](ControlId id) return controls_[&iter->second]; } +/** + * \brief Access a control specified by \a id + * \param[in] id The control ID + * + * This method returns a reference to the control identified by \a id, if it + * exsists or an empty control if it does not. + * + * The behaviour is undefined if the control \a id is not supported by the + * camera that the ControlList refers to. + * + * \return A reference to the value of the control identified by \a id + */ +const ControlValue &ControlList::operator[](ControlId id) const +{ + const ControlInfoMap &controls = camera_->controls(); + static ControlValue empty; + + const auto iter = controls.find(id); + if (iter == controls.end()) { + LOG(Controls, Error) + << "Camera " << camera_->name() + << " does not support control " << id; + return empty; + } + + const auto it = controls_.find(&iter->second); + if (it == controls_.end()) { + LOG(Controls, Error) << "list does not have control " << id; + return empty; + } + + return it->second; +} + /** * \fn ControlList::operator[](const ControlInfo *info) * \brief Access or insert the control specified by \a info From patchwork Wed Aug 28 01:17:04 2019 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: 1872 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2D73460E38 for ; Wed, 28 Aug 2019 03:17:46 +0200 (CEST) X-Halon-ID: 9a8a90d7-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 9a8a90d7-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:30 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:04 +0200 Message-Id: <20190828011710.32128-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/13] libcamera: request: Add RequestData X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:46 -0000 Add a RequestData pointer to the Request class, this is intended to be used by pipeline handlers while handling the request and is invalid outside the pipeline handler context. Signed-off-by: Niklas Söderlund --- include/libcamera/request.h | 5 +++++ src/libcamera/request.cpp | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 9edf1cedc054014f..570924c5ef5e2425 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -21,6 +21,9 @@ class Buffer; class Camera; class Stream; +class RequestData +{ +}; class Request { @@ -46,6 +49,8 @@ public: bool hasPendingBuffers() const { return !pending_.empty(); } + RequestData *data; + private: friend class Camera; friend class PipelineHandler; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index ee2158fc7a9cf0b9..4d7bf177534267ac 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -55,7 +55,7 @@ LOG_DEFINE_CATEGORY(Request) * */ Request::Request(Camera *camera, uint64_t cookie) - : camera_(camera), controls_(camera), cookie_(cookie), + : data(nullptr), camera_(camera), controls_(camera), cookie_(cookie), status_(RequestPending), cancelled_(false) { } @@ -178,6 +178,14 @@ Buffer *Request::findBuffer(Stream *stream) const * otherwise */ +/** + * \var Request::data + * \brief Pipeline handler specific data + * + * Pipeline handlers may associate private data with with an request that + * is valid for the requests liftime inside the pipeline handler. + */ + /** * \brief Validate the request and prepare it for the completion handler * From patchwork Wed Aug 28 01:17:05 2019 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: 1873 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BF94C6192E for ; Wed, 28 Aug 2019 03:17:46 +0200 (CEST) X-Halon-ID: 9b744c35-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 9b744c35-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:31 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:05 +0200 Message-Id: <20190828011710.32128-9-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/13] libcamera: request: Allow read only access to controls X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:47 -0000 Allow the controls in a Request to be examined from a const environment. Signed-off-by: Niklas Söderlund --- include/libcamera/request.h | 1 + src/libcamera/request.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 570924c5ef5e2425..f5de5257bba3f2bb 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -40,6 +40,7 @@ public: ~Request(); ControlList &controls() { return controls_; } + const ControlList &controls() const { return controls_; } const std::map &buffers() const { return bufferMap_; } int addBuffer(std::unique_ptr buffer); Buffer *findBuffer(Stream *stream) const; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 4d7bf177534267ac..79e456db1b7dd282 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -84,6 +84,11 @@ Request::~Request() * \return A reference to the ControlList in this request */ +/** + * \fn Request::controls() const + * \sa Request::controls() + */ + /** * \fn Request::buffers() * \brief Retrieve the request's streams to buffers map From patchwork Wed Aug 28 01:17:06 2019 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: 1874 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6213760C10 for ; Wed, 28 Aug 2019 03:17:48 +0200 (CEST) X-Halon-ID: 9c5e0b87-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 9c5e0b87-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:33 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:06 +0200 Message-Id: <20190828011710.32128-10-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/13] libcamera: ipa: meson: Allow access to internal libcamera headers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:48 -0000 Allow IPA implementations to use internal libcamera headers so they can utilize helpers not exposed to applications. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- src/ipa/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipa/meson.build b/src/ipa/meson.build index 2b9863bce3eabe80..dca7a9461385b68d 100644 --- a/src/ipa/meson.build +++ b/src/ipa/meson.build @@ -9,7 +9,7 @@ foreach t : ipa_dummy_sources ipa = shared_module(t[0], t[1], name_prefix : '', - include_directories : libcamera_includes, + include_directories : includes, install : true, install_dir : ipa_install_dir) endforeach From patchwork Wed Aug 28 01:17:07 2019 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: 1875 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 09B7E60C42 for ; Wed, 28 Aug 2019 03:17:50 +0200 (CEST) X-Halon-ID: 9d08ec28-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 9d08ec28-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:34 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:07 +0200 Message-Id: <20190828011710.32128-11-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/13] libcamera: ipa: Extend to support IPA interactions X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:51 -0000 The IPA interface needs to support interactions with the pipeline, add interfaces to control the sensor and handling of request ISP parameters and statistics. The interface needs to be extended further to support attaching the result of the statistic analyses to the request before the request completes to the user. It also needs to modified to allow proper per frame control of capture parameters. Signed-off-by: Niklas Söderlund --- include/libcamera/ipa/ipa_interface.h | 17 +++++- src/ipa/ipa_dummy.cpp | 11 ++-- src/ipa/ipa_dummy_isolate.cpp | 11 ++-- src/libcamera/ipa_interface.cpp | 72 ++++++++++++++++++++++++- src/libcamera/proxy/ipa_proxy_linux.cpp | 12 ++--- 5 files changed, 98 insertions(+), 25 deletions(-) diff --git a/include/libcamera/ipa/ipa_interface.h b/include/libcamera/ipa/ipa_interface.h index 2c5eb1fd524311cb..38e16ff37214f7b9 100644 --- a/include/libcamera/ipa/ipa_interface.h +++ b/include/libcamera/ipa/ipa_interface.h @@ -7,14 +7,29 @@ #ifndef __LIBCAMERA_IPA_INTERFACE_H__ #define __LIBCAMERA_IPA_INTERFACE_H__ +#include +#include + +#include "v4l2_controls.h" + namespace libcamera { +class Buffer; +class Request; + class IPAInterface { public: virtual ~IPAInterface() {} - virtual int init() = 0; + virtual int initSensor(const V4L2ControlInfoMap &controls) = 0; + virtual void processRequest(const void *cookie, + const ControlList &controls, + Buffer ¶meters) = 0; + virtual void updateStatistics(const void *cookie, Buffer &statistics) = 0; + + Signal updateSensor; + Signal queueRequest; }; } /* namespace libcamera */ diff --git a/src/ipa/ipa_dummy.cpp b/src/ipa/ipa_dummy.cpp index b0e944a17fc5cffb..11dcc54ce4ebc6f4 100644 --- a/src/ipa/ipa_dummy.cpp +++ b/src/ipa/ipa_dummy.cpp @@ -15,15 +15,12 @@ namespace libcamera { class IPADummy : public IPAInterface { public: - int init(); + int initSensor(const V4L2ControlInfoMap &controls) { return 0; } + void processRequest(const void *cookie, const ControlList &controls, + Buffer ¶meters) {} + void updateStatistics(const void *cookie, Buffer &statistics) {} }; -int IPADummy::init() -{ - std::cout << "initializing dummy IPA!" << std::endl; - return 0; -} - /* * External IPA module interface */ diff --git a/src/ipa/ipa_dummy_isolate.cpp b/src/ipa/ipa_dummy_isolate.cpp index 24434e85d31809e2..4d49c0e372466af6 100644 --- a/src/ipa/ipa_dummy_isolate.cpp +++ b/src/ipa/ipa_dummy_isolate.cpp @@ -16,15 +16,12 @@ namespace libcamera { class IPADummyIsolate : public IPAInterface { public: - int init(); + int initSensor(const V4L2ControlInfoMap &controls) { return 0; } + void processRequest(const void *cookie, const ControlList &controls, + Buffer ¶meters) {} + void updateStatistics(const void *cookie, Buffer &statistics) {} }; -int IPADummyIsolate::init() -{ - std::cout << "initializing isolated dummy IPA!" << std::endl; - return 0; -} - /* * External IPA module interface */ diff --git a/src/libcamera/ipa_interface.cpp b/src/libcamera/ipa_interface.cpp index 9d30da29228fabb7..4edcebbe84d5a0d0 100644 --- a/src/libcamera/ipa_interface.cpp +++ b/src/libcamera/ipa_interface.cpp @@ -20,8 +20,76 @@ namespace libcamera { */ /** - * \fn IPAInterface::init() - * \brief Initialise the IPAInterface + * \fn IPAInterface::initSensor() + * \brief Initialize the IPA sensor settings + * \param[in] controls List of controls provided by the sensor + * + * This function is called when a pipeline attaches to an IPA to inform the IPA + * of the controls and limits the sensor in the video pipeline supports. The IPA + * have the option to set controls of the sensor by emitting the updateSensor + * signal. + * + * \return 0 on success or a negative error code otherwise + */ + +/** + * \fn IPAInterface::processRequest() + * \brief Provide IPA with a parameter buffer to fill + * \param[in] cookie Cookie for the request + * \param[in] controls List of controls associated with the request + * \param[in,out] parameters Buffer containing an empty parameters buffer + * + * This function is called by a pipeline handler when it has a request to + * process. The IPA shall fill in the \a parameters buffer to achieve the + * capture result described in \a controls. The \a cookie value identifiers + * the request the controls and parameters buffer corresponds to and can be + * matched in updateStatistics() once the request have been processed by the + * hardware. The cookie value is only valid from that processRequest() is + * called and until updateStatistics() return. + * + * When the \a parameters buffer is filled in and ready to be queued to hardware + * the IPA shall signal pipeline handler using the queueRequest signal with the + * cookie value corresponding to the request the parameters belong to. + */ + +/** + * \fn IPAInterface::updateStatistics() + * \brief Provide IPA with statistic buffer to examine + * \param[in] cookie Cookie for the request + * \param[in] statistics Buffer containing a filled in statistic buffer + * + * This function is called once a statistic buffer is completed and have been + * dequeue. The IPA may inspect the buffer and update its internal view of the + * capture conditions. The \a cookie value can be used to associate the dequeued + * statistics buffer with the parameters buffer filled in by the IPA in + * processRequest(). + * + * \todo Extend this function to return or signal the result of the statistic + * examination by the IPA. + */ + +/** + * \var IPAInterface::updateSensor + * \brief Signal emitted when the IPA wish to update sensor V4L2 controls + * + * This signal is emitted when the IPA wish to update one or more V4L2 control + * of the sensor in the video pipeline. The list of controls to modify is passed + * as a parameter. + * + * \todo Extend this function to work with per-frame control setting of + * controls. + */ + +/** + * \var IPAInterface::queueRequest + * \brief Signal emitted when the IPA is done preparing a request + * + * This signal is emitted then the IPA have finished filling in the parameters + * buffer and is ready for the request to be committed to hardware for capture. + * The request cookie is passed as a parameter. + * + * \todo Extend this function to work with per-frame control setting of + * controls. */ } /* namespace libcamera */ diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp index f881aab5b2e1178a..bb7aeedf12779c66 100644 --- a/src/libcamera/proxy/ipa_proxy_linux.cpp +++ b/src/libcamera/proxy/ipa_proxy_linux.cpp @@ -26,7 +26,10 @@ public: IPAProxyLinux(IPAModule *ipam); ~IPAProxyLinux(); - int init(); + int initSensor(const V4L2ControlInfoMap &controls) { return 0; } + void processRequest(const void *cookie, const ControlList &controls, + Buffer ¶meters) {} + void updateStatistics(const void *cookie, Buffer &statistics) {} private: void readyRead(IPCUnixSocket *ipc); @@ -36,13 +39,6 @@ private: IPCUnixSocket *socket_; }; -int IPAProxyLinux::init() -{ - LOG(IPAProxy, Debug) << "initializing IPA via dummy proxy!"; - - return 0; -} - IPAProxyLinux::IPAProxyLinux(IPAModule *ipam) { LOG(IPAProxy, Debug) From patchwork Wed Aug 28 01:17:08 2019 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: 1876 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A27EF6157F for ; Wed, 28 Aug 2019 03:17:53 +0200 (CEST) X-Halon-ID: 9e52835a-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 9e52835a-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:36 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:08 +0200 Message-Id: <20190828011710.32128-12-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 11/13] include: linux: Add rkisp1-config.h kernel header X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:54 -0000 Add kernel header for Rockchip ISP1 from the rkisp1 patch set. As the driver is currently out of tree, the header file is not exported as part of the standard kernel uAPI. Signed-off-by: Niklas Söderlund Acked-by: Kieran Bingham --- include/linux/rkisp1-config.h | 798 ++++++++++++++++++++++++++++++++++ include/linux/videodev2.h | 4 + 2 files changed, 802 insertions(+) create mode 100644 include/linux/rkisp1-config.h diff --git a/include/linux/rkisp1-config.h b/include/linux/rkisp1-config.h new file mode 100644 index 0000000000000000..53748672dfea4dcb --- /dev/null +++ b/include/linux/rkisp1-config.h @@ -0,0 +1,798 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Rockchip isp1 driver + * Copyright (C) 2017 Rockchip Electronics Co., Ltd. + */ + +/* + * References: + * REF_01 - ISP_user_manual, Rev 2.57 + */ + +#ifndef _RKISP1_CONFIG_H +#define _RKISP1_CONFIG_H + +#include +#include + +#define CIFISP_MODULE_DPCC (1 << 0) +#define CIFISP_MODULE_BLS (1 << 1) +#define CIFISP_MODULE_SDG (1 << 2) +#define CIFISP_MODULE_HST (1 << 3) +#define CIFISP_MODULE_LSC (1 << 4) +#define CIFISP_MODULE_AWB_GAIN (1 << 5) +#define CIFISP_MODULE_FLT (1 << 6) +#define CIFISP_MODULE_BDM (1 << 7) +#define CIFISP_MODULE_CTK (1 << 8) +#define CIFISP_MODULE_GOC (1 << 9) +#define CIFISP_MODULE_CPROC (1 << 10) +#define CIFISP_MODULE_AFC (1 << 11) +#define CIFISP_MODULE_AWB (1 << 12) +#define CIFISP_MODULE_IE (1 << 13) +#define CIFISP_MODULE_AEC (1 << 14) +#define CIFISP_MODULE_WDR (1 << 15) +#define CIFISP_MODULE_DPF (1 << 16) +#define CIFISP_MODULE_DPF_STRENGTH (1 << 17) + +#define CIFISP_CTK_COEFF_MAX 0x100 +#define CIFISP_CTK_OFFSET_MAX 0x800 + +#define CIFISP_AE_MEAN_MAX 25 +#define CIFISP_HIST_BIN_N_MAX 16 +#define CIFISP_AFM_MAX_WINDOWS 3 +#define CIFISP_DEGAMMA_CURVE_SIZE 17 + +#define CIFISP_BDM_MAX_TH 0xFF + +/* + * Black level compensation + */ +/* maximum value for horizontal start address */ +#define CIFISP_BLS_START_H_MAX 0x00000FFF +/* maximum value for horizontal stop address */ +#define CIFISP_BLS_STOP_H_MAX 0x00000FFF +/* maximum value for vertical start address */ +#define CIFISP_BLS_START_V_MAX 0x00000FFF +/* maximum value for vertical stop address */ +#define CIFISP_BLS_STOP_V_MAX 0x00000FFF +/* maximum is 2^18 = 262144*/ +#define CIFISP_BLS_SAMPLES_MAX 0x00000012 +/* maximum value for fixed black level */ +#define CIFISP_BLS_FIX_SUB_MAX 0x00000FFF +/* minimum value for fixed black level */ +#define CIFISP_BLS_FIX_SUB_MIN 0xFFFFF000 +/* 13 bit range (signed)*/ +#define CIFISP_BLS_FIX_MASK 0x00001FFF + +/* + * Automatic white balance measurments + */ +#define CIFISP_AWB_MAX_GRID 1 +#define CIFISP_AWB_MAX_FRAMES 7 + +/* + * Gamma out + */ +/* Maximum number of color samples supported */ +#define CIFISP_GAMMA_OUT_MAX_SAMPLES 17 + +/* + * Lens shade correction + */ +#define CIFISP_LSC_GRAD_TBL_SIZE 8 +#define CIFISP_LSC_SIZE_TBL_SIZE 8 +/* + * The following matches the tuning process, + * not the max capabilities of the chip. + * Last value unused. + */ +#define CIFISP_LSC_DATA_TBL_SIZE 290 + +/* + * Histogram calculation + */ +/* Last 3 values unused. */ +#define CIFISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 28 + +/* + * Defect Pixel Cluster Correction + */ +#define CIFISP_DPCC_METHODS_MAX 3 + +/* + * Denoising pre filter + */ +#define CIFISP_DPF_MAX_NLF_COEFFS 17 +#define CIFISP_DPF_MAX_SPATIAL_COEFFS 6 + +/* + * Measurement types + */ +#define CIFISP_STAT_AWB (1 << 0) +#define CIFISP_STAT_AUTOEXP (1 << 1) +#define CIFISP_STAT_AFM_FIN (1 << 2) +#define CIFISP_STAT_HIST (1 << 3) + +enum cifisp_histogram_mode { + CIFISP_HISTOGRAM_MODE_DISABLE, + CIFISP_HISTOGRAM_MODE_RGB_COMBINED, + CIFISP_HISTOGRAM_MODE_R_HISTOGRAM, + CIFISP_HISTOGRAM_MODE_G_HISTOGRAM, + CIFISP_HISTOGRAM_MODE_B_HISTOGRAM, + CIFISP_HISTOGRAM_MODE_Y_HISTOGRAM +}; + +enum cifisp_awb_mode_type { + CIFISP_AWB_MODE_MANUAL, + CIFISP_AWB_MODE_RGB, + CIFISP_AWB_MODE_YCBCR +}; + +enum cifisp_flt_mode { + CIFISP_FLT_STATIC_MODE, + CIFISP_FLT_DYNAMIC_MODE +}; + +/** + * enum cifisp_exp_ctrl_autostop - stop modes + * @CIFISP_EXP_CTRL_AUTOSTOP_0: continuous measurement + * @CIFISP_EXP_CTRL_AUTOSTOP_1: stop measuring after a complete frame + */ +enum cifisp_exp_ctrl_autostop { + CIFISP_EXP_CTRL_AUTOSTOP_0 = 0, + CIFISP_EXP_CTRL_AUTOSTOP_1 = 1, +}; + +/** + * enum cifisp_exp_meas_mode - Exposure measure mode + * @CIFISP_EXP_MEASURING_MODE_0: Y = 16 + 0.25R + 0.5G + 0.1094B + * @CIFISP_EXP_MEASURING_MODE_1: Y = (R + G + B) x (85/256) + */ +enum cifisp_exp_meas_mode { + CIFISP_EXP_MEASURING_MODE_0, + CIFISP_EXP_MEASURING_MODE_1, +}; + +/*---------- PART1: Input Parameters ------------*/ + +struct cifisp_window { + __u16 h_offs; + __u16 v_offs; + __u16 h_size; + __u16 v_size; +} __attribute__ ((packed)); + +/** + * struct cifisp_bls_fixed_val - BLS fixed subtraction values + * + * The values will be subtracted from the sensor + * values. Therefore a negative value means addition instead of subtraction! + * + * @r: Fixed (signed!) subtraction value for Bayer pattern R + * @gr: Fixed (signed!) subtraction value for Bayer pattern Gr + * @gb: Fixed (signed!) subtraction value for Bayer pattern Gb + * @b: Fixed (signed!) subtraction value for Bayer pattern B + */ +struct cifisp_bls_fixed_val { + __s16 r; + __s16 gr; + __s16 gb; + __s16 b; +} __attribute__ ((packed)); + +/** + * struct cifisp_bls_config - Configuration used by black level subtraction + * + * @enable_auto: Automatic mode activated means that the measured values + * are subtracted. Otherwise the fixed subtraction + * values will be subtracted. + * @en_windows: enabled window + * @bls_window1: Measurement window 1 size + * @bls_window2: Measurement window 2 size + * @bls_samples: Set amount of measured pixels for each Bayer position + * (A, B,C and D) to 2^bls_samples. + * @cifisp_bls_fixed_val: Fixed subtraction values + */ +struct cifisp_bls_config { + __u8 enable_auto; + __u8 en_windows; + struct cifisp_window bls_window1; + struct cifisp_window bls_window2; + __u8 bls_samples; + struct cifisp_bls_fixed_val fixed_val; +} __attribute__ ((packed)); + +/** + * struct cifisp_dpcc_methods_config - Methods Configuration used by Defect Pixel Cluster Correction + * + * @method: Method enable bits + * @line_thresh: Line threshold + * @line_mad_fac: Line MAD factor + * @pg_fac: Peak gradient factor + * @rnd_thresh: Rank Neighbor Difference threshold + * @rg_fac: Rank gradient factor + */ +struct cifisp_dpcc_methods_config { + __u32 method; + __u32 line_thresh; + __u32 line_mad_fac; + __u32 pg_fac; + __u32 rnd_thresh; + __u32 rg_fac; +} __attribute__ ((packed)); + +/** + * struct cifisp_dpcc_methods_config - Configuration used by Defect Pixel Cluster Correction + * + * @mode: dpcc output mode + * @output_mode: whether use hard coded methods + * @set_use: stage1 methods set + * @methods: methods config + * @ro_limits: rank order limits + * @rnd_offs: differential rank offsets for rank neighbor difference + */ +struct cifisp_dpcc_config { + __u32 mode; + __u32 output_mode; + __u32 set_use; + struct cifisp_dpcc_methods_config methods[CIFISP_DPCC_METHODS_MAX]; + __u32 ro_limits; + __u32 rnd_offs; +} __attribute__ ((packed)); + +struct cifisp_gamma_corr_curve { + __u16 gamma_y[CIFISP_DEGAMMA_CURVE_SIZE]; +} __attribute__ ((packed)); + +struct cifisp_gamma_curve_x_axis_pnts { + __u32 gamma_dx0; + __u32 gamma_dx1; +} __attribute__ ((packed)); + +/** + * struct cifisp_gamma_corr_curve - Configuration used by sensor degamma + * + * @curve_x: gamma curve point definition axis for x + * @xa_pnts: x increments + */ +struct cifisp_sdg_config { + struct cifisp_gamma_corr_curve curve_r; + struct cifisp_gamma_corr_curve curve_g; + struct cifisp_gamma_corr_curve curve_b; + struct cifisp_gamma_curve_x_axis_pnts xa_pnts; +} __attribute__ ((packed)); + +/** + * struct cifisp_lsc_config - Configuration used by Lens shading correction + * + * refer to REF_01 for details + */ +struct cifisp_lsc_config { + __u32 r_data_tbl[CIFISP_LSC_DATA_TBL_SIZE]; + __u32 gr_data_tbl[CIFISP_LSC_DATA_TBL_SIZE]; + __u32 gb_data_tbl[CIFISP_LSC_DATA_TBL_SIZE]; + __u32 b_data_tbl[CIFISP_LSC_DATA_TBL_SIZE]; + + __u32 x_grad_tbl[CIFISP_LSC_GRAD_TBL_SIZE]; + __u32 y_grad_tbl[CIFISP_LSC_GRAD_TBL_SIZE]; + + __u32 x_size_tbl[CIFISP_LSC_SIZE_TBL_SIZE]; + __u32 y_size_tbl[CIFISP_LSC_SIZE_TBL_SIZE]; + __u16 config_width; + __u16 config_height; +} __attribute__ ((packed)); + +/** + * struct cifisp_ie_config - Configuration used by image effects + * + * @eff_mat_1: 3x3 Matrix Coefficients for Emboss Effect 1 + * @eff_mat_2: 3x3 Matrix Coefficients for Emboss Effect 2 + * @eff_mat_3: 3x3 Matrix Coefficients for Emboss 3/Sketch 1 + * @eff_mat_4: 3x3 Matrix Coefficients for Sketch Effect 2 + * @eff_mat_5: 3x3 Matrix Coefficients for Sketch Effect 3 + * @eff_tint: Chrominance increment values of tint (used for sepia effect) + */ +struct cifisp_ie_config { + __u16 effect; + __u16 color_sel; + __u16 eff_mat_1; + __u16 eff_mat_2; + __u16 eff_mat_3; + __u16 eff_mat_4; + __u16 eff_mat_5; + __u16 eff_tint; +} __attribute__ ((packed)); + +/** + * struct cifisp_cproc_config - Configuration used by Color Processing + * + * @c_out_range: Chrominance pixel clipping range at output. (0 for limit, 1 for full) + * @y_in_range: Luminance pixel clipping range at output. + * @y_out_range: Luminance pixel clipping range at output. + * @contrast: 00~ff, 0.0~1.992 + * @brightness: 80~7F, -128~+127 + * @sat: saturation, 00~FF, 0.0~1.992 + * @hue: 80~7F, -90~+87.188 + */ +struct cifisp_cproc_config { + __u8 c_out_range; + __u8 y_in_range; + __u8 y_out_range; + __u8 contrast; + __u8 brightness; + __u8 sat; + __u8 hue; +} __attribute__ ((packed)); + +/** + * struct cifisp_awb_meas_config - Configuration used by auto white balance + * + * @awb_wnd: white balance measurement window (in pixels) (from enum cifisp_awb_mode_type) + * @max_y: only pixels values < max_y contribute to awb measurement, set to 0 to disable this feature + * @min_y: only pixels values > min_y contribute to awb measurement + * @max_csum: Chrominance sum maximum value, only consider pixels with Cb+Cr, + * smaller than threshold for awb measurements + * @min_c: Chrominance minimum value, only consider pixels with Cb/Cr + * each greater than threshold value for awb measurements + * @frames: number of frames - 1 used for mean value calculation (ucFrames=0 means 1 Frame) + * @awb_ref_cr: reference Cr value for AWB regulation, target for AWB + * @awb_ref_cb: reference Cb value for AWB regulation, target for AWB + */ +struct cifisp_awb_meas_config { + /* + * Note: currently the h and v offsets are mapped to grid offsets + */ + struct cifisp_window awb_wnd; + __u32 awb_mode; + __u8 max_y; + __u8 min_y; + __u8 max_csum; + __u8 min_c; + __u8 frames; + __u8 awb_ref_cr; + __u8 awb_ref_cb; + __u8 enable_ymax_cmp; +} __attribute__ ((packed)); + +/** + * struct cifisp_awb_gain_config - Configuration used by auto white balance gain + * + * out_data_x = ( AWB_GEAIN_X * in_data + 128) >> 8 + */ +struct cifisp_awb_gain_config { + __u16 gain_red; + __u16 gain_green_r; + __u16 gain_blue; + __u16 gain_green_b; +} __attribute__ ((packed)); + +/** + * struct cifisp_flt_config - Configuration used by ISP filtering + * + * @mode: ISP_FILT_MODE register fields (from enum cifisp_flt_mode) + * @grn_stage1: ISP_FILT_MODE register fields + * @chr_h_mode: ISP_FILT_MODE register fields + * @chr_v_mode: ISP_FILT_MODE register fields + * + * refer to REF_01 for details. + */ + +struct cifisp_flt_config { + __u32 mode; + __u8 grn_stage1; + __u8 chr_h_mode; + __u8 chr_v_mode; + __u32 thresh_bl0; + __u32 thresh_bl1; + __u32 thresh_sh0; + __u32 thresh_sh1; + __u32 lum_weight; + __u32 fac_sh1; + __u32 fac_sh0; + __u32 fac_mid; + __u32 fac_bl0; + __u32 fac_bl1; +} __attribute__ ((packed)); + +/** + * struct cifisp_bdm_config - Configuration used by Bayer DeMosaic + * + * @demosaic_th: threshod for bayer demosaicing texture detection + */ +struct cifisp_bdm_config { + __u8 demosaic_th; +} __attribute__ ((packed)); + +/** + * struct cifisp_ctk_config - Configuration used by Cross Talk correction + * + * @coeff: color correction matrix + * @ct_offset_b: offset for the crosstalk correction matrix + */ +struct cifisp_ctk_config { + __u16 coeff0; + __u16 coeff1; + __u16 coeff2; + __u16 coeff3; + __u16 coeff4; + __u16 coeff5; + __u16 coeff6; + __u16 coeff7; + __u16 coeff8; + __u16 ct_offset_r; + __u16 ct_offset_g; + __u16 ct_offset_b; +} __attribute__ ((packed)); + +enum cifisp_goc_mode { + CIFISP_GOC_MODE_LOGARITHMIC, + CIFISP_GOC_MODE_EQUIDISTANT +}; + +/** + * struct cifisp_goc_config - Configuration used by Gamma Out correction + * + * @mode: goc mode (from enum cifisp_goc_mode) + * @gamma_y: gamma out curve y-axis for all color components + */ +struct cifisp_goc_config { + __u32 mode; + __u16 gamma_y[CIFISP_GAMMA_OUT_MAX_SAMPLES]; +} __attribute__ ((packed)); + +/** + * struct cifisp_hst_config - Configuration used by Histogram + * + * @mode: histogram mode (from enum cifisp_histogram_mode) + * @histogram_predivider: process every stepsize pixel, all other pixels are skipped + * @meas_window: coordinates of the measure window + * @hist_weight: weighting factor for sub-windows + */ +struct cifisp_hst_config { + __u32 mode; + __u8 histogram_predivider; + struct cifisp_window meas_window; + __u8 hist_weight[CIFISP_HISTOGRAM_WEIGHT_GRIDS_SIZE]; +} __attribute__ ((packed)); + +/** + * struct cifisp_aec_config - Configuration used by Auto Exposure Control + * + * @mode: Exposure measure mode (from enum cifisp_exp_meas_mode) + * @autostop: stop mode (from enum cifisp_exp_ctrl_autostop) + * @meas_window: coordinates of the measure window + */ +struct cifisp_aec_config { + __u32 mode; + __u32 autostop; + struct cifisp_window meas_window; +} __attribute__ ((packed)); + +/** + * struct cifisp_afc_config - Configuration used by Auto Focus Control + * + * @num_afm_win: max CIFISP_AFM_MAX_WINDOWS + * @afm_win: coordinates of the meas window + * @thres: threshold used for minimizing the influence of noise + * @var_shift: the number of bits for the shift operation at the end of the calculation chain. + */ +struct cifisp_afc_config { + __u8 num_afm_win; + struct cifisp_window afm_win[CIFISP_AFM_MAX_WINDOWS]; + __u32 thres; + __u32 var_shift; +} __attribute__ ((packed)); + +/** + * enum cifisp_dpf_gain_usage - dpf gain usage + * @CIFISP_DPF_GAIN_USAGE_DISABLED: don't use any gains in preprocessing stage + * @CIFISP_DPF_GAIN_USAGE_NF_GAINS: use only the noise function gains from registers DPF_NF_GAIN_R, ... + * @CIFISP_DPF_GAIN_USAGE_LSC_GAINS: use only the gains from LSC module + * @CIFISP_DPF_GAIN_USAGE_NF_LSC_GAINS: use the noise function gains and the gains from LSC module + * @CIFISP_DPF_GAIN_USAGE_AWB_GAINS: use only the gains from AWB module + * @CIFISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: use the gains from AWB and LSC module + * @CIFISP_DPF_GAIN_USAGE_MAX: upper border (only for an internal evaluation) + */ +enum cifisp_dpf_gain_usage { + CIFISP_DPF_GAIN_USAGE_DISABLED, + CIFISP_DPF_GAIN_USAGE_NF_GAINS, + CIFISP_DPF_GAIN_USAGE_LSC_GAINS, + CIFISP_DPF_GAIN_USAGE_NF_LSC_GAINS, + CIFISP_DPF_GAIN_USAGE_AWB_GAINS, + CIFISP_DPF_GAIN_USAGE_AWB_LSC_GAINS, + CIFISP_DPF_GAIN_USAGE_MAX +}; + +/** + * enum cifisp_dpf_gain_usage - dpf gain usage + * @CIFISP_DPF_RB_FILTERSIZE_13x9: red and blue filter kernel size 13x9 (means 7x5 active pixel) + * @CIFISP_DPF_RB_FILTERSIZE_9x9: red and blue filter kernel size 9x9 (means 5x5 active pixel) + */ +enum cifisp_dpf_rb_filtersize { + CIFISP_DPF_RB_FILTERSIZE_13x9, + CIFISP_DPF_RB_FILTERSIZE_9x9, +}; + +/** + * enum cifisp_dpf_nll_scale_mode - dpf noise level scale mode + * @CIFISP_NLL_SCALE_LINEAR: use a linear scaling + * @CIFISP_NLL_SCALE_LOGARITHMIC: use a logarithmic scaling + */ +enum cifisp_dpf_nll_scale_mode { + CIFISP_NLL_SCALE_LINEAR, + CIFISP_NLL_SCALE_LOGARITHMIC, +}; + +/** + * struct cifisp_dpf_nll - Noise level lookup + * + * @coeff: Noise level Lookup coefficient + * @scale_mode: dpf noise level scale mode (from enum cifisp_dpf_nll_scale_mode) + */ +struct cifisp_dpf_nll { + __u16 coeff[CIFISP_DPF_MAX_NLF_COEFFS]; + __u32 scale_mode; +} __attribute__ ((packed)); + +/** + * struct cifisp_dpf_rb_flt - Red blue filter config + * + * @fltsize: The filter size for the red and blue pixels + * (from enum cifisp_dpf_rb_filtersize) + * @spatial_coeff: Spatial weights + * @r_enable: enable filter processing for red pixels + * @b_enable: enable filter processing for blue pixels + */ +struct cifisp_dpf_rb_flt { + __u32 fltsize; + __u8 spatial_coeff[CIFISP_DPF_MAX_SPATIAL_COEFFS]; + __u8 r_enable; + __u8 b_enable; +} __attribute__ ((packed)); + +/** + * struct cifisp_dpf_g_flt - Green filter Configuration + * + * @spatial_coeff: Spatial weights + * @gr_enable: enable filter processing for green pixels in green/red lines + * @gb_enable: enable filter processing for green pixels in green/blue lines + */ +struct cifisp_dpf_g_flt { + __u8 spatial_coeff[CIFISP_DPF_MAX_SPATIAL_COEFFS]; + __u8 gr_enable; + __u8 gb_enable; +} __attribute__ ((packed)); + +/** + * struct cifisp_dpf_gain - Noise function Configuration + * + * @mode: dpf gain usage (from enum cifisp_dpf_gain_usage) + * @nf_r_gain: Noise function Gain that replaces the AWB gain for red pixels + * @nf_b_gain: Noise function Gain that replaces the AWB gain for blue pixels + * @nf_gr_gain: Noise function Gain that replaces the AWB gain + * for green pixels in a red line + * @nf_gb_gain: Noise function Gain that replaces the AWB gain + * for green pixels in a blue line + */ +struct cifisp_dpf_gain { + __u32 mode; + __u16 nf_r_gain; + __u16 nf_b_gain; + __u16 nf_gr_gain; + __u16 nf_gb_gain; +} __attribute__ ((packed)); + +/** + * struct cifisp_dpf_config - Configuration used by De-noising pre-filter + * + * @gain: noise function gain + * @g_flt: green filter config + * @rb_flt: red blue filter config + * @nll: noise level lookup + */ +struct cifisp_dpf_config { + struct cifisp_dpf_gain gain; + struct cifisp_dpf_g_flt g_flt; + struct cifisp_dpf_rb_flt rb_flt; + struct cifisp_dpf_nll nll; +} __attribute__ ((packed)); + +/** + * struct cifisp_dpf_strength_config - strength of the filter + * + * @r: filter strength of the RED filter + * @g: filter strength of the GREEN filter + * @b: filter strength of the BLUE filter + */ +struct cifisp_dpf_strength_config { + __u8 r; + __u8 g; + __u8 b; +} __attribute__ ((packed)); + +/** + * struct cifisp_isp_other_cfg - Parameters for some blocks in rockchip isp1 + * + * @dpcc_config: Defect Pixel Cluster Correction config + * @bls_config: Black Level Subtraction config + * @sdg_config: sensor degamma config + * @lsc_config: Lens Shade config + * @awb_gain_config: Auto White balance gain config + * @flt_config: filter config + * @bdm_config: demosaic config + * @ctk_config: cross talk config + * @goc_config: gamma out config + * @bls_config: black level subtraction config + * @dpf_config: De-noising pre-filter config + * @dpf_strength_config: dpf strength config + * @cproc_config: color process config + * @ie_config: image effects config + */ +struct cifisp_isp_other_cfg { + struct cifisp_dpcc_config dpcc_config; + struct cifisp_bls_config bls_config; + struct cifisp_sdg_config sdg_config; + struct cifisp_lsc_config lsc_config; + struct cifisp_awb_gain_config awb_gain_config; + struct cifisp_flt_config flt_config; + struct cifisp_bdm_config bdm_config; + struct cifisp_ctk_config ctk_config; + struct cifisp_goc_config goc_config; + struct cifisp_dpf_config dpf_config; + struct cifisp_dpf_strength_config dpf_strength_config; + struct cifisp_cproc_config cproc_config; + struct cifisp_ie_config ie_config; +} __attribute__ ((packed)); + +/** + * struct cifisp_isp_meas_cfg - Rockchip ISP1 Measure Parameters + * + * @awb_meas_config: auto white balance config + * @hst_config: histogram config + * @aec_config: auto exposure config + * @afc_config: auto focus config + */ +struct cifisp_isp_meas_cfg { + struct cifisp_awb_meas_config awb_meas_config; + struct cifisp_hst_config hst_config; + struct cifisp_aec_config aec_config; + struct cifisp_afc_config afc_config; +} __attribute__ ((packed)); + +/** + * struct rkisp1_isp_params_cfg - Rockchip ISP1 Input Parameters Meta Data + * + * @module_en_update: mask the enable bits of which module should be updated + * @module_ens: mask the enable value of each module, only update the module + * which correspond bit was set in module_en_update + * @module_cfg_update: mask the config bits of which module should be updated + * @meas: measurement config + * @others: other config + */ +struct rkisp1_isp_params_cfg { + __u32 module_en_update; + __u32 module_ens; + __u32 module_cfg_update; + + struct cifisp_isp_meas_cfg meas; + struct cifisp_isp_other_cfg others; +} __attribute__ ((packed)); + +/*---------- PART2: Measurement Statistics ------------*/ + +/** + * struct cifisp_bls_meas_val - AWB measured values + * + * @cnt: White pixel count, number of "white pixels" found during laster measurement + * @mean_y_or_g: Mean value of Y within window and frames, Green if RGB is selected. + * @mean_cb_or_b: Mean value of Cb within window and frames, Blue if RGB is selected. + * @mean_cr_or_r: Mean value of Cr within window and frames, Red if RGB is selected. + */ +struct cifisp_awb_meas { + __u32 cnt; + __u8 mean_y_or_g; + __u8 mean_cb_or_b; + __u8 mean_cr_or_r; +} __attribute__ ((packed)); + +/** + * struct cifisp_awb_stat - statistics automatic white balance data + * + * @awb_mean: Mean measured data + */ +struct cifisp_awb_stat { + struct cifisp_awb_meas awb_mean[CIFISP_AWB_MAX_GRID]; +} __attribute__ ((packed)); + +/** + * struct cifisp_bls_meas_val - BLS measured values + * + * @meas_r: Mean measured value for Bayer pattern R + * @meas_gr: Mean measured value for Bayer pattern Gr + * @meas_gb: Mean measured value for Bayer pattern Gb + * @meas_b: Mean measured value for Bayer pattern B + */ +struct cifisp_bls_meas_val { + __u16 meas_r; + __u16 meas_gr; + __u16 meas_gb; + __u16 meas_b; +} __attribute__ ((packed)); + +/** + * struct cifisp_ae_stat - statistics auto exposure data + * + * @exp_mean: Mean luminance value of block xx + * @bls_val: BLS measured values + * + * Image is divided into 5x5 blocks. + */ +struct cifisp_ae_stat { + __u8 exp_mean[CIFISP_AE_MEAN_MAX]; + struct cifisp_bls_meas_val bls_val; +} __attribute__ ((packed)); + +/** + * struct cifisp_af_meas_val - AF measured values + * + * @sum: sharpness, refer to REF_01 for definition + * @lum: luminance, refer to REF_01 for definition + */ +struct cifisp_af_meas_val { + __u32 sum; + __u32 lum; +} __attribute__ ((packed)); + +/** + * struct cifisp_af_stat - statistics auto focus data + * + * @window: AF measured value of window x + * + * The module measures the sharpness in 3 windows of selectable size via + * register settings(ISP_AFM_*_A/B/C) + */ +struct cifisp_af_stat { + struct cifisp_af_meas_val window[CIFISP_AFM_MAX_WINDOWS]; +} __attribute__ ((packed)); + +/** + * struct cifisp_hist_stat - statistics histogram data + * + * @hist_bins: measured bin counters + * + * Measurement window divided into 25 sub-windows, set + * with ISP_HIST_XXX + */ +struct cifisp_hist_stat { + __u16 hist_bins[CIFISP_HIST_BIN_N_MAX]; +} __attribute__ ((packed)); + +/** + * struct rkisp1_stat_buffer - Rockchip ISP1 Statistics Data + * + * @cifisp_awb_stat: statistics data for automatic white balance + * @cifisp_ae_stat: statistics data for auto exposure + * @cifisp_af_stat: statistics data for auto focus + * @cifisp_hist_stat: statistics histogram data + */ +struct cifisp_stat { + struct cifisp_awb_stat awb; + struct cifisp_ae_stat ae; + struct cifisp_af_stat af; + struct cifisp_hist_stat hist; +} __attribute__ ((packed)); + +/** + * struct rkisp1_stat_buffer - Rockchip ISP1 Statistics Meta Data + * + * @meas_type: measurement types (CIFISP_STAT_ definitions) + * @frame_id: frame ID for sync + * @params: statistics data + */ +struct rkisp1_stat_buffer { + __u32 meas_type; + __u32 frame_id; + struct cifisp_stat params; +} __attribute__ ((packed)); + +#endif /* _RKISP1_CONFIG_H */ diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 5e739270116d3a21..2639518e2f58c796 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -727,6 +727,10 @@ struct v4l2_pix_format { #define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */ #define V4L2_META_FMT_D4XX v4l2_fourcc('D', '4', 'X', 'X') /* D4XX Payload Header metadata */ +/* Vendor specific - used for IPU3 camera sub-system */ +#define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 params */ +#define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A statistics */ + /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe From patchwork Wed Aug 28 01:17:09 2019 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: 1877 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E0D6661580 for ; Wed, 28 Aug 2019 03:17:54 +0200 (CEST) X-Halon-ID: 9fc85ab8-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 9fc85ab8-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:39 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:09 +0200 Message-Id: <20190828011710.32128-13-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 12/13] libcamera: ipa: rkisp1: Add basic control of auto exposure X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:55 -0000 Add an IPA which controls the exposure time and analog gain for a sensor connected to the rkisp1 pipeline. The IPA supports turning AE on and off but lacks the support to inform the camera of the status of the AE control loop. Signed-off-by: Niklas Söderlund --- src/ipa/ipa_rkisp1.cpp | 165 +++++++++++++++++++++++++++++++++++++++++ src/ipa/meson.build | 1 + 2 files changed, 166 insertions(+) create mode 100644 src/ipa/ipa_rkisp1.cpp diff --git a/src/ipa/ipa_rkisp1.cpp b/src/ipa/ipa_rkisp1.cpp new file mode 100644 index 0000000000000000..950efb244cfe7879 --- /dev/null +++ b/src/ipa/ipa_rkisp1.cpp @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ipa_rkisp1.cpp - RkISP1 Image Processing Algorithms + */ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "log.h" +#include "utils.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(IPARkISP1) + +class IPARkISP1 : public IPAInterface +{ +public: + int initSensor(const V4L2ControlInfoMap &controls) override; + void processRequest(const void *cookie, const ControlList &controls, + Buffer ¶meters) override; + void updateStatistics(const void *cookie, Buffer &statistics) override; + +private: + void setControls(); + + uint64_t statFrame_; + + /* Camera sensor controls. */ + bool autoExposure_; + uint64_t exposure_; + uint64_t minExposure_; + uint64_t maxExposure_; + uint64_t gain_; + uint64_t minGain_; + uint64_t maxGain_; +}; + +int IPARkISP1::initSensor(const V4L2ControlInfoMap &controls) +{ + statFrame_ = 0; + + const auto itExp = controls.find(V4L2_CID_EXPOSURE); + if (itExp == controls.end()) + return -ENODEV; + + const auto itGain = controls.find(V4L2_CID_ANALOGUE_GAIN); + if (itGain == controls.end()) + return -ENODEV; + + autoExposure_ = true; + + minExposure_ = std::max(itExp->second.min(), 1); + maxExposure_ = itExp->second.max(); + exposure_ = minExposure_; + + minGain_ = std::max(itGain->second.min(), 1); + maxGain_ = itGain->second.max(); + gain_ = minGain_; + + LOG(IPARkISP1, Info) + << "Exposure: " << minExposure_ << "-" << maxExposure_ + << " Gain: " << minGain_ << "-" << maxGain_; + + setControls(); + + return 0; +} + +void IPARkISP1::setControls() +{ + V4L2ControlList ctrls; + ctrls.add(V4L2_CID_EXPOSURE); + ctrls.add(V4L2_CID_ANALOGUE_GAIN); + ctrls[V4L2_CID_EXPOSURE]->setValue(exposure_); + ctrls[V4L2_CID_ANALOGUE_GAIN]->setValue(gain_); + + updateSensor.emit(ctrls); +} + +void IPARkISP1::processRequest(const void *cookie, const ControlList &controls, + Buffer ¶meters) +{ + rkisp1_isp_params_cfg *params = + static_cast(parameters.mem()->planes()[0].mem()); + + memset(params, 0, sizeof(*params)); + + /* Auto Exposure on/off*/ + if (controls.contains(AeEnable)) { + autoExposure_ = controls[AeEnable].getBool(); + if (autoExposure_) + params->module_ens = CIFISP_MODULE_AEC; + + params->module_en_update = CIFISP_MODULE_AEC; + } + + queueRequest.emit(cookie); +} + +void IPARkISP1::updateStatistics(const void *cookie, Buffer &statistics) +{ + const rkisp1_stat_buffer *stats = + static_cast(statistics.mem()->planes()[0].mem()); + const cifisp_stat *params = &stats->params; + + if ((stats->meas_type & CIFISP_STAT_AUTOEXP) && (statFrame_ % 2 == 0)) { + const cifisp_ae_stat *ae = ¶ms->ae; + + const unsigned int target = 60; + + unsigned int value = 0; + unsigned int num = 0; + for (int i = 0; i < CIFISP_AE_MEAN_MAX; i++) { + if (ae->exp_mean[i] > 15) { + value += ae->exp_mean[i]; + num++; + } + } + value /= num; + + double factor = (double)target / value; + double tmp; + + tmp = factor * exposure_ * gain_ / minGain_; + exposure_ = utils::clamp((uint64_t)tmp, minExposure_, maxExposure_); + + tmp = tmp / exposure_ * minGain_; + gain_ = utils::clamp((uint64_t)tmp, minGain_, maxGain_); + + setControls(); + } + + statFrame_++; +} + +/* + * External IPA module interface + */ + +extern "C" { +const struct IPAModuleInfo ipaModuleInfo = { + IPA_MODULE_API_VERSION, + 1, + "PipelineHandlerRkISP1", + "RkISP1 IPA", + "LGPL-2.1-or-later", +}; + +IPAInterface *ipaCreate() +{ + return new IPARkISP1(); +} +}; + +}; /* namespace libcamera */ diff --git a/src/ipa/meson.build b/src/ipa/meson.build index dca7a9461385b68d..16592a71e03990ce 100644 --- a/src/ipa/meson.build +++ b/src/ipa/meson.build @@ -1,6 +1,7 @@ ipa_dummy_sources = [ ['ipa_dummy', 'ipa_dummy.cpp'], ['ipa_dummy_isolate', 'ipa_dummy_isolate.cpp'], + ['ipa_rkisp1', 'ipa_rkisp1.cpp'], ] ipa_install_dir = join_paths(get_option('libdir'), 'libcamera') From patchwork Wed Aug 28 01:17:10 2019 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: 1878 Return-Path: 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 81DD860C37 for ; Wed, 28 Aug 2019 03:17:57 +0200 (CEST) X-Halon-ID: a0d1dcf7-c931-11e9-bdc3-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [95.195.154.80]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id a0d1dcf7-c931-11e9-bdc3-005056917a89; Wed, 28 Aug 2019 03:17:41 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 28 Aug 2019 03:17:10 +0200 Message-Id: <20190828011710.32128-14-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.22.1 In-Reply-To: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> References: <20190828011710.32128-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 13/13] libcamera: pipeline: rkisp1: Attach to an IPA X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2019 01:17:57 -0000 Add the plumbing to the pipeline handler to interact with an IPA module. To support this parameter and statistic buffers needs to be associated with every request queued. The parameters buffer needs to be passed to the IPA before any buffer in the request is queued to hardware and the statistics buffer needs to be passed to the IPA for inspection as soon as it's ready. This change makes the usage of an IPA module mandatory for the rkisp1 pipeline. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 263 ++++++++++++++++++++++- 1 file changed, 252 insertions(+), 11 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index de4ab523d0e4fe36..80d4832c49ebe78c 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include @@ -34,7 +34,7 @@ class RkISP1CameraData : public CameraData { public: RkISP1CameraData(PipelineHandler *pipe) - : CameraData(pipe), sensor_(nullptr) + : CameraData(pipe, 1, 1), sensor_(nullptr) { } @@ -43,8 +43,21 @@ public: delete sensor_; } + int initCameraData() override; + Stream stream_; CameraSensor *sensor_; + +private: + void updateSensor(V4L2ControlList controls); + void queueRequestHardware(const void *cookie); +}; + +class RkISP1RequestData : public RequestData +{ +public: + Buffer *stat; + Buffer *param; }; class RkISP1CameraConfiguration : public CameraConfiguration @@ -99,18 +112,69 @@ private: PipelineHandler::cameraData(camera)); } + friend RkISP1CameraData; + int initLinks(); int createCamera(MediaEntity *sensor); + void tryCompleteRequest(Request *request); void bufferReady(Buffer *buffer); + void statReady(Buffer *buffer); + void paramReady(Buffer *buffer); MediaDevice *media_; V4L2Subdevice *dphy_; V4L2Subdevice *isp_; V4L2VideoDevice *video_; + V4L2VideoDevice *stat_; + V4L2VideoDevice *param_; + + BufferPool statPool_; + BufferPool paramPool_; + + std::queue statBuffers_; + std::queue paramBuffers_; Camera *activeCamera_; }; +int RkISP1CameraData::initCameraData() +{ + ipa_->updateSensor.connect(this, + &RkISP1CameraData::updateSensor); + ipa_->queueRequest.connect(this, + &RkISP1CameraData::queueRequestHardware); + return 0; +} + +void RkISP1CameraData::updateSensor(V4L2ControlList controls) +{ + sensor_->setControls(&controls); +} + +void RkISP1CameraData::queueRequestHardware(const void *cookie) +{ + /* Translate cookie to request. */ + Request *request = reinterpret_cast(const_cast(cookie)); + PipelineHandlerRkISP1 *pipe = + static_cast(pipe_); + RkISP1RequestData *reqData = + static_cast(request->data); + Buffer *buffer = request->findBuffer(&stream_); + int ret; + + ret = pipe->param_->queueBuffer(reqData->param); + if (ret < 0) + LOG(RkISP1, Error) << "Failed to queue paramaeters"; + + ret = pipe->stat_->queueBuffer(reqData->stat); + if (ret < 0) + LOG(RkISP1, Error) << "Failed to queue statistics"; + + ret = pipe->video_->queueBuffer(buffer); + if (ret < 0) + LOG(RkISP1, Error) << "Failed to queue video"; +} + RkISP1CameraConfiguration::RkISP1CameraConfiguration(Camera *camera, RkISP1CameraData *data) : CameraConfiguration() @@ -202,12 +266,14 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) : PipelineHandler(manager), dphy_(nullptr), isp_(nullptr), - video_(nullptr) + video_(nullptr), stat_(nullptr), param_(nullptr) { } PipelineHandlerRkISP1::~PipelineHandlerRkISP1() { + delete param_; + delete stat_; delete video_; delete isp_; delete dphy_; @@ -317,6 +383,20 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) if (ret) return ret; + V4L2DeviceFormat statFormat = {}; + statFormat.fourcc = V4L2_META_FMT_RK_ISP1_STAT_3A; + + ret = stat_->setFormat(&statFormat); + if (ret) + return ret; + + V4L2DeviceFormat paramFormat = {}; + paramFormat.fourcc = V4L2_META_FMT_RK_ISP1_PARAMS; + + ret = param_->setFormat(¶mFormat); + if (ret) + return ret; + if (outputFormat.size != cfg.size || outputFormat.fourcc != cfg.pixelFormat) { LOG(RkISP1, Error) @@ -333,30 +413,92 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera, const std::set &streams) { Stream *stream = *streams.begin(); + int ret; if (stream->memoryType() == InternalMemory) - return video_->exportBuffers(&stream->bufferPool()); + ret = video_->exportBuffers(&stream->bufferPool()); else - return video_->importBuffers(&stream->bufferPool()); + ret = video_->importBuffers(&stream->bufferPool()); + + if (ret) + return ret; + + statPool_.createBuffers(stream->configuration().bufferCount); + ret = stat_->exportBuffers(&statPool_); + if (ret) { + video_->releaseBuffers(); + return ret; + } + + paramPool_.createBuffers(stream->configuration().bufferCount); + ret = param_->exportBuffers(¶mPool_); + if (ret) { + stat_->releaseBuffers(); + video_->releaseBuffers(); + return ret; + } + + for (unsigned int i = 0; i < stream->configuration().bufferCount; i++) { + statBuffers_.push(new Buffer(i)); + paramBuffers_.push(new Buffer(i)); + } + + return ret; } int PipelineHandlerRkISP1::freeBuffers(Camera *camera, const std::set &streams) { + while (!paramBuffers_.empty()) + paramBuffers_.pop(); + + while (!statBuffers_.empty()) + statBuffers_.pop(); + + if (param_->releaseBuffers()) + LOG(RkISP1, Error) << "Failed to release parameters buffers"; + + if (stat_->releaseBuffers()) + LOG(RkISP1, Error) << "Failed to release stat buffers"; + if (video_->releaseBuffers()) - LOG(RkISP1, Error) << "Failed to release buffers"; + LOG(RkISP1, Error) << "Failed to release video buffers"; return 0; } int PipelineHandlerRkISP1::start(Camera *camera) { + RkISP1CameraData *data = cameraData(camera); int ret; + ret = data->ipa_->initSensor(data->sensor_->controls()); + if (ret) + return ret; + + ret = param_->streamOn(); + if (ret) { + LOG(RkISP1, Error) + << "Failed to start parameters " << camera->name(); + return ret; + } + + ret = stat_->streamOn(); + if (ret) { + param_->streamOff(); + LOG(RkISP1, Error) + << "Failed to start statisticis " << camera->name(); + return ret; + } + ret = video_->streamOn(); - if (ret) + if (ret) { + param_->streamOff(); + stat_->streamOff(); + LOG(RkISP1, Error) << "Failed to start camera " << camera->name(); + } activeCamera_ = camera; @@ -372,6 +514,16 @@ void PipelineHandlerRkISP1::stop(Camera *camera) LOG(RkISP1, Warning) << "Failed to stop camera " << camera->name(); + ret = stat_->streamOff(); + if (ret) + LOG(RkISP1, Warning) + << "Failed to stop statisticis " << camera->name(); + + ret = param_->streamOff(); + if (ret) + LOG(RkISP1, Warning) + << "Failed to stop parameters " << camera->name(); + activeCamera_ = nullptr; } @@ -380,6 +532,16 @@ int PipelineHandlerRkISP1::queueRequest(Camera *camera, Request *request) RkISP1CameraData *data = cameraData(camera); Stream *stream = &data->stream_; + if (paramBuffers_.empty()) { + LOG(RkISP1, Error) << "Parameters buffer underrun"; + return -ENOENT; + } + + if (statBuffers_.empty()) { + LOG(RkISP1, Error) << "Statisitc buffer underrun"; + return -ENOENT; + } + Buffer *buffer = request->findBuffer(stream); if (!buffer) { LOG(RkISP1, Error) @@ -387,12 +549,24 @@ int PipelineHandlerRkISP1::queueRequest(Camera *camera, Request *request) return -ENOENT; } - int ret = video_->queueBuffer(buffer); - if (ret < 0) - return ret; + RkISP1RequestData *reqData = new RkISP1RequestData(); + request->data = reqData; + reqData->param = paramBuffers_.front(); + reqData->stat = statBuffers_.front(); + + prepareInternalBuffer(reqData->param, request, + ¶mPool_.buffers()[reqData->param->index()]); + prepareInternalBuffer(reqData->stat, request, + &statPool_.buffers()[reqData->stat->index()]); + + paramBuffers_.pop(); + statBuffers_.pop(); PipelineHandler::queueRequest(camera, request); + data->ipa_->processRequest(request, request->controls(), + *reqData->param); + return 0; } @@ -435,6 +609,10 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) std::unique_ptr data = utils::make_unique(this); + data->controlInfo_.emplace(std::piecewise_construct, + std::forward_as_tuple(AeEnable), + std::forward_as_tuple(AeEnable, false, true)); + data->sensor_ = new CameraSensor(sensor); ret = data->sensor_->init(); if (ret) @@ -478,7 +656,17 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (video_->open() < 0) return false; + stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1-statistics"); + if (stat_->open() < 0) + return false; + + param_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1-input-params"); + if (param_->open() < 0) + return false; + video_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); + stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady); + param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady); /* Configure default links. */ if (initLinks() < 0) { @@ -504,13 +692,66 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) * Buffer Handling */ +void PipelineHandlerRkISP1::tryCompleteRequest(Request *request) +{ + RkISP1RequestData *reqData = + static_cast(request->data); + + if (reqData->param) + return; + + if (reqData->stat) + return; + + if (request->hasPendingBuffers()) + return; + + delete reqData; + request->data = nullptr; + + completeRequest(activeCamera_, request); +} + void PipelineHandlerRkISP1::bufferReady(Buffer *buffer) { ASSERT(activeCamera_); Request *request = buffer->request(); completeBuffer(activeCamera_, request, buffer); - completeRequest(activeCamera_, request); + tryCompleteRequest(request); +} + +void PipelineHandlerRkISP1::statReady(Buffer *buffer) +{ + ASSERT(activeCamera_); + RkISP1CameraData *data = cameraData(activeCamera_); + Request *request = buffer->request(); + RkISP1RequestData *reqData = + static_cast(request->data); + + data->ipa_->updateStatistics(request, *buffer); + + /* TODO: Fetch libcamera status controls from IPA */ + + reqData->stat = nullptr; + + statBuffers_.push(buffer); + + tryCompleteRequest(request); +} + +void PipelineHandlerRkISP1::paramReady(Buffer *buffer) +{ + ASSERT(activeCamera_); + Request *request = buffer->request(); + RkISP1RequestData *reqData = + static_cast(request->data); + + reqData->param = nullptr; + + paramBuffers_.push(buffer); + + tryCompleteRequest(request); } REGISTER_PIPELINE_HANDLER(PipelineHandlerRkISP1);