[libcamera-devel] [PATCH v3 23/33] libcamera: pipeline: ipu3: Switch to FrameBuffer interface for cio2 and stat
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sat Jan 11 02:00:44 CET 2020
Hi Niklas,
Thank you for the patch.
On Fri, Jan 10, 2020 at 08:37:58PM +0100, Niklas Söderlund wrote:
> The V4L2VideoDevice class can now operate using a FrameBuffer interface,
> switch the IPU3 CIO2 and statistics buffer to use it. We can not convert
> the application facing buffers yet.
s/application facing/application-facing/
and please keep my Reviewed-by.
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> * Changes since v2
> - Fix spelling in commit message
> - Update a comment in the code path touch by this patch
> ---
> src/libcamera/pipeline/ipu3/ipu3.cpp | 107 ++++++++++++---------------
> 1 file changed, 46 insertions(+), 61 deletions(-)
>
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 34fc792977d151be..7c4539d488bd2d26 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -45,6 +45,7 @@ public:
> unsigned int pad;
> std::string name;
> BufferPool *pool;
> + std::vector<std::unique_ptr<FrameBuffer>> buffers;
> };
>
> ImgUDevice()
> @@ -70,7 +71,6 @@ public:
> int configureOutput(ImgUOutput *output,
> const StreamConfiguration &cfg);
>
> - int importInputBuffers(BufferPool *pool);
> int importOutputBuffers(ImgUOutput *output, BufferPool *pool);
> int exportOutputBuffers(ImgUOutput *output, BufferPool *pool);
> void freeBuffers();
> @@ -95,7 +95,6 @@ public:
> /* \todo Add param video device for 3A tuning */
>
> BufferPool vfPool_;
> - BufferPool statPool_;
> BufferPool outPool_;
> };
>
> @@ -120,10 +119,10 @@ public:
> int configure(const Size &size,
> V4L2DeviceFormat *outputFormat);
>
> - BufferPool *exportBuffers();
> + int allocateBuffers();
> void freeBuffers();
>
> - int start(std::vector<std::unique_ptr<Buffer>> *buffers);
> + int start();
> int stop();
>
> static int mediaBusToFormat(unsigned int code);
> @@ -132,7 +131,8 @@ public:
> V4L2Subdevice *csi2_;
> CameraSensor *sensor_;
>
> - BufferPool pool_;
> +private:
> + std::vector<std::unique_ptr<FrameBuffer>> buffers_;
> };
>
> class IPU3Stream : public Stream
> @@ -157,16 +157,14 @@ public:
> }
>
> void imguOutputBufferReady(Buffer *buffer);
> - void imguInputBufferReady(Buffer *buffer);
> - void cio2BufferReady(Buffer *buffer);
> + void imguInputBufferReady(FrameBuffer *buffer);
> + void cio2BufferReady(FrameBuffer *buffer);
>
> CIO2Device cio2_;
> ImgUDevice *imgu_;
>
> IPU3Stream outStream_;
> IPU3Stream vfStream_;
> -
> - std::vector<std::unique_ptr<Buffer>> rawBuffers_;
> };
>
> class IPU3CameraConfiguration : public CameraConfiguration
> @@ -638,24 +636,28 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
> int ret;
>
> /* Share buffers between CIO2 output and ImgU input. */
> - BufferPool *pool = cio2->exportBuffers();
> - if (!pool)
> - return -ENOMEM;
> + ret = cio2->allocateBuffers();
> + if (ret < 0)
> + return ret;
>
> - ret = imgu->importInputBuffers(pool);
> - if (ret)
> + bufferCount = ret;
> +
> + ret = imgu->input_->importBuffers(bufferCount);
> + if (ret) {
> + LOG(IPU3, Error) << "Failed to import ImgU input buffers";
> goto error;
> + }
>
> /*
> - * Use for the stat's internal pool the same number of buffer as
> - * for the input pool.
> + * Use for the stat's internal pool the same number of buffers as for
> + * the input pool.
> * \todo To be revised when we'll actually use the stat node.
> */
> - bufferCount = pool->count();
> - imgu->stat_.pool->createBuffers(bufferCount);
> - ret = imgu->exportOutputBuffers(&imgu->stat_, imgu->stat_.pool);
> - if (ret)
> + ret = imgu->stat_.dev->exportBuffers(bufferCount, &imgu->stat_.buffers);
> + if (ret < 0) {
> + LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers";
> goto error;
> + }
>
> /* Allocate buffers for each active stream. */
> for (Stream *s : streams) {
> @@ -722,7 +724,7 @@ int PipelineHandlerIPU3::start(Camera *camera)
> * Start the ImgU video devices, buffers will be queued to the
> * ImgU output and viewfinder when requests will be queued.
> */
> - ret = cio2->start(&data->rawBuffers_);
> + ret = cio2->start();
> if (ret)
> goto error;
>
> @@ -738,7 +740,6 @@ int PipelineHandlerIPU3::start(Camera *camera)
> error:
> LOG(IPU3, Error) << "Failed to start camera " << camera->name();
>
> - data->rawBuffers_.clear();
> return ret;
> }
>
> @@ -752,8 +753,6 @@ void PipelineHandlerIPU3::stop(Camera *camera)
> if (ret)
> LOG(IPU3, Warning) << "Failed to stop camera "
> << camera->name();
> -
> - data->rawBuffers_.clear();
> }
>
> int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
> @@ -885,9 +884,9 @@ int PipelineHandlerIPU3::registerCameras()
> * associated ImgU input where they get processed and
> * returned through the ImgU main and secondary outputs.
> */
> - data->cio2_.output_->bufferReady.connect(data.get(),
> + data->cio2_.output_->frameBufferReady.connect(data.get(),
> &IPU3CameraData::cio2BufferReady);
> - data->imgu_->input_->bufferReady.connect(data.get(),
> + data->imgu_->input_->frameBufferReady.connect(data.get(),
> &IPU3CameraData::imguInputBufferReady);
> data->imgu_->output_.dev->bufferReady.connect(data.get(),
> &IPU3CameraData::imguOutputBufferReady);
> @@ -925,7 +924,7 @@ int PipelineHandlerIPU3::registerCameras()
> * Buffers completed from the ImgU input are immediately queued back to the
> * CIO2 unit to continue frame capture.
> */
> -void IPU3CameraData::imguInputBufferReady(Buffer *buffer)
> +void IPU3CameraData::imguInputBufferReady(FrameBuffer *buffer)
> {
> /* \todo Handle buffer failures when state is set to BufferError. */
> if (buffer->metadata().status == FrameMetadata::FrameCancelled)
> @@ -959,7 +958,7 @@ void IPU3CameraData::imguOutputBufferReady(Buffer *buffer)
> * Buffers completed from the CIO2 are immediately queued to the ImgU unit
> * for further processing.
> */
> -void IPU3CameraData::cio2BufferReady(Buffer *buffer)
> +void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
> {
> /* \todo Handle buffer failures when state is set to BufferError. */
> if (buffer->metadata().status == FrameMetadata::FrameCancelled)
> @@ -1034,7 +1033,6 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index)
>
> stat_.pad = PAD_STAT;
> stat_.name = "stat";
> - stat_.pool = &statPool_;
>
> return 0;
> }
> @@ -1134,22 +1132,6 @@ int ImgUDevice::configureOutput(ImgUOutput *output,
> return 0;
> }
>
> -/**
> - * \brief Import buffers from \a pool into the ImgU input
> - * \param[in] pool The buffer pool to import
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::importInputBuffers(BufferPool *pool)
> -{
> - int ret = input_->importBuffers(pool);
> - if (ret) {
> - LOG(IPU3, Error) << "Failed to import ImgU input buffers";
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> /**
> * \brief Export buffers from \a output to the provided \a pool
> * \param[in] output The ImgU output device
> @@ -1448,37 +1430,40 @@ int CIO2Device::configure(const Size &size,
> }
>
> /**
> - * \brief Allocate CIO2 memory buffers and export them in a BufferPool
> + * \brief Allocate frame buffers for the CIO2 output
> *
> - * Allocate memory buffers in the CIO2 video device and export them to
> - * a buffer pool that can be imported by another device.
> + * Allocate frame buffers in the CIO2 video device to be used to capture frames
> + * from the CIO2 output. The buffers are stored in the CIO2Device::buffers_
> + * vector.
> *
> - * \return The buffer pool with export buffers on success or nullptr otherwise
> + * \return Number of buffers allocated or negative error code
> */
> -BufferPool *CIO2Device::exportBuffers()
> +int CIO2Device::allocateBuffers()
> {
> - pool_.createBuffers(CIO2_BUFFER_COUNT);
> -
> - int ret = output_->exportBuffers(&pool_);
> - if (ret) {
> + int ret = output_->exportBuffers(CIO2_BUFFER_COUNT, &buffers_);
> + if (ret < 0)
> LOG(IPU3, Error) << "Failed to export CIO2 buffers";
> - return nullptr;
> - }
>
> - return &pool_;
> + return ret;
> }
>
> void CIO2Device::freeBuffers()
> {
> + buffers_.clear();
> +
> if (output_->releaseBuffers())
> LOG(IPU3, Error) << "Failed to release CIO2 buffers";
> }
>
> -int CIO2Device::start(std::vector<std::unique_ptr<Buffer>> *buffers)
> +int CIO2Device::start()
> {
> - *buffers = output_->queueAllBuffers();
> - if (buffers->empty())
> - return -EINVAL;
> + for (const std::unique_ptr<FrameBuffer> &buffer : buffers_) {
> + int ret = output_->queueBuffer(buffer.get());
> + if (ret) {
> + LOG(IPU3, Error) << "Failed to queue CIO2 buffer";
> + return ret;
> + }
> + }
>
> return output_->streamOn();
> }
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list