http://linuxtv.org/downloads/v4l-dvb-apis/dmabuf.html

I/O流 (DMA缓存引用)

这是一个实验性接口,将来可能发生改变

DMABUF框架提供了在多设备见共享缓存的通用方法,支持DMABUF的设备驱动可以将一个DMA缓存以文件句柄的方式输出到用户空间(输出者规则),以文件句柄的方式从用户空间获取一个DMA缓存,这个文件句柄是之前其他或相同的设备所输出的(引入者规则),或都是。此章节描述在V4L2中DMABUF的引入者规则。

V4L2缓存以DMABUF文件句柄方式进行DMABUF输出。

支持I/O流方法的输入和输出设备在通过VIDIOC_QUERYCAP ioctl查询时,返回的struct v4l2_capability中capabilities成员会包含V4L2_CAP_STREAMING标签。是否支持通过DMABUF文件句柄引入DMABUF缓存决定了在调用VIDIOC_REQBUFS时内存类型是否要设定为V4L2_MEMORY_DMABUF。

这种I/O方法专用于在不同设备间共享DMA缓存,这些设备可以是V4L设备或是其他视频相关设备(如DRM)。缓存(面)通过应用程序控制驱动来申请。然后,这些缓存通过使用特殊API以文件句柄的方式输出给应用程序,交换的只有文件句柄。句柄和信息存在于struct v4l2_buffer(多平面API中是struct v4l2_plane)。在VIDIOC_REQBUFS ioctl执行后驱动必须切换到DMABUF I/O模式中。

例3.4 通过DMABUF文件句柄初始化I/O流

struct v4l2_requestbuffers reqbuf;

memset(&reqbuf, 0, sizeof (reqbuf));
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_DMABUF;
reqbuf.count = 1; if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
if (errno == EINVAL)
printf("Video capturing or DMABUF streaming is not supported\n");
else
perror("VIDIOC_REQBUFS"); exit(EXIT_FAILURE);
}

缓存(面)文件描述符通过VIDIOC_QBUF ioctl传输。在多平面中,每个面都申请了一个不同的DMABUF描述符,尽管缓存通常是循环的,应用程序也要每次通过不同的DMABUF描述符进行VIDIOC_QBUF请求处理。

例3.5 单一平面API中入列DMABUF

int buffer_queue(int v4lfd, int index, int dmafd)
{
struct v4l2_buffer buf; memset(&buf, 0, sizeof buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_DMABUF;
buf.index = index;
buf.m.fd = dmafd; if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
perror("VIDIOC_QBUF");
return -1;
} return 0;
}

例3.6 多平面API中入列DMABUF

int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
{
struct v4l2_buffer buf;
struct v4l2_plane planes[VIDEO_MAX_PLANES];
int i; memset(&buf, 0, sizeof buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
buf.memory = V4L2_MEMORY_DMABUF;
buf.index = index;
buf.m.planes = planes;
buf.length = n_planes; memset(&planes, 0, sizeof(planes)); for (i = 0; i < n_planes; ++i)
buf.m.planes[i].m.fd = dmafd[i]; if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
perror("VIDIOC_QBUF");
return -1;
} return 0;
}

捕捉或显示缓存都通过VIDIOC_DQBUF ioctl进行出列操作。驱动在这个ioctl和DMA完成的期间可以在任何时候对缓存进行解锁。当VIDIOC_STREAMOFF或VIDIOC_REQBUFS调用,以及设备关闭的时候内存都会被解锁。

对于捕捉应用程序来说,在开始捕捉及进入读循环前通常要入列一定数量的空缓存。一旦已填充过的缓存可以出列,应用程序在其数据不再需要的时候会将此缓存重新入列。而输出程序对缓存进行填充和入列操作,当堆积了足够的缓存后输出就开始了,在写循环中,当程序没有空闲缓存可用了,它需要等待有可出列的空缓存然后对其重新利用。两种方法都会阻塞程序的执行直到有缓存可以出列为止。VIDIOC_DQBUF当输出序列中没有可用缓存时默认是阻塞的,若open()时带有O_NONBLOCK标签,在出现这种情况的时候VIDIOC_DQBUF会直接返回EAGAIN错误码。而select()和poll()函数一直都是有效的。

通过调用VIDIOC_STREAMON和VIDIOC_STREAMOFF ioctl可以开始及停止程序进行捕捉或输出,这里请注意,VIDIOC_STREAMOFF会将所有序列中的缓存都移除,并且解锁。因为在多任务系统中没有“当前”的概念,所以如果程序需要与其他事件进行同步,需要通过捕捉或输出缓存的struct v4l2_buffer中的timestamp成员进行。

