www.pudn.com > cam2fb.rar > cam2fb.c


/*
 * CAMIF test
 *
 * bushi@mizi.com
 *
 * $Id: cam2fb.c,v 1.1.1.1 2004/01/20 10:29:10 laputa Exp $
 *
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*
 * must be 
 *   CAM_WIDTH  == FB_WIDTH
 *   CAM_HEIGHT <= FB_HEIGHT
 */
#define CAM_WIDTH 240
#define CAM_HEIGHT 180
#define FB_WIDTH 240
#define FB_HEIGHT 320

/* kernel stuff */
#define CAMIF_TYPE_RGB16 0
#define CAMIF_TYPE_RGB32 1
#define CAMIF_TYPE_YUV420 2
/*static struct s3c2440_camif_cfg_param {
	int img;	//source image type into the camera interface
			// 0 for SXGA, 1 for VGA, 2 for QVGA
	int dst_x;
	int dst_y;
} camif_cfg;

*/

typedef unsigned short __u16;


struct video_picture
{
        __u16   brightness;
        __u16   hue;
        __u16   colour;
        __u16   contrast;
        __u16   whiteness;      /* Black and white only */
        __u16   depth;          /* Capture depth */
        __u16   palette;        /* Palette in use */
#define VIDEO_PALETTE_GREY      1       /* Linear greyscale */
#define VIDEO_PALETTE_HI240     2       /* High 240 cube (BT848) */
#define VIDEO_PALETTE_RGB565    3       /* 565 16 bit RGB */
#define VIDEO_PALETTE_RGB24     4       /* 24bit RGB */
#define VIDEO_PALETTE_RGB32     5       /* 32bit RGB */
#define VIDEO_PALETTE_RGB555    6       /* 555 15bit RGB */
#define VIDEO_PALETTE_YUV422    7       /* YUV422 capture */
#define VIDEO_PALETTE_YUYV      8
#define VIDEO_PALETTE_UYVY      9       /* The great thing about standards is*/
#define VIDEO_PALETTE_YUV420    10
#define VIDEO_PALETTE_YUV411    11      /* YUV411 capture */
#define VIDEO_PALETTE_RAW       12      /* RAW capture (BT848) */
#define VIDEO_PALETTE_YUV422P   13      /* YUV 4:2:2 Planar */
#define VIDEO_PALETTE_YUV411P   14      /* YUV 4:1:1 Planar */
#define VIDEO_PALETTE_YUV420P   15      /* YUV 4:2:0 Planar */
#define VIDEO_PALETTE_YUV410P   16      /* YUV 4:1:0 Planar */
#define VIDEO_PALETTE_PLANAR    13      /* start of planar entries */
#define VIDEO_PALETTE_COMPONENT 7       /* start of component entries */
}camif_cfg;



/****************/

static int cam_fp = -1;
static int fb_fp = -1;
static char *fb = NULL;

static inline int cam_init(void)
{
	int dev_fp = -1;

	//dev_fp = open("/dev/misc/cam", O_RDWR);
	dev_fp  = open("/dev/video0",O_RDWR);
	if (dev_fp < 0) {
		perror("/dev/video0");
		return -1;
	}
	printf("cam_fp = %d\n\r",dev_fp);
	return dev_fp;
}

static inline int fb_init(void)
{
	int dev_fp = -1;

	dev_fp = open("/mnt/fb", O_RDWR|O_CREAT);
	if (dev_fp < 0) {
		perror("/mnt/fb");
		return -1;
	}

/*if ((fb = (char*)mmap(NULL, FB_WIDTH*FB_HEIGHT*2, 
			PROT_READ | PROT_WRITE, MAP_SHARED, dev_fp, 0)) < 0) 
	{
		  perror("mmap()");
		  return -1;
	}
*/
	return dev_fp;
}

static inline void start_capture(int fp)
{
	char c;

	write(fp, &c, 1);
}

static inline int read_data(int fp, char *buf, int width, int height, int bpp)
{
	int ret;

	if ((ret = read(fp, buf, width*height*bpp/8)) != width*height*bpp/8)
	{
		return 0;
	}
	return ret;
}

static inline void clear(char *dest)
{
#ifdef FB_IMG_BPP
	memcpy(dest, &img_data[0], FB_WIDTH*FB_HEIGHT*2);
#else
	memset(dest, 0, FB_WIDTH*FB_HEIGHT*2);
#endif
}

