Patch Detail
Show a patch.
GET /api/1.1/patches/21850/?format=api
{ "id": 21850, "url": "https://patchwork.libcamera.org/api/1.1/patches/21850/?format=api", "web_url": "https://patchwork.libcamera.org/patch/21850/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20241107114819.57599-5-dan.scally@ideasonboard.com>", "date": "2024-11-07T11:48:12", "name": "[v3,04/11] libcamera: mali-c55: Acquire and plumb in 3a params and stats", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "2456b30163c337683a616beb8bfbe0944e7a61fb", "submitter": { "id": 156, "url": "https://patchwork.libcamera.org/api/1.1/people/156/?format=api", "name": "Dan Scally", "email": "dan.scally@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/21850/mbox/", "series": [ { "id": 4777, "url": "https://patchwork.libcamera.org/api/1.1/series/4777/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4777", "date": "2024-11-07T11:48:08", "name": "Add Mali-C55 IPA Module and Algorithms", "version": 3, "mbox": "https://patchwork.libcamera.org/series/4777/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/21850/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/21850/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 F0473C323E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 7 Nov 2024 11:48:36 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 369F565494;\n\tThu, 7 Nov 2024 12:48:34 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2FAB365475\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 7 Nov 2024 12:48:28 +0100 (CET)", "from mail.ideasonboard.com\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 14DA35B3;\n\tThu, 7 Nov 2024 12:48:19 +0100 (CET)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"UOlaoFQo\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1730980099;\n\tbh=m3XjEBAq8ajXI+bG6mjKAhq+SNX15fY7OlWOUG7t1Ow=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=UOlaoFQoJKrbxR0Zn5ZsP7hgAniiHbnx77g5Kq1IrjPVkIsedW118fov7yjA3a3EQ\n\toyWqp69xlT/zoL6osB1JjeIP2KWt4BS2Y/1rPSuPMoRzYa/EWq8198lrDJ7dFDAQtW\n\t+QG13mKOyNKa4ZldJ28KhTUF41gxRMjUuCRpsJtg=", "From": "Daniel Scally <dan.scally@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Anthony.McGivern@arm.com, Daniel Scally <dan.scally@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tNayden Kanchev <nayden.kanchev@arm.com>,\n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>", "Subject": "[PATCH v3 04/11] libcamera: mali-c55: Acquire and plumb in 3a params\n\tand stats", "Date": "Thu, 7 Nov 2024 11:48:12 +0000", "Message-Id": "<20241107114819.57599-5-dan.scally@ideasonboard.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20241107114819.57599-1-dan.scally@ideasonboard.com>", "References": "<20241107114819.57599-1-dan.scally@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "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>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Acquire the mali-c55 3a stats and parameters video devices during\n::match() and plumb them in.\n\nFor this commit we simply allocate and release buffers for the\nstatistics and parameters. Statistics buffers are queue and dequeued\nfrom the stats video device but their contents are for now untouched.\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\nAcked-by: Nayden Kanchev <nayden.kanchev@arm.com>\nCo-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\nSigned-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n---\nChanges in v3:\n\n\t- None\n\nChanges in v2:\n\n\t- Links between the ISP subdevice and the statistics and parameters\n\t video devices are now enabled (previously they were immutable)\n\n src/libcamera/pipeline/mali-c55/mali-c55.cpp | 153 ++++++++++++++++++-\n 1 file changed, 150 insertions(+), 3 deletions(-)", "diff": "diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\nindex 0845a077..654f776a 100644\n--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n@@ -12,6 +12,7 @@\n #include <set>\n #include <string>\n \n+#include <linux/mali-c55-config.h>\n #include <linux/media-bus-format.h>\n #include <linux/media.h>\n \n@@ -26,6 +27,7 @@\n #include \"libcamera/internal/camera.h\"\n #include \"libcamera/internal/camera_sensor.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n+#include \"libcamera/internal/framebuffer.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/v4l2_subdevice.h\"\n@@ -517,6 +519,8 @@ public:\n \n \tint exportFrameBuffers(Camera *camera, Stream *stream,\n \t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n+\tint allocateBuffers(Camera *camera);\n+\tvoid freeBuffers(Camera *camera);\n \n \tint start(Camera *camera, const ControlList *controls) override;\n \tvoid stopDevice(Camera *camera) override;\n@@ -524,6 +528,7 @@ public:\n \tint queueRequestDevice(Camera *camera, Request *request) override;\n \n \tvoid bufferReady(FrameBuffer *buffer);\n+\tvoid statsBufferReady(FrameBuffer *buffer);\n \n \tbool match(DeviceEnumerator *enumerator) override;\n \n@@ -583,6 +588,14 @@ private:\n \n \tMediaDevice *media_;\n \tstd::unique_ptr<V4L2Subdevice> isp_;\n+\tstd::unique_ptr<V4L2VideoDevice> stats_;\n+\tstd::unique_ptr<V4L2VideoDevice> params_;\n+\n+\tstd::vector<std::unique_ptr<FrameBuffer>> statsBuffers_;\n+\tstd::queue<FrameBuffer *> availableStatsBuffers_;\n+\n+\tstd::vector<std::unique_ptr<FrameBuffer>> paramsBuffers_;\n+\tstd::queue<FrameBuffer *> availableParamsBuffers_;\n \n \tstd::array<MaliC55Pipe, MaliC55NumPipes> pipes_;\n \n@@ -842,6 +855,16 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \t\t\treturn ret;\n \t}\n \n+\tV4L2DeviceFormat statsFormat;\n+\tret = stats_->getFormat(&statsFormat);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (statsFormat.planes[0].size != sizeof(struct mali_c55_stats_buffer)) {\n+\t\tLOG(MaliC55, Error) << \"3a stats buffer size invalid\";\n+\t\treturn -EINVAL;\n+\t}\n+\n \t/*\n \t * Propagate the format to the ISP sink pad and configure the input\n \t * crop rectangle (no crop at the moment).\n@@ -917,27 +940,110 @@ int PipelineHandlerMaliC55::exportFrameBuffers(Camera *camera, Stream *stream,\n \treturn pipe->cap->exportBuffers(count, buffers);\n }\n \n-int PipelineHandlerMaliC55::start([[maybe_unused]] Camera *camera, [[maybe_unused]] const ControlList *controls)\n+void PipelineHandlerMaliC55::freeBuffers([[maybe_unused]] Camera *camera)\n+{\n+\twhile (!availableStatsBuffers_.empty())\n+\t\tavailableStatsBuffers_.pop();\n+\twhile (!availableParamsBuffers_.empty())\n+\t\tavailableParamsBuffers_.pop();\n+\n+\tstatsBuffers_.clear();\n+\tparamsBuffers_.clear();\n+\n+\tif (stats_->releaseBuffers())\n+\t\tLOG(MaliC55, Error) << \"Failed to release stats buffers\";\n+\n+\tif (params_->releaseBuffers())\n+\t\tLOG(MaliC55, Error) << \"Failed to release stats buffers\";\n+\n+\treturn;\n+}\n+\n+int PipelineHandlerMaliC55::allocateBuffers(Camera *camera)\n+{\n+\tMaliC55CameraData *data = cameraData(camera);\n+\tunsigned int bufferCount;\n+\tint ret;\n+\n+\tbufferCount = std::max({\n+\t\tdata->frStream_.configuration().bufferCount,\n+\t\tdata->dsStream_.configuration().bufferCount,\n+\t});\n+\n+\tret = stats_->allocateBuffers(bufferCount, &statsBuffers_);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tfor (std::unique_ptr<FrameBuffer> &buffer : statsBuffers_)\n+\t\tavailableStatsBuffers_.push(buffer.get());\n+\n+\tret = params_->allocateBuffers(bufferCount, ¶msBuffers_);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tfor (std::unique_ptr<FrameBuffer> &buffer : paramsBuffers_)\n+\t\tavailableParamsBuffers_.push(buffer.get());\n+\n+\treturn 0;\n+}\n+\n+int PipelineHandlerMaliC55::start(Camera *camera, [[maybe_unused]] const ControlList *controls)\n {\n+\tint ret;\n+\n+\tret = allocateBuffers(camera);\n+\tif (ret)\n+\t\treturn ret;\n+\n \tfor (MaliC55Pipe &pipe : pipes_) {\n \t\tif (!pipe.stream)\n \t\t\tcontinue;\n \n \t\tStream *stream = pipe.stream;\n \n-\t\tint ret = pipe.cap->importBuffers(stream->configuration().bufferCount);\n+\t\tret = pipe.cap->importBuffers(stream->configuration().bufferCount);\n \t\tif (ret) {\n \t\t\tLOG(MaliC55, Error) << \"Failed to import buffers\";\n+\t\t\tfreeBuffers(camera);\n \t\t\treturn ret;\n \t\t}\n \n \t\tret = pipe.cap->streamOn();\n \t\tif (ret) {\n \t\t\tLOG(MaliC55, Error) << \"Failed to start stream\";\n+\t\t\tfreeBuffers(camera);\n \t\t\treturn ret;\n \t\t}\n \t}\n \n+\tret = stats_->streamOn();\n+\tif (ret) {\n+\t\tLOG(MaliC55, Error) << \"Failed to start stats stream\";\n+\n+\t\tfor (MaliC55Pipe &pipe : pipes_) {\n+\t\t\tif (pipe.stream)\n+\t\t\t\tpipe.cap->streamOff();\n+\t\t}\n+\n+\t\tfreeBuffers(camera);\n+\t\treturn ret;\n+\t}\n+\n+\tret = params_->streamOn();\n+\tif (ret) {\n+\t\tLOG(MaliC55, Error) << \"Failed to start params stream\";\n+\n+\t\tstats_->streamOff();\n+\n+\t\tfor (MaliC55Pipe &pipe : pipes_) {\n+\t\t\tif (pipe.stream)\n+\t\t\t\tpipe.cap->streamOff();\n+\t\t}\n+\n+\t\tfreeBuffers(camera);\n+\t\treturn ret;\n+\t}\n+\n \treturn 0;\n }\n \n@@ -950,6 +1056,10 @@ void PipelineHandlerMaliC55::stopDevice([[maybe_unused]] Camera *camera)\n \t\tpipe.cap->streamOff();\n \t\tpipe.cap->releaseBuffers();\n \t}\n+\n+\tstats_->streamOff();\n+\tparams_->streamOff();\n+\tfreeBuffers(camera);\n }\n \n void PipelineHandlerMaliC55::applyScalerCrop(Camera *camera,\n@@ -1050,8 +1160,24 @@ void PipelineHandlerMaliC55::applyScalerCrop(Camera *camera,\n \n int PipelineHandlerMaliC55::queueRequestDevice(Camera *camera, Request *request)\n {\n+\tFrameBuffer *statsBuffer;\n \tint ret;\n \n+\tif (availableStatsBuffers_.empty()) {\n+\t\tLOG(MaliC55, Error) << \"Stats buffer underrun\";\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tstatsBuffer = availableStatsBuffers_.front();\n+\tavailableStatsBuffers_.pop();\n+\n+\t/*\n+\t * We need to associate the Request to this buffer even though it's a\n+\t * purely internal one because we will need to use request->sequence()\n+\t * later.\n+\t */\n+\tstatsBuffer->_d()->setRequest(request);\n+\n \tfor (auto &[stream, buffer] : request->buffers()) {\n \t\tMaliC55Pipe *pipe = pipeFromStream(cameraData(camera), stream);\n \n@@ -1069,6 +1195,10 @@ int PipelineHandlerMaliC55::queueRequestDevice(Camera *camera, Request *request)\n \t */\n \tapplyScalerCrop(camera, request->controls());\n \n+\tret = stats_->queueBuffer(statsBuffer);\n+\tif (ret)\n+\t\treturn ret;\n+\n \treturn 0;\n }\n \n@@ -1080,6 +1210,11 @@ void PipelineHandlerMaliC55::bufferReady(FrameBuffer *buffer)\n \t\tcompleteRequest(request);\n }\n \n+void PipelineHandlerMaliC55::statsBufferReady(FrameBuffer *buffer)\n+{\n+\tavailableStatsBuffers_.push(buffer);\n+}\n+\n void PipelineHandlerMaliC55::registerMaliCamera(std::unique_ptr<MaliC55CameraData> data,\n \t\t\t\t\t\tconst std::string &name)\n {\n@@ -1157,7 +1292,7 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \tconst MediaPad *ispSink;\n \n \t/*\n-\t * We search for just the ISP subdevice and the full resolution pipe.\n+\t * We search for just the always-available elements of the media graph.\n \t * The TPG and the downscale pipe are both optional blocks and may not\n \t * be fitted.\n \t */\n@@ -1165,6 +1300,8 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \tdm.add(\"mali-c55 isp\");\n \tdm.add(\"mali-c55 resizer fr\");\n \tdm.add(\"mali-c55 fr\");\n+\tdm.add(\"mali-c55 3a stats\");\n+\tdm.add(\"mali-c55 3a params\");\n \n \tmedia_ = acquireMediaDevice(enumerator, dm);\n \tif (!media_)\n@@ -1174,6 +1311,14 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \tif (isp_->open() < 0)\n \t\treturn false;\n \n+\tstats_ = V4L2VideoDevice::fromEntityName(media_, \"mali-c55 3a stats\");\n+\tif (stats_->open() < 0)\n+\t\treturn false;\n+\n+\tparams_ = V4L2VideoDevice::fromEntityName(media_, \"mali-c55 3a params\");\n+\tif (params_->open() < 0)\n+\t\treturn false;\n+\n \tMaliC55Pipe *frPipe = &pipes_[MaliC55FR];\n \tfrPipe->resizer = V4L2Subdevice::fromEntityName(media_, \"mali-c55 resizer fr\");\n \tif (frPipe->resizer->open() < 0)\n@@ -1202,6 +1347,8 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \t\tdsPipe->cap->bufferReady.connect(this, &PipelineHandlerMaliC55::bufferReady);\n \t}\n \n+\tstats_->bufferReady.connect(this, &PipelineHandlerMaliC55::statsBufferReady);\n+\n \tispSink = isp_->entity()->getPadByIndex(0);\n \tif (!ispSink || ispSink->links().empty()) {\n \t\tLOG(MaliC55, Error) << \"ISP sink pad error\";\n", "prefixes": [ "v3", "04/11" ] }