From patchwork Mon Dec 30 12:05:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 2468 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 03CC16046A for ; Mon, 30 Dec 2019 13:06:05 +0100 (CET) X-Halon-ID: c0e1eaf5-2afc-11ea-a00b-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2fd0.dip0.t-ipconnect.de [79.202.47.208]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id c0e1eaf5-2afc-11ea-a00b-005056917a89; Mon, 30 Dec 2019 13:06:04 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= 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 Subject: [libcamera-devel] [PATCH v2 18/25] libcamera: pipelines: Add FrameBuffer handlers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Dec 2019 12:06:06 -0000 Extend the pipeline handlers to support the FrameBuffer API with three new methods to handle allocation, importing and freeing of buffers. The new methods will replace allocateBuffers() and freeBuffers(). The FrameBuffer API will use the methods on a stream level and either allocate or import buffers for each active stream controlled from the Camera class and an upcoming FrameBufferAllocator helper. With this new API the implementation in pipeline handlers can be made simpler as all streams don't need to be handled in allocateBuffers(). Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/include/pipeline_handler.h | 7 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 34 +++++++++++++ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 25 ++++++++++ src/libcamera/pipeline/uvcvideo.cpp | 31 ++++++++++++ src/libcamera/pipeline/vimc.cpp | 31 ++++++++++++ src/libcamera/pipeline_handler.cpp | 62 ++++++++++++++++++++++++ 6 files changed, 190 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index f3622631022d87b9..520d3fccaaa130cc 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -69,6 +69,13 @@ public: const StreamRoles &roles) = 0; virtual int configure(Camera *camera, CameraConfiguration *config) = 0; + virtual int allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) = 0; + virtual int importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) = 0; + virtual void freeFrameBuffers(Camera *camera, Stream *stream) = 0; + virtual int allocateBuffers(Camera *camera, const std::set &streams) = 0; virtual int freeBuffers(Camera *camera, diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 030ba2b6a0df2e0b..f9bddcc88523301f 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -210,6 +210,13 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; + int allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) override; + int importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) override; + void freeFrameBuffers(Camera *camera, Stream *stream) override; + int allocateBuffers(Camera *camera, const std::set &streams) override; int freeBuffers(Camera *camera, @@ -616,6 +623,33 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) return 0; } +int PipelineHandlerIPU3::allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) +{ + IPU3Stream *ipu3stream = static_cast(stream); + V4L2VideoDevice *video = ipu3stream->device_->dev; + + return video->exportBuffers(count, buffers); +} + +int PipelineHandlerIPU3::importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) +{ + IPU3Stream *ipu3stream = static_cast(stream); + V4L2VideoDevice *video = ipu3stream->device_->dev; + + return video->importBuffers(count); +} + +void PipelineHandlerIPU3::freeFrameBuffers(Camera *camera, Stream *stream) +{ + IPU3Stream *ipu3stream = static_cast(stream); + V4L2VideoDevice *video = ipu3stream->device_->dev; + + video->releaseBuffers(); +} + /** * \todo Clarify if 'viewfinder' and 'stat' nodes have to be set up and * started even if not in use. As of now, if not properly configured and diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index ea581aaaa85088cd..e77925f6f9deff08 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -175,6 +175,13 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; + int allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) override; + int importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) override; + void freeFrameBuffers(Camera *camera, Stream *stream) override; + int allocateBuffers(Camera *camera, const std::set &streams) override; int freeBuffers(Camera *camera, @@ -666,6 +673,24 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) return 0; } +int PipelineHandlerRkISP1::allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) +{ + return video_->exportBuffers(count, buffers); +} + +int PipelineHandlerRkISP1::importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) +{ + return video_->importBuffers(count); +} + +void PipelineHandlerRkISP1::freeFrameBuffers(Camera *camera, Stream *stream) +{ + video_->releaseBuffers(); +} + int PipelineHandlerRkISP1::allocateBuffers(Camera *camera, const std::set &streams) { diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 3043366bee38bcfc..655c5e6d96a696d6 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -64,6 +64,13 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; + int allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) override; + int importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) override; + void freeFrameBuffers(Camera *camera, Stream *stream) override; + int allocateBuffers(Camera *camera, const std::set &streams) override; int freeBuffers(Camera *camera, @@ -192,6 +199,30 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config) return 0; } +int PipelineHandlerUVC::allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) +{ + UVCCameraData *data = cameraData(camera); + + return data->video_->exportBuffers(count, buffers); +} + +int PipelineHandlerUVC::importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) +{ + UVCCameraData *data = cameraData(camera); + + return data->video_->importBuffers(count); +} + +void PipelineHandlerUVC::freeFrameBuffers(Camera *camera, Stream *stream) +{ + UVCCameraData *data = cameraData(camera); + + data->video_->releaseBuffers(); +} + int PipelineHandlerUVC::allocateBuffers(Camera *camera, const std::set &streams) { diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 292900bcf8d1b359..02235ffb0515982f 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -82,6 +82,13 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; + int allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) override; + int importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) override; + void freeFrameBuffers(Camera *camera, Stream *stream) override; + int allocateBuffers(Camera *camera, const std::set &streams) override; int freeBuffers(Camera *camera, @@ -259,6 +266,30 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) return 0; } +int PipelineHandlerVimc::allocateFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, + std::vector> *buffers) +{ + VimcCameraData *data = cameraData(camera); + + return data->video_->exportBuffers(count, buffers); +} + +int PipelineHandlerVimc::importFrameBuffers(Camera *camera, Stream *stream, + unsigned int count) +{ + VimcCameraData *data = cameraData(camera); + + return data->video_->importBuffers(count); +} + +void PipelineHandlerVimc::freeFrameBuffers(Camera *camera, Stream *stream) +{ + VimcCameraData *data = cameraData(camera); + + data->video_->releaseBuffers(); +} + int PipelineHandlerVimc::allocateBuffers(Camera *camera, const std::set &streams) { diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 5badf31ce793edf8..fb69ca8e97216e6c 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -287,6 +287,68 @@ const ControlInfoMap &PipelineHandler::controls(Camera *camera) * \return 0 on success or a negative error code otherwise */ +/** + * \fn PipelineHandler::allocateFrameBuffers() + * \brief Allocate buffers for \a stream + * \param[in] camera The camera to allocate buffers on + * \param[in] stream The stream to allocate buffers for + * \param[in] count Number of buffers to allocate + * \param[out] buffers Array of buffers successfully allocated + * + * Allocate buffers for \a stream using the resources associated with the stream + * inside the pipelinehandler. + * + * The method could be called multiple times to operate on different streams. + * It is not allowed to call allocateFrameBuffers() and importFrameBuffers() + * on the same \a stream as they are mutually exclusive operations. The + * pipelinehandler must guarantee that all streams exposed as part of the Camera + * can be used simultaneously with all combinations of the two. + * + * This is a helper which may be used by libcamera helper classes to allocate + * buffers from the stream itself. The allocated buffers may then be treated + * in the same way as if they where externally allocated. + * + * The only intended caller is the FrameBufferAllocator helper. + * + * \return 0 on success or a negative error code otherwise + */ + +/** + * \fn PipelineHandler::importFrameBuffers() + * \brief Prepare \a stream to use external buffers + * \param[in] camera The camera to prepare for import on + * \param[in] stream The stream to prepare for import + * \param[in] count Number of buffers to import + * + * Prepare the \a stream to use \a count number of buffers allocated outside + * the pipelinehandler. + * + * The method could be called multiple times to operate on different streams. + * It is not allowed to call allocateFrameBuffers() and importFrameBuffers() + * on the same \a stream as they are mutually exclusive operations. The + * pipelinehandler must guarantee that all streams exposed as part of the Camera + * can be used simultaneously with all combinations of the two. + * + * This is a helper which may be used by libcamera helper classes to import + * buffers to the \a stream from external sources. + * + * The only intended caller is the FrameBufferAllocator helper. + * + * \return 0 on success or a negative error code otherwise + */ + +/** + * \fn PipelineHandler::freeFrameBuffers() + * \brief Free buffers allocated from the stram + * \param[in] camera The camera to free buffers on + * \param[in] stream The stream to free buffers for + * + * This is a helper that frees buffers and resources allocated using + * allocateFrameBuffers() or importFrameBuffers(). + * + * The only intended caller is the FrameBufferAllocator helper. + */ + /** * \fn PipelineHandler::allocateBuffers() * \brief Allocate buffers for a stream