报错问题
在通过ioctl(fd, VIDIOC_ENUM_FRAMESIZES, frmsize);
接口枚举不到分辨率
排查问题
通过查阅mx6s_capture.c文件,找到枚举分辨率的接口,找到向ov2640驱动调用的代码,在ov2640中查看enum_frame_size函数的实现。
static int mx6s_vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
/* 省略部分代码 */
ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
if (ret)
return ret;
/* 省略部分代码 */
问题原因
在ov2640的驱动源码中,并未实现enum_frame_size
接口,因此上层无法获取该参数。
enum_frame_size
属于struct v4l2_subdev_pad_ops类型的pad参数中的一个成员,在ov2640中,仅定义了core
与video
的部分成员函数,没有定义pad成员。
static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
.s_stream = ov2640_s_stream,
.g_mbus_fmt = ov2640_g_fmt,
.s_mbus_fmt = ov2640_s_fmt,
.try_mbus_fmt = ov2640_try_fmt,
.cropcap = ov2640_cropcap,
.g_crop = ov2640_g_crop,
.enum_mbus_fmt = ov2640_enum_fmt,
.g_mbus_config = ov2640_g_mbus_config,
};
static struct v4l2_subdev_ops ov2640_subdev_ops = {
.core = &ov2640_subdev_core_ops,
.video = &ov2640_subdev_video_ops,
};
解决方法
在ov2640驱动中添加pad
成员与enum_frame_size
接口。对enum_frame_size接口的实现如下。
static int ov2640_enum_frame_sizes(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
int i = ARRAY_SIZE(ov2640_codes);
if (fse->index >= ARRAY_SIZE(ov2640_supported_win_sizes))
return -EINVAL;
while (--i)
if (fse->code == ov2640_codes[i])
break;
fse->min_width = ov2640_supported_win_sizes[fse->index].width;
fse->max_width = fse->min_width;
fse->max_height = ov2640_supported_win_sizes[fse->index].height;
fse->min_height = fse->max_height;
return 0;
}
static struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = {
.enum_frame_size = ov2640_enum_frame_sizes,
};
static struct v4l2_subdev_ops ov2640_subdev_ops = {
/* 省略部分代码 */
.pad = &ov2640_subdev_pad_ops,
};