前言
多数情况下,对于video设备,我们使用v4l2的时候,都是single plane的使用情景,其实v4l2 还支持mplane 的使用场景,本文将详细介绍mplane的具体使用
一、mplane 相关的结构体
1. struct v4l2_buffer
struct v4l2_buffer的定义如下图所示,其中有一个共用体m成员,在共用体中有一个struct v4l2_plane *plane成员,它就是mplane 的核心结构体
2. struct v4l2_plane
在mplane 中,struct v4l2_plane即代表其中的一个plane
3. enum v4l2_buf_type
在mplane使用场景下,对于capture设备,应该使用V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 同样的,对于output设备,应该使用V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
二、mplane 应用层使用实例
1. 内存使用mmap方式
1. 使用3个plane 的场景:
#define BUFFER_NUM 4
unsigned char *buffer1[BUFFER_NUM];
unsigned char *buffer2[BUFFER_NUM];
struct v4l2_capability cap;
struct v4l2_format fmt;
enum v4l2_buf_type type;
int i;
struct v4l2_buffer buf;
struct v4l2_plane planes[VIDEO_MAX_PLANES];
ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
if(ret < 0)
{
printf("VIDIOC_QUERYCAP failed\n");
return -1;
}
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
ret = ioctl(fd,VIDIOC_G_FMT,&fmt);
if(ret < 0)
{
printf("VIDIOC_G_GMT failed\n");
return -1;
}
memset(&fmt,0,sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
fmt.fmt.pix_mp.width = 1280;
fmt.fmt.pix_mp.height = 720;
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; //input data format
fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
fmt.fmt.pix_mp.num_planes = 3; //plane_num
fmt.fmt.pix_mp.plane_fmt[0].bytesperline = 1280; // no use
fmt.fmt.pix_mp.plane_fmt[0].sizeimage = 1280 * 720 * 3 / 2; // no use
fmt.fmt.pix_mp.plane_fmt[1].bytesperline = 1280; //nv12 data bytesperline size
fmt.fmt.pix_mp.plane_fmt[1].sizeimage = 1280 * 720 * 3 / 2; //nv12 data sizeimage size
fmt.fmt.pix_mp.plane_fmt[2].bytesperline = 1280 / 4; // 1/16 Y data bytesperline size
fmt.fmt.pix_mp.plane_fmt[2].sizeimage = 1280 * 720 / 16 ; // 1/16 Y data sizeimage size
ret = ioctl(fd, VIDIOC_S_FMT,&fmt);
struct v4l2_requestbuffers reqbufs;
memset(&reqbufs,0,sizeof(reqbufs));
reqbufs.count = BUFFER_NUM;
reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
reqbufs.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd,VIDIOC_REQBUFS,&reqbufs);
if(ret < 0)
{
printf("VIDIOC_REQBUF failed\n");
return -1;
}
for(i=0;i<BUFFER_NUM;i++)
{
memset(&buf,0,sizeof(buf));
memset(planes,0,sizeof(planes));
buf.index = i;
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
buf.memory = V4L2_MEMORY_MMAP;
buf.length = VIDEO_MAX_PLANES;
buf.m.planes = planes;
buf.m.planes[0].bytesused = 0;
buf.m.planes