2.2.15 V4L2 videobuf2 functions and data structures

enum vb2_memory
表示用于在用户空间中使缓冲区可见的内存模型。
常量:
- `VB2_MEMORY_UNKNOWN`:缓冲区状态未知或尚未在用户空间中使用。
- `VB2_MEMORY_MMAP`:缓冲区由内核分配,并通过`mmap()`ioctl进行内存映射。当用户通过`read()`或`write()`系统调用使用缓冲区时,也会使用此模型。
- `VB2_MEMORY_USERPTR`:缓冲区在用户空间中分配,并通过`mmap()`ioctl进行内存映射。
- `VB2_MEMORY_DMABUF`:缓冲区通过DMA缓冲区传递给用户空间。
VB2_MEMORY_MMAP和VB2_MEMORY_USERPTR的区别:
VB2_MEMORY_MMAP 和 VB2_MEMORY_USERPTR 都是 videobuf2 框架支持的不同内存类型,它们之间有以下区别:
1. 内存来源:
   - VB2_MEMORY_MMAP:该类型的内存来自用户空间的内存映射(mmap),通过对内存区域的映射,驱动程序可以直接读写用户空间的内存。
   - VB2_MEMORY_USERPTR:该类型的内存是由用户空间提供的用户指针(user pointer),驱动程序需要获取用户指针指向的内存进行读写操作。
2. 访问方式:
   - VB2_MEMORY_MMAP:通过内存映射,驱动程序可以直接读写用户空间内存,无需进行额外的拷贝操作,因此访问速度较快。
   - VB2_MEMORY_USERPTR:驱动程序需要从用户空间获取用户指针指向的内存,并进行必要的数据拷贝。这可能会增加一定的开销,因为数据需要在用户空间和内核空间之间进行复制。
3. 缓存同步:
   - VB2_MEMORY_MMAP:由于内存映射和访问过程中使用的是同一块内存,所以缓存同步是相对简单的,不需要进行显式的缓存同步操作。
   - VB2_MEMORY_USERPTR:由于数据需要从用户空间复制到内核空间,或者从内核空间复制到用户空间,因此可能涉及到缓存同步的问题,驱动程序需要在代码中进行必要的缓存同步操作,以确保数据的一致性。
选择使用哪种类型的内存取决于具体的应用需求和硬件平台的限制。一般来说,VB2_MEMORY_MMAP 适用于需要高性能的应用场景,而 VB2_MEMORY_USERPTR 则适用于需要更大的灵活性和兼容性的场景。
struct vb2_mem_ops 
结构体定义了用于内存管理和内存分配的操作。它包含以下成员:

struct vb2_mem_ops {
void *(*alloc)(struct vb2_buffer *vb,struct device *dev, unsigned long size);
void (*put)(void *buf_priv);
struct dma_buf *(*get_dmabuf)(struct vb2_buffer *vb,void *buf_priv, unsigned long flags);
void *(*get_userptr)(struct vb2_buffer *vb,struct device *dev,unsigned long vaddr, unsigned long size);
void (*put_userptr)(void *buf_priv);
void (*prepare)(void *buf_priv);
void (*finish)(void *buf_priv);
void *(*attach_dmabuf)(struct vb2_buffer *vb,struct device *dev,struct dma_buf *dbuf, unsigned long size);
void (*detach_dmabuf)(void *buf_priv);
int (*map_dmabuf)(void *buf_priv);
void (*unmap_dmabuf)(void *buf_priv);
void *(*vaddr)(struct vb2_buffer *vb, void *buf_priv);
void *(*cookie)(struct vb2_buffer *vb, void *buf_priv);
unsigned int (*num_users)(void *buf_priv);
int (*mmap)(void *buf_priv, struct vm_area_struct *vma);
};

- alloc:分配视频内存,并可选地分配分配器的私有数据。如果失败,则返回 ERR_PTR();如果成功,则返回指向分配器私有每个缓冲区数据的指针。此函数的 size 参数应为页对齐。
- put:通知分配器该缓冲区将不再使用;通常会导致分配器释放缓冲区(如果没有其他使用此缓冲区的用户)。buf_priv 参数是之前从 alloc 回调中返回的分配器私有每个缓冲区结构。
- get_dmabuf:获取硬件操作的用户空间内存;用于 DMABUF 内存类型。
- get_userptr:获取用于硬件操作的用户空间内存;用于 USERPTR 内存类型。vaddr 是在将 USERPTR 类型的视频缓冲区排队时传递给 videobuf 层的地址。成功时应返回与缓冲区关联的分配器私有每个缓冲区结构,失败时返回 ERR_PTR();之后其他结构中的操作将使用返回的私有结构作为 buf_priv 参数。
- put_userptr:通知分配器 USERPTR 缓冲区将不再使用。
- prepare:每次将缓冲区从用户空间传递给驱动程序时调用,用于缓存同步,可选。
- finish:每次将缓冲区从驱动程序传递回用户空间时调用,也是可选的。
- attach_dmabuf:为硬件操作附加一个共享的 struct dma_buf;用于 DMABUF 内存类型。dev 是分配设备,dbuf 是共享的 dma_buf;失败时返回 ERR_PTR();成功时返回分配器私有每个缓冲区结构;此后需要使用该结构进一步访问缓冲区。
- detach_dmabuf:通知缓冲区的导出器当前的 DMABUF 缓冲区不再使用;buf_priv 参数是之前从 attach_dmabuf 回调中返回的分配器私有每个缓冲区结构。
- map_dmabuf:请求对 dmabuf 的访问权限;告知 dmabuf 的分配器此驱动程序将使用 dmabuf。
- unmap_dmabuf:释放对 dmabuf 的访问控制权;通知分配器此驱动程序目前已经使用完 dmabuf。
- vaddr:返回与传递的私有结构关联的给定内存缓冲区的内核虚拟地址;如果不存在这样的映射,则返回 NULL。
- cookie:返回与传递的私有结构关联的给定内存缓冲区的分配器特定 cookie;如果不可用,则返回 NULL。
- num_users:返回内存缓冲区的当前用户数;如果 videobuf 层(实际上是使用它的驱动程序)是唯一的用户,则返回 1。
- mmap:为提供的虚拟内存区域设置用户空间映射,用于给定的内存缓冲区。
这些操作由 videobuf2 核心用于实现每种支持的流式 I/O 方法的内存处理/内存分配器。
注意:
1)USERPTR 类型所需的操作:get_userptr、put_userptr。
2)MMAP 类型所需的操作:alloc、put、num_users、mmap。
3)读/写访问类型所需的操作:alloc、put、num_users、vaddr。
4)DMABUF 类型所需的操作:attach_dmabuf、detach_dmabuf、map_dmabuf、unmap_dmabuf。
struct vb2_plane
结构体定义了视频缓冲区中每个平面(plane)的信息。它包含以下成员:

struct vb2_plane {
void *mem_priv;
struct dma_buf
*dbuf;
unsigned int
dbuf_mapped;
unsigned int
bytesused;
unsigned int
length;
unsigned int
min_length;
union {
unsigned int offset;
unsigned long userptr;
int fd;
} m;
unsigned int
data_offset;
};

- mem_priv:与此平面相关的私有数据。
- dbuf:共享缓冲区对象的 dma_buf。
- dbuf_mapped:标志,用于显示 dbuf 是否已映射。
- bytesused:该平面中数据占用的字节数(载荷大小)。
- length:该平面的大小(不包括载荷)以字节为单位。最大有效大小限制为 MAX_UINT - PAGE_SIZE。
- min_length:该平面所需的最小大小(不包括载荷)以字节为单位。length 始终大于或等于 min_length,并且像 length 一样,受到 MAX_UINT - PAGE_SIZE 的限制。
- m:与内存类型相关的联合数据。
  - m.offset:当内存类型为 VB2_MEMORY_MMAP 时,表示该平面相对于设备内存起始位置的偏移量(或者是一个应该传递给在视频节点上调用 mmap() 的 "cookie")。
  - m.userptr:当内存类型为 VB2_MEMORY_USERPTR 时,表示指向该平面的用户空间指针。
  - m.fd:当内存类型为 VB2_MEMORY_DMABUF 时,表示与该平面关联的用户空间文件描述符。
