Chinaunix首页 | 论坛 | 博客
  • 博客访问: 41488
  • 博文数量: 21
  • 博客积分: 840
  • 博客等级: 准尉
  • 技术积分: 225
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-24 00:24
文章分类
文章存档

2010年(21)

我的朋友

分类: LINUX

2010-06-08 21:24:44

#ifdef __cplusplus
extern "C"{
#endif

/*=======================================================================
                                        INCLUDE FILES
=======================================================================*/

/* Standard Include Files */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
    
/* Verification Test Environment Include Files */
#include <sys/types.h>    
#include <sys/stat.h>    
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <asm/types.h>
#include <linux/compiler.h>
#include <linux/videodev.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <math.h>
#include <string.h>
#include <malloc.h>


#if 1
#define OUTDEB(fmt,arg...)        printf("%s--"fmt,__FUNCTION__,##arg)
#else
#define OUTDEB(fmt,arg)
#endif

//#define ROTATE


#define V4L_DEVICE "/dev/video0"

#define BUFF_CNT    3

#define ipu_fourcc(a,b,c,d)\
        (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))

#define IPU_PIX_FMT_RGB332 ipu_fourcc('R','G','B','1') /*!< 8 RGB-3-3-2 */
#define IPU_PIX_FMT_RGB555 ipu_fourcc('R','G','B','O') /*!< 16 RGB-5-5-5 */
#define IPU_PIX_FMT_RGB565 ipu_fourcc('R','G','B','P') /*!< 16 RGB-5-6-5 */
#define IPU_PIX_FMT_RGB666 ipu_fourcc('R','G','B','6') /*!< 18 RGB-6-6-6 */
#define IPU_PIX_FMT_BGR24 ipu_fourcc('B','G','R','3') /*!< 24 BGR-8-8-8 */
#define IPU_PIX_FMT_RGB24 ipu_fourcc('R','G','B','3') /*!< 24 RGB-8-8-8 */
#define IPU_PIX_FMT_BGR32 ipu_fourcc('B','G','R','4') /*!< 32 BGR-8-8-8-8 */
#define IPU_PIX_FMT_BGRA32 ipu_fourcc('B','G','R','A') /*!< 32 BGR-8-8-8-8 */
#define IPU_PIX_FMT_RGB32 ipu_fourcc('R','G','B','4') /*!< 32 RGB-8-8-8-8 */
#define IPU_PIX_FMT_RGBA32 ipu_fourcc('R','G','B','A') /*!< 32 RGB-8-8-8-8 */
#define IPU_PIX_FMT_ABGR32 ipu_fourcc('A','B','G','R') /*!< 32 ABGR-8-8-8-8 */

#ifdef ROTATE
#define V4L2_CID_MXC_ROT        (V4L2_CID_PRIVATE_BASE + 0)
#define V4L2_CID_MXC_FLASH        (V4L2_CID_PRIVATE_BASE + 1)
#define V4L2_CID_MXC_FLICKER        (V4L2_CID_PRIVATE_BASE + 2)
#define V4L2_CID_MXC_TEAR_PROTECT    (V4L2_CID_PRIVATE_BASE + 3)

#define V4L2_MXC_ROTATE_NONE            0
#define V4L2_MXC_ROTATE_VERT_FLIP        1
#define V4L2_MXC_ROTATE_HORIZ_FLIP        2
#define V4L2_MXC_ROTATE_180            3
#define V4L2_MXC_ROTATE_90_RIGHT        4
#define V4L2_MXC_ROTATE_90_RIGHT_VFLIP        5
#define V4L2_MXC_ROTATE_90_RIGHT_HFLIP        6
#define V4L2_MXC_ROTATE_90_LEFT            7
#endif

typedef struct _BUFF_DESC
{
    struct v4l2_buffer        BuffParam;
    unsigned     char            *pMapedAddr;
}BUFF_DESC;

