[PATCH 2/3] libcamera: v4l2_videodevice: Report offset in dequeueBuffer

Paul Elder paul.elder at ideasonboard.com
Thu Apr 3 18:35:43 CEST 2025


On Wed, Apr 02, 2025 at 03:09:42AM +0300, Laurent Pinchart wrote:
> On Fri, Mar 28, 2025 at 04:51:12PM -0400, Nicolas Dufresne wrote:
> > Le mercredi 26 mars 2025 à 16:51 +0900, Paul Elder a écrit :
> > > Fill in the offset field of the frame metadata so that it the
> > > application can read it.
> > > 
> > > Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> > > ---
> > >  src/libcamera/v4l2_videodevice.cpp | 5 ++++-
> > >  1 file changed, 4 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/src/libcamera/v4l2_videodevice.cpp
> > > b/src/libcamera/v4l2_videodevice.cpp
> > > index f5b3fa09d9a0..5d163f7fd853 100644
> > > --- a/src/libcamera/v4l2_videodevice.cpp
> > > +++ b/src/libcamera/v4l2_videodevice.cpp
> > > @@ -1957,10 +1957,13 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
> > >  		 * The number of planes in the frame buffer and in the
> > >  		 * V4L2 buffer is guaranteed to be equal at this point.
> > >  		 */
> > > -		for (unsigned int i = 0; i < numV4l2Planes; ++i)
> > > +		for (unsigned int i = 0; i < numV4l2Planes; ++i) {
> > >  			metadata.planes()[i].bytesused = planes[i].bytesused;
> > > +			metadata.planes()[i].offset = planes[i].data_offset;
> > 
> > In V4L2, data_offset is included in the total bytesused. Once you hit a
> > non-zero offset, you will endup with byteused possibly bigger then
> > FrameBuffer.length, which to my reading contradicts the doc.
> > 
> > https://www.linuxtv.org/downloads/v4l-dvb-apis/userspace-api/v4l/buffer.html?highlight=data_offset#struct-v4l2-plane
> > 
> > > +		}
> > >  	} else {
> > >  		metadata.planes()[0].bytesused = buf.bytesused;
> > > +		metadata.planes()[0].offset = buf.m.offset;
> > 
> > Should be:
> > 
> > +		metadata.planes()[0].offset = 0;
> > 
> > There is no support for data_offset in the original v4l2_buffer API.
> > This offset match planes[i].mem_offset and is only useful for CPU
> > access using mmap() and the video node FD.
> > 
> > I think some introspection is needed, since this offset was expected to
> > be in the framebuffer, which apparently needs to be constant. Once
> > these issue resovled, do you mind fixing GStreamer code to use the
> > right one, it reads like this:
> > 
> > 		GstMemory *mem = gst_fd_allocator_alloc(allocator, plane.fd.get(),
> > 							plane.offset + plane.length,
> > 							GST_FD_MEMORY_FLAG_DONT_CLOSE);
> > 		gst_memory_resize(mem, plane.offset, plane.length);
> > 
> > Plane.offset is never set (always zero atm), but if its constant, its
> > the wrong one, this code should use the metadata once (the variable
> > one). You will also notice the semantic difference, we assume length
> > does not include the offset, this might need adjustment.
> 
> Outside of codec drivers, data_offset is a bit of a problematic API. The
> issue with reporting a dynamic offset is that it make it impossible to
> use fences and queue the buffer with a consumer before we know the
> offset value. The concern is of course theoretical, given that V4L2
> doesn't have fence support, but I would really not to see widespread
> data_offset usage before we figure this issue out.

Ah ok, I see. The data is practically static but it's treated as
dynamic. We can't expose it as static on the libcamera side either
because... it's dynamic as exposed by the kernel.

> Not counting the vivid test driver and codec drivers, data_offset is
> only used by the omap3isp driver, for entirely historical reasons (we
> didn't know what we were doing at the time). I'd like to understand your
> use cases better in order to determine the best way forward.

It's for a client's custom platform, so I suppose I'll keep these
out-of-tree then, since upstream support of this would need a larger
scale kernel change.


Thanks,

Paul

> Note that there is a different, and in my opinion entirely valid, use of
> offsets, which is indicating where a plane is located within a dmabuf.
> This isn't supported by V4L2 at the moment (there are old patches on the
> list for this, but they died out), but is I think a useful and needed
> feature (DRM supports it). The FrameBuffer::Plane::offset field is meant
> for this.
> 
> > >  	}
> > >  
> > >  	return buffer;


More information about the libcamera-devel mailing list