- data_offset:该平面中数据开始的偏移量;通常为0,除非数据前面有一个头部。
struct vb2_plane 结构体应包含足够的信息,以覆盖 videodev2.h 中 struct v4l2_plane 的所有字段。
enum vb2_io_modes
枚举定义了视频缓冲区的访问方法。它包含以下常量:
- VB2_MMAP:驱动程序支持使用流式 API 的内存映射(MMAP)方式访问缓冲区。
- VB2_USERPTR:驱动程序支持使用流式 API 的用户指针(USERPTR)方式访问缓冲区。
- VB2_READ:驱动程序支持使用 read() 风格的访问方式。
- VB2_WRITE:驱动程序支持使用 write() 风格的访问方式。
- VB2_DMABUF:驱动程序支持使用流式 API 的 DMABUF 方式访问缓冲区。
这些常量表示了不同的访问方法,驱动程序可以选择支持其中的一种或多种访问方法来与应用程序进行数据交互。
enum vb2_buffer_state
枚举定义了当前视频缓冲区的状态。它包含以下常量:
- VB2_BUF_STATE_DEQUEUED:缓冲区由用户空间控制。
- VB2_BUF_STATE_IN_REQUEST:缓冲区在媒体请求中排队。
- VB2_BUF_STATE_PREPARING:缓冲区正在视频缓冲区中准备。
- VB2_BUF_STATE_QUEUED:缓冲区在视频缓冲区中排队,但尚未在驱动程序中排队。
- VB2_BUF_STATE_ACTIVE:缓冲区在驱动程序中排队,并可能用于硬件操作。
- VB2_BUF_STATE_DONE:缓冲区从驱动程序返回到视频缓冲区,但尚未从用户空间中出队。
- VB2_BUF_STATE_ERROR:与上述相同,但是缓冲区上的操作以错误结束,当它被出队时将向用户空间报告该错误。
这些常量表示了视频缓冲区所处的不同状态,可用于跟踪和管理缓冲区在不同阶段的使用情况。
struct vb2_buffer
结构体代表一个视频缓冲区。
定义:

struct vb2_buffer {
    struct vb2_queue *vb2_queue;
    unsigned int index;
    unsigned int type;
    unsigned int memory;
    unsigned int num_planes;
    u64 timestamp;
    struct media_request *request;
    struct media_request_object req_obj;
};

成员变量:
- vb2_queue:指向包含此驱动程序所属队列的 struct vb2_queue 的指针。
- index:缓冲区的唯一标识号。
- type:缓冲区的类型。
- memory:实际数据传递的方法。
- num_planes:在内部驱动程序队列中的缓冲区中平面(plane)的数量。
- timestamp:帧的时间戳,以纳秒为单位。
- request:与此缓冲区关联的请求。
- req_obj:用于将该缓冲区绑定到请求的对象。此请求对象具有引用计数。
struct vb2_buffer 结构体表示一个视频缓冲区,并存储了与缓冲区相关的各种属性和信息,包括缓冲区所属的队列、缓冲区的唯一标识、类型、数据传递方法、平面数量、时间戳等。
struct vb2_ops
是一个结构体,用于定义驱动程序的回调函数。
定义:

struct vb2_ops {
int (*queue_setup)(struct vb2_queue *q,unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], struct device *alloc_devs[]);
void (*wait_prepare)(struct vb2_queue *q);
void (*wait_finish)(struct vb2_queue *q);
int (*buf_out_validate)(struct vb2_buffer *vb);
int (*buf_init)(struct vb2_buffer *vb);
int (*buf_prepare)(struct vb2_buffer *vb);
void (*buf_finish)(struct vb2_buffer *vb);
void (*buf_cleanup)(struct vb2_buffer *vb);
int (*start_streaming)(struct vb2_queue *q, unsigned int count);
void (*stop_streaming)(struct vb2_queue *q);
void (*buf_queue)(struct vb2_buffer *vb);
void (*buf_request_complete)(struct vb2_buffer *vb);
};

它包含以下成员:
1. queue_setup:在内存分配之前由VIDIOC_REQBUFS()和VIDIOC_CREATE_BUFS()处理程序调用。如果无法分配所请求的缓冲区的原始数量,则可能会调用两次。驱动程序应在*num_buffers中返回所需的缓冲区数,在*num_planes中返回每个缓冲区的平面数,在sizes[]数组中设置每个平面的大小,并在alloc_devs[]数组中设置每个平面的分配设备(可选)。在从VIDIOC_REQBUFS()调用时,*num_planes == 0,驱动程序必须使用当前配置的格式来确定平面大小,并且*num_buffers是要分配的缓冲区的总数。在从VIDIOC_CREATE_BUFS()调用时,*num_planes != 0,并且它描述了请求的平面数,并且sizes[]包含了请求的平面大小。在这种情况下,*num_buffers将被额外分配给q->num_buffers。如果*num_planes或所请求的大小无效,则回调必须返回-EINVAL。
2. wait_prepare:在需要等待新缓冲区到达之前,释放调用vb2函数时获取的任何锁;必须在ioctl需要等待新缓冲区到达之前调用,以避免阻塞访问类型产生死锁。
3. wait_finish:重新获取在上一个回调中释放的所有锁;必须在等待新缓冲区到达时继续操作之前调用。
4. buf_out_validate:在输出缓冲区被准备或排队到请求时调用;驱动程序可以使用此函数验证用户空间提供的信息;这仅对OUTPUT队列需要。
5. buf_init:在分配缓冲区(在MMAP情况下)或获取新的USERPTR缓冲区后调用一次;驱动程序可以执行其他与缓冲区相关的初始化;如果初始化失败(返回值!= 0),将阻止队列设置成功完成;可选。
6. buf_prepare:每次从用户空间排队缓冲区和VIDIOC_PREPARE_BUF() ioctl调用时调用;驱动程序可以在此回调中执行每个硬件操作之前需要的任何初始化;在此回调中,驱动程序可以访问/修改缓冲区,因为它仍然针对CPU同步;支持VIDIOC_CREATE_BUFS()的驱动程序还必须验证缓冲区大小;如果返回错误,则缓冲区将不会在驱动程序中排队;可选。
7. buf_finish:在每次将缓冲区从驱动程序出队返回给用户空间之前调用;缓冲区已经同步到CPU,因此驱动程序可以访问/修改缓冲区内容;驱动程序可以在用户空间访问缓冲区之前执行任何所需的操作;可选。缓冲区的状态可以是以下之一:DONE和ERROR发生在流媒体进行中时,PREPARED状态发生在队列被取消并且所有等待的缓冲区正在返回其默认的DEQUEUED状态时。通常只有当状态为VB2_BUF_STATE_DONE时才需要执行某些操作,因为在其他情况下缓冲区内容将被忽略。
8. buf_cleanup:在缓冲区被释放之前调用一次;驱动程序可以执行任何额外的清理;可选。
9. start_streaming:用于进入“流媒体”状态的回调函数;在调用start_streaming之前,驱动程序可能会在buf_queue回调之前收到缓冲区;驱动程序可以在硬件失败时返回错误,此时通过调用vb2_buffer_done()并使用VB2_BUF_STATE_QUEUED标记已经由buf_queue回调提供的所有缓冲区来返回缓冲区。如果您需要在开始流传之前至少排队一定数量的缓冲区,则设置vb2_queue->min_buffers_needed。如果这个值非零,则只有在用户空间至少排队了这么多的缓冲区后,才会调用start_streaming。
10. stop_streaming:在需要禁用“流媒体”状态时调用;驱动程序应停止任何DMA事务或等待它们完成,并通过调用vb2_buffer_done()函数将所有从buf_queue回调获得的缓冲区返回,状态为VB2_BUF_STATE_DONE或VB2_BUF_STATE_ERROR;可以使用vb2_wait_for_all_buffers()函数。
11. buf_queue:将缓冲区vb传递给驱动程序;驱动程序可以在此缓冲区上启动硬件操作;驱动程序应使用vb2_buffer_done()函数将缓冲区返回;它始终在调用VIDIOC_STREAMON() ioctl之后调用;如果用户在调用VIDIOC_STREAMON()之前预先排队了缓冲区,则可能在start_streaming回调之前调用。
12. buf_request_complete:一个从未排队到驱动程序的与排队请求相关联的缓冲区被取消。驱动程序将必须标记请求中的关联对象为已完成;如果支持请求,则此回调是必需的。
这些操作在中断上下文中不会调用,除非特别指定。
struct vb2_buf_ops
是一个结构体,用于定义驱动程序特定的回调函数。
定义:

struct vb2_buf_ops {
int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
void (*init_buffer)(struct vb2_buffer *vb);
void (*fill_user_buffer)(struct vb2_buffer *vb, void *pb);
int (*fill_vb2_buffer)(struct vb2_buffer *vb, struct vb2_plane *planes);
void (*copy_timestamp)(struct vb2_buffer *vb, const void *pb);
};

它包含以下成员:
1. verify_planes_array:验证用户空间结构中是否包含足够的平面以存储缓冲区。对于每个出队的缓冲区都会调用此函数。
2. init_buffer:给定一个vb2_buffer,在struct vb2_buffer之后初始化额外的数据。对于V4L2来说,这是一个struct vb2_v4l2_buffer。
3. fill_user_buffer:给定一个vb2_buffer,填充用户空间结构。对于V4L2来说,这是一个struct v4l2_buffer。
4. fill_vb2_buffer:给定一个用户空间结构,填充vb2_buffer。如果用户空间结构无效,则此操作将返回错误。
5. copy_timestamp:将时间戳从用户空间结构复制到struct vb2_buffer。
struct vb2_queue
是一个 videobuf 队列的结构体,用来管理视频缓冲区队列。
定义:

struct vb2_queue {
unsigned int
type;
unsigned int
io_modes;
struct device
*dev;
unsigned long
dma_attrs;
unsigned int
bidirectional:1;
unsigned int
fileio_read_once:1;
unsigned int
fileio_write_immediately:1;
unsigned int
allow_zero_bytesused:1;
unsigned int
quirk_poll_must_check_waiting_for_buffers:1;
unsigned int
supports_requests:1;
unsigned int
requires_requests:1;
unsigned int
uses_qbuf:1;
unsigned int
uses_requests:1;
unsigned int
allow_cache_hints:1;
unsigned int
non_coherent_mem:1;
struct mutex
*lock;
void *owner;
const struct vb2_ops
*ops;
const struct vb2_mem_ops
*mem_ops;
const struct vb2_buf_ops
*buf_ops;
void *drv_priv;
u32 subsystem_flags;
unsigned int
buf_struct_size;
u32 timestamp_flags;
gfp_t gfp_flags;
u32 min_buffers_needed;
struct device
*alloc_devs[VB2_MAX_PLANES];
};

成员变量包括:
- type:私有缓冲区类型,由调用者定义。例如,在 V4L2 中应该与 enum v4l2_buf_type 中定义的类型相匹配。
- io_modes:支持的 I/O 方法,参见 enum vb2_io_modes。
- dev:默认分配上下文中要使用的设备,如果驱动程序没有填充 alloc_devs 数组时使用。
- dma_attrs:用于 DMA 的 DMA 属性。
- bidirectional:当设置了此标志时,该队列的缓冲区的 DMA 方向将被覆盖为 DMA_BIDIRECTIONAL 方向。这在硬件(固件)将写入映射为读取(DMA_TO_DEVICE)的缓冲区,或者从映射为写入(DMA_FROM_DEVICE)的缓冲区中读取以满足某些内部硬件限制或添加处理算法所需的填充时非常有用。如果 DMA 映射不是双向的,但硬件(固件)试图访问缓冲区(在相反的方向上),则可能会导致 IOMMU 保护错误。
- fileio_read_once:在读取第一个缓冲区后报告 EOF。
- fileio_write_immediately:每次调用 write() 后立即将缓冲区排队。
- allow_zero_bytesused:允许将 bytesused 设置为 0 传递给驱动程序。
- quirk_poll_must_check_waiting_for_buffers:在 QBUF 没有被调用时,在 poll 时返回 EPOLLERR。这是 vb1 的习惯用法,也被 vb2 采用。
- supports_requests:该队列支持请求 API。
- requires_requests:该队列要求使用请求 API。如果将其设置为 1,则 supports_requests 必须也设置为 1。
- uses_qbuf:使用了 qbuf 来直接排队该队列的缓冲区。首次调用时设置为 1。取消队列时设置为 0。如果为 1,则无法从请求中排队缓冲区。
- uses_requests:使用请求来排队该队列的缓冲区。首次排队请求时设置为 1。取消队列时设置为 0。如果为 1,则无法直接排队缓冲区。
- allow_cache_hints:当设置时,用户空间可以传递缓存管理提示以跳过对于 ->prepare() 或/和 ->finish() 的缓存刷新/失效操作。
- non_coherent_mem:当设置时,队列将尝试使用非一致性内存分配缓冲区。
- lock:指向互斥锁的指针,用于保护 struct vb2_queue。驱动程序可以将其设置为互斥锁,以使 v4l2 核心对队列的 I/O 控制进行序列化。如果驱动程序想自己处理锁定,则应将其设置为 NULL。该锁不会被 videobuf2 核心 API 使用。
- owner:‘拥有’缓冲区的文件句柄,即调用 reqbufs、create_buffers 或启动 fileio 的文件句柄。该字段不被 videobuf2 核心 API 使用,但它允许驱动程序轻松地将所有者文件句柄与队列关联起来。
- ops:驱动程序特定的回调函数。
- mem_ops:内存分配器特定的回调函数。
- buf_ops:在用户空间和内核空间之间传递缓冲区信息的回调函数。
- drv_priv:驱动程序的私有数据。
- subsystem_flags:子系统特定的标志(V4L2/DVB 等)。不被 vb2 核心使用。
- buf_struct_size:驱动程序特定缓冲区结构的大小;“0”表示驱动程序不希望使用自定义缓冲区结构类型。在这种情况下,将使用一个子系统特定的结构体(在 V4L2 的情况下是 sizeof(struct vb2_v4l2_buffer))。驱动程序特定缓冲区结构的第一个字段必须是子系统特定的结构体(例如,在 V4L2 的情况下是 vb2_v4l2_buffer)。
- timestamp_flags:时间戳标志;V4L2_BUF_FLAG_TIMESTAMP_* 和 V4L2_BUF_FLAG_TSTAMP_SRC_*。
- gfp_flags:在分配缓冲区时使用的附加 gfp 标志。通常为 0,但可以是例如 GFP_DMA 或 __GFP_DMA32,以将缓冲区分配到特定的内存区域。
- min_buffers_needed:在可以调用 start_streaming 之前所需的最小缓冲区数。当 DMA 引擎必须至少已经排队了这个数量的缓冲区才能启动时使用。
- alloc_devs:按平面区域的设备内存类型/分配器特定的设备。
bool vb2_queue_allows_cache_hints(struct vb2_queue *q)
如果队列允许缓存和内存一致性提示,则返回true。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
void * vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
返回给定平面的内核虚拟地址。
参数:
- struct vb2_buffer *vb:指向所讨论平面所属的struct vb2_buffer的指针。
- unsigned int plane_no:要返回地址的平面编号。
描述:
如果存在给定平面的映射,则该函数返回该平面的内核虚拟地址;否则返回NULL。
void * vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
返回给定平面的分配器特定cookie。
参数:
- struct vb2_buffer *vb:指向所讨论平面所属的struct vb2_buffer的指针。
- unsigned int plane_no:要返回cookie的平面编号。
描述:
如果可用,该函数返回给定平面的分配器特定cookie;否则返回NULL。
分配器应提供一些简单的静态内联函数,用于将此cookie转换为分配器特定类型,以便驱动程序可以直接使用它来访问缓冲区。这可以是物理地址、散列列表的指针或IOMMU映射等。
void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
通知videobuf缓冲区上的操作已完成。
参数:
- struct vb2_buffer *vb:指向要使用的struct vb2_buffer的指针。
- enum vb2_buffer_state state:缓冲区的状态,由enum vb2_buffer_state定义。如果操作成功完成,则为VB2_BUF_STATE_DONE;如果操作以错误完成,则为VB2_BUF_STATE_ERROR;如果已被排队,则为VB2_BUF_STATE_QUEUED。
描述:
驱动程序在缓冲区上的硬件操作完成后,应调用此函数,并可以将缓冲区返回给用户空间。在通过vb2_ops->buf_queue回调函数将其排队回驱动程序之前,驱动程序不能再使用该缓冲区。只能将先前通过vb2_ops->buf_queue排队到驱动程序的缓冲区传递给此函数。
在流处理期间,缓冲区只能以状态DONE或ERROR返回。如果由于某种原因无法启动DMA引擎,则vb2_ops->start_streaming操作也可以返回这些状态。在这种情况下,应将缓冲区以状态QUEUED返回,以将其放回队列中。
void vb2_discard_done(struct vb2_queue *q)
丢弃所有标记为DONE的缓冲区。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
此函数用于挂起/恢复操作。它丢弃所有已完成的缓冲区,因为在恢复后它们会变得太旧而无法被请求。
在调用此函数之前,驱动程序必须停止硬件,并与中断处理程序和/或延迟工作进行同步,以确保驱动程序和/或硬件不会访问任何缓冲区。
int vb2_wait_for_all_buffers(struct vb2_queue *q)
等待直到所有缓冲区都被返回给vb2。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
此函数将等待,直到所有已通过vb2_ops->buf_queue提交给驱动程序的缓冲区都被使用vb2_buffer_done()重新返回给vb2。它不调用vb2_ops->wait_prepare/vb2_ops->wait_finish对。它的目的是在拿取所有锁时调用,例如在vb2_ops->stop_streaming回调中。
该函数将阻塞当前线程,直到所有缓冲区都被返回为止。
void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb)
查询视频缓冲区的信息。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned int index:缓冲区的id号码。
- void *pb:从用户空间传递的缓冲区结构体。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_QUERYBUF()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
传递的缓冲区应该经过验证。
该函数填充了用户空间所需的相关信息。
返回:
成功时返回零;否则返回错误码。
int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int flags, unsigned int *count)
启动数据流传输。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- enum vb2_memory memory:内存类型,由enum vb2_memory定义。
- unsigned int flags:辅助队列/缓冲区管理标志。当前仅使用的标志是V4L2_MEMORY_FLAG_NON_COHERENT。
- unsigned int *count:请求的缓冲区数量。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_REQBUF()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
此函数的功能包括:
1) 验证从用户空间传递的流参数;
2) 设置队列;
3) 与驱动程序协商在数据流传输期间要使用的缓冲区数量和每个缓冲区的平面数;
4) 根据协商达成的参数分配内部缓冲区结构(struct vb2_buffer);
5) 对于MMAP内存类型,使用在队列初始化期间提供的内存处理/分配例程分配实际的视频内存。
如果req->count为0,则释放所有内存。
如果队列先前通过前一个vb2_core_reqbufs()调用进行了分配并且队列未忙,则将重新分配内存。
返回:
成功时返回零;否则返回错误码。
int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int flags, unsigned int *count, unsigned int requested_planes, const unsigned int requested_sizes[])
分配缓冲区和任何必需的辅助结构。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- enum vb2_memory memory:内存类型,由enum vb2_memory定义。
- unsigned int flags:辅助队列/缓冲区管理标志。
- unsigned int *count:请求的缓冲区数量。
- unsigned int requested_planes:请求的平面数。
- const unsigned int requested_sizes[]:具有平面大小的数组。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_CREATE_BUFS()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
此函数的功能包括:
1) 验证参数的正确性;
2) 调用vb2_ops->queue_setup队列操作;
3) 执行任何必要的内存分配。
返回:
成功时返回零;否则返回错误码。
int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
将一个缓冲区的所有权从用户空间转移到内核。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned int index:缓冲区的 ID 号码。
- void *pb:从用户空间传递给驱动程序中的v4l2_ioctl_ops->vidioc_prepare_buf处理程序的缓冲区结构。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_PREPARE_BUF()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
传递的缓冲区应已经通过验证。
这个函数调用驱动程序中的vb2_ops->buf_prepare回调(如果提供),在该回调中可以执行驱动程序特定的缓冲区初始化。
返回:
成功时返回零;否则返回错误码。
int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, struct media_request *req)
从用户空间排队一个缓冲区。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned int index:缓冲区的 ID 号码。
- void *pb:从用户空间传递给驱动程序中的v4l2_ioctl_ops->vidioc_qbuf处理程序的缓冲区结构。
- struct media_request *req:指向struct media_request的指针,可以为NULL。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_QBUF()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
这个函数:
1) 如果req非空,则将缓冲区绑定到此媒体请求,并返回。当请求本身被排队时,缓冲区将被准备并排队到驱动程序(即下面的两个步骤)。
2) 如果需要,调用驱动程序中的vb2_ops->buf_prepare回调(如果提供),在该回调中可以执行驱动程序特定的缓冲区初始化。
3) 如果流式处理正在进行,则通过vb2_ops->buf_queue回调将缓冲区排队到驱动程序进行处理。
返回:
成功时返回零;否则返回错误码。
int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, bool nonblocking)
从用户空间出队一个缓冲区。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned int *pindex:指向缓冲区索引的指针。可以为NULL。
- void *pb:从用户空间传递给驱动程序中的v4l2_ioctl_ops->vidioc_dqbuf处理程序的缓冲区结构。
- bool nonblocking:如果为true,则此调用在没有准备好出队的缓冲区时不会休眠等待。通常,驱动程序将在这里传递(file->f_flags & O_NONBLOCK)。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_DQBUF()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
这个函数:
1) 调用驱动程序中的buf_finish回调(如果提供),在此回调中,驱动程序可以在将缓冲区返回给用户空间之前执行任何可能需要的其他操作,例如缓存同步。
2) 填充缓冲区结构的成员与用户空间相关的信息。
返回:
成功时返回零;否则返回错误码。
int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
实现VB2的流打开逻辑。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned int type:要启动的队列的类型。对于V4L2,这由enum v4l2_buf_type类型定义。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_STREAMON()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
此函数用于处理开始数据流的操作。它根据提供的队列类型进行相应的处理,并将其状态设置为流开启。
返回:
成功时返回零;否则返回错误码。
int vb2_core_streamoff(struct vb2_queue *q, unsigned int type)
实现VB2的流关闭逻辑。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned int type:要停止的队列的类型。对于V4L2,这由enum v4l2_buf_type类型定义。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_STREAMOFF()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
此函数用于处理停止数据流的操作。它将相应的队列状态设置为流关闭,并执行任何必要的清理操作,以确保数据流正确停止。
返回:
成功时返回零;否则返回错误码。
int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, unsigned int index, unsigned int plane, unsigned int flags)
将缓冲区导出为文件描述符。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- int *fd:与DMABUF相关联的文件描述符的指针(由驱动程序设置)。
- unsigned int type:缓冲区类型。
- unsigned int index:缓冲区的ID号码。
- unsigned int plane:要导出的平面索引,对于单平面队列为0。
- unsigned int flags:新创建文件的标志,定义在include/uapi/asm-generic/fcntl.h中。目前,唯一使用的标志是O_CLOEXEC。有关更多详情,请参阅open系统调用的手册。
描述:
Videobuf2的核心帮助函数,用于实现VIDIOC_EXPBUF()操作。它由VB2内部调用,由API特定的处理程序(如videobuf2-v4l2.h)处理。
此函数将指定的缓冲区导出为文件描述符。驱动程序将为相关的DMABUF对象创建一个文件描述符,并将其与提供的指针进行关联。
返回:
成功时返回零;否则返回错误码。
int vb2_core_queue_init(struct vb2_queue *q)
初始化一个videobuf2队列。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。这个结构体应该由驱动程序分配。
描述:
vb2_queue结构体应由驱动程序分配。驱动程序负责清除它的内容并为一些必需的条目设置初始值,然后调用此函数。
注意:在调用此函数之前,应设置以下字段的值:vb2_queue->ops、vb2_queue->mem_ops、vb2_queue->type。
该函数的作用是初始化videobuf2队列,为队列分配内部的数据结构,并设置一些必要的默认值。初始化后,队列就可以准备接收数据,并可以通过相关的API进行操作。
返回:
成功时返回零;否则返回错误码。
void vb2_core_queue_release(struct vb2_queue *q)
停止流式传输,释放队列并释放内存。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
该函数停止流式传输并执行必要的清理工作,包括释放视频缓冲区内存。驱动程序负责释放struct vb2_queue本身。
该函数的作用是停止视频数据的传输,并进行必要的清理操作,包括释放视频缓冲区的内存。在调用此函数之后,队列将不再可用,相关的资源将被释放。
返回:
无返回值。
void vb2_queue_error(struct vb2_queue *q)
在队列上发出致命错误信号。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
该函数设置一个致命的、不可恢复的错误标志,并唤醒所有在队列上等待的进程。此后,轮询操作将设置EPOLLERR标志,并且队列中的缓冲区入队和出队操作将返回-EIO错误码。取消队列(例如通过vb2_streamoff()或vb2_queue_release()调用)时,错误标志将被清除。因此,驱动程序在启动流之前不应调用此函数,否则错误标志将保持设置状态,直到关闭设备节点并释放队列时。
该函数的作用是在队列上设置一个致命错误标志,表示发生了一个不可恢复的错误。这个错误标志会通知等待在队列上的进程,让它们知道发生了一个致命错误。此后,对队列的轮询操作将返回一个错误值,而缓冲区的入队和出队操作将返回-EIO错误码。当取消队列时,错误标志将被清除。
返回:
无返回值。
int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
将视频缓冲区映射到应用程序的地址空间。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- struct vm_area_struct *vma:指向包含在驱动程序中的mmap文件操作处理程序中传递给vma的struct vm_area_struct的指针。
描述:
此函数应从驱动程序的mmap文件操作处理程序中调用。该函数将一个可用视频缓冲区的一个平面映射到用户空间。要映射在reqbufs上分配的整个视频内存,需要对之前分配的每个平面的每个缓冲区调用此函数一次。当用户空间应用程序调用mmap时,它会传递一个先前由v4l2_ioctl_ops->vidioc_querybuf处理程序返回的偏移量。该偏移量充当一个"cookie",用于标识要映射的平面。该函数查找具有匹配偏移量的平面,并通过提供的内存操作执行映射。此函数的返回值应直接从驱动程序的mmap处理程序中返回。
返回值:
- 成功:返回0或正数,表示映射成功。
- 失败:返回负数,表示映射失败。可以根据具体的错误码进行错误处理。
unsigned long vb2_get_unmapped_area(struct vb2_queue *q, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
为给定的缓冲区提供地址映射。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned long addr:内存地址。
- unsigned long len:缓冲区大小。
- unsigned long pgoff:页偏移量。
- unsigned long flags:内存标志。
描述:
此函数用于在没有MMU平台上为给定的缓冲区提供地址映射。它旨在作为file_operations->get_unmapped_area操作的处理程序使用。当!CONFIG_MMU时,mmap()系统调用例程将调用此函数以获取映射的建议地址。
返回值:
- 成功:返回一个未映射区域的起始地址(unsigned long类型)。
- 失败:返回-EINVAL,表示无效的参数。
__poll_t vb2_core_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
实现poll系统调用的逻辑。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- struct file *file:传递给poll文件操作处理程序的struct file参数。
- poll_table *wait:传递给poll文件操作处理程序的poll_table wait参数。
描述:
此函数为驱动程序实现了poll文件操作处理程序。对于CAPTURE队列,如果一个缓冲区准备好出队,用户空间将被通知视频设备的文件描述符可用于读取。对于OUTPUT队列,如果一个缓冲区准备好出队,文件描述符将被报告为可用于写入。
此函数的返回值应直接从驱动程序的poll处理程序中返回。
返回值:
- 返回__poll_t类型的值,用于指示文件描述符的状态和事件。常见的返回值是POLLIN(文件描述符可读)和POLLOUT(文件描述符可写)。其他的返回值和标志可以根据具体的需求和条件进行设置。
size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblock)
实现read系统调用的逻辑。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- char __user *data:指向目标用户空间缓冲区的指针。
- size_t count:要读取的字节数。
- loff_t *ppos:文件句柄位置跟踪指针。
- int nonblock:模式选择器(1表示阻塞调用,0表示非阻塞)。
描述:
此函数实现了read文件操作处理程序。它用于从驱动程序的缓冲区中读取数据并将其写入到用户空间提供的缓冲区中。它通过vb2_queue的内部机制从队列中获取数据,并将其拷贝到用户空间缓冲区中。
返回值:
- 返回成功读取的字节数(size_t类型)。
- 如果非阻塞模式下没有可用的数据,则返回0。
- 返回-errno以表示读取操作失败,并相应地设置错误码。
size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, loff_t *ppos, int nonblock)
实现write系统调用的逻辑。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- const char __user *data:指向目标用户空间缓冲区的指针。
- size_t count:要写入的字节数。
- loff_t *ppos:文件句柄位置跟踪指针。
- int nonblock:模式选择器(1表示阻塞调用,0表示非阻塞)。
描述:
此函数实现了write文件操作处理程序。它用于将用户空间提供的数据写入到驱动程序的缓冲区中。它通过vb2_queue的内部机制将数据从用户空间缓冲区拷贝到队列中。
返回值:
- 返回成功写入的字节数(size_t类型)。
- 如果非阻塞模式下无法立即写入所有数据,则返回已写入的部分字节数。
- 返回-errno以表示写入操作失败,并相应地设置错误码。
vb2_thread_fnc函数是用于vb2_thread的回调函数类型。
语法:
int vb2_thread_fnc(struct vb2_buffer *vb, void *priv)
参数:
- struct vb2_buffer *vb:指向struct vb2_buffer的指针。
- void *priv:指向私有数据的指针。
描述:
在线程中出列缓冲区时,会调用此函数。它接收一个指向vb2_buffer的指针以及私有数据的指针作为参数。在函数内部,您可以对缓冲区进行处理和操作。
返回值:
- 返回int类型的值,表示函数执行的结果。通常,返回0表示成功,而其他非零值表示出现错误或异常情况。
int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv, const char *thread_name)
启动一个线程来处理给定的队列。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- vb2_thread_fnc fnc:vb2_thread_fnc回调函数。
- void *priv:传递给回调函数的私有指针。
- const char *thread_name:线程的名称。它将以"vb2-"作为前缀。
描述:
此函数启动一个线程,该线程会持续进行队列入列和出列操作,直到发生错误或调用vb2_thread_stop()函数停止。
注意:
此函数应仅用于videobuf2-dvb支持,不应用于其他情况。如果您认为有其他合适的用例,请先联系Linux Media邮件列表。
int vb2_thread_stop(struct vb2_queue *q)
停止给定队列的线程。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
此函数停止处理给定队列的线程。它会终止线程的执行,并清理任何相关资源。
注意:
在调用该函数之前,请确保线程已经启动,并且不再需要进一步处理队列。
bool vb2_is_streaming(struct vb2_queue *q)
返回队列的流状态。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
此函数返回队列当前的流状态。它用于确定队列是否处于流模式。
返回值:
- 如果队列正在流动,则返回true。
- 如果队列不在流动状态,则返回false。
bool vb2_fileio_is_active(struct vb2_queue *q)
如果fileio处于活动状态,则返回true。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
此函数返回true如果使用read()或write()来流式传输数据,而不是使用流I/O。在几乎所有情况下,这几乎不是一个重要的区别。但在某些罕见情况下,这是重要的区别之一。
其中一个情况是使用read()或write()来流式传输使用V4L2_FIELD_ALTERNATE格式的数据是不允许的,因为你无法将每个缓冲区的字段信息传递给/从用户空间。支持此字段格式的驱动程序应该在vb2_ops->queue_setup操作中检查此情况,并在此函数返回true时拒绝它。
bool vb2_is_busy(struct vb2_queue *q)
返回队列的繁忙状态。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
此函数检查队列是否分配了任何缓冲区。
返回值:
- 如果队列有任何已分配的缓冲区,则返回true。
- 如果队列没有已分配的缓冲区,则返回false。
void * vb2_get_drv_priv(struct vb2_queue *q)
返回与队列相关联的驱动程序私有数据。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
此函数返回与给定队列相关联的驱动程序私有数据的指针。驱动程序可以使用此指针来存储和检索与队列操作相关的任何私有数据。
返回值:
- 返回指向驱动程序私有数据的指针(void *)。
void vb2_set_plane_payload(struct vb2_buffer *vb, unsigned int plane_no, unsigned long size)
设置平面plane_no的bytesused。
参数:
- struct vb2_buffer *vb:指向所讨论的平面所属的struct vb2_buffer的指针。
- unsigned int plane_no:要设置payload的平面编号。
- unsigned long size:以字节为单位的payload大小。
描述:
该函数用于设置给定平面的bytesused值。bytesused表示已使用的数据大小,通常用于视频帧中编码后的数据。
注意:
- 在调用此函数之前,应确保平面plane_no已经分配和初始化。
示例用法:

