7.21. ioctl VIDIOC_EXPBUF

7.21.1. 名称

VIDIOC_EXPBUF - 将缓冲区导出为 DMABUF 文件描述符。

7.21.2. 概要

VIDIOC_EXPBUF

int ioctl(int fd, VIDIOC_EXPBUF, struct v4l2_exportbuffer *argp)

7.21.3. 参数

fd

open() 返回的文件描述符。

argp

指向结构体 v4l2_exportbuffer 的指针。

7.21.4. 描述

此 ioctl 是 内存映射 I/O 方法的扩展,因此仅适用于 V4L2_MEMORY_MMAP 缓冲区。它可用于在通过 ioctl VIDIOC_REQBUFS ioctl 分配缓冲区后的任何时间将缓冲区导出为 DMABUF 文件。

要导出缓冲区,应用程序需要填充结构体 v4l2_exportbuffertype 字段设置为与之前在结构体 v4l2_requestbuffers type 中使用的相同的缓冲区类型。应用程序还必须设置 index 字段。有效的索引号范围从零到使用 ioctl VIDIOC_REQBUFS 分配的缓冲区数量(结构体 v4l2_requestbuffers count)减一。对于多平面 API,应用程序将 plane 字段设置为要导出的平面的索引。有效平面的范围从零到当前活动格式的最大有效平面数。对于单平面 API,应用程序必须将 plane 设置为零。其他标志可以发布在 flags 字段中。有关详细信息,请参阅 open() 的手册。目前仅支持 O_CLOEXEC、O_RDONLY、O_WRONLY 和 O_RDWR。所有其他字段必须设置为零。在多平面 API 的情况下,每个平面使用多个 ioctl VIDIOC_EXPBUF 调用单独导出。

在调用 ioctl VIDIOC_EXPBUF 后,驱动程序将设置 fd 字段。这是一个 DMABUF 文件描述符。应用程序可以将其传递给其他支持 DMABUF 的设备。有关将 DMABUF 文件导入 V4L2 节点的详细信息,请参阅 DMABUF 导入。建议在不再使用 DMABUF 文件时关闭它,以允许回收关联的内存。

7.21.5. 示例

int buffer_export(int v4lfd, enum v4l2_buf_type bt, int index, int *dmafd)
{
    struct v4l2_exportbuffer expbuf;

    memset(&expbuf, 0, sizeof(expbuf));
    expbuf.type = bt;
    expbuf.index = index;
    if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
        perror("VIDIOC_EXPBUF");
        return -1;
    }

    *dmafd = expbuf.fd;

    return 0;
}
int buffer_export_mp(int v4lfd, enum v4l2_buf_type bt, int index,
    int dmafd[], int n_planes)
{
    int i;

    for (i = 0; i < n_planes; ++i) {
        struct v4l2_exportbuffer expbuf;

        memset(&expbuf, 0, sizeof(expbuf));
        expbuf.type = bt;
        expbuf.index = index;
        expbuf.plane = i;
        if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
            perror("VIDIOC_EXPBUF");
            while (i)
                close(dmafd[--i]);
            return -1;
        }
        dmafd[i] = expbuf.fd;
    }

    return 0;
}
type v4l2_exportbuffer
结构体 v4l2_exportbuffer

__u32

type

缓冲区类型,与结构体 v4l2_format type 或结构体 v4l2_requestbuffers type 相同,由应用程序设置。请参阅 v4l2_buf_type

__u32

index

缓冲区编号,由应用程序设置。此字段仅用于 内存映射 I/O,范围从零到使用 ioctl VIDIOC_REQBUFS 和/或 ioctl VIDIOC_CREATE_BUFS ioctl 分配的缓冲区数量。

__u32

plane

使用多平面 API 时要导出的平面的索引。否则,此值必须设置为零。

__u32

flags

新创建的文件的标志,目前仅支持 O_CLOEXECO_RDONLYO_WRONLYO_RDWR,有关详细信息,请参阅 open() 的手册。

__s32

fd

与缓冲区关联的 DMABUF 文件描述符。由驱动程序设置。

__u32

reserved[11]

保留字段供将来使用。驱动程序和应用程序必须将数组设置为零。

7.21.6. 返回值

成功时返回 0,出错时返回 -1 并且会适当设置 errno 变量。通用错误代码在 通用错误代码 章节中描述。

EINVAL

队列未处于 MMAP 模式或不支持 DMABUF 导出,或者 flagstypeindexplane 字段无效。