client: weston-simple-dmabuf-v4l2 does not translate planar video formats correctly from V4L2 to DRM
I recently wanted to use weston-simple-dmabuf-v4l2 to test passing NV12 DMAbuf. I'm using a UVC StreamCam from logic for the test, but using vivid in non-mplane mode should reproduce the same:
./build/client/weston-simple-dmabuf-v4l2 -v /dev/video2 -f NV12 -d NV12
The DMABuf import fails and weston trace that folloing:
[16:08:54.852] NV12 dmabuf must contain 2 planes (1 provided)
The reason is that UVC driver produces 1 DMABuf, but regardless, in wayland protocol you must always pass each plane seperatly. The weston-simple-dmabuf-v4l2 confuses number of allocation and number of planes and is hard to fix, as it has no coded knowledge of the pixel formats yet.
In v4l2, if you have a none-MPLANE driver like UVC, V4L2_PIX_FMT_NV12 can be used and will only have 1 DMABuf exported. The application must, with inner pixel format knowledge, calculate the offset of the second plane and pass twice the same dmabuf to wayland, setting appropriate offset to the second dmabuf. In V4L2, for NV12, the plane offset is (careful not to confuse data_offset with plane offset, this offset in V4L2 is only used when a V4L2 driver need to pass a prefix from one driver to another):
offset[1] = bytesperline * height + data_offset
Though, there can also be MPLANE drivers. The code for MPLANE is correct for V4L2_PIX_FMT_NV12M pixel format (2 dmabufs) but it will fail for MPLANE driver using single allocation (V4L2_PIX_FMT_NV12). For this last, the number of video planes does not match the number of memory planes set in the v4l2_buffer, and the offset must be calculated like for non-MPLANE cases.