Patch Detail
Show a patch.
GET /api/patches/16475/?format=api
{ "id": 16475, "url": "https://patchwork.libcamera.org/api/patches/16475/?format=api", "web_url": "https://patchwork.libcamera.org/patch/16475/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20220630133902.321099-18-jacopo@jmondi.org>", "date": "2022-06-30T13:38:56", "name": "[libcamera-devel,v3,17/23] ipa: ipu3: Configure IPA with libcamera controls", "commit_ref": null, "pull_url": null, "state": "not-applicable", "archived": true, "hash": "2fb725e49d3a26910c42afc2f49437e274237ef8", "submitter": { "id": 3, "url": "https://patchwork.libcamera.org/api/people/3/?format=api", "name": "Jacopo Mondi", "email": "jacopo@jmondi.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/16475/mbox/", "series": [ { "id": 3238, "url": "https://patchwork.libcamera.org/api/series/3238/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3238", "date": "2022-06-30T13:38:39", "name": "Internal controls, sensor delays and IPA rework", "version": 3, "mbox": "https://patchwork.libcamera.org/series/3238/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/16475/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/16475/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 2429DBE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 30 Jun 2022 13:39:50 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B43BC65696;\n\tThu, 30 Jun 2022 15:39:49 +0200 (CEST)", "from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net\n\t[217.70.183.193])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D0BD96569B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Jun 2022 15:39:41 +0200 (CEST)", "(Authenticated sender: jacopo@jmondi.org)\n\tby mail.gandi.net (Postfix) with ESMTPSA id B402924000F;\n\tThu, 30 Jun 2022 13:39:39 +0000 (UTC)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656596389;\n\tbh=4rac9Rtmiyxlxc19x7gSaPtGSORbrQUteRJ1HerjVew=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=iPo78SBra71VkV0QZEhIdu3HFYlQAUCuEt2MLNSlV50p9yOF5yU2CNbrG1U/hnx6b\n\tQUcvU03xAZ/k3VI+6/Pd+q0DrSg3wjpdt2K+WeoU4npG8now5ydCBf3PKpdIqnNEJn\n\t8Ujfy1ccjDJBVa6PvM56SpJ7PHNgdMZZwLHYAdMRRFBUEwGdVVT99NtxErdU1qAsnY\n\tBS1KkUe3RWJn8YdpwQLDwtplb4ACkHhJilNlKNr3Q1Q6UypQVfc5FGyWbSqCozdZKO\n\tJjHN5+lxAK5gAcmBeaXZy9axIhQfT7Xf+UA2WPSkKu81ifb6ELGXnbG0tFGlDyo5TA\n\tgb6nh2SY0TnIw==", "To": "libcamera-devel@lists.libcamera.org", "Date": "Thu, 30 Jun 2022 15:38:56 +0200", "Message-Id": "<20220630133902.321099-18-jacopo@jmondi.org>", "X-Mailer": "git-send-email 2.36.1", "In-Reply-To": "<20220630133902.321099-1-jacopo@jmondi.org>", "References": "<20220630133902.321099-1-jacopo@jmondi.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v3 17/23] ipa: ipu3: Configure IPA with\n\tlibcamera controls", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "From": "Jacopo Mondi via libcamera-devel <libcamera-devel@lists.libcamera.org>", "Reply-To": "Jacopo Mondi <jacopo@jmondi.org>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Pass to the IPA configure() function the list of libcamera\ncontrols::internal controls in place of sending to the IPA the\nraw V4L2 control values.\n\nAs V4L2 controls are removed from the list of arguments passed to\nIPA::configure(), fetch the vertical blanking value from the\nCameraSensorInfo now that it is available there.\n\nWhile at it, rationalize the sequence of operations IPA::configure() to:\n- check the validity of the configuration\n- update the session configuration\n- configure algorithm\n- assign class member variables\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n src/ipa/ipu3/ipa_context.cpp | 4 +-\n src/ipa/ipu3/ipa_context.h | 2 +-\n src/ipa/ipu3/ipu3.cpp | 79 +++++++++++-----------------\n src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +-\n 4 files changed, 36 insertions(+), 51 deletions(-)", "diff": "diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp\nindex 13cdb835ef7f..06fdf2a1efc7 100644\n--- a/src/ipa/ipu3/ipa_context.cpp\n+++ b/src/ipa/ipu3/ipa_context.cpp\n@@ -126,8 +126,8 @@ namespace libcamera::ipa::ipu3 {\n * \\var IPASessionConfiguration::sensor.lineDuration\n * \\brief Line duration in microseconds\n *\n- * \\var IPASessionConfiguration::sensor.defVBlank\n- * \\brief The default vblank value of the sensor\n+ * \\var IPASessionConfiguration::sensor.vBlank\n+ * \\brief The vertical blanking expressed in number of lines\n */\n \n /**\ndiff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h\nindex 42e11141d3a1..a5b878ab7792 100644\n--- a/src/ipa/ipu3/ipa_context.h\n+++ b/src/ipa/ipu3/ipa_context.h\n@@ -43,7 +43,7 @@ struct IPASessionConfiguration {\n \t} agc;\n \n \tstruct {\n-\t\tint32_t defVBlank;\n+\t\tint32_t vBlank;\n \t\tutils::Duration lineDuration;\n \t} sensor;\n };\ndiff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\nindex a6e5dcbaada9..44a7d13225df 100644\n--- a/src/ipa/ipu3/ipu3.cpp\n+++ b/src/ipa/ipu3/ipu3.cpp\n@@ -28,6 +28,7 @@\n #include <libcamera/ipa/ipu3_ipa_interface.h>\n #include <libcamera/request.h>\n \n+#include \"libcamera/internal/control_ids.h\"\n #include \"libcamera/internal/mapped_framebuffer.h\"\n \n #include \"algorithms/af.h\"\n@@ -148,9 +149,9 @@ public:\n \t\t\t\tconst uint32_t bufferId,\n \t\t\t\tconst ControlList &sensorControls) override;\n private:\n-\tvoid updateSessionConfiguration(const ControlInfoMap &sensorControls);\n+\tvoid updateSessionConfiguration(const IPAConfigInfo &info);\n \n-\tbool validateSensorControls();\n+\tbool validateSensorControls(const ControlInfoMap &sensorControls);\n \n \tvoid setControls(unsigned int frame);\n \tvoid calculateBdsGrid(const Size &bdsOutputSize);\n@@ -176,18 +177,12 @@ private:\n * \\brief Compute IPASessionConfiguration using the sensor information and the\n * sensor V4L2 controls\n */\n-void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)\n+void IPAIPU3::updateSessionConfiguration(const IPAConfigInfo &info)\n {\n-\tconst ControlInfo vBlank = sensorControls.find(V4L2_CID_VBLANK)->second;\n-\tcontext_.configuration.sensor.defVBlank = vBlank.def().get<int32_t>();\n+\tconst IPACameraSensorInfo &sensorInfo = info.sensorInfo;\n+\tcontext_.configuration.sensor.vBlank = sensorInfo.vblank;\n \n-\tconst ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;\n-\tint32_t minExposure = v4l2Exposure.min().get<int32_t>();\n-\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>();\n-\n-\tconst ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second;\n-\tint32_t minGain = v4l2Gain.min().get<int32_t>();\n-\tint32_t maxGain = v4l2Gain.max().get<int32_t>();\n+\tconst ControlInfoMap &sensorControls = info.sensorControls;\n \n \t/*\n \t * When the AGC computes the new exposure values for a frame, it needs\n@@ -196,27 +191,30 @@ void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)\n \t *\n \t * \\todo take VBLANK into account for maximum shutter speed\n \t */\n-\tcontext_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration;\n-\tcontext_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration;\n-\tcontext_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain);\n-\tcontext_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain);\n+\tconst ControlInfo &exposure = sensorControls.at(&controls::internal::ExposureTime);\n+\tcontext_.configuration.agc.minShutterSpeed = exposure.min().get<int32_t>() * 1.0us;\n+\tcontext_.configuration.agc.maxShutterSpeed = exposure.max().get<int32_t>() * 1.0us;\n+\n+\tconst ControlInfo &gain = sensorControls.at(&controls::internal::AnalogueGain);\n+\tcontext_.configuration.agc.minAnalogueGain = gain.min().get<float>();\n+\tcontext_.configuration.agc.maxAnalogueGain = gain.max().get<float>();\n }\n \n /**\n * \\brief Validate that the sensor controls mandatory for the IPA exists\n */\n-bool IPAIPU3::validateSensorControls()\n+bool IPAIPU3::validateSensorControls(const ControlInfoMap &sensorControls)\n {\n-\tstatic const uint32_t ctrls[] = {\n-\t\tV4L2_CID_ANALOGUE_GAIN,\n-\t\tV4L2_CID_EXPOSURE,\n-\t\tV4L2_CID_VBLANK,\n+\tstatic constexpr std::array<const ControlId *, 3> ctrls = {\n+\t\t&controls::internal::ExposureTime,\n+\t\t&controls::internal::FrameDuration,\n+\t\t&controls::internal::AnalogueGain,\n \t};\n \n-\tfor (auto c : ctrls) {\n-\t\tif (sensorCtrls_.find(c) == sensorCtrls_.end()) {\n+\tfor (const ControlId *c : ctrls) {\n+\t\tif (sensorControls.find(c) == sensorControls.end()) {\n \t\t\tLOG(IPAIPU3, Error) << \"Unable to find sensor control \"\n-\t\t\t\t\t << utils::hex(c);\n+\t\t\t\t\t << c->name();\n \t\t\treturn false;\n \t\t}\n \t}\n@@ -362,35 +360,19 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)\n */\n int IPAIPU3::configure(const IPAConfigInfo &configInfo)\n {\n-\tif (configInfo.sensorControls.empty()) {\n-\t\tLOG(IPAIPU3, Error) << \"No sensor controls provided\";\n-\t\treturn -ENODATA;\n+\tif (!validateSensorControls(configInfo.sensorControls)) {\n+\t\tLOG(IPAIPU3, Error) << \"Sensor control validation failed.\";\n+\t\treturn -EINVAL;\n \t}\n \n-\tsensorInfo_ = configInfo.sensorInfo;\n-\n-\tlensCtrls_ = configInfo.lensControls;\n-\n-\t/*\n-\t * Compute the sensor V4L2 controls to be used by the algorithms and\n-\t * to be set on the sensor.\n-\t */\n-\tsensorCtrls_ = configInfo.sensorControls;\n-\n-\tcalculateBdsGrid(configInfo.bdsOutputSize);\n-\n \t/* Clean IPAActiveState at each reconfiguration. */\n \tcontext_.activeState = {};\n \tIPAFrameContext initFrameContext;\n \tcontext_.frameContexts.fill(initFrameContext);\n \n-\tif (!validateSensorControls()) {\n-\t\tLOG(IPAIPU3, Error) << \"Sensor control validation failed.\";\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/* Update the IPASessionConfiguration using the sensor settings. */\n-\tupdateSessionConfiguration(sensorCtrls_);\n+\tupdateSessionConfiguration(configInfo);\n+\tcalculateBdsGrid(configInfo.bdsOutputSize);\n \n \tfor (auto const &algo : algorithms_) {\n \t\tint ret = algo->configure(context_, configInfo);\n@@ -398,6 +380,10 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)\n \t\t\treturn ret;\n \t}\n \n+\tsensorInfo_ = configInfo.sensorInfo;\n+\tlensCtrls_ = configInfo.lensControls;\n+\tsensorCtrls_ = configInfo.sensorControls;\n+\n \treturn 0;\n }\n \n@@ -500,7 +486,7 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame,\n \tframeContext.sensor.gain = camHelper_->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>());\n \n \tdouble lineDuration = context_.configuration.sensor.lineDuration.get<std::micro>();\n-\tint32_t vBlank = context_.configuration.sensor.defVBlank;\n+\tint32_t vBlank = context_.configuration.sensor.vBlank;\n \tControlList ctrls(controls::controls);\n \n \tfor (auto const &algo : algorithms_)\n@@ -508,7 +494,6 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame,\n \n \tsetControls(frame);\n \n-\t/* \\todo Use VBlank value calculated from each frame exposure. */\n \tint64_t frameDuration = (vBlank + sensorInfo_.outputSize.height) * lineDuration;\n \tctrls.set(controls::FrameDuration, frameDuration);\n \ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 8c5b6c36ae0b..ce207c968075 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -659,7 +659,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \t}\n \n \tipa::ipu3::IPAConfigInfo configInfo;\n-\tconfigInfo.sensorControls = data->cio2_.sensor()->v4l2Controls();\n+\tconfigInfo.sensorControls = data->cio2_.sensor()->controls();\n \n \tCameraLens *lens = data->cio2_.sensor()->focusLens();\n \tif (lens)\n", "prefixes": [ "libcamera-devel", "v3", "17/23" ] }