Show a patch.

GET /api/patches/10777/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 10777,
    "url": "https://patchwork.libcamera.org/api/patches/10777/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/10777/",
    "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": "<20201229160318.77536-12-niklas.soderlund@ragnatech.se>",
    "date": "2020-12-29T16:03:18",
    "name": "[libcamera-devel,v2,11/11] libcamera: ipu3: Share parameter and statistic buffers with IPA",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "150e7edd5b66464a8d17f012416b3cfb1fc53a21",
    "submitter": {
        "id": 5,
        "url": "https://patchwork.libcamera.org/api/people/5/?format=api",
        "name": "Niklas Söderlund",
        "email": "niklas.soderlund@ragnatech.se"
    },
    "delegate": {
        "id": 16,
        "url": "https://patchwork.libcamera.org/api/users/16/?format=api",
        "username": "neg",
        "first_name": "Niklas",
        "last_name": "Söderlund",
        "email": "niklas.soderlund@ragnatech.se"
    },
    "mbox": "https://patchwork.libcamera.org/patch/10777/mbox/",
    "series": [
        {
            "id": 1559,
            "url": "https://patchwork.libcamera.org/api/series/1559/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1559",
            "date": "2020-12-29T16:03:07",
            "name": "libcamera: ipu3: Attach to an skeleton IPA",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/1559/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/10777/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/10777/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 27EF6C0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 29 Dec 2020 16:04:18 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F252D6200D;\n\tTue, 29 Dec 2020 17:04:17 +0100 (CET)",
            "from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net\n\t[195.74.38.229])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D81D460525\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Dec 2020 17:04:15 +0100 (CET)",
            "from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de\n\t[79.202.36.88])\n\tby bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA\n\tid 7eeba5d3-49ef-11eb-a542-005056917a89;\n\tTue, 29 Dec 2020 17:04:14 +0100 (CET)"
        ],
        "X-Halon-ID": "7eeba5d3-49ef-11eb-a542-005056917a89",
        "Authorized-sender": "niklas.soderlund@fsdn.se",
        "From": "=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Tue, 29 Dec 2020 17:03:18 +0100",
        "Message-Id": "<20201229160318.77536-12-niklas.soderlund@ragnatech.se>",
        "X-Mailer": "git-send-email 2.29.2",
        "In-Reply-To": "<20201229160318.77536-1-niklas.soderlund@ragnatech.se>",
        "References": "<20201229160318.77536-1-niklas.soderlund@ragnatech.se>",
        "MIME-Version": "1.0",
        "Subject": "[libcamera-devel] [PATCH v2 11/11] libcamera: ipu3: Share parameter\n\tand statistic buffers with IPA",
        "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>",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Use the IPU3Frames helper to share parameters and statistics buffers\nwith the IPA. Track which parameter and statistic buffer is used for\nwhich request and make sure the parameter buffers is filled in by the\nIPA before it's needed and that the statistic buffer is consumed and\nmeta data generated before completing the request.\n\nWith this change the IPU3 pipeline is prepared to fully operate with an\nIPA component.\n\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n---\n* Changes since v1\n- Update commit message.\n- s/frameInfo_/frameInfos_/\n- Refactor away isComplete variable.\n---\n src/libcamera/pipeline/ipu3/ipu3.cpp | 115 +++++++++++++++++++++++++--\n 1 file changed, 107 insertions(+), 8 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 141066c528890c8e..6cd1879a76b195bf 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -29,6 +29,7 @@\n #include \"libcamera/internal/v4l2_controls.h\"\n \n #include \"cio2.h\"\n+#include \"frames.h\"\n #include \"imgu.h\"\n \n namespace libcamera {\n@@ -60,6 +61,8 @@ public:\n \n \tvoid imguOutputBufferReady(FrameBuffer *buffer);\n \tvoid cio2BufferReady(FrameBuffer *buffer);\n+\tvoid paramBufferReady(FrameBuffer *buffer);\n+\tvoid statBufferReady(FrameBuffer *buffer);\n \n \tCIO2Device cio2_;\n \tImgUDevice *imgu_;\n@@ -69,6 +72,7 @@ public:\n \tStream rawStream_;\n \n \tstd::unique_ptr<DelayedControls> delayedCtrls_;\n+\tstd::unique_ptr<IPU3Frames> frameInfos_;\n \n private:\n \tvoid actOnIpa(unsigned int id, const IPAOperationData &op);\n@@ -602,6 +606,8 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera)\n \n \tdata->ipa_->mapBuffers(ipaBuffers_);\n \n+\tdata->frameInfos_->init(imgu->paramBuffers_, imgu->statBuffers_);\n+\n \treturn 0;\n }\n \n@@ -609,6 +615,8 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera)\n {\n \tIPU3CameraData *data = cameraData(camera);\n \n+\tdata->frameInfos_->clear();\n+\n \tstd::vector<unsigned int> ids;\n \tfor (IPABuffer &ipabuf : ipaBuffers_)\n \t\tids.push_back(ipabuf.id);\n@@ -720,6 +728,10 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)\n \tIPU3CameraData *data = cameraData(camera);\n \tint error = 0;\n \n+\tIPU3Frames::Info *info = data->frameInfos_->create(request);\n+\tif (!info)\n+\t\treturn -ENOENT;\n+\n \t/*\n \t * Queue a buffer on the CIO2, using the raw stream buffer provided in\n \t * the request, if any, or a CIO2 internal buffer otherwise.\n@@ -729,7 +741,10 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)\n \tif (!rawBuffer)\n \t\treturn -ENOMEM;\n \n+\tinfo->rawBuffer = rawBuffer;\n+\n \t/* Queue all buffers from the request aimed for the ImgU. */\n+\tbool onlyRaw = true;\n \tfor (auto it : request->buffers()) {\n \t\tconst Stream *stream = it.first;\n \t\tFrameBuffer *buffer = it.second;\n@@ -744,6 +759,23 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)\n \n \t\tif (ret < 0)\n \t\t\terror = ret;\n+\n+\t\tonlyRaw = false;\n+\t}\n+\n+\t/* If request only contains a raw buffer do not involve IPA. */\n+\tif (onlyRaw) {\n+\t\tinfo->paramDequeued = true;\n+\t\tinfo->metadataProcessed = true;\n+\t} else {\n+\t\tIPAOperationData op;\n+\t\top.operation = IPU3_IPA_EVENT_FILL_PARAMS;\n+\t\top.data = { info->id, info->paramBuffer->cookie() };\n+\t\top.controls = { request->controls() };\n+\t\tdata->ipa_->processEvent(op);\n+\n+\t\tdata->imgu_->param_->queueBuffer(info->paramBuffer);\n+\t\tdata->imgu_->stat_->queueBuffer(info->statBuffer);\n \t}\n \n \treturn error;\n@@ -893,6 +925,10 @@ int PipelineHandlerIPU3::registerCameras()\n \t\t\t\t\t&IPU3CameraData::imguOutputBufferReady);\n \t\tdata->imgu_->viewfinder_->bufferReady.connect(data.get(),\n \t\t\t\t\t&IPU3CameraData::imguOutputBufferReady);\n+\t\tdata->imgu_->param_->bufferReady.connect(data.get(),\n+\t\t\t\t\t&IPU3CameraData::paramBufferReady);\n+\t\tdata->imgu_->stat_->bufferReady.connect(data.get(),\n+\t\t\t\t\t&IPU3CameraData::statBufferReady);\n \n \t\t/* Create and register the Camera instance. */\n \t\tstd::string cameraId = cio2->sensor()->id();\n@@ -922,10 +958,12 @@ int IPU3CameraData::loadIPA()\n \n \tipa_->init(IPASettings{});\n \n+\tframeInfos_ = std::make_unique<IPU3Frames>();\n+\n \treturn 0;\n }\n \n-void IPU3CameraData::actOnIpa([[maybe_unused]] unsigned int id,\n+void IPU3CameraData::actOnIpa(unsigned int id,\n \t\t\t      const IPAOperationData &action)\n {\n \tswitch (action.operation) {\n@@ -934,6 +972,27 @@ void IPU3CameraData::actOnIpa([[maybe_unused]] unsigned int id,\n \t\tdelayedCtrls_->push(controls);\n \t\tbreak;\n \t}\n+\tcase IPU3_IPA_ACTION_PARAM_FILLED: {\n+\t\tIPU3Frames::Info *info = frameInfos_->find(id);\n+\t\tif (!info)\n+\t\t\tbreak;\n+\n+\t\tinfo->paramFilled = true;\n+\t\tbreak;\n+\t}\n+\tcase IPU3_IPA_ACTION_METADATA_READY: {\n+\t\tIPU3Frames::Info *info = frameInfos_->find(id);\n+\t\tif (!info)\n+\t\t\tbreak;\n+\n+\t\tRequest *request = info->request;\n+\t\trequest->metadata() = action.controls[0];\n+\t\tinfo->metadataProcessed = true;\n+\t\tif (frameInfos_->tryComplete(info))\n+\t\t\tpipe_->completeRequest(request);\n+\n+\t\tbreak;\n+\t}\n \tdefault:\n \t\tLOG(IPU3, Error) << \"Unknown action \" << action.operation;\n \t\tbreak;\n@@ -954,13 +1013,16 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n {\n \tRequest *request = buffer->request();\n \n-\tif (!pipe_->completeBuffer(request, buffer))\n-\t\t/* Request not completed yet, return here. */\n+\tpipe_->completeBuffer(request, buffer);\n+\n+\tIPU3Frames::Info *info = frameInfos_->find(buffer);\n+\tif (!info)\n \t\treturn;\n \n-\t/* Mark the request as complete. */\n \trequest->metadata().set(controls::draft::PipelineDepth, 3);\n-\tpipe_->completeRequest(request);\n+\n+\tif (frameInfos_->tryComplete(info))\n+\t\tpipe_->completeRequest(request);\n }\n \n /**\n@@ -976,6 +1038,10 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)\n \tif (buffer->metadata().status == FrameMetadata::FrameCancelled)\n \t\treturn;\n \n+\tIPU3Frames::Info *info = frameInfos_->find(buffer);\n+\tif (!info)\n+\t\treturn;\n+\n \tRequest *request = buffer->request();\n \n \t/*\n@@ -983,17 +1049,50 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)\n \t * now as there's no need for ImgU processing.\n \t */\n \tif (request->findBuffer(&rawStream_)) {\n-\t\tbool isComplete = pipe_->completeBuffer(request, buffer);\n-\t\tif (isComplete) {\n+\t\tif (pipe_->completeBuffer(request, buffer)) {\n \t\t\trequest->metadata().set(controls::draft::PipelineDepth, 2);\n-\t\t\tpipe_->completeRequest(request);\n+\t\t\tif (frameInfos_->tryComplete(info))\n+\t\t\t\tpipe_->completeRequest(request);\n \t\t\treturn;\n \t\t}\n \t}\n \n+\tif (!info->paramFilled)\n+\t\tLOG(IPU3, Info)\n+\t\t\t<< \"Parameters not ready on time for id \" << info->id;\n+\n \timgu_->input_->queueBuffer(buffer);\n }\n \n+void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)\n+{\n+\tif (buffer->metadata().status == FrameMetadata::FrameCancelled)\n+\t\treturn;\n+\n+\tIPU3Frames::Info *info = frameInfos_->find(buffer);\n+\tif (!info)\n+\t\treturn;\n+\n+\tinfo->paramDequeued = true;\n+\tif (frameInfos_->tryComplete(info))\n+\t\tpipe_->completeRequest(buffer->request());\n+}\n+\n+void IPU3CameraData::statBufferReady(FrameBuffer *buffer)\n+{\n+\tif (buffer->metadata().status == FrameMetadata::FrameCancelled)\n+\t\treturn;\n+\n+\tIPU3Frames::Info *info = frameInfos_->find(buffer);\n+\tif (!info)\n+\t\treturn;\n+\n+\tIPAOperationData op;\n+\top.operation = IPU3_IPA_EVENT_STAT_READY;\n+\top.data = { info->id, info->statBuffer->cookie() };\n+\tipa_->processEvent(op);\n+}\n+\n REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3)\n \n } /* namespace libcamera */\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "11/11"
    ]
}