From patchwork Wed Mar 20 16:30:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 767 Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1AD50611B4 for ; Wed, 20 Mar 2019 17:30:41 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id A2582200012; Wed, 20 Mar 2019 16:30:40 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Mar 2019 17:30:45 +0100 Message-Id: <20190320163055.22056-22-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190320163055.22056-1-jacopo@jmondi.org> References: <20190320163055.22056-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 21/31] RFC: libcamera: pipeline_handlers: Add preAllocateBuffers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Mar 2019 16:30:41 -0000 Add a preAllocateBuffers virtual method to the PipelineHandler base class and call it before performing per-stream memory allocation. Implement the method in the IPU3 pipeline handler to perform memory allocation on the CIO2 unit and the ImgU input and stat video devices. Signed-off-by: Jacopo Mondi --- src/libcamera/camera.cpp | 10 ++++- src/libcamera/include/pipeline_handler.h | 5 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 54 ++++++++++++++---------- src/libcamera/pipeline_handler.cpp | 21 ++++++++- 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 8ee9cc086616..8020dff8f8ea 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -455,6 +455,8 @@ int Camera::configureStreams(std::map &config) */ int Camera::allocateBuffers() { + int ret; + if (disconnected_) return -ENODEV; @@ -467,8 +469,14 @@ int Camera::allocateBuffers() return -EINVAL; } + ret = pipe_->preAllocateBuffers(this, activeStreams_); + if (ret) { + LOG(Camera, Error) << "Buffers pre-allocation failed"; + return ret; + } + for (Stream *stream : activeStreams_) { - int ret = pipe_->allocateBuffers(this, stream); + ret = pipe_->allocateBuffers(this, stream); if (ret) { LOG(Camera, Error) << "Failed to allocate buffers"; freeBuffers(); diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index acb376e07030..7ce5b67cc7fc 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -57,6 +57,11 @@ public: virtual int configureStreams(Camera *camera, std::map &config) = 0; + virtual int preAllocateBuffers(Camera *camera, + const std::set &activeStreams) + { + return 0; + } virtual int allocateBuffers(Camera *camera, Stream *stream) = 0; virtual int freeBuffers(Camera *camera, Stream *stream) = 0; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 0507fc380e68..5f323888d84f 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -105,6 +105,8 @@ public: int configureStreams(Camera *camera, std::map &config) override; + int preAllocateBuffers(Camera *camera, + const std::set &activeStreams) override; int allocateBuffers(Camera *camera, Stream *stream) override; int freeBuffers(Camera *camera, Stream *stream) override; @@ -451,40 +453,48 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera, return 0; } -int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) +int PipelineHandlerIPU3::preAllocateBuffers(Camera *camera, + const std::set &activeStreams) { IPU3CameraData *data = cameraData(camera); - V4L2Device *viewfinder = data->imgu->viewfinder; - V4L2Device *output = data->imgu->output; V4L2Device *input = data->imgu->input; V4L2Device *cio2 = data->cio2.output; V4L2Device *stat = data->imgu->stat; ImgUDevice *imgu = data->imgu; int ret; - if (data->cio2.pool.count() == 0) { - /* Share buffers between CIO2 output and ImgU input. */ - data->cio2.pool.createBuffers(IPU3_CIO2_BUFFER_COUNT); - ret = cio2->exportBuffers(&data->cio2.pool); - if (ret) { - LOG(IPU3, Error) << "Failed to reserve CIO2 memory"; - return ret; - } + /* Share buffers between CIO2 output and ImgU input. */ + data->cio2.pool.createBuffers(IPU3_CIO2_BUFFER_COUNT); + ret = cio2->exportBuffers(&data->cio2.pool); + if (ret) { + LOG(IPU3, Error) << "Failed to reserve CIO2 memory"; + return ret; + } - ret = input->importBuffers(&data->cio2.pool); - if (ret) { - LOG(IPU3, Error) << "Failed to import ImgU memory"; - return ret; - } + ret = input->importBuffers(&data->cio2.pool); + if (ret) { + LOG(IPU3, Error) << "Failed to import ImgU memory"; + return ret; + } - imgu->statPool.createBuffers(IPU3_IMGU_BUFFER_COUNT); - ret = stat->exportBuffers(&imgu->statPool); - if (ret) { - LOG(IPU3, Error) << "Failed to reserve ImgU stat memory"; - return ret; - } + imgu->statPool.createBuffers(IPU3_IMGU_BUFFER_COUNT); + ret = stat->exportBuffers(&imgu->statPool); + if (ret) { + LOG(IPU3, Error) << "Failed to reserve ImgU stat memory"; + return ret; } + return 0; +} + +int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) +{ + IPU3CameraData *data = cameraData(camera); + V4L2Device *viewfinder = data->imgu->viewfinder; + V4L2Device *output = data->imgu->output; + ImgUDevice *imgu = data->imgu; + int ret; + if (isOutput(data, stream)) { /* Export ImgU output buffers to the stream's pool. */ ret = output->exportBuffers(&stream->bufferPool()); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 1a858f2638ce..1f556ed789b6 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -189,6 +189,24 @@ PipelineHandler::~PipelineHandler() * \return 0 on success or a negative error code otherwise */ +/** + * \fn PipelineHandler::preAllocateBuffers() + * \brief Perform operations to prepare for memory allocation. Optional for + * pipeline handlers to implement + * \param[in] camera The camera the streams belongs to + * \param[in] activeStreams The set of active streams + * + * If operations to prepare for the per-stream memory allocation are required, + * this virtual method provides an entry point for pipeline handlers to do so. + * + * This method is optional to implement for pipeline handlers, and its intended + * caller is the Camera class, which calls it once before performing per-stream + * memory allocation by calling the PipelineHandler::allocateBuffers() method + * once per each active stream. + * + * \return 0 on success or a negative error code otherwise + */ + /** * \fn PipelineHandler::allocateBuffers() * \brief Allocate buffers for a stream @@ -198,7 +216,8 @@ PipelineHandler::~PipelineHandler() * This method allocates buffers internally in the pipeline handler and * associates them with the stream's buffer pool. * - * The intended caller of this method is the Camera class. + * The intended caller of this method is the Camera class which calls it + * once per each active stream. * * \return 0 on success or a negative error code otherwise */