[{"id":5099,"web_url":"https://patchwork.libcamera.org/comment/5099/","msgid":"<20200606215447.GH7339@pendragon.ideasonboard.com>","date":"2020-06-06T21:54:47","subject":"Re: [libcamera-devel] [PATCH v2 09/10] libcamera: ipu3: cio2: Hide\n\tbuffer allocation and freeing from users","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nThank you for the patch.\n\nOn Sat, Jun 06, 2020 at 05:04:35PM +0200, Niklas Söderlund wrote:\n> The allocation and freeing of buffers for the CIO2 is handled in the\n> IPU3 pipeline handlers start() and stop() functions. These functions\n> also calls CIO2Device start() and stop() at the appropriate times so\n\ns/calls/call/\n\n> move the CIO2 buffer allocation/freeing inside the CIO2Device and reduce\n> the complexity of the exposed interface.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n> * Changes since v1\n> - Fix potential leaking of buffers if start fails.\n> ---\n>  src/libcamera/pipeline/ipu3/cio2.cpp | 63 +++++++++++++---------------\n>  src/libcamera/pipeline/ipu3/cio2.h   |  2 -\n>  src/libcamera/pipeline/ipu3/ipu3.cpp | 10 +----\n>  3 files changed, 30 insertions(+), 45 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\n> index 2399be8de974ff92..9298f10d8d8c07f7 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.cpp\n> +++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n> @@ -229,44 +229,12 @@ CIO2Device::generateConfiguration(const PixelFormat desiredPixelFormat,\n>  \treturn cfg;\n>  }\n>  \n> -/**\n> - * \\brief Allocate frame buffers for the CIO2 output\n> - *\n> - * Allocate frame buffers in the CIO2 video device to be used to capture frames\n> - * from the CIO2 output. The buffers are stored in the CIO2Device::buffers_\n> - * vector.\n> - *\n> - * \\return Number of buffers allocated or negative error code\n> - */\n> -int CIO2Device::allocateBuffers()\n> -{\n> -\tint ret = output_->allocateBuffers(CIO2_BUFFER_COUNT, &buffers_);\n> -\tif (ret < 0)\n> -\t\treturn ret;\n> -\n> -\tfor (std::unique_ptr<FrameBuffer> &buffer : buffers_)\n> -\t\tavailableBuffers_.push(buffer.get());\n> -\n> -\treturn ret;\n> -}\n> -\n>  int CIO2Device::exportBuffers(unsigned int count,\n>  \t\t\t      std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n>  {\n>  \treturn output_->exportBuffers(count, buffers);\n>  }\n>  \n> -void CIO2Device::freeBuffers()\n> -{\n> -\t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> -\tavailableBuffers_ = std::queue<FrameBuffer *>{};\n> -\n> -\tbuffers_.clear();\n> -\n> -\tif (output_->releaseBuffers())\n> -\t\tLOG(IPU3, Error) << \"Failed to release CIO2 buffers\";\n> -}\n\nShould you keep this function and make it private, to be called from\nstart() and stop() ? One may wonder why we don't have a private\nallocateBuffers() then, I'll leave that one up to you.\n\n> -\n>  FrameBuffer *CIO2Device::getBuffer()\n>  {\n>  \tif (availableBuffers_.empty()) {\n> @@ -288,12 +256,39 @@ void CIO2Device::putBuffer(FrameBuffer *buffer)\n>  \n>  int CIO2Device::start()\n>  {\n> -\treturn output_->streamOn();\n> +\tint ret = output_->allocateBuffers(CIO2_BUFFER_COUNT, &buffers_);\n> +\tif (ret < 0)\n> +\t\treturn ret;\n> +\n> +\tfor (std::unique_ptr<FrameBuffer> &buffer : buffers_)\n> +\t\tavailableBuffers_.push(buffer.get());\n> +\n> +\tret = output_->streamOn();\n> +\tif (ret) {\n> +\t\t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> +\t\tavailableBuffers_ = std::queue<FrameBuffer *>{};\n> +\n> +\t\tbuffers_.clear();\n> +\n> +\t\toutput_->releaseBuffers();\n> +\t}\n> +\n> +\treturn ret;\n>  }\n>  \n>  int CIO2Device::stop()\n>  {\n> -\treturn output_->streamOff();\n> +\tint ret = output_->streamOff();\n> +\n> +\t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> +\tavailableBuffers_ = std::queue<FrameBuffer *>{};\n> +\n> +\tbuffers_.clear();\n> +\n> +\tif (output_->releaseBuffers())\n> +\t\tLOG(IPU3, Error) << \"Failed to release CIO2 buffers\";\n> +\n> +\treturn ret;\n>  }\n>  \n>  int CIO2Device::queueBuffer(FrameBuffer *buffer)\n> diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> index 8c3d9dd24188ef1c..ffb401da6b576556 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.h\n> +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> @@ -39,10 +39,8 @@ public:\n>  \tStreamConfiguration generateConfiguration(const PixelFormat desiredPixelFormat = {},\n>  \t\t\t\t\t\t  const Size desiredSize = {}) const;\n>  \n> -\tint allocateBuffers();\n>  \tint exportBuffers(unsigned int count,\n>  \t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n> -\tvoid freeBuffers();\n>  \n>  \tFrameBuffer *getBuffer();\n>  \tvoid putBuffer(FrameBuffer *buffer);\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 55958a6c5e64dbf1..c95c1bfbce914801 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -646,15 +646,10 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,\n>  int PipelineHandlerIPU3::allocateBuffers(Camera *camera)\n>  {\n>  \tIPU3CameraData *data = cameraData(camera);\n> -\tCIO2Device *cio2 = &data->cio2_;\n>  \tImgUDevice *imgu = data->imgu_;\n>  \tunsigned int bufferCount;\n>  \tint ret;\n>  \n> -\tret = cio2->allocateBuffers();\n> -\tif (ret < 0)\n> -\t\treturn ret;\n> -\n>  \tbufferCount = std::max({\n>  \t\tdata->outStream_.configuration().bufferCount,\n>  \t\tdata->vfStream_.configuration().bufferCount,\n> @@ -662,10 +657,8 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera)\n>  \t});\n>  \n>  \tret = imgu->allocateBuffers(data, bufferCount);\n> -\tif (ret < 0) {\n> -\t\tcio2->freeBuffers();\n> +\tif (ret < 0)\n>  \t\treturn ret;\n> -\t}\n>  \n>  \treturn 0;\n>  }\n> @@ -674,7 +667,6 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera)\n>  {\n>  \tIPU3CameraData *data = cameraData(camera);\n>  \n> -\tdata->cio2_.freeBuffers();\n\nAs commented in the review of v1, the buffers are freed when stopping\nthe CIO2, which happens before stopping the ImgU. I think that's a bit\nfragile. Could we stop the ImgU first to handle this ?\n\n>  \tdata->imgu_->freeBuffers(data);\n>  \n>  \treturn 0;","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E84B861167\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat,  6 Jun 2020 23:55:06 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5D3F530D;\n\tSat,  6 Jun 2020 23:55:06 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"G4ywNElt\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1591480506;\n\tbh=hkSoOuNB4zaPFMdK0ijnsdOB3M5x1qruXKqJMVkHKdg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=G4ywNEltTAzPxBM2mWHBZiIdr9P73GTE0yG/YlHP755ucCwzJHjYQg26bYP1RBDjK\n\tuUPkQHX+DwQYR3cc63PKsZ/TJuFrBSzsNILnIt1wwHeNpgBFo9/g/aRxHmHSEHbfPn\n\tLfr8h9+j52RYjX749o3cfuuQmiWt841RruIDnpFM=","Date":"Sun, 7 Jun 2020 00:54:47 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200606215447.GH7339@pendragon.ideasonboard.com>","References":"<20200606150436.1851700-1-niklas.soderlund@ragnatech.se>\n\t<20200606150436.1851700-10-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200606150436.1851700-10-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH v2 09/10] libcamera: ipu3: cio2: Hide\n\tbuffer allocation and freeing from users","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":"Sat, 06 Jun 2020 21:55:07 -0000"}}]