#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)>(y)?(y):(x))
static inline void draw(char *dest, char *src, int width, int height, int bpp
		,int src_offset_x, int src_offset_y)
{
	int x,y;
	unsigned short *rgb16; 
	unsigned long *rgb32;
	unsigned long offset_x = 0;
	unsigned long offset_y = 0;
	int end_y = MIN(FB_HEIGHT, height - src_offset_y);
	int end_x = MIN(FB_WIDTH, width - src_offset_x);

	offset_x = src_offset_x * bpp/8;
	offset_y = src_offset_y * width * bpp/8;
	src += offset_y;
	if (bpp==16) {
		for (y=0;y>16)&0xff) >> 3) << 11) // red
						| ((((*(rgb32)>>8)&0xff) >> 2) << 5)  // green
						| ((((*(rgb32)>>0)&0xff) >> 3) << 0) ; // blue
				rgb32 ++;
				rgb16 ++;
			}
		}
	}
}

static inline void print_fps(struct timeval *s, struct timeval *e)
{
	unsigned long time;
	unsigned long sec;
	unsigned long usec;
	int fps = 0;

	sec = e->tv_sec - s->tv_sec;
	if (e->tv_usec > s->tv_usec)
		usec = e->tv_usec - s->tv_usec;
	else {
		usec = e->tv_usec + 1000000 - s->tv_usec;	
		sec--;
	}
	time = sec * 1000 + (usec+1) / 1000;
	fps = 1000 / (time / 30);
	printf("%d fps\n", fps);
}

int main(int argc, char *argv[])
{
	unsigned char * rgb; 
	unsigned int frames = 0;
	struct timeval start_tv, end_tv;
	struct timezone tz;
	int width, height, bpp;
	int src_img;
	int i;
  
  
	if (argc != 4) {
		printf("%s    \n", argv[0]);
		return 0;
	}
//	camif_cfg.dst_y = width = atoi(argv[1]);
//	camif_cfg.dst_x = height = atoi(argv[2]);
	width = atoi(argv[1]);
	height = atoi(argv[2]);

	bpp = atoi(argv[3]);
	rgb = (unsigned char *)malloc(width*height*bpp/8);
/*#if 0							//only support RGB16
	if (bpp==16)
		camif_cfg.dst_type = CAMIF_TYPE_RGB16;
	else
		camif_cfg.dst_type = CAMIF_TYPE_RGB32;	//not support yet
#endif
	camif_cfg.img = src_img;
*/
	if(cam_fp) close(cam_fp);
	if(fb_fp) close(fb_fp);
	if ((cam_fp = cam_init()) < 0)
		 goto err;
	if ((fb_fp = fb_init()) < 0)
		 goto err;

	printf("cam2fb: %dx%d %dbpp", width, height, bpp);
/*
	printf("displayed window: left-top (%d,%d), width(%d), height(%d)\n", 
			x_offset, y_offset, 
			MIN(FB_WIDTH, width-x_offset),
			MIN(FB_HEIGHT, height-y_offset));
*/
	fflush(stdout);
	sleep(1);
//	while(1);
#if 0
	printf("camera cam_fp    %d\n\r",cam_fp);
	printf("%0x\n\r",(('v')<<8)|1);
	if (ioctl(cam_fp, ((('v')<<8)|7), &camif_cfg)) 
	{
		perror("ioctl");
		goto err;
	}

	printf("%s\n\r",&camif_cfg);
#endif
  clear(fb);

#if 1
	//gettimeofday(&start_tv, &tz);
#if 0
	start_capture(cam_fp);
#endif
//	while (1) 
//  {
//		if (!read_data(cam_fp, &rgb[0], width, height, bpp))
//    memset(rgb, 0, width*height*2);
		  i=read_data(cam_fp, rgb, width, height, bpp);
//	  break;
#if 0
		start_capture(cam_fp);
#endif
	
#if 1
//	  for(i=0;i<240*320*2;i++)
//	  rgb[i]=0xFF;
//	  draw(fb, &rgb[0], width, height, bpp, 0, 0);
      write(fb_fp, rgb, width*height*bpp/8);

#endif
//	  frames ++;
		
		  /*if ((frames % 30) == 0) 
		    {
			     gettimeofday(&end_tv, &tz);
			     print_fps(&start_tv, &end_tv);
			     gettimeofday(&start_tv, &tz);
		    }*/
//	}
#endif

err:
	   if (cam_fp)
		   close(cam_fp);

#if 0
	if (fb)
		munmap(fb, FB_WIDTH*FB_HEIGHT*2);
#endif
	if (fb_fp)
		close(fb_fp);
  free(rgb);

	return 0;
}