From patchwork Wed Apr 3 15:07:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 909 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 29B63610C5 for ; Wed, 3 Apr 2019 17:06:58 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id B87BDFF80B; Wed, 3 Apr 2019 15:06:57 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 3 Apr 2019 17:07:31 +0200 Message-Id: <20190403150735.27580-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190403150735.27580-1-jacopo@jmondi.org> References: <20190403150735.27580-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 4/8] 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, 03 Apr 2019 15:06:58 -0000 Perform allocation and setup of memory sharing betweent the CIO2 output and the ImgU input and allocate memory for each active stream. --- src/libcamera/pipeline/ipu3/ipu3.cpp | 78 ++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index a12e3f9a496d..f7e75fac1dfe 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -91,6 +91,7 @@ public: BufferPool vfPool_; BufferPool statPool_; + BufferPool outPool_; }; class CIO2Device @@ -428,13 +429,21 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera, return 0; } +/** + * \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 + * enabled, the ImgU processing pipeline stalls. + * + * In order to be able to start the 'viewfinder' and 'stat' nodes, we need + * memory to be reserved. + */ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, const std::set &streams) { IPU3CameraData *data = cameraData(camera); - Stream *stream = *streams.begin(); CIO2Device *cio2 = &data->cio2_; ImgUDevice *imgu = data->imgu_; + unsigned int bufferCount; int ret; /* Share buffers between CIO2 output and ImgU input. */ @@ -446,28 +455,64 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, if (ret) return ret; - /* Export ImgU output buffers to the stream's pool. */ - ret = imgu->exportBuffers(&imgu->output_, &stream->bufferPool()); - if (ret) - return ret; - /* - * Reserve memory in viewfinder and stat output devices. Use the - * same number of buffers as the ones requested for the output - * stream. + * Use for internal pools the same buffer number as the input + * one: it should match the pipeline lenght. */ - unsigned int bufferCount = stream->bufferPool().count(); - - imgu->viewfinder_.pool->createBuffers(bufferCount); - ret = imgu->exportBuffers(&imgu->viewfinder_, imgu->viewfinder_.pool); - if (ret) - return ret; - + bufferCount = pool->count(); imgu->stat_.pool->createBuffers(bufferCount); ret = imgu->exportBuffers(&imgu->stat_, imgu->stat_.pool); if (ret) return ret; + for (Stream *stream : streams) { + if (isOutput(data, stream)) { + /* Export output buffers to the stream's pool. */ + ret = imgu->exportBuffers(&imgu->output_, + &stream->bufferPool()); + if (ret) + return ret; + + if (isViewfinderActive(data)) + continue; + + /* + * Reserve memory in viewfinder device if it is not + * part of the active streams list. Use the same + * number of buffers as the ones requested for the + * output stream. + */ + bufferCount = stream->bufferPool().count(); + imgu->viewfinder_.pool->createBuffers(bufferCount); + ret = imgu->exportBuffers(&imgu->viewfinder_, + imgu->viewfinder_.pool); + if (ret) + return ret; + } else if (isViewfinder(data, stream)) { + /* Export viewfinder buffers to the stream's pool. */ + ret = imgu->exportBuffers(&imgu->viewfinder_, + &stream->bufferPool()); + if (ret) + return ret; + + if (isOutputActive(data)) + continue; + + /* + * Reserve memory in output device if it is not part + * of the active streams list. Use the same number + * of buffers as the ones requested for the viewfinder + * stream. + */ + bufferCount = stream->bufferPool().count(); + imgu->output_.pool->createBuffers(bufferCount); + ret = imgu->exportBuffers(&imgu->output_, + imgu->output_.pool); + if (ret) + return ret; + } + } + return 0; } @@ -819,6 +864,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index) output_.pad = PAD_OUTPUT; output_.name = "output"; + output_.pool = &outPool_; viewfinder_.dev = V4L2Device::fromEntityName(media, name_ + " viewfinder");