天嵌 ARM开发社区

 找回密码
 注册
查看: 4959|回复: 8

usb摄像头不能预览,不能输出数据。。。。。

[复制链接]
memechashang 发表于 2013-1-17 15:24:37 | 显示全部楼层 |阅读模式
平台:TQ2440,内核2.4.30,摄像头中星微uvc无驱的

终端提示信息如下::::
USB Camera Test
dth = 160   Height = 120
frame buffer: 480x272,  16bpp, 0x3fc00byte= 261120


部分代码如下:
int main(int argc, char** argv)
{
    int numBufs;
    printf("USB Camera Test\n");

    int fd = open("/dev/video0", O_RDWR, 0);            //打开摄像头设备,使用阻塞方式打开
    if (fd<0)
    {
        printf("open error\n");
        return  -1;
    }

    struct v4l2_format fmt;                        //设置获取视频的格式
    memset( &fmt, 0, sizeof(fmt));
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                //视频数据流类型,永远都是V4L2_BUF_TYPE_VIDEO_CAPTURE
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;            //视频源的格式为JPEG或YUN4:2:2或RGB
    fmt.fmt.pix.width = 640;                    //设置视频宽度
    fmt.fmt.pix.height = 480;                    //设置视频高度
    if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0)                //使配置生效
    {
        printf("set format failed\n");
        return -1;
    }

    struct v4l2_requestbuffers req;                    //申请帧缓冲
    memset(&req, 0, sizeof (req));
    req.count = 1;                            //缓存数量,即可保存的图片数量
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                //数据流类型,永远都是V4L2_BUF_TYPE_VIDEO_CAPTURE
    req.memory = V4L2_MEMORY_MMAP;                    //存储类型:V4L2_MEMORY_MMAP或V4L2_MEMORY_USERPTR
    if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1)            //使配置生效
    {
        perror("request buffer error \n");
        return -1;
    }

    VideoBuffer *buffers = calloc(req.count, sizeof(VideoBuffer));    //将VIDIOC_REQBUFS获取内存转为物理空间
//    printf("sizeof(VideoBuffer) is %d\n", sizeof(VideoBuffer));
    struct v4l2_buffer buf;
    for (numBufs = 0; numBufs < req.count; numBufs++)
    {
        memset( &buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;            //数据流类型,永远都是V4L2_BUF_TYPE_VIDEO_CAPTURE
        buf.memory = V4L2_MEMORY_MMAP;                //存储类型:V4L2_MEMORY_MMAP(内存映射)或V4L2_MEMORY_USERPTR(用户指针)
        buf.index = numBufs;
        if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0)        //使配置生效
        {
            printf("VIDIOC_QUERYBUF error\n");
            return -1;
        }
//        printf("buf len is %d\n", sizeof(buf));
        buffers[numBufs].length = buf.length;
        buffers[numBufs].offset = (size_t) buf.m.offset;
        buffers[numBufs].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
            MAP_SHARED, fd, buf.m.offset);            //使用mmap函数将申请的缓存地址转换应用程序的绝对地址
#if 0
        printf("buffers.length = %d,buffers.offset = %d ,buffers.start[0] = %d\n",
                buffers[numBufs].length, buffers[numBufs].offset,
                buffers[numBufs].start[0]);

        printf("buf2 len is %d\n", sizeof(buffers[numBufs].start));
