天嵌 ARM开发社区

 找回密码
 注册
查看: 4074|回复: 11

V4L2 mmap is failed

[复制链接]
安仔 发表于 2011-12-26 13:32:00 | 显示全部楼层 |阅读模式
基于国嵌的H264的那个v4l项目,本人想改为V4L2,但是在板子上显示:
USB_video is OK
VIDIOC_S_FMT is OK
VIDIOC_REQBUFS is OK
buffers is OK
VIDIOC_QUERYBUF is OK
the buf length is 32768
the buf offset is 0
mmap is failed
VIDIOC_QBUF is OK
zc3xx: probe 2wr ov vga 0x0000
VIDIOC_STREAMON is OK
VIDIOC_DQBUF is OK
Segmentation fault

发现原来是mmap没有成功,原代码部分如下:
void init_video() /* bpp == bytes per pixel*/
{
   int ret;
/*设备的打开*/
   cam_fd = open( USB_VIDEO, O_NONBLOCK);
  if( cam_fd<0 )
  printf("Can't open video device\n");
else
printf("USB_video is OK\n");

  CLEAR (fmt);
  fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  fmt.fmt.pix.width = 100;//帧宽

  fmt.fmt.pix.height = 100;//帧高

  fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;//像素格式

  fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;//隔行扫描
  //设置当前驱动的视频捕获格式
  if (-1 == ioctl (cam_fd, VIDIOC_S_FMT, &fmt))
  errno_exit ("VIDIOC_S_FMT");
else
  printf("VIDIOC_S_FMT is OK\n");
struct v4l2_requestbuffers req;
  CLEAR (req);
req.count = 1;//在缓存队列里保存多少张照片
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;//内存映射
/*向驱动申请帧缓冲,一般不超过5个。*/
if (-1 == ioctl (cam_fd, VIDIOC_REQBUFS, &req))
{
errno_exit ("VIDIOC_REQBUFS");
}
else
printf("VIDIOC_REQBUFS is OK\n");
buffers = calloc (req.count, sizeof (*buffers));//分配连续的内存给刚才申请的缓冲区,并且初始化为0,返回值是首地址(物理地址)
if (!buffers) {
fprintf (stderr, "Out of memory\n");
exit (EXIT_FAILURE);
}
else
printf("buffers is OK\n");

for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
struct v4l2_buffer buf;
CLEAR (buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;//缓冲区序号
if (-1 == ioctl (cam_fd, VIDIOC_QUERYBUF, &buf))//把数据缓存转换成物理地址
errno_exit ("VIDIOC_QUERYBUF");
else
printf("VIDIOC_QUERYBUF is OK\n");
printf("the buf length is %d\n",buf.length);
printf("the buf offset is %d\n",buf.m.offset);
buffers[n_buffers].length = buf.length;
buffers[n_buffers].offset = (size_t) buf.m.offset;
//buffers[n_buffers].start= (char*)mmap (NULL, buf.length,PROT_READ | PROT_WRITE, MAP_SHARED, cam_fd, buf.m.offset);//确定被映射的内存地址
buffers[n_buffers].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
                        MAP_SHARED, cam_fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
printf("mmap is failed\n");
else
printf("mmap is OK\n");
InitLookupTable();
}
}

求高人指教,究竟哪个地方错了!!!!
TQ-lkp 发表于 2011-12-26 13:56:32 | 显示全部楼层
试下这段代码吧
  1. for (n_buffers = 0; n_buffers < req.count; ++n_buffers)
  2.         {
  3.                 struct v4l2_buffer buf;

  4.                 CLEAR(buf);

  5.                 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  6.                 buf.memory = V4L2_MEMORY_MMAP;
  7.                 buf.index = n_buffers;

  8.                 if (-1 == xioctl(m_iFd, VIDIOC_QUERYBUF, &buf))
  9.                 {
  10.                         errno_exit("VIDIOC_QUERYBUF");
  11.                         return false;
  12.                 }

  13.                 buffers[n_buffers].length = buf.length;
  14.                 buffers[n_buffers].start = (unsigned char *) mmap(
  15.                                 NULL /* start anywhere */, buf.length,
  16.                                 PROT_READ | PROT_WRITE /* required */,
  17.                                 MAP_SHARED /* recommended */, m_iFd, buf.m.offset);

  18.                 if (MAP_FAILED == buffers[n_buffers].start)
  19.                         return false;
  20.         }
复制代码
 楼主| 安仔 发表于 2011-12-26 14:09:33 | 显示全部楼层
好的我试一下
 楼主| 安仔 发表于 2011-12-26 14:27:26 | 显示全部楼层
:'(:'(哎还是如此
 楼主| 安仔 发表于 2011-12-26 14:30:24 | 显示全部楼层
the buf length is 32768
这个buf.length值好大
 楼主| 安仔 发表于 2011-12-26 15:04:42 | 显示全部楼层
TQ那个usb摄像头测试程序里面的buf.length 才68
 楼主| 安仔 发表于 2011-12-26 19:53:20 | 显示全部楼层
已解决结贴
TQ-lkp 发表于 2011-12-26 20:28:38 | 显示全部楼层
本帖最后由 TQ-lkp 于 2011-12-26 20:29 编辑

把如何解决的贴上分享一下,大家营造一个良好的学习,交流环境
 楼主| 安仔 发表于 2011-12-26 22:43:04 | 显示全部楼层
buffers[n_buffers].start =

(char*)mmap (NULL /* 映射起始地址,NULL内核自动选择 */,

buf.length,//被映射内存块的长度

PROT_EXEC|PROT_READ | PROT_WRITE /*标志映射后能否被读写 */,

MAP_PRIVATE /* 可以被其他进城共享 */,

fd, buf.m.offset);//确定被映射的内存地址

 楼主| 安仔 发表于 2011-12-26 22:44:18 | 显示全部楼层
这样就可以了,但是程序还是有问题,有段错误,我是把国嵌的v4l改成v4l2的,搞了好几天了,没成果啊
wyz365889 发表于 2012-3-6 14:35:10 | 显示全部楼层
安仔 发表于 2011-12-26 22:43
buffers[n_buffers].start =

(char*)mmap (NULL /* 映射起始地址,NULL内核自动选择 */,

问下,楼主你这程序可以捕获单幅图像吗?
亚瑟王 发表于 2012-3-12 17:25:30 | 显示全部楼层
wyz365889 发表于 2012-3-6 14:35
问下,楼主你这程序可以捕获单幅图像吗?

亲,从摄像头来的数据都是一帧一帧的(也就是单幅的),只不过速度快,就变成了动态的了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-29 16:49 , Processed in 1.031250 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表