[libcamera-devel] [RFC PATCH v2 2/5] libcamera: MappedFrameBuffer: Use stored plane offset
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Aug 28 22:40:26 CEST 2023
Hello,
On Mon, Aug 21, 2023 at 07:31:29PM +0530, Vedant Paranjape via libcamera-devel wrote:
> On Mon, Aug 21, 2023 at 6:40 PM Gabby George wrote:
> >
> > As it is written, the MappedFrameBuffer causes a failure in mmap when
>
> s/As it is written/ /
> s/the/The
>
> > attempting to map UVC metadata planes. UVC metadata (four character
> > code UVCH) does not support exporting buffers as file descriptors, so
I think you meant dmabuf file descriptors here. The precision is
important, as file descriptors can be many things.
> > mmap can be used to give libcamera access to the metadata buffer
> > planes. It is convenient to use the already-existing
> > MappedFrameBuffers class, but the class must be modified to support
> > mapping using file descriptors of the video node itself.
> >
> > To do this, mmap needs information obtained through a call to
> > QUERYBUF, namely, the plane offset for buffer planes. Modify the
> > constructor of a MappedFrameBuffer to use the plane offset directly in
> > the call to mmap, rather than the hard-coded 0 value.
I don't think I like this :-( It feels a bit of an abuse of this class.
I'd rather implement the mapping manually in the UVC pipeline handler.
> > The current version does not work when a buffer cannot be exported as
> > a dma buf fd. The fd argument to mmap must be the one obtained on a
> > call to open() for the video node (ie, /dev/videoX). This method of
> > mapping buffer planes requires the arguments to mmap to be exactly the
> > length and offset QUERYBUF provides. Mmap will return a -EINVAL if
>
> s/Mmap/mmap
>
> > this is not the case.
> >
> > Signed-off-by: Gabby George <gabbymg94 at gmail.com>
> > ---
> > .../libcamera/internal/mapped_framebuffer.h | 3 ++-
> > src/libcamera/mapped_framebuffer.cpp | 20 ++++++++++++++-----
> > 2 files changed, 17 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h
> > index fb39adbf..04096d1b 100644
> > --- a/include/libcamera/internal/mapped_framebuffer.h
> > +++ b/include/libcamera/internal/mapped_framebuffer.h
> > @@ -54,7 +54,8 @@ public:
> >
> > using MapFlags = Flags<MapFlag>;
> >
> > - MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags);
> > + MappedFrameBuffer(const FrameBuffer *buffer,
> > + MapFlags flags, bool usePlaneOffset = false);
> > };
> >
> > LIBCAMERA_FLAGS_ENABLE_OPERATORS(MappedFrameBuffer::MapFlag)
> > diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp
> > index 6860069b..3d2cc332 100644
> > --- a/src/libcamera/mapped_framebuffer.cpp
> > +++ b/src/libcamera/mapped_framebuffer.cpp
> > @@ -172,12 +172,13 @@ MappedBuffer::~MappedBuffer()
> > * \brief Map all planes of a FrameBuffer
> > * \param[in] buffer FrameBuffer to be mapped
> > * \param[in] flags Protection flags to apply to map
> > + * \param[in] usePlaneOffset Use offset stored in buffer's plane; default false
> > *
> > * Construct an object to map a frame buffer for CPU access. The mapping can be
> > * made as Read only, Write only or support Read and Write operations by setting
> > * the MapFlag flags accordingly.
> > */
> > -MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)
> > +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags, bool usePlaneOffset)
> > {
> > ASSERT(!buffer->planes().empty());
> > planes_.reserve(buffer->planes().size());
> > @@ -223,8 +224,14 @@ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)
> > const int fd = plane.fd.get();
> > auto &info = mappedBuffers[fd];
> > if (!info.address) {
> > - void *address = mmap(nullptr, info.mapLength, mmapFlags,
> > - MAP_SHARED, fd, 0);
> > + void *address;
> > + if (usePlaneOffset) {
> > + address = mmap(nullptr, plane.length, mmapFlags,
> > + MAP_SHARED, fd, plane.offset);
> > + } else {
> > + address = mmap(nullptr, info.mapLength, mmapFlags,
> > + MAP_SHARED, fd, 0);
> > + }
>
> You could make this an oneliner using ternary operators, it would look
> more compact I believe.
>
> size_t length = usePlaneOffset ? plane.length : info.mapLength ;
> off_t offset = usePlaneOffset ? plane.offset : 0
> void *address = mmap(.., length, ..., offset);
>
> > if (address == MAP_FAILED) {
> > error_ = -errno;
> > LOG(Buffer, Error) << "Failed to mmap plane: "
> > @@ -233,10 +240,13 @@ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)
> > }
> >
> > info.address = static_cast<uint8_t *>(address);
> > - maps_.emplace_back(info.address, info.mapLength);
> > + maps_.emplace_back(info.address, usePlaneOffset ? plane.length :
> > + info.mapLength);
> > }
> >
> > - planes_.emplace_back(info.address + plane.offset, plane.length);
> > + uint8_t *storedAddress = usePlaneOffset ? info.address :
> > + info.address + plane.offset;
>
> I maybe wrong here, but looking at the code, shouldn't the operators
> be opposite ? something like this ?
>
> uint8_t *storedAddress = usePlaneOffset ? info.address + plane.offset
> : info.address;
>
> > + planes_.emplace_back(storedAddress, plane.length);
> > }
> > }
> >
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list