[libcamera-devel] [PATCH v2 05/13] libcamera: ipu3: imgu: Move the ImgUDevice class to separate files

Laurent Pinchart laurent.pinchart at ideasonboard.com
Sun Jun 28 08:59:11 CEST 2020


Hi Niklas,

Thank you for the patch.

On Sun, Jun 28, 2020 at 02:15:24AM +0200, Niklas Söderlund wrote:
> In preparation of refactoring the IPU3 pipeline handler breakout the
> ImgUDevice into its own .cpp and .h file, no functional change.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
> ---
> * Changes since v1
> - Remove stray newline
> ---
>  src/libcamera/pipeline/ipu3/imgu.cpp    | 355 +++++++++++++++++++++
>  src/libcamera/pipeline/ipu3/imgu.h      |  86 +++++
>  src/libcamera/pipeline/ipu3/ipu3.cpp    | 404 +-----------------------
>  src/libcamera/pipeline/ipu3/meson.build |   1 +
>  4 files changed, 443 insertions(+), 403 deletions(-)
>  create mode 100644 src/libcamera/pipeline/ipu3/imgu.cpp
>  create mode 100644 src/libcamera/pipeline/ipu3/imgu.h
> 
> diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp
> new file mode 100644
> index 0000000000000000..8965a51c5d26f8ae
> --- /dev/null
> +++ b/src/libcamera/pipeline/ipu3/imgu.cpp
> @@ -0,0 +1,355 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * imgu.cpp - Intel IPU3 ImgU
> + */
> +
> +#include "imgu.h"
> +
> +#include <linux/media-bus-format.h>
> +
> +#include <libcamera/formats.h>
> +#include <libcamera/stream.h>
> +
> +#include "libcamera/internal/log.h"
> +#include "libcamera/internal/media_device.h"
> +
> +namespace libcamera {
> +
> +LOG_DECLARE_CATEGORY(IPU3)
> +
> +/**
> + * \brief Initialize components of the ImgU instance
> + * \param[in] mediaDevice The ImgU instance media device
> + * \param[in] index The ImgU instance index
> + *
> + * Create and open the V4L2 devices and subdevices of the ImgU instance
> + * with \a index.
> + *
> + * In case of errors the created V4L2VideoDevice and V4L2Subdevice instances
> + * are destroyed at pipeline handler delete time.
> + *
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::init(MediaDevice *media, unsigned int index)
> +{
> +	int ret;
> +
> +	index_ = index;
> +	name_ = "ipu3-imgu " + std::to_string(index_);
> +	media_ = media;
> +
> +	/*
> +	 * The media entities presence in the media device has been verified
> +	 * by the match() function: no need to check for newly created
> +	 * video devices and subdevice validity here.
> +	 */
> +	imgu_ = V4L2Subdevice::fromEntityName(media, name_);
> +	ret = imgu_->open();
> +	if (ret)
> +		return ret;
> +
> +	input_ = V4L2VideoDevice::fromEntityName(media, name_ + " input");
> +	ret = input_->open();
> +	if (ret)
> +		return ret;
> +
> +	output_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " output");
> +	ret = output_.dev->open();
> +	if (ret)
> +		return ret;
> +
> +	output_.pad = PAD_OUTPUT;
> +	output_.name = "output";
> +
> +	viewfinder_.dev = V4L2VideoDevice::fromEntityName(media,
> +							  name_ + " viewfinder");
> +	ret = viewfinder_.dev->open();
> +	if (ret)
> +		return ret;
> +
> +	viewfinder_.pad = PAD_VF;
> +	viewfinder_.name = "viewfinder";
> +
> +	stat_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " 3a stat");
> +	ret = stat_.dev->open();
> +	if (ret)
> +		return ret;
> +
> +	stat_.pad = PAD_STAT;
> +	stat_.name = "stat";
> +
> +	return 0;
> +}
> +
> +/**
> + * \brief Configure the ImgU unit input
> + * \param[in] size The ImgU input frame size
> + * \param[in] inputFormat The format to be applied to ImgU input
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::configureInput(const Size &size,
> +			       V4L2DeviceFormat *inputFormat)
> +{
> +	/* Configure the ImgU input video device with the requested sizes. */
> +	int ret = input_->setFormat(inputFormat);
> +	if (ret)
> +		return ret;
> +
> +	LOG(IPU3, Debug) << "ImgU input format = " << inputFormat->toString();
> +
> +	/*
> +	 * \todo The IPU3 driver implementation shall be changed to use the
> +	 * input sizes as 'ImgU Input' subdevice sizes, and use the desired
> +	 * GDC output sizes to configure the crop/compose rectangles.
> +	 *
> +	 * The current IPU3 driver implementation uses GDC sizes as the
> +	 * 'ImgU Input' subdevice sizes, and the input video device sizes
> +	 * to configure the crop/compose rectangles, contradicting the
> +	 * V4L2 specification.
> +	 */
> +	Rectangle rect = {
> +		.x = 0,
> +		.y = 0,
> +		.width = inputFormat->size.width,
> +		.height = inputFormat->size.height,
> +	};
> +	ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_CROP, &rect);
> +	if (ret)
> +		return ret;
> +
> +	ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_COMPOSE, &rect);
> +	if (ret)
> +		return ret;
> +
> +	LOG(IPU3, Debug) << "ImgU input feeder and BDS rectangle = "
> +			 << rect.toString();
> +
> +	V4L2SubdeviceFormat imguFormat = {};
> +	imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> +	imguFormat.size = size;
> +
> +	ret = imgu_->setFormat(PAD_INPUT, &imguFormat);
> +	if (ret)
> +		return ret;
> +
> +	LOG(IPU3, Debug) << "ImgU GDC format = " << imguFormat.toString();
> +
> +	return 0;
> +}
> +
> +/**
> + * \brief Configure the ImgU unit \a id video output
> + * \param[in] output The ImgU output device to configure
> + * \param[in] cfg The requested configuration
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::configureOutput(ImgUOutput *output,
> +				const StreamConfiguration &cfg,
> +				V4L2DeviceFormat *outputFormat)
> +{
> +	V4L2VideoDevice *dev = output->dev;
> +	unsigned int pad = output->pad;
> +
> +	V4L2SubdeviceFormat imguFormat = {};
> +	imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> +	imguFormat.size = cfg.size;
> +
> +	int ret = imgu_->setFormat(pad, &imguFormat);
> +	if (ret)
> +		return ret;
> +
> +	/* No need to apply format to the stat node. */
> +	if (output == &stat_)
> +		return 0;
> +
> +	*outputFormat = {};
> +	outputFormat->fourcc = dev->toV4L2PixelFormat(formats::NV12);
> +	outputFormat->size = cfg.size;
> +	outputFormat->planesCount = 2;
> +
> +	ret = dev->setFormat(outputFormat);
> +	if (ret)
> +		return ret;
> +
> +	LOG(IPU3, Debug) << "ImgU " << output->name << " format = "
> +			 << outputFormat->toString();
> +
> +	return 0;
> +}
> +
> +/**
> + * \brief Allocate buffers for all the ImgU video devices
> + */
> +int ImgUDevice::allocateBuffers(unsigned int bufferCount)
> +{
> +	/* Share buffers between CIO2 output and ImgU input. */
> +	int ret = input_->importBuffers(bufferCount);
> +	if (ret) {
> +		LOG(IPU3, Error) << "Failed to import ImgU input buffers";
> +		return ret;
> +	}
> +
> +	/*
> +	 * The kernel fails to start if buffers are not either imported or
> +	 * allocated for the statisitcs video device. As statistics buffers are
> +	 * not yet used by the pipeline import buffers to save memory.
> +	 *
> +	 * \todo To be revised when we'll actually use the stat node.
> +	 */
> +	ret = stat_.dev->importBuffers(bufferCount);
> +	if (ret < 0) {
> +		LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers";
> +		goto error;
> +	}
> +
> +	/*
> +	 * Import buffers for all outputs, regardless of whether the
> +	 * corresponding stream is active or inactive, as the driver needs
> +	 * buffers to be requested on the V4L2 devices in order to operate.
> +	 */
> +	ret = output_.dev->importBuffers(bufferCount);
> +	if (ret < 0) {
> +		LOG(IPU3, Error) << "Failed to import ImgU output buffers";
> +		goto error;
> +	}
> +
> +	ret = viewfinder_.dev->importBuffers(bufferCount);
> +	if (ret < 0) {
> +		LOG(IPU3, Error) << "Failed to import ImgU viewfinder buffers";
> +		goto error;
> +	}
> +
> +	return 0;
> +
> +error:
> +	freeBuffers();
> +
> +	return ret;
> +}
> +
> +/**
> + * \brief Release buffers for all the ImgU video devices
> + */
> +void ImgUDevice::freeBuffers()
> +{
> +	int ret;
> +
> +	ret = output_.dev->releaseBuffers();
> +	if (ret)
> +		LOG(IPU3, Error) << "Failed to release ImgU output buffers";
> +
> +	ret = stat_.dev->releaseBuffers();
> +	if (ret)
> +		LOG(IPU3, Error) << "Failed to release ImgU stat buffers";
> +
> +	ret = viewfinder_.dev->releaseBuffers();
> +	if (ret)
> +		LOG(IPU3, Error) << "Failed to release ImgU viewfinder buffers";
> +
> +	ret = input_->releaseBuffers();
> +	if (ret)
> +		LOG(IPU3, Error) << "Failed to release ImgU input buffers";
> +}
> +
> +int ImgUDevice::start()
> +{
> +	int ret;
> +
> +	/* Start the ImgU video devices. */
> +	ret = output_.dev->streamOn();
> +	if (ret) {
> +		LOG(IPU3, Error) << "Failed to start ImgU output";
> +		return ret;
> +	}
> +
> +	ret = viewfinder_.dev->streamOn();
> +	if (ret) {
> +		LOG(IPU3, Error) << "Failed to start ImgU viewfinder";
> +		return ret;
> +	}
> +
> +	ret = stat_.dev->streamOn();
> +	if (ret) {
> +		LOG(IPU3, Error) << "Failed to start ImgU stat";
> +		return ret;
> +	}
> +
> +	ret = input_->streamOn();
> +	if (ret) {
> +		LOG(IPU3, Error) << "Failed to start ImgU input";
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +int ImgUDevice::stop()
> +{
> +	int ret;
> +
> +	ret = output_.dev->streamOff();
> +	ret |= viewfinder_.dev->streamOff();
> +	ret |= stat_.dev->streamOff();
> +	ret |= input_->streamOff();
> +
> +	return ret;
> +}
> +
> +/**
> + * \brief Enable or disable a single link on the ImgU instance
> + *
> + * This method assumes the media device associated with the ImgU instance
> + * is open.
> + *
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::linkSetup(const std::string &source, unsigned int sourcePad,
> +			  const std::string &sink, unsigned int sinkPad,
> +			  bool enable)
> +{
> +	MediaLink *link = media_->link(source, sourcePad, sink, sinkPad);
> +	if (!link) {
> +		LOG(IPU3, Error)
> +			<< "Failed to get link: '" << source << "':"
> +			<< sourcePad << " -> '" << sink << "':" << sinkPad;
> +		return -ENODEV;
> +	}
> +
> +	return link->setEnabled(enable);
> +}
> +
> +/**
> + * \brief Enable or disable all media links in the ImgU instance to prepare
> + * for capture operations
> + *
> + * \todo This method will probably be removed or changed once links will be
> + * enabled or disabled selectively.
> + *
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::enableLinks(bool enable)
> +{
> +	std::string viewfinderName = name_ + " viewfinder";
> +	std::string outputName = name_ + " output";
> +	std::string statName = name_ + " 3a stat";
> +	std::string inputName = name_ + " input";
> +	int ret;
> +
> +	ret = linkSetup(inputName, 0, name_, PAD_INPUT, enable);
> +	if (ret)
> +		return ret;
> +
> +	ret = linkSetup(name_, PAD_OUTPUT, outputName, 0, enable);
> +	if (ret)
> +		return ret;
> +
> +	ret = linkSetup(name_, PAD_VF, viewfinderName, 0, enable);
> +	if (ret)
> +		return ret;
> +
> +	return linkSetup(name_, PAD_STAT, statName, 0, enable);
> +}
> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h
> new file mode 100644
> index 0000000000000000..9bb1b88e2ca8ea2d
> --- /dev/null
> +++ b/src/libcamera/pipeline/ipu3/imgu.h
> @@ -0,0 +1,86 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * imgu.h - Intel IPU3 ImgU
> + */
> +#ifndef __LIBCAMERA_PIPELINE_IPU3_IMGU_H__
> +#define __LIBCAMERA_PIPELINE_IPU3_IMGU_H__
> +
> +#include <memory>
> +#include <string>
> +#include <vector>

I think memory and vector are not needed here (don't forget then to
include memory in patch 13/13).

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> +
> +#include "libcamera/internal/v4l2_subdevice.h"
> +#include "libcamera/internal/v4l2_videodevice.h"
> +
> +namespace libcamera {
> +
> +class FrameBuffer;
> +class MediaDevice;
> +struct Size;
> +struct StreamConfiguration;
> +
> +class ImgUDevice
> +{
> +public:
> +	static constexpr unsigned int PAD_INPUT = 0;
> +	static constexpr unsigned int PAD_OUTPUT = 2;
> +	static constexpr unsigned int PAD_VF = 3;
> +	static constexpr unsigned int PAD_STAT = 4;
> +
> +	/* ImgU output descriptor: group data specific to an ImgU output. */
> +	struct ImgUOutput {
> +		V4L2VideoDevice *dev;
> +		unsigned int pad;
> +		std::string name;
> +	};
> +
> +	ImgUDevice()
> +		: imgu_(nullptr), input_(nullptr)
> +	{
> +		output_.dev = nullptr;
> +		viewfinder_.dev = nullptr;
> +		stat_.dev = nullptr;
> +	}
> +
> +	~ImgUDevice()
> +	{
> +		delete imgu_;
> +		delete input_;
> +		delete output_.dev;
> +		delete viewfinder_.dev;
> +		delete stat_.dev;
> +	}
> +
> +	int init(MediaDevice *media, unsigned int index);
> +	int configureInput(const Size &size, V4L2DeviceFormat *inputFormat);
> +	int configureOutput(ImgUOutput *output, const StreamConfiguration &cfg,
> +			    V4L2DeviceFormat *outputFormat);
> +
> +	int allocateBuffers(unsigned int bufferCount);
> +	void freeBuffers();
> +
> +	int start();
> +	int stop();
> +
> +	int linkSetup(const std::string &source, unsigned int sourcePad,
> +		      const std::string &sink, unsigned int sinkPad,
> +		      bool enable);
> +	int enableLinks(bool enable);
> +
> +	unsigned int index_;
> +	std::string name_;
> +	MediaDevice *media_;
> +
> +	V4L2Subdevice *imgu_;
> +	V4L2VideoDevice *input_;
> +	ImgUOutput output_;
> +	ImgUOutput viewfinder_;
> +	ImgUOutput stat_;
> +	/* \todo Add param video device for 3A tuning */
> +};
> +
> +} /* namespace libcamera */
> +
> +#endif /* __LIBCAMERA_PIPELINE_IPU3_IMGU_H__ */
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index fd2725c7bd0c144b..b41a789e8dc2a7b2 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -11,8 +11,6 @@
>  #include <queue>
>  #include <vector>
>  
> -#include <linux/media-bus-format.h>
> -
>  #include <libcamera/camera.h>
>  #include <libcamera/formats.h>
>  #include <libcamera/request.h>
> @@ -25,77 +23,14 @@
>  #include "libcamera/internal/pipeline_handler.h"
>  #include "libcamera/internal/utils.h"
>  #include "libcamera/internal/v4l2_controls.h"
> -#include "libcamera/internal/v4l2_subdevice.h"
> -#include "libcamera/internal/v4l2_videodevice.h"
>  
>  #include "cio2.h"
> +#include "imgu.h"
>  
>  namespace libcamera {
>  
>  LOG_DEFINE_CATEGORY(IPU3)
>  
> -class ImgUDevice
> -{
> -public:
> -	static constexpr unsigned int PAD_INPUT = 0;
> -	static constexpr unsigned int PAD_OUTPUT = 2;
> -	static constexpr unsigned int PAD_VF = 3;
> -	static constexpr unsigned int PAD_STAT = 4;
> -
> -	/* ImgU output descriptor: group data specific to an ImgU output. */
> -	struct ImgUOutput {
> -		V4L2VideoDevice *dev;
> -		unsigned int pad;
> -		std::string name;
> -	};
> -
> -	ImgUDevice()
> -		: imgu_(nullptr), input_(nullptr)
> -	{
> -		output_.dev = nullptr;
> -		viewfinder_.dev = nullptr;
> -		stat_.dev = nullptr;
> -	}
> -
> -	~ImgUDevice()
> -	{
> -		delete imgu_;
> -		delete input_;
> -		delete output_.dev;
> -		delete viewfinder_.dev;
> -		delete stat_.dev;
> -	}
> -
> -	int init(MediaDevice *media, unsigned int index);
> -	int configureInput(const Size &size,
> -			   V4L2DeviceFormat *inputFormat);
> -	int configureOutput(ImgUOutput *output,
> -			    const StreamConfiguration &cfg,
> -			    V4L2DeviceFormat *outputFormat);
> -
> -	int allocateBuffers(unsigned int bufferCount);
> -	void freeBuffers();
> -
> -	int start();
> -	int stop();
> -
> -	int linkSetup(const std::string &source, unsigned int sourcePad,
> -		      const std::string &sink, unsigned int sinkPad,
> -		      bool enable);
> -	int enableLinks(bool enable);
> -
> -	unsigned int index_;
> -	std::string name_;
> -	MediaDevice *media_;
> -
> -	V4L2Subdevice *imgu_;
> -	V4L2VideoDevice *input_;
> -	ImgUOutput output_;
> -	ImgUOutput viewfinder_;
> -	ImgUOutput stat_;
> -	/* \todo Add param video device for 3A tuning */
> -};
> -
>  class IPU3Stream : public Stream
>  {
>  public:
> @@ -952,343 +887,6 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
>  	imgu_->input_->queueBuffer(buffer);
>  }
>  
> -/* -----------------------------------------------------------------------------
> - * ImgU Device
> - */
> -
> -/**
> - * \brief Initialize components of the ImgU instance
> - * \param[in] mediaDevice The ImgU instance media device
> - * \param[in] index The ImgU instance index
> - *
> - * Create and open the V4L2 devices and subdevices of the ImgU instance
> - * with \a index.
> - *
> - * In case of errors the created V4L2VideoDevice and V4L2Subdevice instances
> - * are destroyed at pipeline handler delete time.
> - *
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::init(MediaDevice *media, unsigned int index)
> -{
> -	int ret;
> -
> -	index_ = index;
> -	name_ = "ipu3-imgu " + std::to_string(index_);
> -	media_ = media;
> -
> -	/*
> -	 * The media entities presence in the media device has been verified
> -	 * by the match() function: no need to check for newly created
> -	 * video devices and subdevice validity here.
> -	 */
> -	imgu_ = V4L2Subdevice::fromEntityName(media, name_);
> -	ret = imgu_->open();
> -	if (ret)
> -		return ret;
> -
> -	input_ = V4L2VideoDevice::fromEntityName(media, name_ + " input");
> -	ret = input_->open();
> -	if (ret)
> -		return ret;
> -
> -	output_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " output");
> -	ret = output_.dev->open();
> -	if (ret)
> -		return ret;
> -
> -	output_.pad = PAD_OUTPUT;
> -	output_.name = "output";
> -
> -	viewfinder_.dev = V4L2VideoDevice::fromEntityName(media,
> -							  name_ + " viewfinder");
> -	ret = viewfinder_.dev->open();
> -	if (ret)
> -		return ret;
> -
> -	viewfinder_.pad = PAD_VF;
> -	viewfinder_.name = "viewfinder";
> -
> -	stat_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " 3a stat");
> -	ret = stat_.dev->open();
> -	if (ret)
> -		return ret;
> -
> -	stat_.pad = PAD_STAT;
> -	stat_.name = "stat";
> -
> -	return 0;
> -}
> -
> -/**
> - * \brief Configure the ImgU unit input
> - * \param[in] size The ImgU input frame size
> - * \param[in] inputFormat The format to be applied to ImgU input
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::configureInput(const Size &size,
> -			       V4L2DeviceFormat *inputFormat)
> -{
> -	/* Configure the ImgU input video device with the requested sizes. */
> -	int ret = input_->setFormat(inputFormat);
> -	if (ret)
> -		return ret;
> -
> -	LOG(IPU3, Debug) << "ImgU input format = " << inputFormat->toString();
> -
> -	/*
> -	 * \todo The IPU3 driver implementation shall be changed to use the
> -	 * input sizes as 'ImgU Input' subdevice sizes, and use the desired
> -	 * GDC output sizes to configure the crop/compose rectangles.
> -	 *
> -	 * The current IPU3 driver implementation uses GDC sizes as the
> -	 * 'ImgU Input' subdevice sizes, and the input video device sizes
> -	 * to configure the crop/compose rectangles, contradicting the
> -	 * V4L2 specification.
> -	 */
> -	Rectangle rect = {
> -		.x = 0,
> -		.y = 0,
> -		.width = inputFormat->size.width,
> -		.height = inputFormat->size.height,
> -	};
> -	ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_CROP, &rect);
> -	if (ret)
> -		return ret;
> -
> -	ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_COMPOSE, &rect);
> -	if (ret)
> -		return ret;
> -
> -	LOG(IPU3, Debug) << "ImgU input feeder and BDS rectangle = "
> -			 << rect.toString();
> -
> -	V4L2SubdeviceFormat imguFormat = {};
> -	imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> -	imguFormat.size = size;
> -
> -	ret = imgu_->setFormat(PAD_INPUT, &imguFormat);
> -	if (ret)
> -		return ret;
> -
> -	LOG(IPU3, Debug) << "ImgU GDC format = " << imguFormat.toString();
> -
> -	return 0;
> -}
> -
> -/**
> - * \brief Configure the ImgU unit \a id video output
> - * \param[in] output The ImgU output device to configure
> - * \param[in] cfg The requested configuration
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::configureOutput(ImgUOutput *output,
> -				const StreamConfiguration &cfg,
> -				V4L2DeviceFormat *outputFormat)
> -{
> -	V4L2VideoDevice *dev = output->dev;
> -	unsigned int pad = output->pad;
> -
> -	V4L2SubdeviceFormat imguFormat = {};
> -	imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> -	imguFormat.size = cfg.size;
> -
> -	int ret = imgu_->setFormat(pad, &imguFormat);
> -	if (ret)
> -		return ret;
> -
> -	/* No need to apply format to the stat node. */
> -	if (output == &stat_)
> -		return 0;
> -
> -	*outputFormat = {};
> -	outputFormat->fourcc = dev->toV4L2PixelFormat(formats::NV12);
> -	outputFormat->size = cfg.size;
> -	outputFormat->planesCount = 2;
> -
> -	ret = dev->setFormat(outputFormat);
> -	if (ret)
> -		return ret;
> -
> -	LOG(IPU3, Debug) << "ImgU " << output->name << " format = "
> -			 << outputFormat->toString();
> -
> -	return 0;
> -}
> -
> -/**
> - * \brief Allocate buffers for all the ImgU video devices
> - */
> -int ImgUDevice::allocateBuffers(unsigned int bufferCount)
> -{
> -	/* Share buffers between CIO2 output and ImgU input. */
> -	int ret = input_->importBuffers(bufferCount);
> -	if (ret) {
> -		LOG(IPU3, Error) << "Failed to import ImgU input buffers";
> -		return ret;
> -	}
> -
> -	/*
> -	 * The kernel fails to start if buffers are not either imported or
> -	 * allocated for the statisitcs video device. As statistics buffers are
> -	 * not yet used by the pipeline import buffers to save memory.
> -	 *
> -	 * \todo To be revised when we'll actually use the stat node.
> -	 */
> -	ret = stat_.dev->importBuffers(bufferCount);
> -	if (ret < 0) {
> -		LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers";
> -		goto error;
> -	}
> -
> -	/*
> -	 * Import buffers for all outputs, regardless of whether the
> -	 * corresponding stream is active or inactive, as the driver needs
> -	 * buffers to be requested on the V4L2 devices in order to operate.
> -	 */
> -	ret = output_.dev->importBuffers(bufferCount);
> -	if (ret < 0) {
> -		LOG(IPU3, Error) << "Failed to import ImgU output buffers";
> -		goto error;
> -	}
> -
> -	ret = viewfinder_.dev->importBuffers(bufferCount);
> -	if (ret < 0) {
> -		LOG(IPU3, Error) << "Failed to import ImgU viewfinder buffers";
> -		goto error;
> -	}
> -
> -	return 0;
> -
> -error:
> -	freeBuffers();
> -
> -	return ret;
> -}
> -
> -/**
> - * \brief Release buffers for all the ImgU video devices
> - */
> -void ImgUDevice::freeBuffers()
> -{
> -	int ret;
> -
> -	ret = output_.dev->releaseBuffers();
> -	if (ret)
> -		LOG(IPU3, Error) << "Failed to release ImgU output buffers";
> -
> -	ret = stat_.dev->releaseBuffers();
> -	if (ret)
> -		LOG(IPU3, Error) << "Failed to release ImgU stat buffers";
> -
> -	ret = viewfinder_.dev->releaseBuffers();
> -	if (ret)
> -		LOG(IPU3, Error) << "Failed to release ImgU viewfinder buffers";
> -
> -	ret = input_->releaseBuffers();
> -	if (ret)
> -		LOG(IPU3, Error) << "Failed to release ImgU input buffers";
> -}
> -
> -int ImgUDevice::start()
> -{
> -	int ret;
> -
> -	/* Start the ImgU video devices. */
> -	ret = output_.dev->streamOn();
> -	if (ret) {
> -		LOG(IPU3, Error) << "Failed to start ImgU output";
> -		return ret;
> -	}
> -
> -	ret = viewfinder_.dev->streamOn();
> -	if (ret) {
> -		LOG(IPU3, Error) << "Failed to start ImgU viewfinder";
> -		return ret;
> -	}
> -
> -	ret = stat_.dev->streamOn();
> -	if (ret) {
> -		LOG(IPU3, Error) << "Failed to start ImgU stat";
> -		return ret;
> -	}
> -
> -	ret = input_->streamOn();
> -	if (ret) {
> -		LOG(IPU3, Error) << "Failed to start ImgU input";
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -int ImgUDevice::stop()
> -{
> -	int ret;
> -
> -	ret = output_.dev->streamOff();
> -	ret |= viewfinder_.dev->streamOff();
> -	ret |= stat_.dev->streamOff();
> -	ret |= input_->streamOff();
> -
> -	return ret;
> -}
> -
> -/**
> - * \brief Enable or disable a single link on the ImgU instance
> - *
> - * This method assumes the media device associated with the ImgU instance
> - * is open.
> - *
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::linkSetup(const std::string &source, unsigned int sourcePad,
> -			  const std::string &sink, unsigned int sinkPad,
> -			  bool enable)
> -{
> -	MediaLink *link = media_->link(source, sourcePad, sink, sinkPad);
> -	if (!link) {
> -		LOG(IPU3, Error)
> -			<< "Failed to get link: '" << source << "':"
> -			<< sourcePad << " -> '" << sink << "':" << sinkPad;
> -		return -ENODEV;
> -	}
> -
> -	return link->setEnabled(enable);
> -}
> -
> -/**
> - * \brief Enable or disable all media links in the ImgU instance to prepare
> - * for capture operations
> - *
> - * \todo This method will probably be removed or changed once links will be
> - * enabled or disabled selectively.
> - *
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::enableLinks(bool enable)
> -{
> -	std::string viewfinderName = name_ + " viewfinder";
> -	std::string outputName = name_ + " output";
> -	std::string statName = name_ + " 3a stat";
> -	std::string inputName = name_ + " input";
> -	int ret;
> -
> -	ret = linkSetup(inputName, 0, name_, PAD_INPUT, enable);
> -	if (ret)
> -		return ret;
> -
> -	ret = linkSetup(name_, PAD_OUTPUT, outputName, 0, enable);
> -	if (ret)
> -		return ret;
> -
> -	ret = linkSetup(name_, PAD_VF, viewfinderName, 0, enable);
> -	if (ret)
> -		return ret;
> -
> -	return linkSetup(name_, PAD_STAT, statName, 0, enable);
> -}
> -
>  REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3);
>  
>  } /* namespace libcamera */
> diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build
> index b2602d30123f908d..d60e07ae6ccac2bc 100644
> --- a/src/libcamera/pipeline/ipu3/meson.build
> +++ b/src/libcamera/pipeline/ipu3/meson.build
> @@ -2,5 +2,6 @@
>  
>  libcamera_sources += files([
>      'cio2.cpp',
> +    'imgu.cpp',
>      'ipu3.cpp',
>  ])

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list