• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : tiny6410 linux2.6.38 cam130 mmap方式 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 52688
精华: 0
发帖: 8
金钱: 40 两
威望: 8 点
综合积分: 16 分
注册时间: 2011-07-23
最后登录: 2011-08-10
楼主  发表于: 2011-07-25 11:12

 tiny6410 linux2.6.38 cam130 mmap方式

主板:tiny6410
内核:linux 2.6.38
摄像头:cam130
采集方式:mmap
主板和内核都没有经过修改,主板上的cmos摄像头测试程序正常,但是是采用overlay方式的
想问下你们有没有使用mmap方式实现过cmos的采集,我这的程序总是会在vidioc_querybuf 的时候提示错误,而且那个start_uvc.sh(采用的是mmap方式)也会报错:

MJPG Streamer Version.: 2.0
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 640 x 480
i: Frames Per Second.: 5
s3c-fimc: changing to default resolution
i: Format............: MJPG
s3c-fimc: invalid target size
Unable to query buffer: Invalid argument
Init v4L2 failed !! exit fatal
i: init_VideoIn failed
搞了几天了,请回复一下,如果有例子源码,最好提供下,不然都不知道是不是驱动的问题了。
^很多问题的背后都是简单的原因......
级别: 荣誉会员
UID: 34780
精华: 0
发帖: 1219
金钱: 6230 两
威望: 1246 点
综合积分: 2438 分
注册时间: 2010-12-21
最后登录: 2017-09-18
1楼  发表于: 2011-07-25 16:48
级别: 新手上路
UID: 52688
精华: 0
发帖: 8
金钱: 40 两
威望: 8 点
综合积分: 16 分
注册时间: 2011-07-23
最后登录: 2011-08-10
2楼  发表于: 2011-07-25 20:24
那个帖子我之前也看了,可是按照他那样改,后面mmap的时候会报错,我看了buf的length都是0,所以mmap肯定是会报错的,都不知道是不是他说的那样了!
级别: 新手上路
UID: 52688
精华: 0
发帖: 8
金钱: 40 两
威望: 8 点
综合积分: 16 分
注册时间: 2011-07-23
最后登录: 2011-08-10
3楼  发表于: 2011-07-25 20:46
其实我最想弄清楚的是,到底是驱动有问题,还是我的程序有问题,如果你们有自己在这种情况下应用成功过,那么我就可以肯定是我的程序有问题,而不是驱动,我想你们这么大的公司应该也有自己测试过这种情况吧。我只需要你们告诉我一个答案,你们自己试了是成功的,还是不成功的。
^很多问题的背后都是简单的原因......
级别: 荣誉会员
UID: 34780
精华: 0
发帖: 1219
金钱: 6230 两
威望: 1246 点
综合积分: 2438 分
注册时间: 2010-12-21
最后登录: 2017-09-18
4楼  发表于: 2011-07-26 10:17
严格来说, 这应该是在使用mmap方式时2.6.38的V4L2与三星的fimc部分配合有问题
但由于V4L2是公共的, 一般情况下是不会随便去修改的, 这有可能会影响到其它的设备

对于你来说, 如果你要使用mmap, 你需要根据 http://www.aiothome.net/read.php?tid-11869.html 去修改
然后再调试你的程序, 就像那个帖子里说的, 你可以在V4L2加些打印看看, 应该很快能解决问题

另外, 对于你的程序, 不清楚你是完全自己写的还是怎么样的, 建议你看看V4L2的api
级别: 新手上路
UID: 52688
精华: 0
发帖: 8
金钱: 40 两
威望: 8 点
综合积分: 16 分
注册时间: 2011-07-23
最后登录: 2011-08-10
5楼  发表于: 2011-07-27 14:53
折腾了好几天还是不行,只好把源代码贴上来给大家看看:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/videodev2.h>

#define VIDEO_WIDTH 320
#define VIDEO_HEIGHT 240
#define CLEAR(x) memset(&(x),0,sizeof(x))
struct fimc_buffer{
    int length;
    void *start;
}framebuf[4];


static int read_frame(int fd)
{
    struct v4l2_buffer buf;
    int ret;
    unsigned int i;
    CLEAR(buf);
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    ret = ioctl(fd,VIDIOC_DQBUF,&buf);
    if(ret < 0)
    {
        printf("dqbuf error\n");
        return -1;
    }
//    assert(buf.index < 4);
    printf("buf.index dq is %d\n",buf.index);
    FILE *fp;
    fp = fopen("test.jpg","wb");
    if(fp == NULL)
    {
        printf("open file error\n");
        return -1;
    }
    fwrite(framebuf[buf.index].start,1,buf.length,fp);
    fclose(fp);
    printf("capture one frame over\n");
    ret = ioctl(fd,VIDIOC_QBUF,&buf);
    if(ret < 0)
    {
        printf("vidioc failue\n");
        return -1;
    }
    return 1;
}

