[libcamera-devel] [RFC PATCH v1 06/12] libcamera: framebuffer: Add a function to check if planes are contiguous

Laurent Pinchart laurent.pinchart at ideasonboard.com
Thu Sep 2 20:07:58 CEST 2021


Hi Kieran,

On Thu, Sep 02, 2021 at 10:43:56AM +0100, Kieran Bingham wrote:
> On 02/09/2021 05:22, Laurent Pinchart wrote:
> > Multi-planar frame buffers can store their planes contiguously in
> > memory, or split them in discontiguous memory areas. Add a private
> > function to check in which of these two categories the frame buffer
> > belongs. This will be used to correctly handle the differences between
> > the V4L2 single and multi planar APIs.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> >  include/libcamera/internal/framebuffer.h |  2 ++
> >  src/libcamera/framebuffer.cpp            | 45 +++++++++++++++++++++++-
> >  2 files changed, 46 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h
> > index 606aed2b4782..cd33c295466e 100644
> > --- a/include/libcamera/internal/framebuffer.h
> > +++ b/include/libcamera/internal/framebuffer.h
> > @@ -21,9 +21,11 @@ public:
> >  	Private();
> >  
> >  	void setRequest(Request *request) { request_ = request; }
> > +	bool isContiguous() const { return isContiguous_; }
> >  
> >  private:
> >  	Request *request_;
> > +	bool isContiguous_;
> >  };
> >  
> >  } /* namespace libcamera */
> > diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp
> > index 53ef89bf458f..99265b44da43 100644
> > --- a/src/libcamera/framebuffer.cpp
> > +++ b/src/libcamera/framebuffer.cpp
> > @@ -106,7 +106,7 @@ LOG_DEFINE_CATEGORY(Buffer)
> >   */
> >  
> >  FrameBuffer::Private::Private()
> > -	: request_(nullptr)
> > +	: request_(nullptr), isContiguous_(true)
> >  {
> >  }
> >  
> > @@ -120,6 +120,17 @@ FrameBuffer::Private::Private()
> >   * handlers, it is called by the pipeline handlers themselves.
> >   */
> >  
> > +/**
> > + * \fn FrameBuffer::Private::isContiguous()
> > + * \brief Check if the frame buffer stores planes contiguously in memory
> > + *
> > + * Multi-planar frame buffers can store their planes contiguously in memory, or
> > + * split them in discontiguous memory areas. This function checks in which of
> 
> 'split them into discontiguous'
> 
> > + * these two categories the frame buffer belongs.
> > + *
> > + * \return True if the planes are stored contiguously in memory, false otherwise
> > + */
> > +
> >  /**
> >   * \class FrameBuffer
> >   * \brief Frame buffer data and its associated dynamic metadata
> > @@ -199,9 +210,41 @@ FrameBuffer::FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie)
> >  	: Extensible(std::make_unique<Private>()), planes_(planes),
> >  	  cookie_(cookie)
> >  {
> > +	unsigned int offset = 0;
> > +
> >  	/* \todo Remove the assertions after sufficient testing */
> >  	for (const auto &plane : planes_)
> >  		ASSERT(plane.offset != Plane::kInvalidOffset);
> > +
> > +	bool isContiguous = true;
> > +	ino_t inode = 0;
> > +
> > +	for (const auto &plane : planes_) {
> > +		if (plane.offset != offset) {
> > +			isContiguous = false;
> > +			break;
> > +		}
> > +
> > +		/*
> > +		 * Two different dmabuf file descriptors may still refer to the
> > +		 * same dmabuf instance. Check this using inodes.
> 
> Going back to the FileDescriptor::inode() extension, if that cached the
> inode (it can't change) on either first call, or construction, couldn't
> this whole check be simplified to:
> 
> 		if (plane.fd.inode() != planes_[0].fd.inode()) {
> 			isContiguous = false;
> 			break;
> 		}

This would call fstat() every time, while the fd comparison here is
meant to skip the fstat() calls in case the numerical fd match. We could
do

		if (plane.fd != planes_[0].fd)

if we introduced an operator==(), but as explained in a reply to the
patch that adds inode(), I'd like to handle that later, to avoid
blocking this series.

> > +		 */
> > +		if (plane.fd.fd() != planes_[0].fd.fd()) {
> > +			if (!inode)
> > +				inode = planes_[0].fd.inode();
> > +			if (plane.fd.inode() != inode) {
> > +				isContiguous = false;
> > +				break;
> > +			}
> > +		}
> > +
> > +		offset += plane.length;
> > +	}
> > +
> > +	LOG(Buffer, Debug)
> > +		<< "Buffer is " << (isContiguous ? "not " : "") << "contiguous";
> > +
> > +	_d()->isContiguous_ = isContiguous;
> >  }
> >  
> >  /**

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list