#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
|