videobuf处理流程


videobuf是应用程序和v4l2驱动程序的一个中间层,用它来进行视频数据缓冲区的分配和管理。

它根据应用程序的需求(缓冲区的数量的大小),分配相应的视频缓冲区,这个缓冲区是在内核空间分配的,并通过mmap方法映射到用户空间,在内核空间形成一个缓冲区队列,在应用程序中有相应的缓冲区数组对应,它们指向的内存地址是一样的。在驱动程序中,根据配置的硬件参数(FIFO阈值),将vip硬件图像存储器中的数据放到缓冲区队列中的 每个缓冲区,然后等待应用程序来读取该缓冲区的数据。videobuf主要由一些特殊的数据结构和ioctl调用组成,下边对其做整体分析:

一、 初始化

初始化缓冲区队列:
1、驱动层的调用
在v4l2_vip.c文件中:

static int vip_open(struct file *file)
{
 struct vip_dev *dev = video_drvdata(file);
 struct vip_fh *fh = NULL;
 int retval = 0;

、、、、、、、、、

 /*allocate and initialize per filehandle data*/
 fh = kzalloc(sizeof(*fh), GFP_KERNEL);//此时已经把vb_vidq成员的空间分配好
 if(NULL == fh){
  dev->users--;
  retval = -ENOMEM;
 }

、、、、、、、、、、

 fh->type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 fh->fmt    = &formats[0];

、、、、、、、、

 /*初始化videobuf缓冲区队列 vip_video_qops 是驱动层的videobuf回掉函数*/
 videobuf_queue_vmalloc_init(&fh->vb_vidq, &vip_video_qops, NULL,
     &dev->slock, fh->type,  V4L2_FIELD_INTERLACED,
     sizeof(struct vip_buffer), fh);
 return 0;
}


2、videobuf层的操作
在videobuf-vmalloc.c中:

videobuf_queue_vmalloc_init(struct videobuf_queue *q,
    struct videobuf_queue_ops *ops,
    struct device *dev,
    spinlock_t *irqlock,
    enum v4l2_buf_type type,
    enum v4l2_field field,
    unsigned int msize,
    void *priv
)
{
 videobuf_queue_core_init(q, ops, dev, irlock, type, field, msize, priv, &qops);
}

//上边函数多了一个qops参数,它是 videobuf层的数据操作函数集
void videobuf_queue_core_init(struct videobuf_queue *q,
    struct videobuf_queue_ops *ops,
    struct device *dev,
    spinlock_t *irqlock,
    enum v4l2_buf_type type,
    enum v4l2_field field,
    unsigned int msize,
    void *priv,
    struct videobuf_qtype_ops *int_ops)
{
 BUG_ON(!q);
 memset(q, 0, sizeof(*q));
//初始化队列的一些成员
 q->irqlock   = irqlock;
 q->dev       = dev;
 q->type      = type;
 q->field     = field;
 q->msize     = msize;
 q->ops       = ops;
 q->priv_data = priv;
 q->int_ops   = int_ops;

//检测必要的成员数据是否不为空
 /* All buffer operations are mandatory */
 BUG_ON(!q->ops->buf_setup);
 BUG_ON(!q->ops->buf_prepare);
 BUG_ON(!q->ops->buf_queue);
 BUG_ON(!q->ops->buf_release);

 /* Lock is mandatory for queue_cancel to work */
 BUG_ON(!irqlock);

 /* Having implementations for abstract methods are mandatory */
 BUG_ON(!q->int_ops);

 mutex_init(&q->vb_lock);//初始化自旋锁
 init_waitqueue_head(&q->wait);//初始化videobuf队列queue中的等待队列
 INIT_LIST_HEAD(&q->stream);//初始化链表
}


二、 videobuf的相关ioctl()操作
这些操作有三部分组成,1是应用程序通过ioctl函数调用v4l2驱动中实现的接口函数,2这些接口函数在调用videobuf层的响应函数来做出处理,3如果有的处理参数需要v4l2层来决定的话,就调用v4l2层的videobuf设置函数。

1、ioctl接口函数列表

static const struct v4l2_ioctl_ops vip_capture_ioctl_fops = {

、、、、、、

 .vidioc_reqbufs  = vip_reqbufs,
 .vidioc_querybuf = vip_querybuf,
 .vidioc_qbuf  = vip_qbuf,
 .vidioc_dqbuf  = vip_dqbuf,
 .vidioc_streamon = vip_streamon,
 .vidioc_streamoff = vip_streamoff,

、、、、、、
};


2、v4l2层设置回掉函数列表

Static struct videobuf_queue_ops vip_video_qops = {
 .buf_setup   = buffer_setbuf,
 .buf_prepare  = buffer_prepare,
 .buf_queue  = buffer_queue,
 .buf_release  &
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值