V4L2 捕获图像超时 求解

tracyjk 2011-11-21 03:01:23

//表示了处理图像的代码位置。
static void process_image(const void *p)
{
FILE* fp;
fp = fopen("test","w+");
fputs(p, fp);
fclose(fp);
// fflush(stdout);
}

static void mainloop(void)
{
unsigned int count;

count = 100;

while (count-- > 0) {
for (;;) {
fd_set fds;
struct timeval tv;
int r;

FD_ZERO(&fds);
FD_SET(fd, &fds);

/* Timeout. */
//tv.tv_sec = 2;
tv.tv_sec = 60;
tv.tv_usec = 0;

r = select (fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) {
if (EINTR == errno)
continue;

errno_exit("select");
}

if (0 == r) {
fprintf(stderr, "select timeout\n");
exit(EXIT_FAILURE);
}

if (read_frame())
break;

/* EAGAIN - continue select loop. */
}
}
}

static void start_capturing(void)
{
unsigned int i;
enum v4l2_buf_type type;

switch (io) {
case IO_METHOD_MMAP:
for (i = 0; i < n_buffers; ++i) {
struct v4l2_buffer buf;

CLEAR(buf);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;

if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
}

type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
errno_exit("VIDIOC_STREAMON");
break;

case IO_METHOD_USERPTR:
for (i = 0; i < n_buffers; ++i) {
struct v4l2_buffer buf;

CLEAR(buf);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_USERPTR;
buf.index = i;
buf.m.userptr = (unsigned long) buffers[i].start;
buf.length = buffers[i].length;

if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
}

type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
errno_exit("VIDIOC_STREAMON");

break;
}
}

static void init_mmap(void)
{
struct v4l2_requestbuffers req;

CLEAR(req);

req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;

if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
printf("EINVAL == errno\n");
fprintf(stderr, "%s does not support "
"memory mapping\n", dev_name);
exit(EXIT_FAILURE);
} else {
printf("errno_exit(VIDIOC_REQBUFS);\n");
errno_exit("VIDIOC_REQBUFS");
}
}

if (req.count < 2) {
fprintf(stderr, "Insufficient buffer memory on %s\n",
dev_name);
exit(EXIT_FAILURE);
}

buffers = calloc(req.count, sizeof (*buffers));

if (!buffers) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}

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 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
errno_exit("VIDIOC_QUERYBUF");

buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =
mmap(NULL /* start anywhere */,
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
errno_exit("mmap");
}
}

static void init_device(void)
{
struct v4l2_capability cap;
struct v4l2_cropcap cropcap;
struct v4l2_crop crop;
struct v4l2_format fmt;
unsigned int min;

if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
if (EINVAL == errno) {
fprintf(stderr, "%s is no V4L2 device\n",
dev_name);
exit(EXIT_FAILURE);
} else {
errno_exit("VIDIOC_QUERYCAP");
}
}

if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf(stderr, "%s is no video capture device\n",
dev_name);
exit(EXIT_FAILURE);
}

switch (io) {
case IO_METHOD_MMAP:
case IO_METHOD_USERPTR:
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
fprintf(stderr, "%s does not support streaming i/o\n",
dev_name);
exit(EXIT_FAILURE);
}

break;
}
CLEAR(cropcap);

cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect; /* reset to default */

if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
printf("VIDIOC_S_CROP is [%d]\n",errno);
switch (errno) {
case EINVAL:
printf("Cropping not supported\n");
/* Cropping not supported. */
break;
default:
/* Errors ignored. */
break;
}
}
} else {
printf("xioctl(fd, VIDIOC_CROPCAP, &cropcap) Errors ignored\n");
/* Errors ignored. */
}


CLEAR(fmt);

fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
// fmt.fmt.pix.width = 50;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
// fmt.fmt.pix.height = 40;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; /* Four-character-code (FOURCC) */
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
errno_exit("VIDIOC_S_FMT");
/* Note VIDIOC_S_FMT may change width and height. */

/* Buggy driver paranoia. */
min = fmt.fmt.pix.width * 2;
if (fmt.fmt.pix.bytesperline < min)
fmt.fmt.pix.bytesperline = min;
min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
if (fmt.fmt.pix.sizeimage < min)
fmt.fmt.pix.sizeimage = min;

switch (io) {
case IO_METHOD_MMAP:
init_mmap();
break;
}
}

int main(int argc,char **argv)
{
dev_name = "/dev/video0";

open_device();

init_device();

start_capturing();

mainloop();

stop_capturing();

uninit_device();

close_device();

exit(EXIT_SUCCESS);

return 0;
}

由于代码太长,删减掉了无关的代码,采用的是video capture.c代码。
采用MMAP--内存映射的方式,打开/dev/video0设备文件。
打开open_device()、初始化init_device()、捕获图像start_capturing()、的时候都可以顺利执行
到了mainloop()中的select语句的时候总是返回超时的错误
请教下各位有可能是什么原因造成的
...全文
574 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
yzb__2011 2013-07-03
  • 打赏
  • 举报
回复
解决方法啊, 9527就这样结贴了啊?
kuling729 2013-04-17
  • 打赏
  • 举报
回复
同求解决方法~
yuxiaohuan7000 2012-08-27
  • 打赏
  • 举报
回复
同求楼主指导啊
shiwai2011 2012-08-24
  • 打赏
  • 举报
回复
请问楼主怎么解决的啊?急求指教啊~~谢谢!!!
方窗 2012-06-03
  • 打赏
  • 举报
回复
我也遇到类似问题,请问楼主怎么解决的啊、求解~
tracyjk 2011-12-01
  • 打赏
  • 举报
回复
解决了
和应用程序没关系
是底层驱动设置有点问题
hello_kitty8888 2011-11-30
  • 打赏
  • 举报
回复
r有赋值吗?
关注

4,465

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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