{"id":808,"url":"https://patchwork.libcamera.org/api/patches/808/?format=json","web_url":"https://patchwork.libcamera.org/patch/808/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20190326083902.26121-14-jacopo@jmondi.org>","date":"2019-03-26T08:38:56","name":"[libcamera-devel,v5,13/19] libcamera: ipu3: Implement memory handling","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"2b30b3bdb3928eeb188622509980fd03db04e869","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/?format=json","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/808/mbox/","series":[{"id":219,"url":"https://patchwork.libcamera.org/api/series/219/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=219","date":"2019-03-26T08:38:43","name":"libcamera: ipu3: Add ImgU support","version":5,"mbox":"https://patchwork.libcamera.org/series/219/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/808/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/808/checks/","tags":{},"headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay10.mail.gandi.net (relay10.mail.gandi.net\n\t[217.70.178.230])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 052476110D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Mar 2019 09:38:39 +0100 (CET)","from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay10.mail.gandi.net (Postfix) with ESMTPSA id 71477240006;\n\tTue, 26 Mar 2019 08:38:38 +0000 (UTC)"],"From":"Jacopo Mondi <jacopo@jmondi.org>","To":"libcamera-devel@lists.libcamera.org","Date":"Tue, 26 Mar 2019 09:38:56 +0100","Message-Id":"<20190326083902.26121-14-jacopo@jmondi.org>","X-Mailer":"git-send-email 2.21.0","In-Reply-To":"<20190326083902.26121-1-jacopo@jmondi.org>","References":"<20190326083902.26121-1-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH v5 13/19] 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":"Tue, 26 Mar 2019 08:38:40 -0000"},"content":"Implement buffer allocation and relase in IPU3 pipeline handlers.\nAs the pipeline handler supports a single stream, provide two internal\nbuffer pools for 'viewfinder' and 'stat' video devices, and export\nthe 'output' video device buffers to the Stream's pool.\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\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n src/libcamera/pipeline/ipu3/ipu3.cpp | 174 ++++++++++++++++++++++++---\n 1 file changed, 160 insertions(+), 14 deletions(-)","diff":"diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 63b84706b9b2..d3519bb1d536 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -64,6 +64,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@@ -94,6 +95,10 @@ public:\n \t{\n \t\treturn outputMap[id].name;\n \t}\n+\tBufferPool *outputPool(enum OutputId id)\n+\t{\n+\t\treturn outputMap[id].pool;\n+\t}\n \n \tint init(MediaDevice *media, unsigned int index);\n \tint configureInput(const StreamConfiguration &config,\n@@ -101,6 +106,11 @@ public:\n \tint configureOutput(enum OutputId id,\n \t\t\t    const StreamConfiguration &config);\n \n+\tint importBuffers(BufferPool *pool);\n+\tint exportBuffers(enum OutputId id, BufferPool *pool);\n+\tint exportBuffers(enum OutputId id, unsigned int count);\n+\tvoid freeBuffers();\n+\n \tunsigned int index_;\n \tstd::string name_;\n \tMediaDevice *media_;\n@@ -114,11 +124,16 @@ public:\n \n \t/* ImgU output map: associate an output id with its descriptor. */\n \tstd::map<enum OutputId, struct outputDesc> outputMap;\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@@ -136,12 +151,17 @@ public:\n \tint configure(const StreamConfiguration &config,\n \t\t      V4L2SubdeviceFormat *format);\n \n+\tBufferPool *exportBuffers();\n+\tvoid freeBuffers();\n+\n \tV4L2Device *output_;\n \tV4L2Subdevice *csi2_;\n \tV4L2Subdevice *sensor_;\n \n \t/* Maximum sizes and the mbus code used to produce them. */\n \tstd::pair<unsigned int, SizeRange> maxSizes_;\n+\n+\tBufferPool pool_;\n };\n \n class PipelineHandlerIPU3 : public PipelineHandler\n@@ -301,18 +321,39 @@ 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(ImgUDevice::MAIN_OUTPUT,\n+\t\t\t\t  &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+\tret = imgu->exportBuffers(ImgUDevice::SECONDARY_OUTPUT, bufferCount);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = imgu->exportBuffers(ImgUDevice::STAT, bufferCount);\n+\tif (ret)\n \t\treturn ret;\n-\t}\n \n \treturn 0;\n }\n@@ -320,13 +361,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@@ -592,6 +629,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index)\n \tdesc.dev = viewfinder_;\n \tdesc.pad = PAD_VF;\n \tdesc.name = \"viewfinder\";\n+\tdesc.pool = &vfPool;\n \toutputMap[SECONDARY_OUTPUT] = desc;\n \n \tstat_ = V4L2Device::fromEntityName(media, name_ + \" 3a stat\");\n@@ -603,6 +641,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index)\n \tdesc.dev = stat_;\n \tdesc.pad = PAD_STAT;\n \tdesc.name = \"stat\";\n+\tdesc.pool = &statPool;\n \toutputMap[STAT] = desc;\n \n \treturn 0;\n@@ -714,6 +753,86 @@ int ImgUDevice::configureOutput(enum OutputId id,\n \treturn 0;\n }\n \n+/**\n+ * \\brief Import buffers from CIO2 device into the ImgU\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+\treturn input_->importBuffers(pool);\n+}\n+\n+/**\n+ * \\brief Export buffers from output \\a id to the provided \\a pool\n+ * \\param[in] id The ImgU output identifier\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+ * output \\a 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(enum OutputId id, BufferPool *pool)\n+{\n+\tV4L2Device *output = outputDevice(id);\n+\tconst std::string &name = outputName(id);\n+\n+\tint ret = output->exportBuffers(pool);\n+\tif (ret) {\n+\t\tLOG(IPU3, Error) << \"Failed to reserve ImgU \"\n+\t\t\t\t << name << \" buffers\";\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * \\brief Export buffers from output \\a id to the an internal buffer pool\n+ * \\param[in] id The ImgU output identifier\n+ * \\param[in] count The number of buffers to reserve\n+ *\n+ * Export memory buffers reserved in the video device memory associated with\n+ * output \\a id to the output internal buffer pool.\n+ *\n+ * \\return 0 on success or a negative error code otherwise\n+ */\n+int ImgUDevice::exportBuffers(enum OutputId id, unsigned int count)\n+{\n+\tBufferPool *pool = outputPool(id);\n+\n+\t/* Internal buffer pools needs memory to be allocated first. */\n+\tpool->createBuffers(count);\n+\n+\treturn exportBuffers(id, pool);\n+}\n+\n+/**\n+ * \\brief Release buffers of the ImgU devices\n+ */\n+void ImgUDevice::freeBuffers()\n+{\n+\tint ret;\n+\n+\tret = output_->releaseBuffers();\n+\tif (ret)\n+\t\tLOG(IPU3, Error) << \"Failed to release ImgU output buffers\";\n+\n+\tret = stat_->releaseBuffers();\n+\tif (ret)\n+\t\tLOG(IPU3, Error) << \"Failed to release ImgU stat buffers\";\n+\n+\tret = viewfinder_->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@@ -880,6 +999,33 @@ int CIO2Device::configure(const StreamConfiguration &config,\n \treturn 0;\n }\n \n+/**\n+ * \\brief Reserve 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 will be later imported by the ImgU 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 REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3);\n \n } /* namespace libcamera */\n","prefixes":["libcamera-devel","v5","13/19"]}