/**
 * struct v4l2_selection - selection info
 * @type:	buffer type (do not use *_MPLANE types)
 * @target:	Selection target, used to choose one of possible rectangles;
 *		defined in v4l2-common.h; V4L2_SEL_TGT_* .
 * @flags:	constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*.
 * @r:		coordinates of selection window
 * @reserved:	for future use, rounds structure size to 64 bytes, set to zero
 *
 * Hardware may use multiple helper windows to process a video stream.
 * The structure is used to exchange this selection areas between
 * an application and a driver.
 */
struct v4l2_selection {
	__u32			type;
	__u32			target;
	__u32                   flags;
	struct v4l2_rect        r;
	__u32                   reserved[9];
};

这个问题是这样的,上面是v4l2_selection的定义,我将type设置为V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,但是传递到我的驱动内以后,类型就变成

V4L2_BUF_TYPE_VIDEO_CAPTURE了,我一度怀疑是我眼睛被相机的红外照瞎了。直到在文件drivers\media\v4l2-core\v4l2-ioctl.c中看到v4l_s_selection函数,有卧龙必有凤雏,于是,看到

v4l_g_selection,还有v4l_g_crop和v4l_s_crop。

v4l_s_selection函数的运行如下所示:

static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
			   struct file *file, void *fh, void *arg)
{
	struct v4l2_selection *p = arg;
	u32 old_type = p->type;
	int ret;

	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	ret = ops->vidioc_s_selection(file, fh, p);
	p->type = old_type;
	return ret;
}
static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
			   struct file *file, void *fh, void *arg)
{
	struct v4l2_selection *p = arg;
	u32 old_type = p->type;
	int ret;

	if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
	{
		//p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	}
	else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
		p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	ret = ops->vidioc_g_selection(file, fh, p);
	p->type = old_type;
	return ret;
}

修改后,重新编译内核,确实得到解决了。 

 小结

07-17 15:11