```
struct vb2_buffer *buffer; // 假设有一个vb2_buffer对象
unsigned int plane_no = 0; // 假设要设置的平面编号为0
unsigned long size = 1024; // 假设payload大小为1024字节

vb2_set_plane_payload(buffer, plane_no, size);
```

这将把平面0的bytesused设置为1024字节。
unsigned long vb2_get_plane_payload(struct vb2_buffer *vb, unsigned int plane_no)
获取平面plane_no的bytesused。
参数:
- struct vb2_buffer *vb:指向所讨论的平面所属的struct vb2_buffer的指针。
- unsigned int plane_no:要获取payload的平面编号。
描述:
该函数用于获取给定平面的bytesused值。bytesused表示已使用的数据大小,通常用于视频帧中编码后的数据。
注意:
- 在调用此函数之前,应确保平面plane_no已经分配和初始化。
返回值:
- 返回平面plane_no的bytesused值(unsigned long)。
示例用法:

```
struct vb2_buffer *buffer; // 假设有一个vb2_buffer对象
unsigned int plane_no = 0; // 假设要获取的平面编号为0

unsigned long payload_size = vb2_get_plane_payload(buffer, plane_no);
```

这将返回平面0的bytesused值,即payload的大小。
unsigned long vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
返回平面plane_no的大小(以字节为单位)。
参数:
- struct vb2_buffer *vb:指向所讨论的平面所属的struct vb2_buffer的指针。
- unsigned int plane_no:要返回大小的平面编号。
描述:
该函数用于获取给定平面的大小。大小表示平面的容量,通常用于视频帧中的数据存储。
注意:
- 在调用此函数之前,应确保平面plane_no已经分配和初始化。
返回值:
- 返回平面plane_no的大小(unsigned long)。
示例用法:

