[libcamera-devel] [PATCH v2 08/10] libcamera: ipu3: cio2: Make the V4L2 devices private

Niklas Söderlund niklas.soderlund at ragnatech.se
Tue Jun 23 04:16:48 CEST 2020


Hi Laurent,

Thanks for your feedback.

On 2020-06-07 00:48:14 +0300, Laurent Pinchart wrote:
> Hi Niklas,
> 
> Thank you for the patch.
> 
> On Sat, Jun 06, 2020 at 05:04:34PM +0200, Niklas Söderlund wrote:
> > In order to make the CIO2 easier to extend with new features make the
> > V4L2 deices (sensor, CIO2 and video device) private members. This
> 
> s/deices/devices/
> 
> > requires a few helper functions to be added to allow for the IPU3 driver
> > to still be able to interact with all parts of the CIO2. These helper
> > functions will later be extended to add new features to the IPU3
> > pipeline.
> 
> I understand it may feel cleaner, but is it really, given that the
> CIO2Device class is closely related to the rest of the IPU3 pipeline
> handler ?

Yes and no, maybe some of these requirements can be relaxed with future 
work. Right now whats on top of my refactor list is to break it all 
apart to be able to see what can be grouped better and what can not.

I think observing the CIO2 as a sub-pipeline makesens and adds to a nice 
abstraction. The only thing I don't like is that we have a slot that 
calls a slot in the hot-path. Even with that I still think this is 
better then what we have in master today and with a bit of luck we can 
address this together with the ImgU work.

