/**
* 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;
}
修改后,重新编译内核,确实得到解决了。