- First, it is necessary to state that the new kernel has already adopted
Vb2_queue and Vb2_buffer Replace the Videobuf_queue and videobuf_buffer that are often used in older versions of the kernel. The two are mainly used when applying vidioc_reqbuf to the user layer. From the user layer request of the type of memory, the typical two are: V4l2_memory_userptr and V4l2_memory_mmap, the former is located in the user layer, the video output memory address of the driver is provided by the user layer, The latter mmap operation of the memory cache type generally need to drive themselves to achieve the allocation of memory.
In the older kernel, it is assumed that two types of video device operation interfaces are required, one for each of the two memory_type, and the Ops interface that is generally required is as follows: v4l2_memory_userptr:static const struct V4L2_FILE_ Operations Xxx_video0_fops= {. Owner = This_module,. open = xxx,. release = xxx,. poll = xxx,. unlocked_ioc TL = xxx,};
V4l2_memory_mmap:
static const struct V4l2_file_operations xxxx_video1_fops = {. Owner = This_module,. open = xxx,. release = xxx, . poll = xxx,. unlocked_ioctl = xxx,. mmap = xxx,}; The difference between the two is that one morethe interface of the mmap operation. In addition, for the older kernel, the mmap operation can be implemented by the kernel-provided mmap way, the general processing method is as follows: void Videobuf_queue_dma_contig_init (struct videobuf_queue *q, const struct Videobuf_queue_ops *ops, & nbsp struct device *dev, &NBSP ; spinlock_t *irqlock, enum V4l2_buf_type type,& nbsp enum V4l2_field field, &N Bsp unsigned int msize, void *priv, struct mutex *ext_lock) { VIDEOBUF _queue_core_init (q, Ops, Dev, irqlock, type, field, msize,  PR IV, &qops, Ext_lock);}
Here, the kernel provides a qops to complete each videobuf_buffer ALLOC_VB operation, the process is mainly to apply for a videobuf_buffer but does not directly request the storage of video image data memory block,so generally in the request_buffer process is the main completion of ALLOC_VB operations, the focus is to record the application of each videobuf_buffer where the index value, the process of v4l2_memory_userptr and v4l2_ The Memory_mmap is consistent. static struct Videobuf_qtype_ops Qops = {. Magic = Magic_qtype_ops,
. Alloc_vb = __videobuf_alloc_vb,. Iolock = __videobuf_iolock,. Mmap_mapper = __videobuf_mmap_mapper,. Vaddr = __videobuf_to_vaddr,};V4l2_memory_mmapCache area, he needs the kernel to complete the request that the buffer really stores the memory block of the data, usually through the user layer of the mmap, and in this mmap process to complete the buffer area Alloc operation, in the lower version of the kernel through the __videobuf_ Mmap_mapper to achieve: Mem->size = Page_align (buf->bsize); MEM->VADDR = Dma_alloc_coherent (Q->dev, Mem->size, &mem->dma_handle, GFP_KERNEL) in the completion of the actual object Once you have applied for the storage area, you will not be executed again mmap
- Comparing the processing mechanism of MMAP in the old version, the above pattern can no longer be used when the new kernel needs attention, and for the v4l2_memory_mmap type of vb2_buffer, it is directly Request_ In the process of buffer, you need to complete the application of the actual memory area block (Vb2_reqbufs->__vb2_buf_mem_alloc), and this application interface is implemented in the new kernel by implementing the Vb2_mem_ops interface, which is mainly used for processing V4l2_memory_mmap :
struct Vb2_mem_ops { void * (*alloc) (void *alloc_ctx, unsigned long size); &N Bsp void (*put) (void *buf_priv); void * (*get_userptr) (void *alloc_ctx, unsigned long vaddr, unsigned long size, int write); void (*put_userptr) (void *buf_priv); void & nbsp * (*VADDR) (void *buf_priv); void * (*cookie) (void *buf_priv); u nsigned int (*num_users) (void *buf_priv); int (*MMAP) (void *buf_priv , struct vm_area_struct *vma);}; The interface needs to be implemented in the driver, Alloc generally completes the application of the actual physical memory area block, and Mmap is the interface response for mmap operation of the user space. Of course, in the new version of the kernel still support the above described in the 1 section of the processing process, you can still use this way to implement video-related drivers. In the same way, this approach can be implemented in the old kernel, which is the Vb2_queuethe implementation of VIDEOBUF_QTYPE_OP.
After carefully reading the source code, you can find the process that is essentially described in sections 1 and 2The fundamental difference is that the old version of the schema in the MMAP process to complete the actual buffer physical memory request and memory mapping operations, the new version is the alloc process in the Requestbuffer process, and mmap mapping in the actual mmap operation implemented,。
Overall, the reason for this is that the old and new versions are being processed because more v4l2_memory_userptr types of cache requests are now available (mainly in the now-new Android system where the video request cache is mainly from the GPU, shared memory/dev/ Ion and so on the area block, generally again by memory application words will increase the complexity of the drive, so there is no need to implement MMAP operation, it is generally not necessary to implement the Vb2_mem_ops interface. And if you still use the old version of the process, then you need to videobuf_queue_dma_contig_init to provide a videobuf_qtype_ops, because Alloc_vb is the old version of eitherV4l2_memory_mmap is stillv4l2_memory_userptr all to achieveVideobuf_qtype_ops. In contrast, forV4l2_memory_userptr the new version can reduce a certain amount of code, without vb2_mem_ops.
Of course, the architecture can be implemented in a variety of ways, the essence of the purpose is to the same V4L2 framework based on the video device can work properly.
The difference between video buffer alloc and mmap in the new and old version of Linux V4L2 driver