📄 testcamera1.c
字号:
}
printf("set slave address to 0x%x success!\n", CAMERA_I2C_ADDR);
if(i2c_read(fd, CAMERA_MIDH, id)||i2c_read(fd, CAMERA_MIDL, id+1)) {
printf("fail to get camera MID!\n");
close(fd);
return -1;
}
printf("manufactory ID is 0x%04x\n", (id[0]<<8)|id[1]);
i2c_read(fd, CAMERA_PIDH, id+2);
i2c_read(fd, CAMERA_PIDL, id+3);
printf("product ID is 0x%04x\n", (id[2]<<8)|id[3]);
for(i=0; i<CAMERA_REGS; i++) {
if(camera_regs[i].subaddr==CHIP_DELAY)
delay_ms(camera_regs[i].value);
else if(i2c_write(fd, camera_regs[i].subaddr, camera_regs[i].value))
printf("write subaddr 0x%x fail!\n", camera_regs[i].subaddr);
//delay_ms(2);
//printf("%d\n", i);
}
if(cpu_type==1) { //s3c2440a
i2c_write(fd, 0x15, 0x00); //always has PCLK
i2c_write(fd, 0x3a, 0x01); //YCbYCr order
}
close(fd);
return 0;
}
#else
#define camera_i2c_init() 0
#endif
#ifdef SCCB_INIT
static int sccb_init(int fd)
{
int i;
__u16 val;
__u8 id[4];
val = CAMERA_MIDH<<8;
if(ioctl(fd, WCAM_VIDIOCGCAMREG, &val)<0) {
printf("get camera register fail!\n");
return -1;
}
id[0] = val;
val = CAMERA_MIDL<<8;
if(ioctl(fd, WCAM_VIDIOCGCAMREG, &val)<0) {
printf("get camera register fail!\n");
return -1;
}
id[1] = val;
printf("manufactory ID is 0x%04x\n", (id[0]<<8)|id[1]);
val = CAMERA_PIDH<<8;
if(ioctl(fd, WCAM_VIDIOCGCAMREG, &val)<0) {
printf("get camera register fail!\n");
return -1;
}
id[2] = val;
val = CAMERA_PIDL<<8;
if(ioctl(fd, WCAM_VIDIOCGCAMREG, &val)<0) {
printf("get camera register fail!\n");
return -1;
}
id[3] = val;
printf("product ID is 0x%04x\n", (id[2]<<8)|id[3]);
for(i=0; i<CAMERA_REGS; i++) {
if(camera_regs[i].subaddr==CHIP_DELAY)
delay_ms(camera_regs[i].value);
else {
val = (camera_regs[i].subaddr<<8)|camera_regs[i].value;
if(ioctl(fd, WCAM_VIDIOCSCAMREG, &val)<0)
printf("write subaddr 0x%x fail!\n", camera_regs[i].subaddr);
}
}
return 0;
}
#else
#define sccb_init(fd) 0
#endif
/*************************************************************/
static void usage(void)
{
int i;
printf("testcamera [-x/y/p/m/v/o/f/u/h options]\n");
printf("-w width (set output image width, must be 4 alignment)\n");
printf("-h height (set output image height, must be 4 alignment)\n");
printf("-p palette (set output image color space)\n");
printf(" optional image:\n");
for(i=0; i<MAX_IMAGE_FORMAT; i++)
printf(" [%2d] : %s\n", i, optional_image_format[i].name);
printf("-m (use mmap method for camera)\n");
printf("-v (capture video instead of still image)\n");
printf("-o number (set save jpeg file optimization, must be 0~100)\n");
printf("-f name (set save jpeg file prefix name)\n");
printf("-u arch (set CPU type)\n");
printf(" current special CPU:\n");
printf(" pxa27x\n");
printf(" s3c2440a\n");
printf(" default is pxa27x\n");
printf("-h show help\n");
}
static int getoptions(int argc, char *argv[])
{
int ret = 0;
char c;
opterr = 0; //don't print error message
while ((c = getopt (argc, argv, "x:y:p:o:f:u:mvh")) != (char)EOF)
/* Scan the command line for options */
switch (c) {
case 'x':
image_width = atoi(optarg);
if((image_width%4)||(image_width>FIXED_SOURCE_WIDTH))
ret = -1;
break;
case 'y':
image_height = atoi(optarg);
if((image_height%4)||(image_height>FIXED_SOURCE_HEIGHT))
ret = -1;
break;
case 'p':
image_format = atoi(optarg);
if(image_format>=MAX_IMAGE_FORMAT)
ret = -1;
break;
case 'o':
optimization = atoi(optarg);
if(optimization>100)
ret = -1;
break;
case 'f':
image_file = optarg;
break;
case 'm':
mmap_camera = 1;
break;
case 'v':
capture_video = 1;
break;
case 'u':
if(strncmp(optarg, "pxa27x", 6)==0)
cpu_type = 0;
else if(strncmp(optarg, "s3c2440a", 8)==0)
cpu_type = 1;
else
printf("unknown CPU type\n");
break;
case 'h':
//ret = -1;
//break;
default:
ret = -1;
break;
}
return ret;
}
/*************************************************************/
int main(int argc, char *argv[])
{
int i, fd, fbfd;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
__u8 *fb_buf;
__u32 screensize;
struct video_capability vc;
struct video_window vw;
struct video_capture vcp;
struct video_picture vp;
struct video_mbuf vm;
struct video_channel vid_ch;
struct video_buffer vid_buf;
__u8 *buf = NULL;
int show, cnt;
fd_set rfds;
struct timeval tv;
struct termios tio;
int c_lflag;
fbfd = open("/dev/fb0", O_RDWR);
if (fbfd < 0) {
fbfd = open("/dev/fb/0", O_RDWR);
if(fbfd<0) {
printf("Error: cannot open framebuffer device.\n");
return -1;
}
}
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information.\n");
close(fbfd);
return -1;
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error reading variable information.\n");
close(fbfd);
return -1;
}
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
fb_xres = vinfo.xres;
fb_yres = vinfo.yres;
fb_bpp = vinfo.bits_per_pixel;
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
fb_buf = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);
if ((int)fb_buf == -1) {
printf("Error: failed to map framebuffer device to memory.\n");
close(fbfd);
return -1;
}
test_ycbcr_to_rgb(fb_buf);
if(getoptions(argc, argv)<0) {
close(fbfd);
usage();
return -1;
}
fd = open("/dev/video0", O_RDONLY); //rd&wr
if(fd<0) {
fprintf(stderr, "Open camera fail!\n");
close(fbfd);
return -1;
} else
fprintf(stdout, "Open camera success\n");
#if 0
if(camera_i2c_init()||sccb_init(fd)) {
printf("fail to initialize the I2C interface of camera!\n");
close(fd);
close(fbfd);
return -1;
}
#endif
if(ioctl(fd, VIDIOCGCAP, &vc)<0)
printf("VIDIOCGCAP fail\n");
else
printf("max width %d, height %d\nmin width %d, height %d\n",
vc.maxwidth, vc.maxheight, vc.minwidth, vc.minheight);
int input = 0;
vid_ch.channel = input;
if(ioctl(fd,VIDIOCGCHAN,&vid_ch) ==-1)
printf("VIDIOCGCHAN fail \n");
{
//printf("current channel :%d\n",vid_ch.channel);
vid_ch.channel = input;
if(ioctl(fd,VIDIOCSCHAN,&vid_ch) ==-1)
printf("VIDIOCSCHAN fail \n");
}
printf("chanel info is: \nchannel name=%s\n type is %u\n norm is %u\n flag is %u\n", vid_ch.name, vid_ch.type, vid_ch.norm, vid_ch.flags);
if(ioctl(fd,VIDIOCGFBUF,&vid_buf)== -1)
printf("VIDIOCGFBUF fail \n");
else
printf("frame buffer:\n width=%u,height=%u,depth=%u\n",vid_buf.width,vid_buf.height,vid_buf.depth);
if(ioctl(fd, VIDIOCGPICT, &vp)<0)
printf("VIDIOCGPICT fail\n");
printf("PICT property:\n brightness=%u\n colour=%u\n depth=%u\n palette=%u\n", vp.brightness, vp.colour, vp.depth, vp.palette);
vp.depth=24;
vp.palette =VIDEO_PALETTE_RGB24;
vp.brightness -=200;
vp.contrast +=100;
if(ioctl(fd, VIDIOCSPICT, &vp)<0)
printf("VIDIOCSPICT fail\n");
if(ioctl(fd, VIDIOCGPICT, &vp)<0)
printf("VIDIOCGPICT fail\n");
else
printf("PICT property:\n brightness=%u\n colour=%u\n depth=%u\n palette=%u\n", vp.brightness, vp.colour, vp.depth, vp.palette);
vw.width = FIXED_SOURCE_WIDTH; //fixed in this application
vw.height = FIXED_SOURCE_HEIGHT; //fixed in this application
vw.clipcount = 0;
if(ioctl(fd, VIDIOCSWIN, &vw)<0)
printf("VIDIOCSWIN fail\n");
if(ioctl(fd, VIDIOCGWIN, &vw)<0)
printf("VIDIOCGWIN fail\n");
else
printf("current width %d, height %d\n", vw.width, vw.height);
//检测一下看我们是否可以使用 mmap,mmap机制使得我们可以将采集到的图片数据映射到指定的内存缓冲
if(0 == ioctl(fd, VIDIOCGMBUF, &vm))
{
printf("this device support mmap\n");
printf("mmap return parameter:\n size=%d\n frames= %d\n offset= %d\n", vm.size, vm.frames, vm.offsets[0]);
//如果可以使用 mmap,那么分配用于存储采集到的图片数据的内存缓冲,请注意分配的缓冲大小是由
//上面的获取的mbuf变量的值决定的
char* map = (char*)mmap(0, vm.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if ((u_char*)map == ((u_char*)-1) )
{
printf("!!!!!!!!!!!!!!!!failed to map memory space for pic\n");
exit(1);
}
else
{
memset(map, 0, vm.size);
}
}
if(ioctl(fd, VIDIOCGMBUF, &vm)<0) {
printf("VIDIOCGMBUF fail\n");
} else {
printf("current camera buffer size %d, total frames %d\n",
vm.size, vm.frames);
buf = (__u8 *)mmap(0, vm.size, PROT_READ, MAP_SHARED, fd, 0);
if((int)buf==-1) {
printf("mmap camera fail!\n");
mmap_camera = 0;
} else
puts("mmap camera ok.\n");
}
if(!mmap_camera) {
puts("allocate memory for camera buffer.\n");
buf = malloc(image_width*image_height*2);
if(!buf) {
printf("fail to allocate memory for camera!\n");
close(fd);
munmap(fb_buf, screensize);
close(fbfd);
return -1;
}
}
printf("buffer at 0x%08x\n", (int)buf);
//puts("press enter to start...\n");
//getchar();
if(tcgetattr(0, &tio)<0) {
printf("tcgetattr fail!\n");
goto fail;
} else {
c_lflag = tio.c_lflag;
tio.c_lflag &= ~(ICANON | ECHO);
if(tcsetattr(0, TCSAFLUSH, &tio)<0) {
printf("tcsetattr fail!\n");
goto fail;
}
}
printf("now start capture...\n");
printf("press Esc key to exit, 'c' to save picture, 'd' to enable/disable display\n");
if(capture_video) {
if(ioctl(fd, VIDIOCCAPTURE, VIDEO_START)<0) {
printf("VIDIOCCAPTURE fail\n");
goto fail;
}
} else if(!cpu_type){
if(ioctl(fd, VIDIOCCAPTURE, STILL_IMAGE)<0) {
printf("VIDIOCCAPTURE fail\n");
goto fail;
}
}
FD_ZERO(&rfds);
//FD_SET(0, &rfds);
//FD_SET(fd, &rfds);
show = 1;
cnt = 0;
while(1) {
//in pxa270, if capture still image, can do it just one time
if(!capture_video&&cpu_type)
if(ioctl(fd, VIDIOCCAPTURE, STILL_IMAGE)<0) {
printf("VIDIOCCAPTURE fail\n");
break;
}
//FD_ZERO(&rfds);
FD_SET(0, &rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 3;
tv.tv_usec = 0;
select(fd+1, &rfds, NULL, NULL, &tv);
if(FD_ISSET(0, &rfds)) {
char cmd;
//printf("stdin input\n");
if(read(0, &cmd, 1)<0) {
printf("read stdin fail!\n");
break;
}
if(cmd=='d'||cmd=='D') {
show = !show;
printf("%s display\n", show?"enable":"disable");
} else if(cmd=='c'||cmd=='C') {
printf("save picture...\n");
save_picture(buf);
} else if(cmd==0x1b)
break;
} else if(FD_ISSET(fd, &rfds)) {
if(mmap_camera) {
#if 1
//just for performance test in video capturing, int(rdy)->show->int->show
//use read to clear ready flag in driver
i = read(fd, buf, 0); //mmap camera for read, so read 0 byte to buf
if(i<0) {
printf("read fail!%d\n", i);
break;
}
#endif
} else {
i = read(fd, buf, image_width*image_height*2);
if(i<0) {
fprintf(stderr, "read fail! %d\n", i);
break;
}
//printf("read %d bytes\n", i);
cnt++;
}
} else {
printf("wait timeout, break...\n");
break;
}
#if 0
{
FILE *wfp;
wfp = fopen("/tmp/dat", "w+b");
if(wfp==NULL) {
printf("fail to open file for save data!\n");
break;
}
printf("write %d bytes.\n", fwrite(buf, i, 1, wfp)*i);
fclose(wfp);
break;
}
#endif
if(show)
show_cam_img(fb_buf, buf,
buf+image_width*image_height,
buf+(image_width*image_height*3)/2);
}
tio.c_lflag = c_lflag;
tcsetattr(0, TCSAFLUSH, &tio);
fail:
if(mmap_camera)
munmap(buf, vm.size);
else
free(buf);
close(fd);
munmap(fb_buf, screensize);
close(fbfd);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -