首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

V4L2 捕获图像超时 求解解决方法

2012-02-15 
V4L2 捕获图像超时 求解C/C++ code//表示了处理图像的代码位置。static void process_image(const void *p)

V4L2 捕获图像超时 求解

C/C++ code
//表示了处理图像的代码位置。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语句的时候总是返回超时的错误
请教下各位有可能是什么原因造成的

[解决办法]
r有赋值吗?
关注

热点排行