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

📄 vdc.c

📁 linux 嵌入式原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Sample program for FR400 Companion Chip VDC axLinux driver. *   *  Copyright (C) 2002  AXE,Inc. * */#include <stdio.h>#include <stdlib.h>#include <time.h>#include <fcntl.h>#include <unistd.h>#include <sys/mman.h>#include <sys/stat.h>#include <linux/fr400cc_vdc.h>/* *   [memory map] *   0x00000000 - 0x01000000	kernel *   0x01000000 - 0x01c00000    vdc.c *   0x01c00000 - 0x03c00000	(don't use, broken??) *   0x03c00000 - 0x04000000    romdisk */#define TMPBUF_BASE   0x01000000#define TMPBUF_SIZE   0x02c00000static unsigned char *local_area = (unsigned char *)TMPBUF_BASE;static unsigned char *mmap_area = NULL;static struct fr400vdc_config cfg;static int fd = -1;#define REGIO_TEST	1	/* 2003/Jan/27 */#define CSRON_OPT	1	/* 2003/Jan/21 */#define PIXUT		1	/* 2003/Jan/21 */#define CFGCHK		1	/* 2002/Dec/20 */#define OPTCHK		1	/* 2002/Dec/19 */#define YUV_TEST_DATA	1	/* 2202/Dec/17 */#define RGB_DBL		1	/* 2002/Dec/17 */#define VDC_CFG_MOD	1	/* 2002/Nov/11 */#define RGB		1	/* 2002/Nov/01 */#define TXT_DEBUG	0#define DBG_MSG		0#if REGIO_TEST#include <linux/fr400cc_io.h>#endif#if TXT_DEBUGstatic char txtbufline[1024]; /* 1 line */static char txtbuf[100*1024];static const int txtbufsz = sizeof(txtbuf);static int txtbufcnt = 0;static int txtbufidx = 0;static char *txtbuf_get(){ return txtbufline; }static void txtbuf_add_sub(char *src, int sz){	char *dst;	dst = txtbuf + txtbufidx;	bcopy(src, dst, sz);	txtbufidx = (txtbufidx + sz) % txtbufsz;	if(txtbufcnt < txtbufsz){		txtbufcnt += sz;		if(txtbufcnt >= txtbufsz) txtbufcnt = txtbufsz;	}}static void txtbuf_add(){	char *src;	int sz, rest, cpsz;	sz = strlen(txtbufline);	if(sz > sizeof(txtbufline)-1) sz = sizeof(txtbufline)-1;	src = txtbufline;	cpsz = sz;	rest = txtbufsz - txtbufidx;	if(cpsz > rest) cpsz = rest;	txtbuf_add_sub(src, cpsz);	src += cpsz;	sz -= cpsz;	if(sz <= 0) return;		txtbuf_add_sub(src, sz);}static void txtbuf_dump(){	int i, j, st;	fprintf(stderr, "--> txtbuf dump\n");	st = 0;	if(txtbufcnt >= txtbufsz) st = txtbufidx;	for(i=0; i<txtbufcnt; i++){		j = (st + i) % txtbufsz;		fputc(txtbuf[j], stderr);	}	fprintf(stderr, "<-- txtbuf dump\n");}#endif /* TXT_DEBUG */static voidtm_dif(	struct timeval *a,	struct timeval *b,	struct timeval *re){	re->tv_sec = a->tv_sec - b->tv_sec;	re->tv_usec = a->tv_usec - b->tv_usec;	while(re->tv_usec < 0){		re->tv_sec--;		re->tv_usec += 1000000;	}}static void *mmap_fd(int fd){	void *start;	int length, prot, flags, offset;	start = NULL;	length = cfg.buf_unit_sz * cfg.buf_num;	prot = PROT_READ | PROT_WRITE;	flags = MAP_SHARED;	offset = 0;	return mmap(start, length, prot, flags, fd, offset);}static intfile_sz(char *fn){	struct stat st;	if(stat(fn, &st) == -1) return -1;	return st.st_size;}static intload_area(char *fn, unsigned char *buf){	FILE *fp;	int fsz, sz, x;	unsigned char *p;	fprintf(stderr, "load %s ... ", fn); fflush(stderr);	if((fsz = file_sz(fn)) < 0){		fprintf(stderr, "%s ???\n", fn);		return -1;	}	if((fp = fopen(fn, "r")) == NULL) return -1;	sz = fsz;	p = buf;	while(sz > 0){		if((x = fread(p, 1, sz, fp)) < 0){			fclose(fp);			return -1;		}		p += x;		sz -= x;	}	fclose(fp);	if(cfg.pix_x == 640){ /* !!! */		int i, j, n;		p = buf;		n = fsz / 4;		for(i=0; i<n; i++){			j = n - i - 1;			bcopy(p+j*4, p+j*2*4, 4);			bcopy(p+j*4, p+(j*2+1)*4, 4);		}		if(!cfg.skipbf){			sz = fsz * 2;			bcopy(p, p+sz, sz);		}	}	fprintf(stderr, "ok.\n");	return 0;}static voidhelp(){	printf("--help , -help , -?\n");	printf("-dma-mode <0|1|3> : DA,SCA,2D\n");	printf("-hdc n\n");	printf("-hfp n\n");	printf("-hsc n\n");	printf("-hbp n\n");	printf("-hsop n\n");	printf("-vdc n\n");	printf("-vfp n\n");	printf("-vsc n\n");	printf("-vbp n\n");	printf("-vsop n\n");	printf("-hip n\n");	printf("-vip n\n");	printf("-rck n\n");	printf("-rddl n\n");	printf("-cscv n\n");	printf("-ats n\n");	printf("-dsm n\n");	printf("-interlace n\n");	printf("-csron n\n");	printf("-bit <8|16>\n");	printf("-qvga\n");	printf("-rgb\n");	printf("-y2rgb\n");	printf("-yuv\n");	printf("-xga\n");	printf("-h320\n");	printf("-lcd\n");	printf("-skipbf N (N=0|1|2 , default:0\n"	       "           0 top bottom same dma (once)\n"	       "           1 top bottom another dma , same data\n"	       "           2 top bottom another dma , anoter data)\n");	printf("-rd_count_buf_idx\n");	printf("-f <yuv filepath>\n");	printf("-load N N (start .. cnt)\n");	printf("-fmt <load format string> (defalut: cap%%03d.yuv)\n");	printf("-nonblock N (N=0|1 , default:1\n");	printf("-block ( == -nonblock 0)\n");	printf("-vsync (vsync test)\n");	printf("-vsync-auto (vsync test 2)\n");	printf("-cnt N\n");	printf("-sec N\n");	printf("-showall-stop\n");	printf("-pack\n");	printf("-grad\n");	printf("-cbar\n");	printf("-bw\n");	printf("-mix\n");	printf("-dbl\n");	printf("-v\n");	printf("-dma-mode\n");#if REGIO_TEST	printf("-rct1 0xHHHHHHHH\n");	printf("-rct2 0xHHHHHHHH\n");	printf("-csr-x N\n");	printf("-csr-y N\n");	printf("-bci\n");	printf("-show-rs\n");	printf("-regio-w 0xHHHHHHHH 0xHHHHHHHH\n");	printf("-regio-r 0xHHHHHHHH\n");#endif}static intopt_chk(int ac, char **av, char *key){	int i;	for(i=1; i<ac; i++){		if(strcmp(av[i], key) == 0) return i;	}	return 0;}static intopt_chk_str(int ac, char **av, char *key, char **re){	int i;	i = opt_chk(ac, av, key);	if(i!=0 && i+1<ac){		*re = av[i+1];		return 0;	}	return -1;}static voidopt_chk_int(int ac, char **av, char *key, int *re){	int i;	i = opt_chk(ac, av, key);	if(i!=0 && i+1<ac){		sscanf(av[i+1], "%d", re);	}}static voidopt_chk_int2(int ac, char **av, char *key, int *re1, int *re2){	int i;	i = opt_chk(ac, av, key);	if(i!=0 && i+2<ac){		sscanf(av[i+1], "%d", re1);		sscanf(av[i+2], "%d", re2);	}}#if REGIO_TESTstatic ints2val(char *s, unsigned *re){	unsigned v;	int cnt, neg, d;	if(s == NULL) return -2;	if(strncmp(s, "0x", 2) == 0){		if((cnt = sscanf(s, "0x%x", &v)) != 1) return -1;		*re = v;		return 0;	}	neg = 0;	if(s[0] == '-'){		neg = 1;				s++;	}	if((cnt = sscanf(s, "%d", &d)) != 1) return -1;	if(neg) d = -d;	*re = (unsigned)d;	return 0;}static intopt_chk_val(int ac, char **av, char *key, unsigned *re){	char *str;	if(opt_chk_str(ac, av, key, &str) != 0) return -1;	if(s2val(str, re) != 0) return -2;	return 0;}#endif#if CFGCHKstatic int verbose = 0;static voidconfig_show(struct fr400vdc_config *cfg){	int *prm;	prm = cfg->prm;	printf("pix_x:%d , pix_y:%d , pix_sz:%d\n",	       cfg->pix_x, cfg->pix_y, cfg->pix_sz);	printf("skipbf:%d , buf_unit_sz:%d , buf_num:%d\n",	       cfg->skipbf, cfg->buf_unit_sz, cfg->buf_num);	printf("stop_immidiate:%d , rd_count_buf_idx:%d\n",	       cfg->stop_immidiate, cfg->rd_count_buf_idx);	printf("H: %d + %d + %d + %d + %d*2 = %d\n",	       prm[1], prm[2], prm[3], prm[4], prm[10],	       prm[1]+prm[2]+prm[3]+prm[4]+prm[10]*2);	printf("V: %d + %d + %d + %d + %d*2 = %d\n",	       prm[6], prm[7], prm[8], prm[9], prm[11], 	       prm[6]+prm[7]+prm[8]+prm[9]+prm[11]*2);	printf("RCK: %d RDDL: %d\n", prm[12], cfg->rddl);	printf("HLS:%d , PAL:%d , CSCV:%d , DBLS:%d\n",	       cfg->hls, cfg->pal, cfg->cscv, cfg->dbls);	printf("R601:%d , TFOP:%d , DSM:%d , DFP:%d\n",	       cfg->r601, cfg->tfop, cfg->dsm, cfg->dfp);	printf("DIE:%d , ENOP:%d , VSOP:%d , HSOP:%d\n",	       cfg->die, cfg->enop, cfg->vsop, cfg->hsop);	printf("DSR:%d , CSRON:%d , DPF:%d , DMS:%d\n",	       cfg->dsr, cfg->csron, cfg->dpf, cfg->dms);	printf("dma_mode:%d , dma_ats:%d , dma_rs:%d\n",	       cfg->dma_mode, cfg->dma_ats, cfg->dma_rs);}#if REGIO_TESTstatic intbci_set(int fd, char *text, int len){	char ch[3], c;	unsigned buf[64];	int x, y, v, pos, div, mod, i;	struct fr400cc_vdc_regio regio;	int ret;	ch[0] = *text++; len--;	ch[1] = *text++; len--;	ch[2] = *text++; len--;	bzero(buf, sizeof(buf));	for(y=0; y<32; y++){		for(x=0; x<32; x++){			if(len <= 0) continue;			c = *text++; len--;			if(c == ch[0]) continue;			v = 0;			if(c == ch[1]) v = 1;			else if(c == ch[2]) v = 2;			pos = y * 32 + x;			div = pos / 16;			mod = pos % 16;			buf[div] |= v << ((15-mod) * 2);		}	}	for(i=0; i<64; i++){		regio.reg_offset = FR400CC_VDC_BCI + i*4;		regio.value = buf[i];		if((ret = ioctl(fd, VDCIOCSREGIO, &regio)) != 0){			fprintf(stderr, "ioctl sregio bci err\n");			 return ret;		}	}	return 0;}static intregio_test(int ac, char **av, int fd){	int ret, i;	unsigned val, mask;	int cx, cy;	struct fr400cc_vdc_regio regio;	static char *bci_def = ".*@"		"********************************"		"********************************"		"**............................**"		"**............................**"		"**..@@@@@@@@@@@@@@@@@@@@@@@@..**"		"**..@@@@@@@@@@@@@@@@@@@@@@@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@....................@@..**"		"**..@@@@@@@@@@@@@@@@@@@@@@@@..**"		"**..@@@@@@@@@@@@@@@@@@@@@@@@..**"		"**............................**"		"**............................**"		"********************************"		"********************************";	ret = 0;	if(opt_chk_val(ac, av, "-rct1", &val) == 0){		regio.reg_offset = FR400CC_VDC_RCT1;		regio.value = val;		if((ret = ioctl(fd, VDCIOCSREGIO, &regio)) != 0){			fprintf(stderr, "ioctl sregio rct1 err\n");			return ret;		}	}	if(opt_chk_val(ac, av, "-rct2", &val) == 0){		regio.reg_offset = FR400CC_VDC_RCT2;		regio.value = val;		if((ret = ioctl(fd, VDCIOCSREGIO, &regio)) != 0){			fprintf(stderr, "ioctl sregio rct2 err\n");			return ret;		}	}	cx = cy = -1;	opt_chk_int(ac, av, "-csr-x", &cx);	opt_chk_int(ac, av, "-csr-y", &cy);	if(cx != -1 || cy != -1){		regio.reg_offset = FR400CC_VDC_RCH;		if((ret = ioctl(fd, VDCIOCGREGIO, &regio)) != 0){			fprintf(stderr, "ioctl gregio rch err\n");			return ret;		}		if(cx != -1){			mask = ((1 << 11) - 1) << 16;			regio.value &= ~mask;			cx <<= 16;			cx &= mask;			regio.value |= cx;		}		if(cy != -1){			mask = ((1 << 11) - 1) << 0;			regio.value &= ~mask;			cy <<= 0;			cy &= mask;			regio.value |= cy;		}		if((ret = ioctl(fd, VDCIOCSREGIO, &regio)) != 0){			fprintf(stderr, "ioctl sregio rch err\n");			return ret;		}	}	if(opt_chk(ac, av, "-bci")){		if((ret = bci_set(fd, bci_def, strlen(bci_def))) != 0){			return ret;		}	}		if(opt_chk(ac, av, "-show-rs")){		regio.reg_offset = FR400CC_VDC_RS;		if((ret = ioctl(fd, VDCIOCGREGIO, &regio)) != 0){			fprintf(stderr, "ioctl gregio rs err\n");			return ret;		}		printf("-show-rs : %08x\n", regio.value);	}	if(opt_chk_val(ac, av, "-regio-r", &val) == 0){		regio.reg_offset = val;		if((ret = ioctl(fd, VDCIOCGREGIO, &regio)) != 0){			fprintf(stderr, "ioctl gregio regio-r err\n");			return ret;		}		printf("-regio-r : offset=%08x value=08x\n",		       regio.reg_offset, regio.value);	}	if((i = opt_chk(ac, av, "-regio-w")) != 0 && i+2<ac){		if((ret = s2val(av[i+1], &regio.reg_offset)) != 0){			fprintf(stderr, "-regio-w offset ???\n");			return ret;		}		if((ret = s2val(av[i+2], &regio.value)) != 0){			fprintf(stderr, "-regio-w value ???\n");			return ret;		}		if((ret = ioctl(fd, VDCIOCSREGIO, &regio)) != 0){			fprintf(stderr, "ioctl sregio regio-w err\n");			return ret;		}	}	return ret;}#endifstatic int#if REGIO_TESTioctl_start(int ac, char **av, int fd, unsigned long prm)#elseioctl_start(int fd, unsigned long prm)#endif{	if(verbose){		struct fr400vdc_config cfg;		if(ioctl(fd, VDCIOCGCFG, &cfg) != 0){			fprintf(stderr, "ioctl get cfg err\n");			return -1;		}		config_show(&cfg);	}#if REGIO_TEST	{		int ret;		if((ret = ioctl(fd, VDCIOCSTART, prm)) != 0) return ret;		if((ret = regio_test(ac, av, fd)) != 0) return ret;		return ret;	}#else	return ioctl(fd, VDCIOCSTART, prm);#endif}#endif /* CFGCHK */#if PIXUT/* pix_type */#define PIXUT_RGB_NOPACK	2#define PIXUT_RGB_PACK		3#define PIXUT_YUV		4static intpix_sz(int pix_type){	switch(pix_type){	case PIXUT_RGB_NOPACK:	return 4;	case PIXUT_RGB_PACK:	return 3;	case PIXUT_YUV:		return 2;	}	return 0;}static intpix_type_rgb(int pack){	return pack ? PIXUT_RGB_PACK : PIXUT_RGB_NOPACK;}static voidpix_rgb2yuv(unsigned char *src, unsigned char *dst){	unsigned int r1, r2, g1, g2, b1, b2;	double R, G, B;	double Y1, Y2, U, V;	unsigned int y1, y2, u, v;	r1 = *src++;	g1 = *src++;	b1 = *src++;	r2 = *src++;	g2 = *src++;	b2 = *src++;	Y1 = 0.2989*r1 + 0.5866*g1 + 0.1145*b1;	Y2 = 0.2989*r2 + 0.5866*g2 + 0.1145*b2;	R = (r1 + r2) / 2.0;	G = (g1 + g2) / 2.0;	B = (b1 + b2) / 2.0;	U = -0.1684*R -0.3311*G + 0.4997*B;	V = 0.4998*R - 0.4187*G - 0.0813*B;	y1 = Y1;	y2 = Y2;	u = U + 128;	v = V + 128;	*dst++ = y1;	*dst++ = u;	*dst++ = y1;	*dst++ = v;}static voidpix_yuv2rgb(unsigned char *src, unsigned char *dst, int pack){	int y1, y2, u, v;	unsigned int r1, r2;	unsigned int g1, g2;	unsigned int b1, b2;	double R, G, B;	y1 = *src++;	u = *src++;	y2 = *src++;	v = *src++;	u -= 128;	v -= 128;	R = y1 + 1.4022*v; r1 = R;	R = y2 + 1.4022*v; r2 = R;	G = y1 - 0.3441*u - 0.7139*v; g1 = G;	G = y2 - 0.3441*u - 0.7139*v; g2 = G;	B = y1 + 1.7718*u - 0.0012*v; b1 = B;	B = y2 + 1.7718*u - 0.0012*v; b2 = B;	if(!pack) *dst++ = 0;	*dst++ = r1;	*dst++ = g1;	*dst++ = b1;	if(!pack) *dst++ = 0;	*dst++ = r2;	*dst++ = g2;	*dst++ = b2;}struct pix_prm{	int x, y, w, h;	int r, g, b;	char *buf;	int pix_type;	int interlace;};char *pix_buf_posi(struct pix_prm *p){	int y;	y = p->y;	if(p->interlace){		y /= 2;		if(p->y & 1) y += cfg.pix_y / 2;	}	return p->buf + (y * cfg.pix_x + p->x) * pix_sz(p->pix_type);}static voidpix_set(struct pix_prm *p){	struct pix_prm p2;	unsigned char *ubuf, yuv_buf[10], *up;	p2 = *p;	if(p2.pix_type == PIXUT_YUV) p2.x &= ~1;	ubuf = (unsigned char *)pix_buf_posi(&p2);	switch(p2.pix_type){	case PIXUT_YUV:		pix_yuv2rgb(ubuf, yuv_buf, 1);		up = yuv_buf;		if(p->x & 1) up += 3;		*up++ = p2.r;		*up++ = p2.g;		*up++ = p2.b;		pix_rgb2yuv(yuv_buf, ubuf);		break;			case PIXUT_RGB_NOPACK:		*ubuf++ = 0;	case PIXUT_RGB_PACK:		*ubuf++ = p2.r;		*ubuf++ = p2.g;		*ubuf++ = p2.b;		break;	}}static voidpix_set2(struct pix_prm *p){	struct pix_prm p2;	unsigned char *ubuf, yuv_buf[10], *up;	p2 = *p;	switch(p2.pix_type){	case PIXUT_YUV:		if((p->x & 1) == 0){			ubuf = (unsigned char *)pix_buf_posi(&p2);			up = yuv_buf;			*up++ = p2.r;			*up++ = p2.g;			*up++ = p2.b;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -