From patchwork Wed Mar 20 16:30:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 766 Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 779986110A for ; Wed, 20 Mar 2019 17:30:40 +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 1779520000D; Wed, 20 Mar 2019 16:30:39 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Mar 2019 17:30:44 +0100 Message-Id: <20190320163055.22056-21-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 20/31] libcamera: ipu3: Add multiple stream memory management 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:40 -0000 Add support for allocating and freeing memory for multiple streams. --- src/libcamera/pipeline/ipu3/ipu3.cpp | 140 ++++++++++++++++++--------- 1 file changed, 96 insertions(+), 44 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 4ed8c1fec1e3..0507fc380e68 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -70,6 +70,7 @@ public: BufferPool vfPool; BufferPool statPool; + BufferPool outputPool; }; struct CIO2Device { @@ -458,42 +459,70 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) V4L2Device *input = data->imgu->input; V4L2Device *cio2 = data->cio2.output; V4L2Device *stat = data->imgu->stat; + ImgUDevice *imgu = data->imgu; int 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; - } + 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; + } - 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; + } - /* Prepare the buffer pools for viewfinder and stat. */ - data->imgu->vfPool.createBuffers(IPU3_IMGU_BUFFER_COUNT); - ret = viewfinder->exportBuffers(&data->imgu->vfPool); - if (ret) { - LOG(IPU3, Error) << "Failed to reserve ImgU viewfinder 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; + } } - data->imgu->statPool.createBuffers(IPU3_IMGU_BUFFER_COUNT); - ret = stat->exportBuffers(&data->imgu->statPool); - if (ret) { - LOG(IPU3, Error) << "Failed to reserve ImgU stat memory"; - return ret; - } + if (isOutput(data, stream)) { + /* Export ImgU output buffers to the stream's pool. */ + ret = output->exportBuffers(&stream->bufferPool()); + if (ret) { + LOG(IPU3, Error) + << "Failed to reserve ImgU output memory"; + return ret; + } - /* Export ImgU output buffers to the stream's pool. */ - ret = output->exportBuffers(&stream->bufferPool()); - if (ret) { - LOG(IPU3, Error) << "Failed to reserve ImgU output memory"; - return ret; + if (!isViewfinderActive(data)) { + /* Internally allocate buffers for viewfinder. */ + imgu->vfPool.createBuffers(IPU3_IMGU_BUFFER_COUNT); + ret = viewfinder->exportBuffers(&imgu->vfPool); + if (ret) { + LOG(IPU3, Error) + << "Failed to reserve ImgU viewfinder memory"; + return ret; + } + } + } else if (isViewfinder(data, stream)) { + /* Export ImgU viewfinder buffers to the stream's pool. */ + ret = viewfinder->exportBuffers(&stream->bufferPool()); + if (ret) { + LOG(IPU3, Error) + << "Failed to reserve ImgU viewfinder memory"; + return ret; + } + + if (!isOutputActive(data)) { + /* Internally allocate buffers for output. */ + imgu->outputPool.createBuffers(IPU3_IMGU_BUFFER_COUNT); + ret = output->exportBuffers(&imgu->outputPool); + if (ret) { + LOG(IPU3, Error) + << "Failed to reserve ImgU output memory"; + return ret; + } + } } return 0; @@ -509,25 +538,48 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera, Stream *stream) V4L2Device *stat = data->imgu->stat; int ret; - ret = output->releaseBuffers(); - if (ret) - LOG(IPU3, Error) << "Failed to release ImgU output memory"; + if (data->cio2.pool.count()) { + ret = input->releaseBuffers(); + if (ret) + LOG(IPU3, Error) << "Failed to release ImgU input memory"; - ret = stat->releaseBuffers(); - if (ret) - LOG(IPU3, Error) << "Failed to release ImgU stat memory"; + ret = cio2->releaseBuffers(); + if (ret) + LOG(IPU3, Error) << "Failed to release CIO2 memory"; - ret = viewfinder->releaseBuffers(); - if (ret) - LOG(IPU3, Error) << "Failed to release ImgU viewfinder memory"; + ret = stat->releaseBuffers(); + if (ret) + LOG(IPU3, Error) << "Failed to release ImgU stat memory"; - ret = input->releaseBuffers(); - if (ret) - LOG(IPU3, Error) << "Failed to release ImgU input memory"; + } - ret = cio2->releaseBuffers(); - if (ret) - LOG(IPU3, Error) << "Failed to release CIO2 memory"; + if (isOutput(data, stream)) { + ret = output->releaseBuffers(); + if (ret) + LOG(IPU3, Error) + << "Failed to release ImgU output memory"; + + if (isViewfinderActive(data)) + return 0; + + ret = viewfinder->releaseBuffers(); + if (ret) + LOG(IPU3, Error) + << "Failed to release ImgU viewfinder memory"; + } else if (isViewfinder(data, stream)) { + ret = viewfinder->releaseBuffers(); + if (ret) + LOG(IPU3, Error) + << "Failed to release ImgU viewfinder memory"; + + if (isOutputActive(data)) + return 0; + + ret = output->releaseBuffers(); + if (ret) + LOG(IPU3, Error) + << "Failed to release ImgU output memory"; + } return 0; }