mplane方式v4l2应用分析 -- mmap(映射)

Linux v4l2架构学习总链接

gitee源码

mmap

同样的先去看从应用调用vivi驱动分析v4l2 – 映射 mmap
这里看看怎么找到plane的

static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
			unsigned int *_buffer, unsigned int *_plane)
{
	struct vb2_buffer *vb;
	unsigned int buffer, plane;

	/*
	 * Go over all buffers and their planes, comparing the given offset
	 * with an offset assigned to each plane. If a match is found,
	 * return its buffer and plane numbers.
	 */
	for (buffer = 0; buffer < q->num_buffers; ++buffer) {
		vb = q->bufs[buffer];

		for (plane = 0; plane < vb->num_planes; ++plane) {
			/* 可以看到通过offset的值,精确找到对应的plane
			 * 用于映射到应用空间
			 */
			if (vb->planes[plane].m.offset == off) {
				*_buffer = buffer;
				*_plane = plane;
				return 0;
			}
		}
	}

	return -EINVAL;
}

编写对应的应用程序

	struct plane_start {
	    void * start;
	};
	
	struct buffer {
	    struct plane_start* plane_start;
	    struct v4l2_plane* planes_buffer;
	};
	buffers = malloc(req.count * sizeof(*buffers));
	
	for(i = 0; i < req.count; i++) {
		  memset(&buf, 0, sizeof(buf));
		  planes_buffer = calloc(num_planes, sizeof(*planes_buffer));
		  plane_start = calloc(num_planes, sizeof(*plane_start));
		  memset(planes_buffer, 0, sizeof(*planes_buffer));
		  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
		  buf.memory = V4L2_MEMORY_MMAP;
		  buf.m.planes = planes_buffer;
		  buf.length = num_planes;
		  buf.index = i;
		  if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buf)) {
		      printf("Querybuf fail\n");
		      goto err;
		  }
		
		  (buffers + i)->planes_buffer = planes_buffer;
		  (buffers + i)->plane_start = plane_start;
		  for(j = 0; j < num_planes; j++) {
		      printf("plane[%d]: length = %d\n", j, (planes_buffer + j)->length);
		      printf("plane[%d]: offset = %d\n", j, (planes_buffer + j)->m.mem_offset);
		      /* 这里要记录每个plane的映射地址 */
		      (plane_start + j)->start = mmap (NULL /* start anywhere */,
		                              (planes_buffer + j)->length,
		                              PROT_READ | PROT_WRITE /* required */,
		                              MAP_SHARED /* recommended */,
		                              fd,
		                              (planes_buffer + j)->m.mem_offset);
		      if (MAP_FAILED == (plane_start +j)->start) {
		          printf ("mmap failed\n");
		          req.count = i;
		          goto unmmap;
		      }
		  }
	}

可以看到和传统的方式对比,传统方式可以认为只有1个plane,所以只需要对没有buffer进行mmap就可以了。
对于mplane的情况,要对每个buffer的每个plane进行mmap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dianlong_lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值