{"id":2468,"url":"https://patchwork.libcamera.org/api/patches/2468/?format=json","web_url":"https://patchwork.libcamera.org/patch/2468/","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":"<20191230120510.938333-19-niklas.soderlund@ragnatech.se>","date":"2019-12-30T12:05:03","name":"[libcamera-devel,v2,18/25] libcamera: pipelines: Add FrameBuffer handlers","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"964e89cd7ccc57cced0fe78bd0971908bb907dbd","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/?format=json","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/2468/mbox/","series":[{"id":593,"url":"https://patchwork.libcamera.org/api/series/593/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=593","date":"2019-12-30T12:04:45","name":"libcamera: Rework buffer API","version":2,"mbox":"https://patchwork.libcamera.org/series/593/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/2468/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/2468/checks/","tags":{},"headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net\n\t[195.74.38.228])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 03CC16046A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 30 Dec 2019 13:06:05 +0100 (CET)","from bismarck.berto.se (p4fca2fd0.dip0.t-ipconnect.de\n\t[79.202.47.208]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA\n\tid c0e1eaf5-2afc-11ea-a00b-005056917a89;\n\tMon, 30 Dec 2019 13:06:04 +0100 (CET)"],"X-Halon-ID":"c0e1eaf5-2afc-11ea-a00b-005056917a89","Authorized-sender":"niklas@soderlund.pp.se","From":"=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","To":"libcamera-devel@lists.libcamera.org","Date":"Mon, 30 Dec 2019 13:05:03 +0100","Message-Id":"<20191230120510.938333-19-niklas.soderlund@ragnatech.se>","X-Mailer":"git-send-email 2.24.1","In-Reply-To":"<20191230120510.938333-1-niklas.soderlund@ragnatech.se>","References":"<20191230120510.938333-1-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH v2 18/25] libcamera: pipelines: Add\n\tFrameBuffer handlers","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>","X-List-Received-Date":"Mon, 30 Dec 2019 12:06:06 -0000"},"content":"Extend the pipeline handlers to support the FrameBuffer API with three\nnew methods to handle allocation, importing and freeing of buffers. The\nnew methods will replace allocateBuffers() and freeBuffers().\n\nThe FrameBuffer API will use the methods on a stream level and either\nallocate or import buffers for each active stream controlled from the\nCamera class and an upcoming FrameBufferAllocator helper. With this new\nAPI the implementation in pipeline handlers can be made simpler as all\nstreams don't need to be handled in allocateBuffers().\n\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n---\n src/libcamera/include/pipeline_handler.h |  7 +++\n src/libcamera/pipeline/ipu3/ipu3.cpp     | 34 +++++++++++++\n src/libcamera/pipeline/rkisp1/rkisp1.cpp | 25 ++++++++++\n src/libcamera/pipeline/uvcvideo.cpp      | 31 ++++++++++++\n src/libcamera/pipeline/vimc.cpp          | 31 ++++++++++++\n src/libcamera/pipeline_handler.cpp       | 62 ++++++++++++++++++++++++\n 6 files changed, 190 insertions(+)","diff":"diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h\nindex f3622631022d87b9..520d3fccaaa130cc 100644\n--- a/src/libcamera/include/pipeline_handler.h\n+++ b/src/libcamera/include/pipeline_handler.h\n@@ -69,6 +69,13 @@ public:\n \t\tconst StreamRoles &roles) = 0;\n \tvirtual int configure(Camera *camera, CameraConfiguration *config) = 0;\n \n+\tvirtual int allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t unsigned int count,\n+\t\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;\n+\tvirtual int importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t       unsigned int count) = 0;\n+\tvirtual void freeFrameBuffers(Camera *camera, Stream *stream) = 0;\n+\n \tvirtual int allocateBuffers(Camera *camera,\n \t\t\t\t    const std::set<Stream *> &streams) = 0;\n \tvirtual int freeBuffers(Camera *camera,\ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 030ba2b6a0df2e0b..f9bddcc88523301f 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -210,6 +210,13 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n+\tint allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t unsigned int count,\n+\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n+\tint importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t       unsigned int count) override;\n+\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n+\n \tint allocateBuffers(Camera *camera,\n \t\t\t    const std::set<Stream *> &streams) override;\n \tint freeBuffers(Camera *camera,\n@@ -616,6 +623,33 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \treturn 0;\n }\n \n+int PipelineHandlerIPU3::allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t      unsigned int count,\n+\t\t\t\t\t      std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n+{\n+\tIPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);\n+\tV4L2VideoDevice *video = ipu3stream->device_->dev;\n+\n+\treturn video->exportBuffers(count, buffers);\n+}\n+\n+int PipelineHandlerIPU3::importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t    unsigned int count)\n+{\n+\tIPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);\n+\tV4L2VideoDevice *video = ipu3stream->device_->dev;\n+\n+\treturn video->importBuffers(count);\n+}\n+\n+void PipelineHandlerIPU3::freeFrameBuffers(Camera *camera, Stream *stream)\n+{\n+\tIPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);\n+\tV4L2VideoDevice *video = ipu3stream->device_->dev;\n+\n+\tvideo->releaseBuffers();\n+}\n+\n /**\n  * \\todo Clarify if 'viewfinder' and 'stat' nodes have to be set up and\n  * started even if not in use. As of now, if not properly configured and\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex ea581aaaa85088cd..e77925f6f9deff08 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -175,6 +175,13 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n+\tint allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t unsigned int count,\n+\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n+\tint importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t       unsigned int count) override;\n+\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n+\n \tint allocateBuffers(Camera *camera,\n \t\tconst std::set<Stream *> &streams) override;\n \tint freeBuffers(Camera *camera,\n@@ -666,6 +673,24 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)\n \treturn 0;\n }\n \n+int PipelineHandlerRkISP1::allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t\tunsigned int count,\n+\t\t\t\t\t\tstd::vector<std::unique_ptr<FrameBuffer>> *buffers)\n+{\n+\treturn video_->exportBuffers(count, buffers);\n+}\n+\n+int PipelineHandlerRkISP1::importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t      unsigned int count)\n+{\n+\treturn video_->importBuffers(count);\n+}\n+\n+void PipelineHandlerRkISP1::freeFrameBuffers(Camera *camera, Stream *stream)\n+{\n+\tvideo_->releaseBuffers();\n+}\n+\n int PipelineHandlerRkISP1::allocateBuffers(Camera *camera,\n \t\t\t\t\t   const std::set<Stream *> &streams)\n {\ndiff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\nindex 3043366bee38bcfc..655c5e6d96a696d6 100644\n--- a/src/libcamera/pipeline/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo.cpp\n@@ -64,6 +64,13 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n+\tint allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t unsigned int count,\n+\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n+\tint importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t       unsigned int count) override;\n+\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n+\n \tint allocateBuffers(Camera *camera,\n \t\t\t    const std::set<Stream *> &streams) override;\n \tint freeBuffers(Camera *camera,\n@@ -192,6 +199,30 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config)\n \treturn 0;\n }\n \n+int PipelineHandlerUVC::allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t     unsigned int count,\n+\t\t\t\t\t     std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n+{\n+\tUVCCameraData *data = cameraData(camera);\n+\n+\treturn data->video_->exportBuffers(count, buffers);\n+}\n+\n+int PipelineHandlerUVC::importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t   unsigned int count)\n+{\n+\tUVCCameraData *data = cameraData(camera);\n+\n+\treturn data->video_->importBuffers(count);\n+}\n+\n+void PipelineHandlerUVC::freeFrameBuffers(Camera *camera, Stream *stream)\n+{\n+\tUVCCameraData *data = cameraData(camera);\n+\n+\tdata->video_->releaseBuffers();\n+}\n+\n int PipelineHandlerUVC::allocateBuffers(Camera *camera,\n \t\t\t\t\tconst std::set<Stream *> &streams)\n {\ndiff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\nindex 292900bcf8d1b359..02235ffb0515982f 100644\n--- a/src/libcamera/pipeline/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc.cpp\n@@ -82,6 +82,13 @@ public:\n \t\tconst StreamRoles &roles) override;\n \tint configure(Camera *camera, CameraConfiguration *config) override;\n \n+\tint allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t unsigned int count,\n+\t\t\t\t std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n+\tint importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t       unsigned int count) override;\n+\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n+\n \tint allocateBuffers(Camera *camera,\n \t\t\t    const std::set<Stream *> &streams) override;\n \tint freeBuffers(Camera *camera,\n@@ -259,6 +266,30 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)\n \treturn 0;\n }\n \n+int PipelineHandlerVimc::allocateFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t      unsigned int count,\n+\t\t\t\t\t      std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n+{\n+\tVimcCameraData *data = cameraData(camera);\n+\n+\treturn data->video_->exportBuffers(count, buffers);\n+}\n+\n+int PipelineHandlerVimc::importFrameBuffers(Camera *camera, Stream *stream,\n+\t\t\t\t\t    unsigned int count)\n+{\n+\tVimcCameraData *data = cameraData(camera);\n+\n+\treturn data->video_->importBuffers(count);\n+}\n+\n+void PipelineHandlerVimc::freeFrameBuffers(Camera *camera, Stream *stream)\n+{\n+\tVimcCameraData *data = cameraData(camera);\n+\n+\tdata->video_->releaseBuffers();\n+}\n+\n int PipelineHandlerVimc::allocateBuffers(Camera *camera,\n \t\t\t\t\t const std::set<Stream *> &streams)\n {\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex 5badf31ce793edf8..fb69ca8e97216e6c 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -287,6 +287,68 @@ const ControlInfoMap &PipelineHandler::controls(Camera *camera)\n  * \\return 0 on success or a negative error code otherwise\n  */\n \n+/**\n+ * \\fn PipelineHandler::allocateFrameBuffers()\n+ * \\brief Allocate buffers for \\a stream\n+ * \\param[in] camera The camera to allocate buffers on\n+ * \\param[in] stream The stream to allocate buffers for\n+ * \\param[in] count Number of buffers to allocate\n+ * \\param[out] buffers Array of buffers successfully allocated\n+ *\n+ * Allocate buffers for \\a stream using the resources associated with the stream\n+ * inside the pipelinehandler.\n+ *\n+ * The method could be called multiple times to operate on different streams.\n+ * It is not allowed to call allocateFrameBuffers() and importFrameBuffers()\n+ * on the same \\a stream as they are mutually exclusive operations. The\n+ * pipelinehandler must guarantee that all streams exposed as part of the Camera\n+ * can be used simultaneously with all combinations of the two.\n+ *\n+ * This is a helper which may be used by libcamera helper classes to allocate\n+ * buffers from the stream itself. The allocated buffers may then be treated\n+ * in the same way as if they where externally allocated.\n+ *\n+ * The only intended caller is the FrameBufferAllocator helper.\n+ *\n+ * \\return 0 on success or a negative error code otherwise\n+ */\n+\n+/**\n+ * \\fn PipelineHandler::importFrameBuffers()\n+ * \\brief Prepare \\a stream to use external buffers\n+ * \\param[in] camera The camera to prepare for import on\n+ * \\param[in] stream The stream to prepare for import\n+ * \\param[in] count Number of buffers to import\n+ *\n+ * Prepare the \\a stream to use \\a count number of buffers allocated outside\n+ * the pipelinehandler.\n+ *\n+ * The method could be called multiple times to operate on different streams.\n+ * It is not allowed to call allocateFrameBuffers() and importFrameBuffers()\n+ * on the same \\a stream as they are mutually exclusive operations. The\n+ * pipelinehandler must guarantee that all streams exposed as part of the Camera\n+ * can be used simultaneously with all combinations of the two.\n+ *\n+ * This is a helper which may be used by libcamera helper classes to import\n+ * buffers to the \\a stream from external sources.\n+ *\n+ * The only intended caller is the FrameBufferAllocator helper.\n+ *\n+ * \\return 0 on success or a negative error code otherwise\n+ */\n+\n+/**\n+ * \\fn PipelineHandler::freeFrameBuffers()\n+ * \\brief Free buffers allocated from the stram\n+ * \\param[in] camera The camera to free buffers on\n+ * \\param[in] stream The stream to free buffers for\n+ *\n+ * This is a helper that frees buffers and resources allocated using\n+ * allocateFrameBuffers() or importFrameBuffers().\n+ *\n+ * The only intended caller is the FrameBufferAllocator helper.\n+ */\n+\n /**\n  * \\fn PipelineHandler::allocateBuffers()\n  * \\brief Allocate buffers for a stream\n","prefixes":["libcamera-devel","v2","18/25"]}