typedef struct _V4L_PRO
{
    struct v4l2_format     fmt;
    int                     nOutId;

    struct v4l2_control    CtrlId;
    struct v4l2_crop         Crop;//senser input    


    struct v4l2_framebuffer V4l2Fb;

    int                    bStart;
    int                     bOverlay;
/*for capture:*/
    struct v4l2_streamparm    StreamParm;
    struct v4l2_requestbuffers    ReqBufs;
    int                    CapFrameCnt;
    BUFF_DESC            BuffDesc[BUFF_CNT];
}V4L_PRO;

V4L_PRO        CtlParam;


static int CaptureYUV(int hCam)
{
    int i;
    FILE     *hFile;

    hFile = fopen("mm.yuv","wb");
    if(hFile<0)
    {
        printf("%s--open file mm.yuv failed\n",__FUNCTION__);
        return -1;
    }
    
    CtlParam.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    CtlParam.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
    CtlParam.fmt.fmt.pix.width = 320;
    CtlParam.fmt.fmt.pix.height = 240;
    CtlParam.fmt.fmt.pix.bytesperline = 320;//????????????????????????

    CtlParam.fmt.fmt.pix.sizeimage = 0;

    if (ioctl(hCam, VIDIOC_S_FMT, &CtlParam.fmt) < 0)
        {
                printf("set format failed\n");
                fclose(hFile);
                return 0;
        }

    CtlParam.StreamParm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    CtlParam.StreamParm.parm.capture.timeperframe.denominator = 30;
    CtlParam.StreamParm.parm.capture.timeperframe.numerator = 1;
    CtlParam.StreamParm.parm.capture.capturemode = 0;

    if (ioctl(hCam, VIDIOC_S_PARM, &CtlParam.StreamParm) < 0)
        {
                printf("VIDIOC_S_PARM failed\n");
                fclose(hFile);
                return -1;
        }

    CtlParam.ReqBufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    CtlParam.ReqBufs.count = BUFF_CNT;
    CtlParam.ReqBufs.memory = V4L2_MEMORY_MMAP;

    if (ioctl(hCam, VIDIOC_REQBUFS, &CtlParam.ReqBufs) < 0)
        {
                printf("v4l_capture_setup: VIDIOC_REQBUFS failed\n");
                fclose(hFile);
                return 0;
        }

    for(i=0; i<BUFF_CNT; i++)
    {
        CtlParam.BuffDesc[i].BuffParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        CtlParam.BuffDesc[i].BuffParam.index = i;

         /*获得length和m.offset传入下面MMAP函数*/
        if (ioctl(hCam, VIDIOC_QUERYBUF, &CtlParam.BuffDesc[i].BuffParam) < 0)
                {
                        printf("VIDIOC_QUERYBUF error\n");
                        fclose(hFile);
                        return -1;
                }
             
        CtlParam.BuffDesc[i].pMapedAddr = mmap(NULL, CtlParam.BuffDesc[i].BuffParam.length, PROT_READ|PROT_WRITE,
                                            MAP_SHARED, hCam, CtlParam.BuffDesc[i].BuffParam.m.offset);
        if(CtlParam.BuffDesc[i].pMapedAddr==NULL)
        {
            printf("buffer mmap failed!\n");
            goto __out;
        }
        
        memset(CtlParam.BuffDesc[i].pMapedAddr, 0xff, CtlParam.BuffDesc[i].BuffParam.length);
    }

    for(i=0; i<BUFF_CNT; i++)
    {
        CtlParam.BuffDesc[i].BuffParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        CtlParam.BuffDesc[i].BuffParam.index = i;
        CtlParam.BuffDesc[i].BuffParam.memory = V4L2_MEMORY_MMAP;
        /*让该BUFFER 入队列*/
        if (ioctl (hCam, VIDIOC_QBUF, &CtlParam.BuffDesc[i].BuffParam) < 0)
        {
                      printf("VIDIOC_QBUF error\n");
                      goto __out;
              }
    }
       if (ioctl (hCam, VIDIOC_STREAMON, &i) < 0)
       {
              printf("VIDIOC_STREAMON error\n");
              goto __out;
       }

       CtlParam.CapFrameCnt = 50;

       while(CtlParam.CapFrameCnt-->0)
       {
           struct v4l2_buffer    tmp;
           //CtlParam.BuffDesc[i].BuffParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

           //CtlParam.BuffDesc[i].BuffParam.memory = V4L2_MEMORY_MMAP;

        /*让该 BUFFER 出队列*/
           if (ioctl (hCam, VIDIOC_DQBUF, &tmp) < 0)
        {
                      printf("VIDIOC_QBUF error\n");
                      goto __out;
              }
              
              fwrite(CtlParam.BuffDesc[tmp.index].pMapedAddr, CtlParam.fmt.fmt.pix.sizeimage, 1, hFile);

              if (CtlParam.CapFrameCnt >= BUFF_CNT)
              {
                        if (ioctl (hCam, VIDIOC_QBUF, &tmp) < 0)
                        {
                                printf("VIDIOC_QBUF failed\n");
                                break;
                        }
               }
           printf("buf.index %d\n", tmp.index);
       }

       if (ioctl (hCam, VIDIOC_STREAMOFF, &i) < 0)
       {
              printf("VIDIOC_STREAMOFF error\n");
              goto __out;
       }
__out:
    for(i=0;i<BUFF_CNT;i++)
    {
        if(CtlParam.BuffDesc[i].pMapedAddr!=NULL)
            mumap(CtlParam.BuffDesc[i].pMapedAddr);
    }
       fclose(hFile);
       return 0;
}

static int GetFbInfo(void)
{
    int     hFb;
    struct fb_fix_screeninfo    fix;
    struct fb_var_screeninfo    var;
    
    hFb = open("/dev/fb0",O_RDWR);
    if(hFb<0)
    {
        printf("%s--failed to open fb0\n",__FUNCTION__);
        return -1;
    }

    if(ioctl(hFb, FBIOGET_FSCREENINFO,&fix))
    {
        printf("%s--failed to get fix\n",__FUNCTION__);
        close(hFb);
        return -1;
    }

    if(ioctl(hFb, FBIOGET_VSCREENINFO, &var))
    {
        printf("%s--failed to get var\n",__FUNCTION__);
        close(hFb);
        return -1;
    }

    OUTDEB("fb addr:0x%x, xres:%d,yres:%d\n",fix.smem_start,var.xres,var.yres);
    CtlParam.V4l2Fb.fmt.width = var.xres;
    CtlParam.V4l2Fb.fmt.height = var.yres;
    CtlParam.V4l2Fb.fmt.pixelformat = IPU_PIX_FMT_RGB565;
    CtlParam.V4l2Fb.fmt.bytesperline = 2*var.xres;
    CtlParam.V4l2Fb.base = (void *)fix.smem_start;
    CtlParam.V4l2Fb.flags = V4L2_FBUF_FLAG_PRIMARY;

    close(hFb);
    return 0;
}

int main(int argc, char ** argv)
{
    int     hCam;
    int     i;
#ifdef ROTATE
    struct v4l2_control sCtrl;
#endif
    //struct v4l2_format        fmt;


    hCam = open(V4L_DEVICE, O_RDWR, 0);
    if(hCam<0)
    {
        printf("failed to open device!\n");
        return -1;
    }
#if 1
    CtlParam.nOutId = 0;//LCD


    if (ioctl(hCam, VIDIOC_S_OUTPUT, &CtlParam.nOutId) < 0)
        {
                printf("VIDIOC_S_OUTPUT failed\n");
                return -1;
        }

    CtlParam.Crop.type= V4L2_BUF_TYPE_VIDEO_OVERLAY;//overlay??

    CtlParam.Crop.c.top = 0;//1;

    CtlParam.Crop.c.left = 0;
    CtlParam.Crop.c.width = 640;//680;//640;//800;//640;

    CtlParam.Crop.c.height = 480;//510;//600;//480;


    if (ioctl(hCam, VIDIOC_S_CROP, &CtlParam.Crop) < 0)
       {
               printf("set cropping failed\n");
               goto __err;
       }

    CtlParam.fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    CtlParam.fmt.fmt.win.w.top = 0;
    CtlParam.fmt.fmt.win.w.left = 0;
    CtlParam.fmt.fmt.win.w.width = 320;//320;//640;//320;

    CtlParam.fmt.fmt.win.w.height = 240;//240;//480;//240;

    
    if (ioctl(hCam, VIDIOC_S_FMT, &CtlParam.fmt) < 0)
        {
                printf("set format failed\n");
                goto __err;
        }

{
/*
     struct v4l2_streamparm parm;
    
        parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        parm.parm.capture.timeperframe.numerator = 1;
        parm.parm.capture.timeperframe.denominator = 30;
        parm.parm.capture.capturemode = 1;
         
        if (ioctl(hCam, VIDIOC_S_PARM, &parm) < 0)
        {
                printf("VIDIOC_S_PARM failed\n");
                goto __err;
        }
  */

}
#ifdef ROTATE
sCtrl.id = V4L2_CID_MXC_ROT;
    sCtrl.value = V4L2_MXC_ROTATE_90_RIGHT;
    if(ioctl(hCam, VIDIOC_S_CTRL, &sCtrl)<0)
    {
        printf("%s--set ctrl failed!\n",__FUNCTION__);
        goto __err;
    }
#endif
    CtlParam.bOverlay = 1;

    if(!CtlParam.bOverlay)
    {
        if(GetFbInfo())
        goto __err;
    }
    else
    {
        if (ioctl(hCam, VIDIOC_G_FBUF, &CtlParam.V4l2Fb) < 0)
        {
                       printf("Get framebuffer failed\n");
                       goto __err;
              }
        CtlParam.V4l2Fb.flags = V4L2_FBUF_FLAG_OVERLAY;        
    }

    if (ioctl(hCam, VIDIOC_S_FBUF, &CtlParam.V4l2Fb) < 0)
       {
               printf("set framebuffer failed\n");
               goto __err;
       }

    if (ioctl(hCam, VIDIOC_G_FBUF, &CtlParam.V4l2Fb) < 0)
    {
                printf("set framebuffer failed\n");
                goto __err;
        }

        printf("\n frame buffer width %d, height %d, bytesperline %d, format:0x%x\n",
                CtlParam.V4l2Fb.fmt.width, CtlParam.V4l2Fb.fmt.height, CtlParam.V4l2Fb.fmt.bytesperline, CtlParam.V4l2Fb.fmt.pixelformat);

    CtlParam.bStart =1;
    if (ioctl(hCam, VIDIOC_OVERLAY, &CtlParam.bStart) < 0)
        {
                printf("VIDIOC_OVERLAY start failed\n");
        }
/*
    for (i = 0; i < 3 ; i++)
    {
                // flash a frame
                CtlParam.CtrlId.id = V4L2_CID_PRIVATE_BASE + 1;
                if (ioctl(hCam, VIDIOC_S_CTRL, &CtlParam.CtrlId) < 0)
                {
                        printf("set ctl failed\n");
                        goto __err;
                }
     sleep(1);
        }
*/

    //sleep(50);

#endif
    CaptureYUV(hCam);
    

    CtlParam.bStart =0;
    if (ioctl(hCam, VIDIOC_OVERLAY, &CtlParam.bStart) < 0)
        {
                printf("VIDIOC_OVERLAY stop failed\n");
        }

    return 0;
__err:
    close(hCam);
    return -1;
}
#ifdef __cplusplus
}
#endif


阅读(908) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~