从vivi学习V4L2架构(十二):关键数据结构关系

自己大概捋了下几个关键数据结构之间的关系,如下图

从vivi学习V4L2架构(十二):关键数据结构关系_第1张图片

总的来说:

一、申请buffer,根据上层申请的buffer数量,驱动层会申请对应数量的vb2_buffer。plane_size对应的是之前设置的分辨率再乘以2.其中申请好存数据的buffer地址存放在vb2_buffer->planes[]->mem_priv。

二、映射申请好的buf到用户空间。

三、QBUF 将申请好的vb2_buffer加入到vb2_queue的queued_list链表中。如果QBUF时,已经stream on的话,那么vb2_buffer从queued_list链表中取出并放入到vivi_buffer->vivi_dmaqueue->active链表中。

四、STREAM ON,先创建vivi_thread线程,线程主要就是从vivi_dmaqueue->active中取下vb2_buffer,并填充数据,填好数据后,将vb2_buffer挂载到vb2_queue->done_list中去,并唤醒等待vb2_queue->done_wq上面的任务。然后休眠等下一帧数据时间到来后唤醒。

五、DQBUF,判读vb2_queue->done_wq链表上是否有数据,有数据从done_list链表中取出vb2_buffer,并将相关信息填充到v4l2_buffer,返回给上层。如果vb2_queue->done_wq没有数据则通过wait queue在done_wq上休眠等待,等待数据的到来。

六、STREAM OFF, 将streamon创建的vivi_thread给停下来,再从vidq->active链表中将还未填数据的vivi_buffer删除掉,并将vb2_buffer加入到vb2_queue的done_list链表中,唤醒done_wq去处理。 唤醒done_wq其实就是将vb2_buffer从done_list里面取出并删除,并把vb2_buffer的信息返回给上层应用,还有将vb2_buffer从vb2_queue->queued_list链表中删除。最后将vb2_queue的queued_list、done_list两个链表重新初始化, vb2_buffer的state重新初始化为VB2_BUF_STATE_DEQUEUED。

你可能感兴趣的:(v4l2,学习)