主题 : 请问2.6.36内核中,V4L2驱动的问题 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 8824
精华: 0
发帖: 54
金钱: 285 两
威望: 63 点
综合积分: 108 分
注册时间: 2009-09-07
最后登录: 2018-02-08
楼主  发表于: 2011-01-11 10:51

 请问2.6.36内核中,V4L2驱动的问题

OV9650的CMOS摄像头,在使用V4L2的API,在调用ioctl     VIDIOC_QUERYBUF的时候返回值为-1.查询了许多的说明和代码,觉得我的应用程序没啥问题。由此怀疑是不是内核驱动在V4L2这一部分没有完整。  
自由,自强,共享,共创。
级别: 论坛版主
UID: 12573
精华: 27
发帖: 8838
金钱: 46490 两
威望: 9298 点
综合积分: 18216 分
注册时间: 2010-01-09
最后登录: 2019-07-16
1楼  发表于: 2011-01-11 11:43
要验证驱动是否有问题,使用我们提供的camtest程序就可以了,命令行的camtest是有源代码的。
新手如何向我们反馈有效的信息,以便解决问题,见此贴:
http://www.arm9home.net/read.php?tid-14431.html

[注]: 此处签名链接仅为指引方向,而非解答问题本身.
级别: 侠客
UID: 8824
精华: 0
发帖: 54
金钱: 285 两
威望: 63 点
综合积分: 108 分
注册时间: 2009-09-07
最后登录: 2018-02-08
2楼  发表于: 2011-01-11 14:53
int main (int argc,char ** argv)
{
    struct v4l2_capability cap;
    struct v4l2_cropcap cropcap;
    struct v4l2_crop crop;
    struct v4l2_format fmt,fmt1;
    unsigned int i;
    int ret;
//    enum v4l2_buf_type type;
    cam_fd = open (dev_name, O_RDWR);
    ret=xioctl (cam_fd, VIDIOC_QUERYCAP, &cap);
    printf("Debug...........VIDIOC_QUERYCAP: \n        driver is: %s!\n        card is: %s!\n        bus_info is: %s!\n        version is: %d!\n        capabilities is: 0x%x!\n\n",
        cap.driver,cap.card,cap.bus_info,cap.version,cap.capabilities);
    CLEAR(cropcap);
    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret=xioctl(cam_fd,VIDIOC_CROPCAP,&cropcap);
    if(ret==0){
        crop.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
        crop.c=cropcap.defrect;
        printf("Debug...........VIDIOC_CROPCAP: \n        cropcap.defrect.height is: %d!\n        cropcap.defrect.width is: %d!\n",
            cropcap.defrect.height,cropcap.defrect.width);
        }
    
    
    
    CLEAR (fmt);
    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width       = 640;
    fmt.fmt.pix.height      = 480;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    ret=xioctl (cam_fd, VIDIOC_S_FMT, &fmt);
    if (ret==0){
        printf("Debug...........VIDIOC_S_FMT: ret=%d  \n",ret);
        CLEAR (fmt1);
        fmt1.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
        ret=xioctl(cam_fd,VIDIOC_G_FMT,&fmt1);
        if(ret==0)
            printf("Debug...........VIDIOC_G_FMT: ret=%d\n        pix.width is:%d\n        pix.pixelformat is :0x%x\n\n",
                ret,fmt1.fmt.pix.width,fmt1.fmt.pix.pixelformat);
        }
    struct v4l2_requestbuffers req;
    CLEAR (req);
    req.count               =4;
    req.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory              = V4L2_MEMORY_MMAP;
    ret=xioctl (cam_fd, VIDIOC_REQBUFS, &req);

    printf("Debug........ VIDIOC_REQBUFS: \n           ret=    %d\n        req.count=%d,\n",ret,req.count);

    struct buffer *vbuffer = calloc( req.count, sizeof(*vbuffer) );
    if (vbuffer!=NULL)
        printf("Debug...........sizeof(VideoBuffer) is %d\n",sizeof(struct buffer));
    struct v4l2_buffer    buf;
    for (i = 0; i < req.count; i++)    {
        CLEAR(buf);
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    
        buf.memory = V4L2_MEMORY_MMAP;    
        buf.index = i;
        ret=xioctl(cam_fd, VIDIOC_QUERYBUF, &buf);
        printf("Debug........... ret=%d\n",ret);
        if (ret < 0)    {
            printf("VIDIOC_QUERYBUF error\n");
            //return -1;
            }
        else {
            printf("Debug...........buf len is %d\n",sizeof(buf));
            vbuffer.length = buf.length;
            //vbuffer.offset = (size_t) buf.m.offset;
            vbuffer.start = mmap (NULL, buf.length,PROT_READ | PROT_WRITE, MAP_SHARED, cam_fd, buf.m.offset);
            printf("Debug...........\n            i=%d\n",i);
            printf("buf2 len is %d\n",sizeof(vbuffer.start));
            if (vbuffer.start == MAP_FAILED)    {
                perror("buffers error\n");
                //return -1;
                }
            if (ioctl (cam_fd, VIDIOC_QBUF, &buf) < 0) {
                printf("VIDIOC_QBUF error\n");
                //return -1;
                }
            }
        }    
    
    close(cam_fd);



粘上我的代码。
友善给出的camtest 是使用 V4L2_BUF_TYPE_VIDEO_OVERLAY 方式,我所说的驱动中的问题是指是否支持 V4L2_BUF_TYPE_VIDEO_CAPTURE方式。
自由,自强,共享,共创。
级别: 论坛版主
UID: 12573
精华: 27
发帖: 8838
金钱: 46490 两
威望: 9298 点
综合积分: 18216 分
注册时间: 2010-01-09
最后登录: 2019-07-16
3楼  发表于: 2011-01-11 16:21
支持,估计你的程序可能有问题。
新手如何向我们反馈有效的信息,以便解决问题,见此贴:
http://www.arm9home.net/read.php?tid-14431.html

[注]: 此处签名链接仅为指引方向,而非解答问题本身.
级别: 侠客
UID: 8824
精华: 0
发帖: 54
金钱: 285 两
威望: 63 点
综合积分: 108 分
注册时间: 2009-09-07
最后登录: 2018-02-08
4楼  发表于: 2011-01-12 09:11
请问有配置成功的例程吗?
我总是在ret=xioctl(cam_fd, VIDIOC_QUERYBUF, &buf);这一句出错。查阅了无数的资料,标准的配置过程都是一样的啊。
级别: 新手上路
UID: 37486
精华: 0
发帖: 15
金钱: 75 两
威望: 15 点
综合积分: 30 分
注册时间: 2011-02-10
最后登录: 2017-09-13
5楼  发表于: 2011-04-30 21:03
我也是遇到这个,楼主解决了嘛...
级别: 新手上路
UID: 81493
精华: 0
发帖: 19
金钱: 95 两
威望: 19 点
综合积分: 38 分
注册时间: 2012-11-09
最后登录: 2013-05-04
6楼  发表于: 2012-11-25 09:33
Preview通道可以将YCbCr4:2:2格式的图像转换为RGB(16bit或24bit)格式的数据,并存放于 为Preview DMA分配的内存中,最大分辨率为640*480。主要用于本地液晶屏显示。如果将Preview DMA的内存和Framebuffer内存重叠的话,就可以实现采集直接输出到液晶屏上了。
Codec通道可以输出YCbCr4:2:0或YCbCr4:2:2格式到为Codec DMA分配的内存中。最大分辨率为4096*4096。主要用于图像的编解码处理。