嵌入式爱好者

查看: 9513|回复: 4

[Linux] 摄像头怎么读取不了图片???

[复制链接]

2

主题

8

帖子

11

积分

扫一扫,手机访问本帖
发表于 2014-5-29 21:14:35 | 显示全部楼层 |阅读模式
写了一个程序,在pc机的linux下可以读取图像。
但是交叉编译后却不能读取了。
显示select timeout  就是在select超时了。。。
怎么回事呢。。。。
当然我是改了设备文件的。
插入摄像头/dev目下了多了一个video2设备文件的。

附上源代码:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<malloc.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/time.h>
#include<sys/mman.h>
#include<sys/ioctl.h>
#include<asm/types.h>
#include<linux/videodev2.h>
#define CLEAR(x) memset(&(x), 0, sizeof(x))
struct buffer
{
        void *start;
        size_t length;
};

static char *dev_name = "/dev/video2";
static int fd = -1;
struct buffer *buffers = NULL;
static unsigned int n_buffers = 0;

FILE *fp;
char *filename = "test.yuv\0";
static void open_device(void)
{
        fd = open(dev_name, O_RDWR|O_NONBLOCK, 0);
        if(-1 == fd)
        {
                perror("open");
                exit(EXIT_FAILURE);
        }
}
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 == ioctl(fd, VIDIOC_REQBUFS, &req))
        {
                if(EINVAL == errno)
                {
                        fprintf(stderr, "%s does not support memory mapping\n", dev_name);
                        exit(EXIT_FAILURE);
                }
                else
                {
                        perror("VIDIOC_REQBUFS");
                        exit(EXIT_FAILURE);
                }
        }
       
        buffers = calloc(req.count, sizeof(*buffers));

        if(!buffers)
        {
                fprintf(stderr, "Out of memory");
                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 == ioctl(fd, VIDIOC_QUERYBUF, &buf))
                {
                        perror("VIDIOC_QUERYBUF");
                        exit(EXIT_FAILURE);
                }
                buffers[n_buffers].length = buf.length;
                buffers[n_buffers].start = mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
                if(MAP_FAILED == buffers[n_buffers].start)
                {
                        perror("mmap");
                        exit(EXIT_FAILURE);
                }
        }
}
static void init_device(void)
{
        struct v4l2_capability cap;
        struct v4l2_format fmt;
       
        if(-1 == ioctl(fd, VIDIOC_QUERYCAP, &cap))
        {
                if(EINVAL == errno)
                {
                        fprintf(stderr, "%s is no v4l2 device\n", dev_name);
                        exit(EXIT_FAILURE);
                }
                else
                {
                        perror("VIDIOC_QUERYCAP");
                        exit(EXIT_FAILURE);
                }
        }
        if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
        {
                fprintf(stderr, "%s is no video capture device\n", dev_name);
                exit(EXIT_FAILURE);
        }
        if(!(cap.capabilities & V4L2_CAP_STREAMING))
        {
                fprintf(stderr, "%s does not support streaming i/o \n", dev_name);
                exit(EXIT_FAILURE);
        }

        CLEAR(fmt);
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.width = 320;
        fmt.fmt.pix.height = 240;
        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

        if(-1 == ioctl(fd, VIDIOC_S_FMT, &fmt))
        {
                perror("VIDIOC_S_FMT");
                exit(EXIT_FAILURE);
        }
        init_mmap();
}
void start_capturing(void)
{
        unsigned int i;
        enum v4l2_buf_type type;
        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 == ioctl(fd, VIDIOC_QBUF, &buf))
                {
                        perror("VIDIOC_QBUF");
                        exit(EXIT_FAILURE);
                }
        }

        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if(-1 == ioctl(fd, VIDIOC_STREAMON, &type))
        {
                perror("VIDIOC_STREAMON");
                exit(EXIT_FAILURE);
        }

}
static void process_image(const void *p, int size)
{
        fwrite(p, size, 1, fp);
}
static int read_frame(void)
{
        struct v4l2_buffer buf;
        unsigned int i;

        CLEAR(buf);
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        if(-1 == ioctl(fd, VIDIOC_DQBUF, &buf))
        {
                switch(errno)
                {
                        case EAGAIN:
                                return 0;
                        case EIO:
                        default:
                                perror("VIDIOC_DQBUF");
                                exit(EXIT_FAILURE);
                }
        }
        process_image(buffers[buf.index].start, buf.length);
        return 1;
}
void mainloop()
{
        unsigned int count;

        count = 1;

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

                        FD_ZERO(&fds);
                        FD_SET(fd, &fds);
                        tv.tv_sec = 2;
                        tv.tv_usec = 0;
                       
                        r = select(fd + 1, &fds, NULL, NULL, &tv);
                        if(-1 == r)
                        {
                                if(EINTR == errno)
                                        continue;
                                perror("select");
                                exit(EXIT_FAILURE);
                        }
                        if(0 == r)
                        {
                                fprintf(stderr, "select timeout\n");
                                exit(EXIT_FAILURE);
                        }
                        if(read_frame())
                                break;
                }
        }
}
static void stop_capturing()
{
        enum v4l2_buf_type type;
        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if(-1 == ioctl(fd, VIDIOC_STREAMOFF, &type))
        {
                perror("VIDIOC_STREAMOFF");
                exit(EXIT_FAILURE);
        }
}
static void uninit_device()
{
        unsigned int i;
        for(i = 0; i < n_buffers; i++)
        {
                if(-1 == munmap(buffers[i].start, buffers[i].length))
                {
                        perror("munmap");
                        exit(EXIT_FAILURE);
                }
        }
        free(buffers);
}
static void close_device()
{
        if(-1 == close(fd))
        {
                perror("close");
                exit(EXIT_FAILURE);
        }
        fd = -1;
}
int main()
{
//        dev_name = "/dev/video0";
        open_device();
        init_device();
        start_capturing();
        fp = fopen(filename, "wa+");
        mainloop();
        fclose(fp);
        stop_capturing();
        uninit_device();
        close_device();

        exit(EXIT_SUCCESS);
        return 0;
}
回复

使用道具 举报

2

主题

8

帖子

11

积分

 楼主| 发表于 2014-5-29 21:15:06 | 显示全部楼层
希望可以解答一下。各位飞凌的大神们。
点评回复 支持 反对

使用道具 举报

2

主题

8

帖子

11

积分

 楼主| 发表于 2014-5-29 21:15:54 | 显示全部楼层
板子为256RAM  2GNandflash
内核为3.0.1
点评回复 支持 反对

使用道具 举报

2

主题

8

帖子

11

积分

 楼主| 发表于 2014-5-30 16:45:17 | 显示全部楼层
求解答啊!!!!!

用飞凌板子的自带程序也用不了,一样是显示select timeout......
点评回复 支持 反对

使用道具 举报

2

主题

8

帖子

11

积分

 楼主| 发表于 2014-5-30 22:48:21 | 显示全部楼层
确实是。修改select它的等待时候可以解决select timeout的问题。。
不过。。不可能读取一张图片需要那么久啊!!!!
就算2440下select 2s都是绰绰有余的。
H264 编码后点播的视频那么卡,读取一张图片是得多久!!!
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-12-21 13:03

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

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