分类: LINUX
2011-04-15 17:58:06
#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