#endif
        if (buffers[numBufs].start == MAP_FAILED)
        {
            perror("buffers error\n");
            return -1;
        }
        if (ioctl(fd, VIDIOC_QBUF, &buf) < 0)            //放入缓存队列
        {
            printf("VIDIOC_QBUF error\n");
            return -1;
        }

    }

    enum v4l2_buf_type type;                    //开始视频显示
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                //数据流类型,永远都是V4L2_BUF_TYPE_VIDEO_CAPTURE
    if (ioctl(fd, VIDIOC_STREAMON, &type) < 0)
    {
        printf("VIDIOC_STREAMON error\n");
        return -1;
    }

    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                //数据流类型,永远都是V4L2_BUF_TYPE_VIDEO_CAPTURE
    if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0)                //读取视频源格式
    {
        printf("get format failed\n");
        return -1;
    }
    else
    {
        printf("Picture:Width = %d   Height = %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
//        printf("Image size = %d\n", fmt.fmt.pix.sizeimage);
//        printf("pixelformat = %d\n", fmt.fmt.pix.pixelformat);
    }

    FILE * fd_y_file = 0;
    int a=0;
    int k = 0;

    //设置显卡设备framebuffer
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE *infile;                            //Jpeg文件的句柄
    unsigned char *buffer;

    int fb;
    char *fb_device;
    unsigned int x;
    unsigned int y;

    if ((fb = open("/dev/fb0", O_RDWR)) < 0)            //打开显卡设备
    {
        perror(__func__);
        return (-1);
    }

    //获取framebuffer的状态
    fb_stat(fb);                            //获取显卡驱动中的长、宽和显示位宽
    printf("frame buffer: %dx%d,  %dbpp, 0x%xbyte= %d\n",
        fbdev.fb_width, fbdev.fb_height, fbdev.fb_bpp, fbdev.fb_size, fbdev.fb_size);

    //映射framebuffer的地址
    fbdev.fb_mem = mmap (NULL, fbdev.fb_size, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
                                    //映射显存地址
    fbdev.fb = fb;
    //预览采集到的图像
    while (1)
    {

        //如果把处理JPEG格式的数据和显示程序分离,把处理JPEG部分的数据作成一个新的线程,预览时会更加流畅。
        for (numBufs = 0; numBufs < req.count; numBufs++)
        {
            char s[15];
            sprintf(s, "%d.jpg", a);
            if ((fd_y_file = fopen(s, "wb")) < 0)
            {
                printf("Unable to create y frame recording file\n");
                return -1;
            }

            buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;        //取得原始采集数据
            buf.memory = V4L2_MEMORY_MMAP;            //存储类型:V4L2_MEMORY_MMAP(内存映射)或V4L2_MEMORY_USERPTR(用户指针)
            if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0)//程序运行到这里就不动了,不知道什么原因?
            {
                perror("VIDIOC_DQBUF failed.\n");
                return -1;
            }




TQ-lkp 发表于 2013-1-17 18:19:08 | 显示全部楼层
本帖最后由 TQ-lkp 于 2013-1-17 18:19 编辑

楼主先试下我们提供的应用程序源码行不行
TQ-ZQL 发表于 2013-1-18 08:39:39 | 显示全部楼层
  req.count = 1; 改用2或者4试下
 楼主| memechashang 发表于 2013-1-19 13:47:33 | 显示全部楼层
TQ-lkp 发表于 2013-1-17 18:19
楼主先试下我们提供的应用程序源码行不行

这个程序就你们提供的apps_20100601.tar.bz2\opt\EmbedSky\apps\USB_camera_Test
 楼主| memechashang 发表于 2013-1-19 13:49:12 | 显示全部楼层
TQ-ZQL 发表于 2013-1-18 08:39
req.count = 1; 改用2或者4试下

试过了,还是不行,一直卡在ioctl(fd, VIDIOC_DQBUF, &buf)这句里面,没返回。。。。。
 楼主| memechashang 发表于 2013-1-19 14:26:50 | 显示全部楼层
同一个程序:编译成pc版本,在Ubuntu下运行没问题,可以预览。编译成ARM版本,在开发板上就不行。
fanyundemuzi 发表于 2013-1-20 11:20:00 | 显示全部楼层
关注。。。
 楼主| memechashang 发表于 2013-1-21 11:45:14 | 显示全部楼层
测试过网上很多的例子,包括天嵌入提供的例子。都卡在ret = ioctl(vd->fd, VIDIOC_DQBUF, &vd->buf)这一句话里,没返回。是我摄像头的问题吗?很急很急,天嵌的工程师们帮忙看看吧!
☆牛牛☆ 发表于 2013-7-9 11:10:17 | 显示全部楼层
碰到同样的问题,楼主是怎么解决的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

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

GMT+8, 2024-5-16 02:53 , Processed in 1.031250 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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