V4L2问题,streamon总是失败

leooelleooel 2016-05-05 10:58:20
小弟初来乍到,给各位大神请安。

摄像头是ov5640。板子是omap4-vkboard。摄像头与板子连接接口是MIPI接口。系统是UBUNTU12.04。
问题如下:
我写好的程序在PC虚拟机上没有问题。但是在板子上跑的时候,
1,streamon这个环节总是失败(ioctl操作streamon返回值是-1)。
2,fmt.fmt.pix.colorspace输出值是0,(在PC上输出值是8)。是什么原因呢。


V4L2部分代码如下:


int i,ret; ///ret用来记录对硬件操作后的返回值。
fd = open(CAMERA_DEVICE, O_RDWR, 0); ///打开设备 返回一个文件描述
ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); /////查询设备属性

memset(&fmtdesc,0,sizeof(fmtdesc)); //////将设备所支持的格式清零
fmtdesc.index=0; ////给查询序号归零
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ////给支持的类型赋值
ret=ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc); ////查询设备属性
if(ret==-1)
printf("cant get the capability of device\n ");
else
printf("devicename:%s\ndrivename:%s\nbus info:%s\ncapabilities:%u\n",cap.driver,cap.card,cap.bus_info,cap.capabilities);


while (ret != 0)
{
fmtdesc.index++;
ret=ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc);
}


memset(&fmt,0,sizeof(fmt)); /////将每一帧图像的信息清零

/////给图像信息赋值
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width=VIDEO_WIDTH;
fmt.fmt.pix.height=VIDEO_HEIGHT;
fmt.fmt.pix.pixelformat=VIDEO_FORMAT;//fmtdesc.pixelformat;V4L2_PIX_FMT_YUYV; V4L2_PIX_FMT_UYVY
fmt.fmt.pix.field=V4L2_FIELD_INTERLACED; ////隔行扫描


ret = ioctl(fd, VIDIOC_S_FMT, &fmt); ///把赋值的格式设置
if(ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
printf("Unable to set format\n");
else printf("set fmt successfully\n");


ret = ioctl(fd, VIDIOC_G_FMT, &fmt); ///获取设置以后现在的图像格式
if(ret==-1)
printf("get format failed\n");
else
printf("fmt.fmt.pix.width is %d\nfmt.fmt.pix.height is %d\nfmt.fmt.pix.colorspace is %d\n",fmt.fmt.pix.width,fmt.fmt.pix.height,fmt.fmt.pix.colorspace);


reqbuf.count = BUFFER_COUNT; /////定义申请几个缓存
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ////定义每个缓存的格式
reqbuf.memory = V4L2_MEMORY_MMAP; ///定义缓存的映射方式
ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf); ////申请缓存
if(ret==-1)
printf("request buffers failed\n");
else
printf("request %d buffers successfully\n",reqbuf.count);


//////////////查询申请到的缓存的物理地址,并把物理地址通过mmap映射到用户空间的缓存
i=0;
for(i=0;i<reqbuf.count;i++)
{
buf.index =i; ////给缓存地址赋上编号
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ///给缓存地址定义类型
buf.memory = V4L2_MEMORY_MMAP; ///给缓存地址定义映射类型

ret = ioctl(fd , VIDIOC_QUERYBUF, &buf); ////查询缓存地址
if(ret==-1)
printf("findding address failed\n");
else
printf("findding address successfully\n");

framebuf[i].length = buf.length; ///给用户空间的缓存长度赋值
framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset); //1
if (framebuf[i].start == MAP_FAILED)
printf("mmap (%d) failed: %s\n", i, strerror(errno));
else
printf("map %d successfully\n",i);
////把内核空间的缓存映射到用户空间 用指针指向它


ret = ioctl(fd , VIDIOC_QBUF, &buf); //操作 找到缓存地址
if (ret < 0)
{
printf("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
return;
}
printf("Frame buffer %d: address=0x%x, length=%d\n", i, (unsigned int)framebuf[i].start, framebuf[i].length);
}



enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 开启视频流的格式
ret = ioctl(fd, VIDIOC_STREAMON, &type); ///开启视频流
if(ret==-1)
printf("streamon failed\n");
else
printf("streamon successfully\n");

ret = ioctl(fd, VIDIOC_DQBUF, &buf); ///取出一帧
if(ret==-1)
printf("get out queue failed\n");
else
printf("get out queue successfully\n");



...全文
859 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