I see. I'm also not conviced gstreamer is not doing a zero copy pipeline in that case.
thanks for the info and the suggestion, I'll try that at some point as I'd really like to use gstreamer in my application.
But I'm now doing a step back and I'm testing the same pipeline in pure C leveraging V4l2 directly.
capture from /video0 -> passing DMABUF buffers to for /video12 to scale them
I'm facing an issue though:
1) opened /dev/video0 and /dev/video12, configured resolution and pixel format
2) requested and mapped 4 V4L2_BUF_TYPE_VIDEO_CAPTURE / V4L2_MEMORY_MMAP buffers for the /video0 device, and then successfully exported the DMABUF buffers out of them with the VIDIOC_EXPBUF IOCTL
3) successfully requested 4 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE / V4L2_MEMORY_DMABUF buffers for the /video12 device
4) successfully requested 4 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE / V4L2_MEMORY_DMABUF buffers for the /video12 device
5) queued all the capture buffers in /video0 with VIDIOC_QBUF IOCTL
6) started streaming
so far so good. in the main loop though I can capture successfully from /video0 but I always get EINOVAL when I try to pass the V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE DMABUF to /video12.
the arguments seem correct. If I comment out that IOCTL and the rest of the code, and dequeue the capture buffer I can capture 50 frames per second as expected.
program output is this
I really cannot figure out why that IOCTL is failing. any suggestion?
thanks for the info and the suggestion, I'll try that at some point as I'd really like to use gstreamer in my application.
But I'm now doing a step back and I'm testing the same pipeline in pure C leveraging V4l2 directly.
capture from /video0 -> passing DMABUF buffers to for /video12 to scale them
I'm facing an issue though:
1) opened /dev/video0 and /dev/video12, configured resolution and pixel format
2) requested and mapped 4 V4L2_BUF_TYPE_VIDEO_CAPTURE / V4L2_MEMORY_MMAP buffers for the /video0 device, and then successfully exported the DMABUF buffers out of them with the VIDIOC_EXPBUF IOCTL
3) successfully requested 4 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE / V4L2_MEMORY_DMABUF buffers for the /video12 device
4) successfully requested 4 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE / V4L2_MEMORY_DMABUF buffers for the /video12 device
5) queued all the capture buffers in /video0 with VIDIOC_QBUF IOCTL
6) started streaming
Code:
type = V4L2_BUF_TYPE_VIDEO_CAPTURE; IOCTL_OR_EXIT(fd_cam, VIDIOC_STREAMON, &type, "VIDIOC_STREAMON (camera)"); type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; IOCTL_OR_EXIT(fd_isp, VIDIOC_STREAMON, &type, "VIDIOC_STREAMON (ISP input)"); type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;the arguments seem correct. If I comment out that IOCTL and the rest of the code, and dequeue the capture buffer I can capture 50 frames per second as expected.
Code:
// *** Main processing loop *** while (frame_count < MAX_FRAMES) { // 1. Capture frame from camera struct v4l2_buffer cam_buf; memset(&cam_buf, 0, sizeof(cam_buf)); cam_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cam_buf.memory = V4L2_MEMORY_MMAP; IOCTL_OR_EXIT(fd_cam, VIDIOC_DQBUF, &cam_buf, "VIDIOC_DQBUF (camera)"); unsigned cam_index = cam_buf.index; // (cam_buf.bytesused contains the size of the captured frame) // 2. Queue buffer to ISP input (using camera buffer DMABUF) struct v4l2_buffer isp_in_buf; struct v4l2_plane isp_in_planes[1]; memset(&isp_in_buf, 0, sizeof(isp_in_buf)); memset(isp_in_planes, 0, sizeof(isp_in_planes)); isp_in_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; isp_in_buf.memory = V4L2_MEMORY_DMABUF; isp_in_buf.index = cam_index % CAM_BUFFER_COUNT; // use corresponding slot isp_in_buf.m.planes = isp_in_planes; isp_in_buf.length = 1; isp_in_buf.m.planes[0].m.fd = cam_buffers[cam_index].dmabuf_fd; isp_in_buf.m.planes[0].data_offset = 0; isp_in_buf.m.planes[0].length = cam_buffers[cam_index].length; isp_in_buf.m.planes[0].bytesused = cam_buf.bytesused; // YUYV data size printf("%d %d %d %x\n",cam_buffers[cam_index].length,isp_in_buf.m.planes[0].bytesused,cam_index, cam_buffers[> printf("%d %x\n",sizeof(isp_in_planes),isp_in_buf.m.planes); printf("%d %d %d\n",cam_buf.memory,cam_buf.type,cam_buf.length); IOCTL_OR_EXIT(fd_isp, VIDIOC_QBUF, &isp_in_buf, "VIDIOC_QBUF (ISP input)");Code:
Opened camera, ISP, and encoder devices.Device capabilities verified.Camera format set: 720x576 YUYV.ISP configured: input 720x576 YUYV -> output 1440x1080 NV12.Encoder configured: input 1440x1080 NV12 -> H264 output.Camera buffers allocated and exported via DMABUF.ISP output buffers allocated and exported via DMABUF.Encoder output buffers allocated and memory-mapped.Streaming started on camera, ISP, and encoder.829440 829440 0 764 f11d7e101 1 829440VIDIOC_QBUF (ISP input): Invalid argumentStatistics: Posted by platux — Sat Jun 14, 2025 1:43 am