1. 程式人生 > >從cimutils到核心-(6)VIDIOC_DQBUF(從視訊快取佇列中取出有資料的buffer)

從cimutils到核心-(6)VIDIOC_DQBUF(從視訊快取佇列中取出有資料的buffer)

應用層:

 

 

case IO_METHOD_MMAP:

CLEAR(buf);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

buf.memory = V4L2_MEMORY_MMAP;

if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {

switch (errno) {

case EAGAIN:

return 0;

case EIO:

default:

errno_exit("VIDIOC_DQBUF");

}

}

assert(buf.index < n_buffers);

camera_inf->buf_vaddr = (void *)buffers[buf.index].start;

if (camera_ctl->cam_opt == OPS_PREVIEW)

{

if (camera_ctl->ops.priview_picture){

camera_ctl->ops.priview_picture(camera_inf);

}

} else if (camera_ctl->cam_opt == OPS_CAPTURE){

if (camera_ctl->ops.capture_picture)

camera_ctl->ops.capture_picture(camera_inf, camera_ctl);

}

if (camera_inf->param.debug == 1 && camera_ctl->cam_opt == OPS_PREVIEW)

{

if (camera_ctl->ops.camera_fps)

camera_ctl->ops.camera_fps(camera_inf);

}

if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))

errno_exit("VIDIOC_QBUF");

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

核心:

 

(1)

drivers/media/v4l2-core/v4l2-ioctl.c

IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE)

 

static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,

struct file *file, void *fh, void *arg)

{

struct v4l2_buffer *p = arg;

int ret = check_fmt(file, p->type);

return ret ? ret : ops->vidioc_dqbuf(file, fh, p);

}

 

 

(2)

drivers/media/platform/soc_camera/soc_camera.c

static int soc_camera_dqbuf(struct file *file, void *priv,

struct v4l2_buffer *p)

{

struct soc_camera_device *icd = file->private_data;

struct soc_camera_host *ici = to_soc_camera_host(icd->parent);

WARN_ON(priv != file->private_data);

if (icd->streamer != file)

return -EBUSY;

if (ici->ops->init_videobuf)

return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);

else

return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);

}

 

(3)

drivers/media/v4l2-core/videobuf2-core.c

int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)

{

ret = __vb2_get_done_vb(q, &vb, b, nonblocking); //從done_list的連結串列中取出buffer 然後刪除buffer list_del(&(*vb)->done_entry);

 

ret = call_qop(q, buf_finish, vb);

 

/* Fill buffer information for the userspace */

__fill_v4l2_buffer(vb, b); //填充v4l2_buffer結構體返回給應用層

/* Remove from videobuf queue */

list_del(&vb->queued_entry); //刪除queued_list連結串列的一個節點。

/* go back to dequeued state */

__vb2_dqbuf(vb);

}

 

 

(3)

VIDIOC_QBUF 入隊一個buffer