```
struct vb2_buffer *buffer; // 假设有一个vb2_buffer对象
unsigned int plane_no = 0; // 假设要获取大小的平面编号为0

unsigned long plane_size = vb2_plane_size(buffer, plane_no);
```

这将返回平面0的大小,即平面的容量大小。
bool vb2_start_streaming_called(struct vb2_queue *q)
返回驱动程序的流式传输状态。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
该函数用于检查驱动程序的流式传输状态。它返回一个布尔值,指示vb2_start_streaming()方法是否已被调用。
返回值:
- 如果vb2_start_streaming()方法已被调用,则返回true;否则返回false。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue对象

bool streaming_status = vb2_start_streaming_called(queue);
```

这将返回驱动程序的流式传输状态。如果vb2_start_streaming()方法已被调用,则streaming_status为true;否则为false。
void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
清除队列的最后一个已出列缓冲区标志。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
描述:
该函数用于清除队列的最后一个已出列缓冲区标志。通常在每次处理完缓冲区后,可以调用此函数来重置已出列缓冲区的状态。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue对象

vb2_clear_last_buffer_dequeued(queue);
```

这将清除队列的最后一个已出列缓冲区标志。
struct vb2_buffer *vb2_get_buffer(struct vb2_queue *q, unsigned int index)
从队列中获取一个缓冲区。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- unsigned int index:要获取的缓冲区的索引。
描述:
该函数通过索引从队列中获取一个缓冲区。请注意,此操作中没有引用计数,因此应考虑缓冲区的生命周期。
返回值:
- 返回获取到的缓冲区的指针,类型为struct vb2_buffer。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue对象
unsigned int buffer_index = 0; // 假设要获取的缓冲区的索引为0

struct vb2_buffer *buffer = vb2_get_buffer(queue, buffer_index);
```

这将返回队列中索引为0的缓冲区的指针。
bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
如果缓冲区正在使用中,无法通过VID_IOC_REQBUFS(0)调用释放队列,则返回true。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- struct vb2_buffer *vb:要检查的缓冲区。
描述:
该函数用于检查缓冲区是否正在使用中,即被其他组件或操作占用,并且无法通过调用VID_IOC_REQBUFS(0)来释放队列。
返回值:
- 如果缓冲区正在使用中且队列无法被释放,则返回true;否则返回false。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue对象
struct vb2_buffer *buffer; // 假设有一个vb2_buffer对象

bool in_use = vb2_buffer_in_use(queue, buffer);
```

这将检查缓冲区是否正在使用中并且无法释放队列。如果缓冲区正在使用中且队列无法被释放,则in_use为true;否则为false。
int vb2_verify_memory_type(struct vb2_queue *q, enum vb2_memory memory, unsigned int type)
检查内存类型和缓冲区类型是否与队列兼容。
参数:
- struct vb2_queue *q:指向具有videobuf2队列的struct vb2_queue的指针。
- enum vb2_memory memory:内存模型,由enum vb2_memory定义。
- unsigned int type:私有缓冲区类型,其内容由vb2-core调用方定义。例如,对于V4L2,它应与enum v4l2_buf_type中定义的类型匹配。
描述:
此函数用于检查内存类型和缓冲区类型是否与队列兼容。在进行缓冲区操作时,需要确保传递的内存类型和缓冲区类型与队列兼容,以确保正确的操作。
返回值:
- 如果内存类型和缓冲区类型与队列兼容,则返回0;否则返回负数错误代码。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue对象
enum vb2_memory mem_type; // 假设有一个vb2_memory枚举值
unsigned int buffer_type; // 假设有一个私有缓冲区类型

int result = vb2_verify_memory_type(queue, mem_type, buffer_type);
if (result < 0) {
    // 错误处理
} else {
    // 执行其他操作
}
```

这将检查内存类型和缓冲区类型是否与队列兼容。如果兼容,result将为0,表示通过验证。如果不兼容,result将为负数,表示错误代码,可以根据需要进行适当的错误处理。
bool vb2_request_object_is_buffer(struct media_request_object *obj)
如果对象是缓冲区,则返回true。
参数:
- struct media_request_object *obj:请求对象。
描述:
该函数用于检查给定的请求对象是否是缓冲区。
返回值:
- 如果对象是缓冲区,则返回true;否则返回false。
示例用法:

```
struct media_request_object *request_obj; // 假设有一个media_request_object对象

bool is_buffer = vb2_request_object_is_buffer(request_obj);
```

这将检查给定的请求对象是否是缓冲区。如果是缓冲区,则is_buffer为true;否则为false。
unsigned int vb2_request_buffer_cnt(struct media_request *req)
返回请求中缓冲区的数量。
参数:
- struct media_request *req:请求对象。
描述:
该函数用于获取请求中缓冲区的数量。
返回值:
- 返回请求中缓冲区的数量。
示例用法:

```
struct media_request *request; // 假设有一个media_request对象

unsigned int buffer_count = vb2_request_buffer_cnt(request);
```

这将返回请求中缓冲区的数量。将数量存储在buffer_count变量中供进一步使用。
struct vb2_v4l2_buffer
v4l2的视频缓冲区信息。
定义

struct vb2_v4l2_buffer {
    struct vb2_buffer vb2_buf;
    __u32 flags;
    __u32 field;
    struct v4l2_timecode timecode;
    __u32 sequence;
    __s32 request_fd;
    bool is_held;
    struct vb2_plane planes[VB2_MAX_PLANES];
};

成员
- vb2_buf:嵌入的struct vb2_buffer。
- flags:缓冲区的信息标志。
- field:图像在缓冲区中的场顺序,由enum v4l2_field定义。
- timecode:帧时间码。
- sequence:该帧的序列计数。
- request_fd:与此缓冲区关联的请求文件描述符。
- is_held:如果为true,则表示该捕获缓冲区已被保留。
- planes:平面信息(userptr/fd、长度、已使用字节数、数据偏移量)。
描述
该结构体应包含足够的信息,以涵盖videodev2.h中struct v4l2_buffer的所有字段。
该结构体用于表示v4l2视频缓冲区的信息。它是vb2_buffer结构体的扩展,添加了v4l2特定的字段和平面信息。通过使用这个结构体,可以方便地访问和操作v4l2的视频缓冲区。
int vb2_find_timestamp(const struct vb2_queue *q, u64 timestamp, unsigned int start_idx)
在队列中查找具有给定时间戳的缓冲区。
参数:
- const struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- u64 timestamp:要查找的时间戳。
- unsigned int start_idx:在缓冲区数组中开始搜索的起始索引(通常为0)。
请注意,可能会有多个具有相同时间戳值的缓冲区,因此可以通过将start_idx设置为先前找到的索引+1来重新开始搜索。
描述:
该函数用于在给定的队列中查找具有给定时间戳的缓冲区。
返回值:
- 返回具有给定时间戳的缓冲区的索引,如果未找到具有时间戳的缓冲区,则返回-1。
示例用法:

```
const struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
u64 timestamp = 1234567890; // 要查找的时间戳
unsigned int start_idx = 0; // 开始搜索的索引

int buffer_index = vb2_find_timestamp(queue, timestamp, start_idx);
```

这将在给定的队列中查找具有给定时间戳的缓冲区。如果找到具有时间戳的缓冲区,则将其索引存储在buffer_index变量中;如果未找到具有时间戳的缓冲区,则将-1存储在buffer_index变量中。
int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
这是vb2_core_reqbufs()的包装函数,还会验证内存和类型的值。
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- struct v4l2_requestbuffers *req:从用户空间传递给驱动程序中v4l2_ioctl_ops->vidioc_reqbufs处理程序的struct v4l2_requestbuffers结构体。
描述:
该函数用于请求分配视频缓冲区,并对内存和类型的值进行验证。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
struct v4l2_requestbuffers req; // 假设有一个struct v4l2_requestbuffers结构体对象

// 设置req的值
int ret = vb2_reqbufs(queue, &req);
```

