Linux v4l2架构学习总链接
gitee源码
VIDIOC_REQBUFS(申请缓冲区)
大部分代码和从应用调用vivi驱动分析v4l2 – 申请缓存(VIDIOC_REQBUFS)是通用的,这里只分析不同的地方
queue_setup
rv1126这里queue_setup
对应代码rkcif_queue_setup
和vivi是不一样的
static int rkcif_queue_setup(struct vb2_queue *queue,
unsigned int *num_buffers,
unsigned int *num_planes,
unsigned int sizes[],
struct device *alloc_ctxs[])
{
struct rkcif_stream *stream = queue->drv_priv;
struct rkcif_device *dev = stream->cifdev;
const struct v4l2_pix_format_mplane *pixm = NULL;
const struct cif_output_fmt *cif_fmt;
u32 i, height;
/* pixm 和 cif_fmt 值得由来,可以看 VIDIOC_S_FMT章节 */
pixm = &stream->pixm;
cif_fmt = stream->cif_fmt_out;
/* 获取planes数量 */
*num_planes = cif_fmt->mplanes;
if (stream->crop_enable)
height = stream->crop[CROP_SRC_ACT].height;
else
height = pixm->height;
/* 下面for循环的主要目的就是获取每个plane的大小
* 记录在sizes中
*/
for (i = 0; i < cif_fmt->mplanes; i++) {
const struct v4l2_plane_pix_format *plane_fmt;
int h = round_up(height, MEMORY_ALIGN_ROUND_UP_HEIGHT);
plane_fmt = &pixm->plane_fmt[i];
sizes[i] = plane_fmt->sizeimage / height * h;
}
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "%s count %d, size %d\n",
v4l2_type_names[queue->type], *num_buffers, sizes[0]);
return 0;
}
经过__vb2_queue_alloc
之后,就是这样的一个结构
和之前的vivi中对比,其实差距并不大,这里先关注m.offset
,后面有用。