📄 vccvdc.c
字号:
/* * 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_vcc.h>#include <linux/fr400cc_vdc.h>#define REGIO_TEST 1 /* 2003/Jan/27 */#define RGBOUT 1 /* 2003/Jan/14 */#define CFGCHK 1 /* 2002/Dec/20 */#define OPTCHK 1 /* 2002/Dec/19 */#define B8_16 1 /* 2002/Oct/30 */#define C2 1 /* 2002/Oct/23 */#if REGIO_TEST#include <linux/fr400cc_io.h>#endif#if OPTCHKstatic char *opt_list[] = {#if RGBOUT "lcd", "vga",#endif#if REGIO_TEST "rhy", "rhc", "rv",#endif "v"};static intoptchk_top(int ac, char **av){ int i, j, n, ret; ret = 0; n = sizeof(opt_list) / sizeof(opt_list[0]); for(i=1; i<ac; i++){ if(av[i][0] != '-') continue; if('0' <= av[i][1] && av[i][1] <= '9') continue; for(j=0; j<n; j++){ if(strcmp(&av[i][1], opt_list[j]) == 0) break; } if(j<n) continue; fprintf(stderr, "ignore option '%s' ?\n", av[i]); ret = -1; } return ret;}#endif /* OPTCHK */#if CFGCHKstatic int verbose = 0;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;}#if REGIO_TESTstatic 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 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;}#endifstatic voidconfig_show_vcc(struct fr400cc_vcc_config *cfg){ printf("encoding:%d , interlace:%d , skipbf:%d\n", cfg->encoding, cfg->interlace, cfg->skipbf); printf("fw:%d , fh:%d\n", cfg->fw, cfg->fh); printf("rhtcc:0x%08x , rhcc:0x%08x , rhbc:0x%08x, rvcc:0x%08x\n", cfg->rhtcc, cfg->rhcc, cfg->rhbc, cfg->rvcc); printf("rvbc:0x%08x , rhr:0x%08x , rvr:0x%08x\n", cfg->rvbc, cfg->rhr, cfg->rvr); printf("rssp:0x%08x , rsep:0x%08x\n", cfg->rssp, cfg->rsep); printf("rcc_fdts:0x%08x , rcc_ifi:0x%08x\n", cfg->rcc_fdts, cfg->rcc_ifi); printf("rhyf0:0x%08x , rhyf1:0x%08x , rhyf2:0x%08x\n", cfg->rhyf0, cfg->rhyf1, cfg->rhyf2); printf("rhcf0:0x%08x , rhcf1:0x%08x , rhcf2:0x%08x\n", cfg->rhcf0, cfg->rhcf1, cfg->rhcf2); printf("rvf0:0x%08x , rvf1:0x%08x\n", cfg->rvf0, cfg->rvf1);}static voidconfig_show_vdc(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 = %d\n", prm[1], prm[2], prm[3], prm[4], prm[10], prm[1]+prm[2]+prm[3]+prm[4]+prm[10]); printf("V: %d + %d + %d + %d + %d = %d\n", prm[6], prm[7], prm[8], prm[9], prm[11], prm[6]+prm[7]+prm[8]+prm[9]+prm[11]); 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);}static intioctl_start_vcc(int fd, int prm){ if(verbose){ struct fr400cc_vcc_config cfg; if(ioctl(fd, VCCIOCGCFG, &cfg) != 0){ fprintf(stderr, "ioctl vcc get cfg err\n"); return -1; } printf("VCC config\n"); config_show_vcc(&cfg); printf("\n"); } return ioctl(fd, VCCIOCSTART, prm);}static intioctl_start_vdc(int fd, unsigned long prm){ if(verbose){ struct fr400vdc_config cfg; if(ioctl(fd, VDCIOCGCFG, &cfg) != 0){ fprintf(stderr, "ioctl vdc get cfg err\n"); return -1; } printf("VDC config\n"); config_show_vdc(&cfg); printf("\n"); } return ioctl(fd, VDCIOCSTART, prm);}#endif /* CFGCHK */#if B8_16/* cut */#else /* B8_16 */#define W_SUB (720-640)#if C2static int prms_640[13] = {0, 720-W_SUB, 16, 120, 2, 0, 240, 2, 19, 1, W_SUB/2, 0, 2};#elsestatic int prms_640[13] = {858, 720-W_SUB, 11, 67, 60, 262, 240, 2, 19, 1, W_SUB/2, 0, 1};#endif#endif /* B8_16 */main(int ac, char **av){ int vcc_fd, vdc_fd, max_fd; int vdc_buf_idx; unsigned char *vcc_buf, *vdc_buf; struct fr400cc_vcc_config vcc_conf; struct fr400vdc_config vdc_conf; struct fr400cc_vcc_mbuf vcc_mbuf; struct fr400cc_vcc_read vcc_rd; struct fr400vdc_read vdc_rd; struct fr400cc_vcc_wait vcc_w; struct fr400cc_vcc_info vcc_inf; struct fr400cc_vcc_frame_info vcc_finf; fd_set rset; int x, sz;#if RGBOUT int rgbout; /* 1: LCD(320x242) , 2: VGA(640x480) */#endif#if OPTCHK if(optchk_top(ac,av) != 0) return -1;#endif#if CFGCHK verbose = (opt_chk(ac,av, "-v") != 0);#endif#if RGBOUT rgbout = 0; if(opt_chk(ac,av,"-lcd")) rgbout = 1; else if(opt_chk(ac,av,"-vga")) rgbout = 2;#endif if((vcc_fd = open("/dev/fr400cc_vcc", O_RDONLY | O_NONBLOCK)) < 0){ fprintf(stderr, "open vcc err\n"); return -1; } if(ioctl(vcc_fd, VCCIOCGMBUF, &vcc_mbuf)){ fprintf(stderr, "ioctl vcc get mbuf err\n"); return -1; } if((vcc_buf = mmap(0, vcc_mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, vcc_fd, 0)) == (void*)-1){ fprintf(stderr, "mmap vcc_buf err\n"); return -1; } if(ioctl(vcc_fd, VCCIOCGCFG, &vcc_conf)){ fprintf(stderr, "ioctl vcc get cfg err\n"); return -1; } vcc_conf.rcc_fdts = 0; vcc_conf.rcc_ifi = 0; vcc_conf.fw = 320; vcc_conf.fh = 240; vcc_conf.skipbf = 1; vcc_conf.rhcc = 720; vcc_conf.rvcc = 240; vcc_conf.rhr = 0x240; vcc_conf.rvr = 0x100; if(ioctl(vcc_fd, VCCIOCSCFG, &vcc_conf)){ fprintf(stderr, "ioctl vcc set cfg err\n"); return -1; } sleep(1); if((vdc_fd = open("/dev/fr400cc_vdc", O_RDONLY | O_NONBLOCK)) < 0){ fprintf(stderr, "open vdc err\n"); return -1; } if(ioctl(vdc_fd, VDCIOCGCFG, &vdc_conf)){ fprintf(stderr, "ioctl vdc get cfg err\n"); return -1; }#if RGBOUT if(rgbout == 1){ /* LCD */ vdc_conf.prm[1] = 320; vdc_conf.prm[2] = 1; vdc_conf.prm[3] = 1; vdc_conf.prm[4] = 1; vdc_conf.prm[6] = 242; vdc_conf.prm[7] = 1; vdc_conf.prm[8] = 1; vdc_conf.prm[9] = 1; vdc_conf.prm[10] = 0; vdc_conf.prm[11] = 0; vdc_conf.prm[12] = 6; vdc_conf.pix_x = vdc_conf.prm[1]; vdc_conf.pix_y = vdc_conf.prm[6]; vdc_conf.cscv = 2; /* y2rgb */ vdc_conf.dsm = 0; /* no interlace */ vdc_conf.dpf = 1; /* RGB */ vdc_conf.skipbf = 0; }else if(rgbout == 2){ /* VGA */ vdc_conf.prm[1] = 640; vdc_conf.prm[2] = 18; vdc_conf.prm[3] = 48; vdc_conf.prm[4] = 56; vdc_conf.prm[6] = 480; vdc_conf.prm[7] = 8; vdc_conf.prm[8] = 4; vdc_conf.prm[9] = 33; vdc_conf.prm[10] = 0; vdc_conf.prm[11] = 0; vdc_conf.prm[12] = 2; vdc_conf.pix_x = vdc_conf.prm[1]; vdc_conf.pix_y = vdc_conf.prm[6]; vdc_conf.cscv = 2; /* y2rgb */ vdc_conf.dsm = 0; /* no interlace */ vdc_conf.dpf = 1; /* RGB */ vdc_conf.skipbf = 0; }else{#endif vdc_conf.pix_x = 640;#if B8_16 vdc_conf.pix_x = 640; vdc_conf.prm[1] = 640; vdc_conf.prm[10] = (720-640)/2;#else /* B8_16 */ bcopy(prms_640, vdc_conf.prm, 4*13);#endif /* B8_16 */ vdc_conf.skipbf = 1;#if RGBOUT }#endif#if 1 if(ioctl(vdc_fd, VDCIOCSCFG, &vdc_conf)){ fprintf(stderr, "ioctl vdc set cfg err\n"); return -1; } if(ioctl(vdc_fd, VDCIOCGCFG, &vdc_conf)){ fprintf(stderr, "ioctl vdc get cfg err\n"); return -1; } if((vdc_buf = mmap(NULL, vdc_conf.buf_unit_sz * vdc_conf.buf_num, PROT_READ | PROT_WRITE, MAP_SHARED, vdc_fd, 0)) == (void*)-1){ fprintf(stderr, "mmap vdc err\n"); return -1; }#endif vdc_conf.stop_immidiate = 1; vdc_conf.rd_count_buf_idx = 1; if(ioctl(vdc_fd, VDCIOCSCFG, &vdc_conf)){ fprintf(stderr, "ioctl vdc set cfg err\n"); return -1; } if(ioctl(vdc_fd, VDCIOCGCFG, &vdc_conf)){ fprintf(stderr, "ioctl vdc get cfg err\n"); return -1; }#if RGBOUT bzero(vdc_buf, vdc_conf.buf_unit_sz * vdc_conf.buf_num);#endif vdc_buf_idx = 0 ; ioctl(vdc_fd, VDCIOCSDAT, vdc_buf_idx); vdc_buf_idx++; vdc_buf_idx %= vdc_conf.buf_num; /**/#if REGIO_TEST { unsigned value; struct fr400cc_vcc_regio regio; if(opt_chk_val(ac, av, "-rhy", &value) == 0){ regio.reg_offset = FR400CC_VCC_RHY; regio.value = value; if(ioctl(vcc_fd, VCCIOCSREGIO, ®io) != 0){ fprintf(stderr, "ioctl VCCIOSREGIO err\n"); return -1; } } if(opt_chk_val(ac, av, "-rhc", &value) == 0){ regio.reg_offset = FR400CC_VCC_RHC; regio.value = value; if(ioctl(vcc_fd, VCCIOCSREGIO, ®io) != 0){ fprintf(stderr, "ioctl VCCIOSREGIO err\n"); return -1; } } if(opt_chk_val(ac, av, "-rv", &value) == 0){ regio.reg_offset = FR400CC_VCC_RV; regio.value = value; if(ioctl(vcc_fd, VCCIOCSREGIO, ®io) != 0){ fprintf(stderr, "ioctl VCCIOSREGIO err\n"); return -1; } } }#endif#if CFGCHK if(ioctl_start_vcc(vcc_fd, -1) < 0){#else if(ioctl(vcc_fd, VCCIOCSTART, -1) < 0){#endif fprintf(stderr, "ioctl vcc start err\n"); return -1; }#if CFGCHK if(ioctl_start_vdc(vdc_fd, 0) < 0){#else if(ioctl(vdc_fd, VDCIOCSTART, 0) < 0){#endif fprintf(stderr, "ioctl vdc start err\n"); return -1; } /**/ for(;;){ FD_ZERO(&rset); FD_SET(vcc_fd, &rset); FD_SET(vdc_fd, &rset); max_fd = vcc_fd > vdc_fd ? vcc_fd : vdc_fd; if(select(max_fd + 1, &rset, NULL, NULL, NULL) <= 0){ continue; } do{ if(FD_ISSET(vcc_fd, &rset)){#if 0 sz = sizeof(vcc_rd); if((x = read(vcc_fd, (void*)&vcc_rd, sz))<= 0){ fprintf(stderr, "read vcc err\n"); break; } if(vcc_rd.type != FR400CC_VCC_RTYPE_CAPTURE){ break; }#endif vcc_w.num = 1; if(ioctl(vcc_fd, VCCIOCWAIT, &vcc_w) < 0){ fprintf(stderr, "ioctl vcc wait err\n"); break; }#if 0 if(ioctl(vcc_fd, VCCIOCGINF, &vcc_inf) < 0){ fprintf(stderr, "ioctl vcc get inf err\n"); break; } vcc_finf.frame = vcc_w.first_frame; if(ioctl(vcc_fd, VCCIOCGFINF, &vcc_finf) < 0){ fprintf(stderr, "ioctl vcc get finf err\n"); break; } fprintf(stderr, ".");#endif#if RGBOUT if(rgbout == 1){ /* LCD */ unsigned char *src, *dst; int i, n, j; unsigned *sp, *dp; sz = 320 * 240 * 2; src = vcc_buf + vcc_mbuf.offsets[vcc_w.first_frame]; dst = vdc_buf + vdc_conf.buf_unit_sz * vdc_buf_idx; sp = (unsigned *)src; dp = (unsigned *)dst; n = sz / 4; for(i=0; i<n; i++){ *dp++ = *sp++; } }else if(rgbout == 2){ /* VGA */ unsigned char *src, *dst; int i, n, j; unsigned *sp, *dp; sz = 320 * 240 * 2; src = vcc_buf + vcc_mbuf.offsets[vcc_w.first_frame]; dst = vdc_buf + vdc_conf.buf_unit_sz * vdc_buf_idx; sp = (unsigned *)src; dp = (unsigned *)dst; n = sz / 4; for(i=0; i<n; i++){ *dp++ = *sp; *dp++ = *sp++; } sp = (unsigned *)src; for(i=0; i<n; i++){ *dp++ = *sp; *dp++ = *sp++; } }else#endif { unsigned char *src, *dst; int i, n, j; unsigned *sp, *dp; sz = 320 * 240 * 2; src = vcc_buf + vcc_mbuf.offsets[vcc_w.first_frame]; dst = vdc_buf + vdc_conf.buf_unit_sz * vdc_buf_idx; sp = (unsigned *)src; dp = (unsigned *)dst; n = sz / 4; for(i=0; i<n; i++){ *dp++ = *sp; *dp++ = *sp++; } } if(ioctl(vcc_fd, VCCIOCFREE, 1) < 0){ fprintf(stderr, "ioctl vcc free err\n"); break; } if(ioctl(vdc_fd, VDCIOCSDAT, vdc_buf_idx) < 0){ fprintf(stderr, "ioctl vdc sdat err\n"); break; } vdc_buf_idx++; vdc_buf_idx %= vdc_conf.buf_num; }}while(0); do{ if(FD_ISSET(vdc_fd, &rset)){#if 1 struct fr400vdc_read vdc_rds[100]; sz = sizeof(vdc_rds); if((x = read(vdc_fd, (void*)vdc_rds, sz)) <= 0){ break; }#else sz = sizeof(vdc_rd); if((x = read(vdc_fd, (void*)&vdc_rd, sz)) < sz){ fprintf(stderr, "read vdc err\n"); break; } if(vdc_rd.type != FR400CC_VDC_RTYPE_FRAME_FIN){ break; }#endif#if 0 fprintf(stderr, "vdc cnt=%d\n", vdc_rd.count);#endif }}while(0); } close(vcc_fd); close(vdc_fd); return 0;}/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -