[libcamera-devel] [PATCH v5 11/19] libcamera: ipu3: Create ImgUDevice class

Niklas Söderlund niklas.soderlund at ragnatech.se
Tue Apr 2 13:28:48 CEST 2019


Hi Jacopo,

Thanks for your work.

On 2019-03-26 09:38:54 +0100, Jacopo Mondi wrote:
> Group ImgU components in a class associated with a camera at camera
> registration time and provide an intialization method to create and open
> all video devices and subdevices of the ImgU.
> 
> Statically assign imgu0 to the first camera and imgu1 to the second one
> and limit support to two cameras. This will have to be revised in the future.
> 
> Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> ---
>  src/libcamera/pipeline/ipu3/ipu3.cpp | 154 +++++++++++++++++++++++++--
>  1 file changed, 145 insertions(+), 9 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 21205b39afee..0a059b75cadf 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -44,6 +44,43 @@ static int mediaBusToCIO2Format(unsigned int code)
>  	}
>  }
>  
> +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;
> +
> +	ImgUDevice()
> +		: imgu_(nullptr), input_(nullptr), output_(nullptr),
> +		  viewfinder_(nullptr), stat_(nullptr)
> +	{
> +	}
> +
> +	~ImgUDevice()
> +	{
> +		delete imgu_;
> +		delete input_;
> +		delete output_;
> +		delete viewfinder_;
> +		delete stat_;
> +	}
> +
> +	int init(MediaDevice *media, unsigned int index);
> +
> +	unsigned int index_;
> +	std::string name_;
> +	MediaDevice *media_;
> +
> +	V4L2Subdevice *imgu_;
> +	V4L2Device *input_;
> +	V4L2Device *output_;
> +	V4L2Device *viewfinder_;
> +	V4L2Device *stat_;
> +	/* \todo Add param video device for 3A tuning */
> +};
> +
>  class CIO2Device
>  {
>  public:
> @@ -106,6 +143,7 @@ private:
>  		void bufferReady(Buffer *buffer);
>  
>  		CIO2Device cio2_;
> +		ImgUDevice *imgu_;
>  
>  		Stream stream_;
>  	};
> @@ -116,8 +154,10 @@ private:
>  			PipelineHandler::cameraData(camera));
>  	}
>  
> -	void registerCameras();
> +	int registerCameras();
>  
> +	ImgUDevice imgu0_;
> +	ImgUDevice imgu1_;
>  	std::shared_ptr<MediaDevice> cio2MediaDev_;
>  	std::shared_ptr<MediaDevice> imguMediaDev_;
>  };
> @@ -303,6 +343,8 @@ int PipelineHandlerIPU3::queueRequest(Camera *camera, Request *request)
>  
>  bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
>  {
> +	int ret;
> +
>  	DeviceMatch cio2_dm("ipu3-cio2");
>  	cio2_dm.add("ipu3-csi2 0");
>  	cio2_dm.add("ipu3-cio2 0");
> @@ -358,36 +400,75 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
>  		return false;
>  	}
>  
> -	registerCameras();
> +	if (imguMediaDev_->open()) {
> +		cio2MediaDev_->close();
> +		return false;
> +	}
> +
> +	if (imguMediaDev_->disableLinks())
> +		goto error;
> +
> +	ret = registerCameras();
> +	if (ret)
> +		goto error;
>  
>  	cio2MediaDev_->close();
> +	imguMediaDev_->close();
>  
>  	return true;
> +
> +error:
> +	cio2MediaDev_->close();
> +	imguMediaDev_->close();
> +
> +	return false;

You could make this a bit more neat,

error:
    cio2MediaDev_->close();
    imguMediaDev_->close();

    return ret == 0;

It would align the error and normal error path, with Laurents comments 
addressed and with or without this fixed,

Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>

>  }
>  
> -/*
> - * Cameras are created associating an image sensor (represented by a
> - * media entity with function MEDIA_ENT_F_CAM_SENSOR) to one of the four
> - * CIO2 CSI-2 receivers.
> +/**
> + * \brief Initialize ImgU devices and CIO2 ones associated with cameras
> + *
> + * Initialize the two ImgU instances and create cameras with an associated
> + * CIO2 device instance.
> + *
> + * \return 0 on success or a negative error code for error or if no camera
> + * has been created
> + * \retval -ENODEV no camera has been created
>   */
> -void PipelineHandlerIPU3::registerCameras()
> +int PipelineHandlerIPU3::registerCameras()
>  {
> +	int ret;
> +
> +	ret = imgu0_.init(imguMediaDev_.get(), 0);
> +	if (ret)
> +		return ret;
> +
> +	ret = imgu1_.init(imguMediaDev_.get(), 1);
> +	if (ret)
> +		return ret;
> +
>  	/*
>  	 * For each CSI-2 receiver on the IPU3, create a Camera if an
>  	 * image sensor is connected to it and it can produce images in
>  	 * a compatible format.
>  	 */
>  	unsigned int numCameras = 0;
> -	for (unsigned int id = 0; id < 4; ++id) {
> +	for (unsigned int id = 0; id < 4 && numCameras < 2; ++id) {
>  		std::unique_ptr<IPU3CameraData> data =
>  			utils::make_unique<IPU3CameraData>(this);
>  		std::set<Stream *> streams{ &data->stream_ };
>  		CIO2Device *cio2 = &data->cio2_;
>  
> -		int ret = cio2->init(cio2MediaDev_.get(), id);
> +		ret = cio2->init(cio2MediaDev_.get(), id);
>  		if (ret)
>  			continue;
>  
> +		/**
> +		 * \todo Dynamically assign ImgU devices; as of now, limit
> +		 * support to two cameras only, and assign imgu0 to the first
> +		 * one and imgu1 to the second.
> +		 */
> +		data->imgu_ = numCameras ? &imgu1_ : &imgu0_;
> +
>  		std::string cameraName = cio2->name() + " "
>  				       + std::to_string(id);
>  		std::shared_ptr<Camera> camera = Camera::create(this,
> @@ -406,6 +487,8 @@ void PipelineHandlerIPU3::registerCameras()
>  
>  		numCameras++;
>  	}
> +
> +	return numCameras ? 0 : -ENODEV;
>  }
>  
>  void PipelineHandlerIPU3::IPU3CameraData::bufferReady(Buffer *buffer)
> @@ -416,6 +499,59 @@ void PipelineHandlerIPU3::IPU3CameraData::bufferReady(Buffer *buffer)
>  	pipe_->completeRequest(camera_, request);
>  }
>  
> +/* -----------------------------------------------------------------------------
> + * 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 V4L2Device 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;
> +
> +	imgu_ = V4L2Subdevice::fromEntityName(media, name_);
> +	ret = imgu_->open();
> +	if (ret)
> +		return ret;
> +
> +	input_ = V4L2Device::fromEntityName(media, name_ + " input");
> +	ret = input_->open();
> +	if (ret)
> +		return ret;
> +
> +	output_ = V4L2Device::fromEntityName(media, name_ + " output");
> +	ret = output_->open();
> +	if (ret)
> +		return ret;
> +
> +	viewfinder_ = V4L2Device::fromEntityName(media, name_ + " viewfinder");
> +	ret = viewfinder_->open();
> +	if (ret)
> +		return ret;
> +
> +	stat_ = V4L2Device::fromEntityName(media, name_ + " 3a stat");
> +	ret = stat_->open();
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
>  /*------------------------------------------------------------------------------
>   * CIO2 Device
>   */
> -- 
> 2.21.0
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

-- 
Regards,
Niklas Söderlund


More information about the libcamera-devel mailing list