注意:在使用此函数之前,应确保已正确设置req结构体的值。该函数将请求为队列分配视频缓冲区,并对内存和类型的值进行验证。返回值ret表示函数执行的结果,成功为0,失败为负数。
int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
这是vb2_core_create_bufs()的包装函数,还会验证内存和类型的值。
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- struct v4l2_create_buffers *create:从用户空间传递给驱动程序中v4l2_ioctl_ops->vidioc_create_bufs处理程序的struct v4l2_create_buffers结构体。
描述:
该函数用于创建视频缓冲区,并对内存和类型的值进行验证。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
struct v4l2_create_buffers create; // 假设有一个struct v4l2_create_buffers结构体对象

// 设置create的值
int ret = vb2_create_bufs(queue, &create);
```

注意:在使用此函数之前,应确保已正确设置create结构体的值。该函数将创建视频缓冲区,并对内存和类型的值进行验证。返回值ret表示函数执行的结果,成功为0,失败为负数。
int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev, struct v4l2_buffer *b)
这个函数用于将一个缓冲区从用户空间传递到内核空间。
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- struct media_device *mdev:指向struct media_device的指针,可以为NULL。
- struct v4l2_buffer *b:从用户空间传递给驱动程序中v4l2_ioctl_ops->vidioc_prepare_buf处理程序的缓冲区结构体。
描述:
该函数应该在驱动程序的v4l2_ioctl_ops->vidioc_prepare_buf ioctl处理程序中被调用。函数执行以下操作:
1)验证传递的缓冲区。
2)调用驱动程序中的vb2_ops->buf_prepare回调函数(如果提供),在此函数中可以执行特定于驱动程序的缓冲区初始化操作。
3)如果b->request_fd非零且mdev->ops->req_queue已设置,则将准备好的缓冲区绑定到请求。
该函数的返回值可直接从驱动程序的v4l2_ioctl_ops->vidioc_prepare_buf处理程序中返回。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
struct media_device *media_dev; // 假设有一个media_device对象
struct v4l2_buffer buffer; // 假设有一个v4l2_buffer结构体对象

// 设置buffer的值
int ret = vb2_prepare_buf(queue, media_dev, &buffer);
```

注意:在使用此函数之前,应确保已正确设置buffer结构体的值。该函数将验证缓冲区、执行驱动程序中的特定操作,并将准备好的缓冲区绑定到请求(如果适用)。返回值ret表示函数执行的结果,可直接从驱动程序的v4l2_ioctl_ops->vidioc_prepare_buf处理程序中返回。
int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev, struct v4l2_buffer *b)
这个函数用于将一个缓冲区从用户空间入队到队列中。
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- struct media_device *mdev:指向struct media_device的指针,可以为NULL。
- struct v4l2_buffer *b:从用户空间传递给驱动程序中v4l2_ioctl_ops->vidioc_qbuf处理程序的缓冲区结构体。
描述:
该函数应该在驱动程序的v4l2_ioctl_ops->vidioc_qbuf ioctl处理程序中被调用。函数执行以下操作:
1)验证传递的缓冲区。
2)如果b->request_fd非零且mdev->ops->req_queue已设置,则将缓冲区绑定到请求。
3)如果需要,在驱动程序中调用vb2_ops->buf_prepare回调函数(如果提供),在此函数中可以执行特定于驱动程序的缓冲区初始化操作。
4)如果正在进行流式传输,通过vb2_ops->buf_queue回调函数将缓冲区入队到驱动程序中进行处理。
该函数的返回值可直接从驱动程序的v4l2_ioctl_ops->vidioc_qbuf处理程序中返回。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
struct media_device *media_dev; // 假设有一个media_device对象
struct v4l2_buffer buffer; // 假设有一个v4l2_buffer结构体对象


// 设置buffer的值
int ret = vb2_qbuf(queue, media_dev, &buffer);
```

注意:在使用此函数之前,应确保已正确设置缓冲区结构体的值。该函数将验证缓冲区、绑定缓冲区到请求(如果适用)、执行驱动程序中的特定操作,并将缓冲区入队到驱动程序进行处理(如果正在进行流式传输)。返回值ret表示函数执行的结果,可直接从驱动程序的v4l2_ioctl_ops->vidioc_qbuf处理程序中返回。
int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
这个函数用于将一个缓冲区导出为文件描述符。
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- struct v4l2_exportbuffer *eb:从用户空间传递给驱动程序中v4l2_ioctl_ops->vidioc_expbuf处理程序的导出缓冲区结构体。
描述:
该函数应该在驱动程序的v4l2_ioctl_ops->vidioc_expbuf ioctl处理程序中被调用。函数执行以下操作:
1)将缓冲区导出为文件描述符,并将文件描述符存储在导出缓冲区结构体的fd字段中。
该函数的返回值可直接从驱动程序的v4l2_ioctl_ops->vidioc_expbuf处理程序中返回。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
struct v4l2_exportbuffer export_buffer; // 假设有一个v4l2_exportbuffer结构体对象

// 设置export_buffer的值
int ret = vb2_expbuf(queue, &export_buffer);
```

注意:在使用此函数之前,应确保已正确设置导出缓冲区结构体的值。该函数将将缓冲区导出为文件描述符,并将文件描述符存储在导出缓冲区结构体的fd字段中。返回值ret表示函数执行的结果,可直接从驱动程序的v4l2_ioctl_ops->vidioc_expbuf处理程序中返回。
int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
这个函数用于将一个缓冲区从队列中出队到用户空间。
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- struct v4l2_buffer *b:从用户空间传递给驱动程序中v4l2_ioctl_ops->vidioc_dqbuf处理程序的缓冲区结构体。
- bool nonblocking:表示是否以非阻塞方式出队。
描述:
该函数应该在驱动程序的v4l2_ioctl_ops->vidioc_dqbuf ioctl处理程序中被调用。函数执行以下操作:
1)尝试从队列中出队一个可用缓冲区。
2)如果nonblocking为false并且没有可用缓冲区,则将进程设置为睡眠状态,直到有可用缓冲区或者驱动程序使用vb2_ops->buf_release回调函数释放了某个缓冲区。
3)如果成功出队了一个缓冲区,则将缓冲区的信息存储在传递的缓冲区结构体中。
该函数的返回值可直接从驱动程序的v4l2_ioctl_ops->vidioc_dqbuf处理程序中返回。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
struct v4l2_buffer buffer; // 假设有一个v4l2_buffer结构体对象

// 设置buffer的值
int ret = vb2_dqbuf(queue, &buffer, false);
```

注意:在使用此函数之前,应确保已正确设置缓冲区结构体的值。该函数将尝试从队列中出队一个可用缓冲区,并将出队的缓冲区的信息存储在传递的缓冲区结构体中。返回值ret表示函数执行的结果,可直接从驱动程序的v4l2_ioctl_ops->vidioc_dqbuf处理程序中返回。
int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
开始数据流传输
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- enum v4l2_buf_type type:从用户空间传递给驱动程序中vidioc_streamon处理程序的类型参数,由enum v4l2_buf_type定义。
描述:
该函数应该在驱动程序的v4l2_ioctl_ops->vidioc_streamon ioctl处理程序中被调用。函数执行以下操作:
1)验证当前状态。
2)将任何先前排队的缓冲区传递给驱动程序,并开始数据流传输。
该函数的返回值可直接从驱动程序的v4l2_ioctl_ops->vidioc_streamon处理程序中返回。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
enum v4l2_buf_type buf_type; // 假设有一个v4l2_buf_type类型的变量

// 设置buf_type的值
int ret = vb2_streamon(queue, buf_type);
```

注意:在使用此函数之前,应确保已正确设置缓冲区类型。该函数将验证当前状态,并将任何先前排队的缓冲区传递给驱动程序,然后开始数据流传输。返回值ret表示函数执行的结果,可直接从驱动程序的v4l2_ioctl_ops->vidioc_streamon处理程序中返回。
int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
停止数据流传输
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- enum v4l2_buf_type type:从用户空间传递给驱动程序中vidioc_streamoff处理程序的类型参数,由enum v4l2_buf_type定义。
描述:
该函数应该在驱动程序的vidioc_streamoff处理程序中被调用。函数执行以下操作:
1)验证当前状态。
2)停止数据流传输,并从队列中出队任何排队的缓冲区,包括先前传递给驱动程序的缓冲区(等待驱动程序完成后)。
此调用可用于暂停播放。该函数的返回值可直接从驱动程序的vidioc_streamoff处理程序中返回。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
enum v4l2_buf_type buf_type; // 假设有一个v4l2_buf_type类型的变量

