Show a patch.

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

{
    "id": 893,
    "url": "https://patchwork.libcamera.org/api/patches/893/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/893/",
    "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": "<20190403080148.11479-8-jacopo@jmondi.org>",
    "date": "2019-04-03T08:01:42",
    "name": "[libcamera-devel,v8,07/13] libcamera: ipu3: Implement memory handling",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "a87ba09f22605d949bddcea8efdde38a332623ad",
    "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/893/mbox/",
    "series": [
        {
            "id": 235,
            "url": "https://patchwork.libcamera.org/api/series/235/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=235",
            "date": "2019-04-03T08:01:35",
            "name": "libcamera: ipu3: Add ImgU support",
            "version": 8,
            "mbox": "https://patchwork.libcamera.org/series/235/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/893/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/893/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<jacopo@jmondi.org>",
        "Received": [
            "from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net\n\t[217.70.183.195])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0035061111\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  3 Apr 2019 10:01:15 +0200 (CEST)",
            "from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 3D00E60006;\n\tWed,  3 Apr 2019 08:01:14 +0000 (UTC)"
        ],
        "X-Originating-IP": "2.224.242.101",
        "From": "Jacopo Mondi <jacopo@jmondi.org>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Wed,  3 Apr 2019 10:01:42 +0200",
        "Message-Id": "<20190403080148.11479-8-jacopo@jmondi.org>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20190403080148.11479-1-jacopo@jmondi.org>",
        "References": "<20190403080148.11479-1-jacopo@jmondi.org>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v8 07/13] libcamera: ipu3: Implement\n\tmemory handling",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.23",
        "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>",
        "X-List-Received-Date": "Wed, 03 Apr 2019 08:01:16 -0000"
    },
    "content": "Implement buffer allocation and release in IPU3 pipeline handlers.\n\nAs the pipeline handler currently supports a single stream, provide two\ninternal buffer pools for 'viewfinder' and 'stat' video devices, and\nexport the 'output' video device buffers to the stream's pool. This\nworks around the fact that the ImgU requires buffers to be queued on all\nits outputs, even when they are not in use.\n\nShare buffers between the CIO2 output and the ImgU input video devices,\nas the output of the former should immediately be provided to the\nlatter for further processing.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n src/libcamera/pipeline/ipu3/ipu3.cpp | 154 ++++++++++++++++++++++++---\n 1 file changed, 140 insertions(+), 14 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex a4e6f28d1da9..a838fd3a096d 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -40,6 +40,7 @@ public:\n \t\tV4L2Device *dev;\n \t\tunsigned int pad;\n \t\tstd::string name;\n+\t\tBufferPool *pool;\n \t};\n \n \tImgUDevice()\n@@ -65,6 +66,10 @@ public:\n \tint configureOutput(ImgUOutput *output,\n \t\t\t    const StreamConfiguration &config);\n \n+\tint importBuffers(BufferPool *pool);\n+\tint exportBuffers(ImgUOutput *output, BufferPool *pool);\n+\tvoid freeBuffers();\n+\n \tunsigned int index_;\n \tstd::string name_;\n \tMediaDevice *media_;\n@@ -75,11 +80,16 @@ public:\n \tImgUOutput viewfinder_;\n \tImgUOutput stat_;\n \t/* \\todo Add param video device for 3A tuning */\n+\n+\tBufferPool vfPool_;\n+\tBufferPool statPool_;\n };\n \n class CIO2Device\n {\n public:\n+\tstatic constexpr unsigned int CIO2_BUFFER_COUNT = 4;\n+\n \tCIO2Device()\n \t\t: output_(nullptr), csi2_(nullptr), sensor_(nullptr)\n \t{\n@@ -96,6 +106,9 @@ public:\n \tint configure(const StreamConfiguration &config,\n \t\t      V4L2DeviceFormat *outputFormat);\n \n+\tBufferPool *exportBuffers();\n+\tvoid freeBuffers();\n+\n \tstatic int mediaBusToFormat(unsigned int code);\n \n \tV4L2Device *output_;\n@@ -105,6 +118,8 @@ public:\n \t/* Maximum sizes and the mbus code used to produce them. */\n \tunsigned int mbusCode_;\n \tSize maxSize_;\n+\n+\tBufferPool pool_;\n };\n \n class PipelineHandlerIPU3 : public PipelineHandler\n@@ -268,18 +283,41 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera,\n \n int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream)\n {\n-\tconst StreamConfiguration &cfg = stream->configuration();\n \tIPU3CameraData *data = cameraData(camera);\n-\tV4L2Device *cio2 = data->cio2_.output_;\n+\tCIO2Device *cio2 = &data->cio2_;\n+\tImgUDevice *imgu = data->imgu_;\n+\tint ret;\n \n-\tif (!cfg.bufferCount)\n-\t\treturn -EINVAL;\n+\t/* Share buffers between CIO2 output and ImgU input. */\n+\tBufferPool *pool = cio2->exportBuffers();\n+\tif (!pool)\n+\t\treturn -ENOMEM;\n \n-\tint ret = cio2->exportBuffers(&stream->bufferPool());\n-\tif (ret) {\n-\t\tLOG(IPU3, Error) << \"Failed to request memory\";\n+\tret = imgu->importBuffers(pool);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Export ImgU output buffers to the stream's pool. */\n+\tret = imgu->exportBuffers(&imgu->output_, &stream->bufferPool());\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/*\n+\t * Reserve memory in viewfinder and stat output devices. Use the\n+\t * same number of buffers as the ones requested for the output\n+\t * stream.\n+\t */\n+\tunsigned int bufferCount = stream->bufferPool().count();\n+\n+\timgu->viewfinder_.pool->createBuffers(bufferCount);\n+\tret = imgu->exportBuffers(&imgu->viewfinder_, imgu->viewfinder_.pool);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\timgu->stat_.pool->createBuffers(bufferCount);\n+\tret = imgu->exportBuffers(&imgu->stat_, imgu->stat_.pool);\n+\tif (ret)\n \t\treturn ret;\n-\t}\n \n \treturn 0;\n }\n@@ -287,13 +325,9 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream)\n int PipelineHandlerIPU3::freeBuffers(Camera *camera, Stream *stream)\n {\n \tIPU3CameraData *data = cameraData(camera);\n-\tV4L2Device *cio2 = data->cio2_.output_;\n \n-\tint ret = cio2->releaseBuffers();\n-\tif (ret) {\n-\t\tLOG(IPU3, Error) << \"Failed to release memory\";\n-\t\treturn ret;\n-\t}\n+\tdata->cio2_.freeBuffers();\n+\tdata->imgu_->freeBuffers();\n \n \treturn 0;\n }\n@@ -553,6 +587,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index)\n \n \tviewfinder_.pad = PAD_VF;\n \tviewfinder_.name = \"viewfinder\";\n+\tviewfinder_.pool = &vfPool_;\n \n \tstat_.dev = V4L2Device::fromEntityName(media, name_ + \" 3a stat\");\n \tret = stat_.dev->open();\n@@ -561,6 +596,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index)\n \n \tstat_.pad = PAD_STAT;\n \tstat_.name = \"stat\";\n+\tstat_.pool = &statPool_;\n \n \treturn 0;\n }\n@@ -665,6 +701,69 @@ int ImgUDevice::configureOutput(ImgUOutput *output,\n \treturn 0;\n }\n \n+/**\n+ * \\brief Import buffers from \\a pool into the ImgU input\n+ * \\param[in] pool The buffer pool to import\n+ *\n+ * \\return 0 on success or a negative error code otherwise\n+ */\n+int ImgUDevice::importBuffers(BufferPool *pool)\n+{\n+\tint ret = input_->importBuffers(pool);\n+\tif (ret) {\n+\t\tLOG(IPU3, Error) << \"Failed to import ImgU input buffers\";\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * \\brief Export buffers from \\a output to the provided \\a pool\n+ * \\param[in] output The ImgU output device\n+ * \\param[in] pool The buffer pool where to export buffers\n+ *\n+ * Export memory buffers reserved in the video device memory associated with\n+ * \\a output id to the buffer pool provided as argument.\n+ *\n+ * \\return 0 on success or a negative error code otherwise\n+ */\n+int ImgUDevice::exportBuffers(ImgUOutput *output, BufferPool *pool)\n+{\n+\tint ret = output->dev->exportBuffers(pool);\n+\tif (ret) {\n+\t\tLOG(IPU3, Error) << \"Failed to export ImgU \"\n+\t\t\t\t << output->name << \" buffers\";\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * \\brief Release buffers for all the ImgU video devices\n+ */\n+void ImgUDevice::freeBuffers()\n+{\n+\tint ret;\n+\n+\tret = output_.dev->releaseBuffers();\n+\tif (ret)\n+\t\tLOG(IPU3, Error) << \"Failed to release ImgU output buffers\";\n+\n+\tret = stat_.dev->releaseBuffers();\n+\tif (ret)\n+\t\tLOG(IPU3, Error) << \"Failed to release ImgU stat buffers\";\n+\n+\tret = viewfinder_.dev->releaseBuffers();\n+\tif (ret)\n+\t\tLOG(IPU3, Error) << \"Failed to release ImgU viewfinder buffers\";\n+\n+\tret = input_->releaseBuffers();\n+\tif (ret)\n+\t\tLOG(IPU3, Error) << \"Failed to release ImgU input buffers\";\n+}\n+\n /*------------------------------------------------------------------------------\n  * CIO2 Device\n  */\n@@ -831,6 +930,33 @@ int CIO2Device::configure(const StreamConfiguration &config,\n \treturn 0;\n }\n \n+/**\n+ * \\brief Allocate CIO2 memory buffers and export them in a BufferPool\n+ *\n+ * Allocate memory buffers in the CIO2 video device and export them to\n+ * a buffer pool that can be imported by another device.\n+ *\n+ * \\return The buffer pool with export buffers on success or nullptr otherwise\n+ */\n+BufferPool *CIO2Device::exportBuffers()\n+{\n+\tpool_.createBuffers(CIO2_BUFFER_COUNT);\n+\n+\tint ret = output_->exportBuffers(&pool_);\n+\tif (ret) {\n+\t\tLOG(IPU3, Error) << \"Failed to export CIO2 buffers\";\n+\t\treturn nullptr;\n+\t}\n+\n+\treturn &pool_;\n+}\n+\n+void CIO2Device::freeBuffers()\n+{\n+\tif (output_->releaseBuffers())\n+\t\tLOG(IPU3, Error) << \"Failed to release CIO2 buffers\";\n+}\n+\n int CIO2Device::mediaBusToFormat(unsigned int code)\n {\n \tswitch (code) {\n",
    "prefixes": [
        "libcamera-devel",
        "v8",
        "07/13"
    ]
}