声明了DMABUF流方法的驱动必须支持VIDIOC_REQBUFS,VIDIOC_QBUF,VIDIOC_DQBUF,VIDIOC_STREAMON,VIDIOC_STREAMOFF这些ioctl,以及select()和poll()函数。

同步I/O

此方法尚未定义。

Streaming I/O (DMA buffer importing)

The DMABUF framework provides a generic method for sharing buffers between multiple devices. Device drivers that support DMABUF can export a DMA buffer to userspace as a file descriptor (known as the exporter role),
import a DMA buffer from userspace using a file descriptor previously exported for a different or the same device (known as the importer role), or both. This section describes the DMABUF importer role API in V4L2.

Refer to DMABUF exporting for details about exporting V4L2 buffers as DMABUF file
descriptors.

Input and output devices support the streaming I/O method when the V4L2_CAP_STREAMING flag in the capabilities field
of struct v4l2_capability returned by the VIDIOC_QUERYCAP ioctl
is set. Whether importing DMA buffers through DMABUF file descriptors is supported is determined by calling the VIDIOC_REQBUFS ioctl
with the memory type set to V4L2_MEMORY_DMABUF.

This I/O method is dedicated to sharing DMA buffers between different devices, which may be V4L devices or other video-related devices (e.g. DRM). Buffers (planes) are allocated by a driver on behalf of an application.
Next, these buffers are exported to the application as file descriptors using an API which is specific for an allocator driver. Only such file descriptor are exchanged. The descriptors and meta-information are passed in struct v4l2_buffer (or
in struct v4l2_plane in the multi-planar API case). The driver must be switched into DMABUF I/O mode by calling
the VIDIOC_REQBUFS with the desired buffer type.

Example 3.4. Initiating streaming I/O with DMABUF file descriptors

struct v4l2_requestbuffers reqbuf;

memset(&reqbuf, 0, sizeof (reqbuf));
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_DMABUF;
reqbuf.count = 1; if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
if (errno == EINVAL)
printf("Video capturing or DMABUF streaming is not supported\n");
else
perror("VIDIOC_REQBUFS"); exit(EXIT_FAILURE);
}

The buffer (plane) file descriptor is passed on the fly with the VIDIOC_QBUF ioctl.
In case of multiplanar buffers, every plane can be associated with a different DMABUF descriptor. Although buffers are commonly cycled, applications can pass a different DMABUF descriptor at each VIDIOC_QBUF call.

Example 3.5. Queueing DMABUF using single plane API

int buffer_queue(int v4lfd, int index, int dmafd)
{
struct v4l2_buffer buf; memset(&buf, 0, sizeof buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_DMABUF;
buf.index = index;
buf.m.fd = dmafd; if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
perror("VIDIOC_QBUF");
return -1;
} return 0;
}

Example 3.6. Queueing DMABUF using multi plane API

int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
{
struct v4l2_buffer buf;
struct v4l2_plane planes[VIDEO_MAX_PLANES];
int i; memset(&buf, 0, sizeof buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
buf.memory = V4L2_MEMORY_DMABUF;
buf.index = index;
buf.m.planes = planes;
buf.length = n_planes; memset(&planes, 0, sizeof planes); for (i = 0; i < n_planes; ++i)
buf.m.planes[i].m.fd = dmafd[i]; if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
perror("VIDIOC_QBUF");
return -1;
} return 0;
}

Captured or displayed buffers are dequeued with the VIDIOC_DQBUF ioctl.
The driver can unlock the buffer at any time between the completion of the DMA and this ioctl. The memory is also unlocked when VIDIOC_STREAMOFF is
called, VIDIOC_REQBUFS, or when the device is closed.

For capturing applications it is customary to enqueue a number of empty buffers, to start capturing and enter the read loop. Here the application waits until a filled buffer can be dequeued, and re-enqueues the
buffer when the data is no longer needed. Output applications fill and enqueue buffers, when enough buffers are stacked up output is started. In the write loop, when the application runs out of free buffers it must wait until an empty buffer can be dequeued
and reused. Two methods exist to suspend execution of the application until one or more buffers can be dequeued. By default VIDIOC_DQBUF blocks when no buffer is in the outgoing queue. When the O_NONBLOCK flag
was given to the open() function, VIDIOC_DQBUF returns immediately with an EAGAIN error
code when no buffer is available. The select() and poll() functions
are always available.

To start and stop capturing or displaying applications call the VIDIOC_STREAMON and VIDIOC_STREAMOFF ioctls.
Note that VIDIOC_STREAMOFF removes all buffers from both queues and unlocks all buffers as a side effect. Since there is no notion of doing anything "now" on a multitasking system, if an application needs to synchronize with another
event it should examine the struct v4l2_buffer timestamp of
captured or outputted buffers.