// 设置buf_type的值
int ret = vb2_streamoff(queue, buf_type);
```

注意:在使用此函数之前,应确保已正确设置缓冲区类型。该函数将验证当前状态,并停止数据流传输,并将任何排队的缓冲区出队,包括先前传递给驱动程序的缓冲区(等待驱动程序完成后)。返回值ret表示函数执行的结果,可直接从驱动程序的vidioc_streamoff处理程序中返回。
int vb2_queue_init(struct vb2_queue *q)
初始化videobuf2队列
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
描述:
vb2_queue结构体应该由驱动程序进行分配。在调用此函数之前,驱动程序应负责清除其内容并为一些必需的条目设置初始值。
其中,q->ops、q->mem_ops、q->type和q->io_modes是强制要求的。更多信息请参考include/media/videobuf2-core.h中struct vb2_queue的描述。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象

// 在分配和设置其他必需的条目之后,进行队列初始化
int ret = vb2_queue_init(queue);
```

注意:在调用此函数之前,驱动程序应负责分配vb2_queue结构体,并设置其中的必需条目。该函数将根据提供的初始化值对队列进行初始化。返回值ret表示函数执行的结果。
int vb2_queue_init_name(struct vb2_queue *q, const char *name)
使用名称初始化videobuf2队列
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- const char *name:队列的名称。
描述:
此函数与vb2_queue_init()相同,还会设置队列的名称。队列名称用于日志记录的目的,并且应在所属设备的上下文中唯一标识队列。这对于将内核日志消息归属到正确的队列非常有用,例如m2m设备或其他处理多个队列的设备。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
const char *queue_name = "my_vb2_queue"; // 设置队列的名称

// 在分配和设置其他必需的条目之后,使用名称进行队列初始化
int ret = vb2_queue_init_name(queue, queue_name);
```

注意:在调用此函数之前,驱动程序应负责分配vb2_queue结构体,并设置其中的必需条目。该函数将根据提供的初始化值对队列进行初始化,并设置队列的名称。返回值ret表示函数执行的结果。
void vb2_queue_release(struct vb2_queue *q)
停止流传输,释放队列并释放内存
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
描述:
此函数停止流传输并执行必要的清理工作,包括释放视频缓冲区内存。驱动程序负责释放vb2_queue结构体本身。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象

// 停止流传输并释放队列及相关内存
vb2_queue_release(queue);
```

注意:该函数将停止流传输并释放与队列相关的资源,但不会负责释放vb2_queue结构体本身。驱动程序应自行负责释放vb2_queue结构体。
int vb2_queue_change_type(struct vb2_queue *q, unsigned int type)
更改非活动vb2_queue的类型
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- unsigned int type:要更改为的类型(V4L2_BUF_TYPE_VIDEO_*)。
描述:
此函数更改vb2_queue的类型。只有在队列未忙碌(即没有分配缓冲区)时才能进行此操作。
vb2_queue_change_type()可用于使用同一队列支持多个缓冲区类型。驱动程序可以实现v4l2_ioctl_ops.vidioc_reqbufs和v4l2_ioctl_ops.vidioc_create_bufs函数,并在调用vb2_ioctl_reqbufs()或vb2_ioctl_create_bufs()之前调用vb2_queue_change_type(),从而“锁定”缓冲区类型,直到缓冲区被释放。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
unsigned int new_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 要更改为的新类型

// 更改队列的类型
int ret = vb2_queue_change_type(queue, new_type);
```

注意:在调用此函数之前,请确保队列处于非活动状态,即没有已分配的缓冲区。返回值ret表示函数执行的结果。
__poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
实现用于poll用户空间操作的函数
参数:
- struct vb2_queue *q:指向带有videobuf2队列的struct vb2_queue的指针。
- struct file *file:传递给poll文件操作处理程序的文件参数。
- poll_table *wait:传递给poll文件操作处理程序的等待参数。
描述:
该函数实现了驱动程序的poll文件操作处理程序。对于CAPTURE队列,如果有缓冲区准备好出队列,用户空间将被通知视频设备的文件描述符可用于读取。对于OUTPUT队列,如果有缓冲区准备好出队列,文件描述符将被报告为可用于写入。
如果驱动程序使用struct v4l2_fh,则vb2_poll()还将检查是否有任何挂起的事件。
该函数的返回值可直接从驱动程序中的poll处理程序返回。
示例用法:

```
struct vb2_queue *queue; // 假设有一个vb2_queue队列对象
struct file *file; // 假设有一个文件对象
poll_table wait; // 假设有一个poll_table对象

// 在驱动程序的poll处理程序中调用vb2_poll
__poll_t ret = vb2_poll(queue, file, &wait);

// 将返回值直接返回给poll处理程序
return ret;
```

void vb2_video_unregister_device(struct video_device *vdev)
注销视频设备并释放队列
参数:
- struct video_device *vdev:指向struct video_device的指针。
描述:
如果驱动程序使用vb2_fop_release()/_vb2_fop_release(),则应该使用vb2_video_unregister_device()而不是video_unregister_device()。
该函数将调用video_unregister_device(),然后在流传输进行中时释放vb2_queue。这将停止流传输,并简化解绑序列,因为在此调用之后,所有的子设备也将停止流传输。
示例用法:

```
struct video_device *vdev; // 假设有一个视频设备对象

// 注销视频设备并释放队列
vb2_video_unregister_device(vdev);
```

注意:在调用此函数之前,请确保在流传输期间停止了流传输。
void vb2_ops_wait_prepare(struct vb2_queue *vq)
锁定struct vb2_queue的辅助函数
参数:
- struct vb2_queue *vq:指向struct vb2_queue的指针。
描述:
注意:只在vq->lock非空时使用。
该函数是一个辅助函数,用于锁定struct vb2_queue对象。在使用该函数之前,请确保vq->lock不为空。
示例用法:

```
struct vb2_queue *vq; // 假设有一个vb2_queue队列对象

// 在需要锁定队列的地方调用vb2_ops_wait_prepare
vb2_ops_wait_prepare(vq);
```

注意:在调用此函数之前,请确保vq->lock不为空,以避免空指针异常。
void vb2_ops_wait_finish(struct vb2_queue *vq)
解锁struct vb2_queue的辅助函数
参数:
- struct vb2_queue *vq:指向struct vb2_queue的指针。
描述:
注意:只在vq->lock非空时使用。
该函数是一个辅助函数,用于解锁struct vb2_queue对象。在使用该函数之前,请确保vq->lock不为空。
示例用法:

```
struct vb2_queue *vq; // 假设有一个vb2_queue队列对象

// 在需要解锁队列的地方调用vb2_ops_wait_finish
vb2_ops_wait_finish(vq);
```

注意:在调用此函数之前,请确保vq->lock不为空,以避免空指针异常。
struct vb2_vmarea_handler
通用的vma引用计数跟踪处理程序。
定义:

struct vb2_vmarea_handler {
    refcount_t *refcount;
    void (*put)(void *arg);
    void *arg;
};

成员:
- refcount:指向缓冲区中refcount_t条目的指针。
- put:用于减少缓冲区引用计数的回调函数。
- arg:put回调函数的参数。
解释:
vb2_vmarea_handler结构体定义了一个通用的vma引用计数跟踪处理程序。它包含了以下成员:
- refcount:指向缓冲区中refcount_t类型的引用计数条目的指针。该引用计数用于跟踪缓冲区的引用数量。
- put:一个回调函数,用于减少缓冲区的引用计数。通过调用put函数,可以减少对缓冲区的引用计数,当引用计数达到零时,可以采取相应的操作(如释放缓冲区)。
- arg:put回调函数的参数。这是一个可选的参数,可根据需要传递给put回调函数。
示例用法:

```
struct vb2_vmarea_handler handler;
refcount_t refcount;
void my_put_callback(void *arg);

// 设置refcount和put回调函数
handler.refcount = &refcount;
handler.put = my_put_callback;
handler.arg = NULL;

// 使用vb2_vmarea_handler对象进行引用计数跟踪
// ...在代码中对缓冲区进行操作,并使用handler来增加/减少引用计数...

// 在适当的位置,调用put回调函数来减少引用计数
handler.put(handler.arg);
```


注意:在实际使用时,需要确保正确初始化和管理vb2_vmarea_handler对象,并根据具体需求实现相关的put回调函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值