⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testcamera1.c

📁 camera模组测试程序,在开发平台2440 2410,2443上都可以运行.并且已经解决了图象倒置的问题
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	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 + -