> 
> > Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> > ---
> > * Changes since v1
> > - Drop sensor access helpers and replace with a sensor() call to get
> >   hold of the CameraSensor pointer directly.
> > ---
> >  src/libcamera/pipeline/ipu3/cio2.cpp | 20 +++++++++++++++++++-
> >  src/libcamera/pipeline/ipu3/cio2.h   | 16 +++++++++++++---
> >  src/libcamera/pipeline/ipu3/ipu3.cpp | 16 +++++++---------
> >  3 files changed, 39 insertions(+), 13 deletions(-)
> > 
> > diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp
> > index 0d961ae8f5a0682b..2399be8de974ff92 100644
> > --- a/src/libcamera/pipeline/ipu3/cio2.cpp
> > +++ b/src/libcamera/pipeline/ipu3/cio2.cpp
> > @@ -32,7 +32,7 @@ const std::map<uint32_t, PixelFormat> sensorMbusToPixel = {
> >  } /* namespace */
> >  
> >  CIO2Device::CIO2Device()
> > -	: output_(nullptr), csi2_(nullptr), sensor_(nullptr)
> > +	: sensor_(nullptr), csi2_(nullptr), output_(nullptr)
> >  {
> >  }
> >  
> > @@ -123,6 +123,8 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index)
> >  	if (ret)
> >  		return ret;
> >  
> > +	output_->bufferReady.connect(this, &CIO2Device::cio2BufferReady);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -248,6 +250,12 @@ int CIO2Device::allocateBuffers()
> >  	return ret;
> >  }
> >  
> > +int CIO2Device::exportBuffers(unsigned int count,
> > +			      std::vector<std::unique_ptr<FrameBuffer>> *buffers)
> > +{
> > +	return output_->exportBuffers(count, buffers);
> > +}
> > +
> >  void CIO2Device::freeBuffers()
> >  {
> >  	/* The default std::queue constructor is explicit with gcc 5 and 6. */
> > @@ -288,4 +296,14 @@ int CIO2Device::stop()
> >  	return output_->streamOff();
> >  }
> >  
> > +int CIO2Device::queueBuffer(FrameBuffer *buffer)
> > +{
> > +	return output_->queueBuffer(buffer);
> > +}
> > +
> > +void CIO2Device::cio2BufferReady(FrameBuffer *buffer)
> > +{
> > +	bufferReady.emit(buffer);
> > +}
> > +
> >  } /* namespace libcamera */
> > diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h
> > index b7eb69a4e104f400..8c3d9dd24188ef1c 100644
> > --- a/src/libcamera/pipeline/ipu3/cio2.h
> > +++ b/src/libcamera/pipeline/ipu3/cio2.h
> > @@ -13,6 +13,7 @@
> >  
> >  #include <libcamera/geometry.h>
> >  #include <libcamera/pixel_format.h>
> > +#include <libcamera/signal.h>
> >  
> >  namespace libcamera {
> >  
> > @@ -39,6 +40,8 @@ public:
> >  						  const Size desiredSize = {}) const;
> >  
> >  	int allocateBuffers();
> > +	int exportBuffers(unsigned int count,
> > +			  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
> >  	void freeBuffers();
> >  
> >  	FrameBuffer *getBuffer();
> > @@ -47,11 +50,18 @@ public:
> >  	int start();
> >  	int stop();
> >  
> > -	V4L2VideoDevice *output_;
> > -	V4L2Subdevice *csi2_;
> > -	CameraSensor *sensor_;
> > +	CameraSensor *sensor() { return sensor_; }
> > +
> > +	int queueBuffer(FrameBuffer *buffer);
> > +	Signal<FrameBuffer *> bufferReady;
> 
> Proxying the signal emitted by the output video device is a bit costly,
> and is executed in a hot path :-( Is there a way we could improve that ?

I'm hoping this can be done on-top of this. I have no clear idea on how 
at the moment as I still have a hard time reading this driver as it's 
been reworkd in parts so many times. Why did we not know the complete 
and design the first time we wrote it ;-)

> 
> >  
> >  private:
> > +	void cio2BufferReady(FrameBuffer *buffer);
> > +
> > +	CameraSensor *sensor_;
> > +	V4L2Subdevice *csi2_;
> > +	V4L2VideoDevice *output_;
> > +
> >  	std::vector<std::unique_ptr<FrameBuffer>> buffers_;
> >  	std::queue<FrameBuffer *> availableBuffers_;
> >  };
> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > index 85d4e64396e77222..55958a6c5e64dbf1 100644
> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > @@ -447,7 +447,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
> >  			 * available sensor resolution and to the IPU3
> >  			 * alignment constraints.
> >  			 */
> > -			const Size &res = data->cio2_.sensor_->resolution();
> > +			const Size &res = data->cio2_.sensor()->resolution();
> >  			unsigned int width = std::min(1280U, res.width);
> >  			unsigned int height = std::min(720U, res.height);
> >  			cfg.size = { width & ~7, height & ~3 };
> > @@ -627,13 +627,11 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,
> >  	IPU3CameraData *data = cameraData(camera);
> >  	IPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);
> >  	unsigned int count = stream->configuration().bufferCount;
> > -	V4L2VideoDevice *video;
> >  
> >  	if (ipu3stream->raw_)
> > -		video = data->cio2_.output_;
> > -	else
> > -		video = ipu3stream->device_->dev;
> > +		return data->cio2_.exportBuffers(count, buffers);
> >  
> > +	V4L2VideoDevice *video = ipu3stream->device_->dev;
> >  	return video->exportBuffers(count, buffers);
> 
> This could be
> 
>  	return ipu3stream->device_->dev->exportBuffers(count, buffers);
> 
> >  }
> >  
> > @@ -744,7 +742,7 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)
> >  		return -EINVAL;
> >  
> >  	buffer->setRequest(request);
> > -	data->cio2_.output_->queueBuffer(buffer);
> > +	data->cio2_.queueBuffer(buffer);
> >  
> >  	for (auto it : request->buffers()) {
> >  		IPU3Stream *stream = static_cast<IPU3Stream *>(it.first);
> > @@ -857,7 +855,7 @@ int PipelineHandlerIPU3::registerCameras()
> >  			continue;
> >  
> >  		/* Initialize the camera properties. */
> > -		data->properties_ = cio2->sensor_->properties();
> > +		data->properties_ = cio2->sensor()->properties();
> >  
> >  		/**
> >  		 * \todo Dynamically assign ImgU and output devices to each
> > @@ -881,7 +879,7 @@ 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_.bufferReady.connect(data.get(),
> >  					&IPU3CameraData::cio2BufferReady);
> >  		data->imgu_->input_->bufferReady.connect(data.get(),
> >  					&IPU3CameraData::imguInputBufferReady);
> > @@ -891,7 +889,7 @@ int PipelineHandlerIPU3::registerCameras()
> >  					&IPU3CameraData::imguOutputBufferReady);
> >  
> >  		/* Create and register the Camera instance. */
> > -		std::string cameraName = cio2->sensor_->entity()->name();
> > +		std::string cameraName = cio2->sensor()->entity()->name();
> >  		std::shared_ptr<Camera> camera = Camera::create(this,
> >  								cameraName,
> >  								streams);
> 
> -- 
> Regards,
> 
> Laurent Pinchart

-- 
Regards,
Niklas Söderlund


More information about the libcamera-devel mailing list