分享

Linux v4l2架构之v4l2-ctl抓取、设置图像

 charlie_linux 2022-07-15 发布于广东

一、本开发、测试基于RV1126-1109的SDK上进行。一个mipi的摄像头,接到rv1126上看看能不能抓到图。不需要配置寄存器。例如这个摄像头参数:raw8,4lanes,512*192,30fps

二、v4l2-ctl工具则是针对/dev/video0,/dev/video1等 video设备,它在video设备上进行set_fmt、reqbuf、qbuf、dqbuf、stream_on、stream_off 等一系列操作。

复制一份索尼imx291的代码直接修改,改完之后测试。测试方法如下:

v4l2-ctl -d /dev/video0 --set-fmt-video=width=512,height=192,pixelformat=BG10 --stream-mmap=3 --stream-to=/tmp/bg10.bin --stream-count=1 --stream-poll

三、测试方法和步骤如下:

执行发现,没有抓到数据也没有timeout,直接退出了。dmesg发现出现了如下一条信息

rkcif_mipi_lvds: crop size is bigger than input

这部分代码如下:

rkcif_start_streaming() -> rkcif_sanity_check_fmt(stream, NULL)

static int rkcif_sanity_check_fmt(struct rkcif_stream *stream,
				  const struct v4l2_rect *s_crop)
{
	struct rkcif_device *dev = stream->cifdev;
	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
	struct v4l2_rect input, *crop;
 
	stream->cif_fmt_in = get_input_fmt(dev->active_sensor->sd,
					   &input, stream->id + 1);
	if (!stream->cif_fmt_in) {
		v4l2_err(v4l2_dev, "Input fmt is invalid\n");
		return -EINVAL;
	}
 
	if (s_crop)
		crop = (struct v4l2_rect *)s_crop;
	else
		crop = &stream->crop[CROP_SRC_ACT];
 
	if (crop->width + crop->left > input.width ||
	    crop->height + crop->top > input.height) {
		v4l2_err(v4l2_dev, "crop size is bigger than input\n");
		return -EINVAL;
	}
       
        ...
}

查看代码可以知道input.width及heigth小于crop的width或者heigth。于是去找crop的赋值代码 ,查看函数rkcif_stream_init()

#define RKCIF_DEFAULT_WIDTH	640
#define RKCIF_DEFAULT_HEIGHT	480
 
void rkcif_stream_init(struct rkcif_device *dev, u32 id)
{
	...
 
	for (i = 0; i < CROP_SRC_MAX; i++) {
		stream->crop[i].left = 0;
		stream->crop[i].top = 0;
		stream->crop[i].width = RKCIF_DEFAULT_WIDTH;
		stream->crop[i].height = RKCIF_DEFAULT_HEIGHT;
	}
 
	...
}

定位之后,只需修改大小即可:

#define RKCIF_DEFAULT_WIDTH    480
#define RKCIF_DEFAULT_HEIGHT    240

再次测试,正常!

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多