Drivers implementing DMABUF importing I/O must support the VIDIOC_REQBUFSVIDIOC_QBUFVIDIOC_DQBUFVIDIOC_STREAMON and VIDIOC_STREAMOFF ioctls,
and the select() and poll() functions

【Linux开发】IO streaming DMA buffer importing的更多相关文章

  1. 【linux开发】IO端口和IO内存的区别及分别使用的函数接口

    IO端口和IO内存的区别及分别使用的函数接口 每个外设都是通过读写其寄存器来控制的.外设寄存器也称为I/O端口,通常包括:控制寄存器.状态寄存器和数据寄存器三大类.根据访问外设寄存器的不同方式,可以把 ...

  2. Linux非阻塞IO(三)非阻塞IO中缓冲区Buffer的实现

    本文我们来实现回射服务器的Buffer.   Buffer的实现   上节提到了非阻塞IO必须具备Buffer.再次将Buffer的设计描述一下: 这里必须补充一点,writeIndex指向空闲空间的 ...

  3. 转 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  4. 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  5. <摘录>linux文件IO

    这篇文章写的比较全面,也浅显易懂,备份下.转载自:http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的 ...

  6. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  7. linux标准io的copy

    ---恢复内容开始--- 1.linux标准io的copy #include<stdio.h> int main(int argc,char **argv) { if(argc<3) ...

  8. 嵌入式Linux开发板

    嵌入式Linux开发板开发介绍: iTOP-4412嵌入式Linux开发板搭载三星Exynos四核处理器,配备1GB内存,4GB固态硬盘EMMC存储,独家配备三星S5M8767电源管理,配备Andro ...

  9. Linux Network IO Model、Socket IO Model - select、poll、epoll

    目录 . 引言 . IO机制简介 . 阻塞式IO模型(blocking IO model) . 非阻塞式IO模型(noblocking IO model) . IO复用式IO模型(IO multipl ...

随机推荐

  1. idea 导出可以直接运行的jar 文件

    刚开始采用的maven插件是 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId ...

  2. FCC 成都社区·前端周刊 第 3 期

    01. Chrome65 的新功能 CSS Paint API 允许使用编程方式生成图像:Server Timing API允许服务器将时间信息通过HTTP headers传递给浏览器: CSS di ...

  3. Eclipse/MyEclipse超全常用快捷键汇总,绝对实用

    [MyEclipse CI 2019.4.0安装包下载] Eclipse的编辑功能非常强大,掌握了Eclipse快捷键功能,能大大提高开发效率.Eclipse中有如下一些和编辑相关的快捷键. 常用快捷 ...

  4. pymysql ,主键, 索引

    目录 一.pymysql模块的使用 1. 安装pymysql 2. 连接MySQL 3. sql注入问题 二.索引 1. 什么是索引 2. 索引有什么用 3. 索引的底层原理 4. 主键 5. MyS ...

  5. 轻松学习JVM——垃圾回收器

    原文链接:https://www.cnblogs.com/leefreeman/p/7402695.html 上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某 ...

  6. 【NOIP2016提高A组模拟9.15】Map

    题目 分析 发现,当原图是一棵树的时候,那么新建一条边后,就会变成环套树, 而环内的所有点对都是安全点对,如果环中有k个点,答案就是\(k(k-1)\) 联想到,当把原图做一遍tarjan缩点,每个环 ...

  7. kafka——分布式的消息队列系统

    总听公司人说kafka kafka... 所以这玩意到底是个啥? 好像是一个高级版的消息队列,什么高吞吐量,数据持久,消息均衡,emmm https://blog.csdn.net/nawenqian ...

  8. TypeScript作为前端开发你必须学习的技能二)

    TypeScript 变量声明 变量是一种使用方便的占位符,用于引用计算机内存地址.我们可以把变量看做存储数据的容器. TypeScript 变量的命名规则:和javascript一样.除了下划线 _ ...

  9. LeetCode - LRU怎么将书架上的旧书完美淘汰呢

    你有一排书架,有空时会拿些书来看,经常性会买些新书.无奈书架容量有限,当新买的书放不下时,需要一个策略将旧书淘汰. LRU(最近最少使用)缓存淘汰机制正合适. 1)新买的书放在最左侧. 2)最近常看的 ...

  10. IDEA中Springboot静态文件加载(热部署)

    Springboot项目静态文件加载 昨天写项目的时候碰到一个问题,就是静态文件css无法读取到项目中,我仔细思考了下,总结了下,可能有两个问题 1.页面未加载更新 这个可能性非常大,Chrome就是 ...