int main() {
    int i,ret,fd;
         printf("open video start\n");
    fd = open("/dev/video0",O_RDWR,0);
        
    if(fd < 0) {
        printf("open device error\n");
        return -1;
    }
    struct v4l2_capability cap;
    ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
    if(ret < 0 )
    {
        printf("video query failed\n");
        return ret;
    }
    
        if((cap.capabilities && V4L2_CAP_VIDEO_CAPTURE) != 1)
    {
        printf("not support v4l2_cap_video_capture\n");
        return -1;
    }
    if((cap.capabilities & V4L2_CAP_STREAMING) ==0)
    {
        printf("NOT SUPPORT V4L2_CAP_STREAM\n");
        return -1;
    }
    printf("capability over\n");

        struct v4l2_format fmt;
    CLEAR(fmt);
    fmt.fmt.pix.width = 480;
    fmt.fmt.pix.height = 272;
    fmt.fmt.pix.sizeimage = 480*272*2;
     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.field = V4L2_FIELD_ANY;
    
        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;    
    ret = ioctl(fd,VIDIOC_S_FMT,&fmt);

    printf("fmt.type is %d\n",fmt.type);
    printf("fmt.fmt.pix.width = %d\n",fmt.fmt.pix.width);
    printf("fmt.fmt.pix.heigth= %d\n",fmt.fmt.pix.height);
    printf("fmt.fmt.pix.sizeimage = %d\n",fmt.fmt.pix.sizeimage);

    if(ret < 0)
    {
        printf("vidioc_s_fmt error\n");
        return -1;
    }

    struct v4l2_requestbuffers reqbuf;
    memset(&reqbuf,0,sizeof(reqbuf));
     reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    reqbuf.memory = V4L2_MEMORY_MMAP;
    reqbuf.count = 4;
    ret = ioctl(fd,VIDIOC_REQBUFS,&reqbuf);
    printf("req.type is %d\n",reqbuf.type);
    printf("req.memory is %d\n",reqbuf.memory);
    printf("req.count is %d\n",reqbuf.count);
    printf("vidioc_reqbufs start\n");
    if(ret < 0)
    {
        printf("vidioc_reqbufs error\n");
        return -1;
    }
    printf("the reqbuf count is %d\n",reqbuf.count);
    struct v4l2_buffer buf;
    for(i = 0;i<4;++i)
    {
               buf.index = i;
        buf.type = reqbuf.type;
        buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(fd,VIDIOC_QUERYBUF,&buf);
        printf("vidioc_querybuf start\n");    
        printf("the index is %d \n",i);
        if(ret < 0){
            printf("vidioc_querybuf error\n");
        return -1;
        }
        
        printf("the buf length is %d\n",buf.length);
        framebuf.length = buf.length;
        framebuf.start = (char*)(mmap(0,buf.length,
                PROT_READ|PROT_WRITE,MAP_SHARED,
                fd,buf.m.offset));
        if(framebuf.start == MAP_FAILED){
            printf("mmap  failed\n");
            return -1;
        }
        printf("mmap over\n");

        printf("queue buffer\n");
        ret = ioctl(fd,VIDIOC_QBUF,&buf);
        if(ret < 0){
            printf("qbuf error\n");
            return -1;
        }
    }
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd,VIDIOC_STREAMON,&type);
    printf("capture start\n");
    if(ret < 0)
    {
        printf("stream on error\n");
        return -1;
    
    }
    for(;;)
    {
        fd_set fds;
        struct timeval tv;
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        ret = select(fd+1,&fds,NULL,NULL,&tv);
        if(-1 == ret )
            if(EINTR == errno)
                continue;
        if(0 == ret){
            printf("select timeout\n");
        }
        if(read_frame(fd) == 1)break;
    }
    read_frame(fd);
    ret = ioctl(fd,VIDIOC_STREAMOFF,&type);
    if(ret < 0)
    {
        printf("capture off\n");
        return -1;
    }
        
    for(i = 0;i < 4;i++)
    {
        munmap(framebuf.start,framebuf.length);
    }
    close(fd);
    printf("camera test done\n");
    return 0;
    }    
级别: 新手上路
UID: 55369
精华: 0
发帖: 14
金钱: 70 两
威望: 14 点
综合积分: 28 分
注册时间: 2011-09-16
最后登录: 2014-03-27
6楼  发表于: 2011-09-20 16:44
引用第2楼yuan2sh于2011-07-25 20:24发表的  :
那个帖子我之前也看了,可是按照他那样改,后面mmap的时候会报错,我看了buf的length都是0,所以mmap肯定是会报错的,都不知道是不是他说的那样了!

遇到同样的问题,修改后返回buffer.length为0。
级别: 新手上路
UID: 71606
精华: 0
发帖: 30
金钱: 150 两
威望: 30 点
综合积分: 60 分
注册时间: 2012-06-07
最后登录: 2012-06-28
7楼  发表于: 2012-06-14 19:38
mark一下
级别: 新手上路
UID: 42535
精华: 0
发帖: 5
金钱: 25 两
威望: 5 点
综合积分: 10 分
注册时间: 2011-04-09
最后登录: 2013-03-09
8楼  发表于: 2012-08-24 21:26

 回 6楼(chenjx00) 的帖子

问题解决了吗?怎么修改的
级别: 新手上路
UID: 90424
精华: 0
发帖: 3
金钱: 15 两
威望: 3 点
综合积分: 6 分
注册时间: 2013-04-17
最后登录: 2017-09-13
9楼  发表于: 2013-04-17 18:10
问题是如何解决的?
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go