#include #include #include #include #include #include #include #include #include #include "display-X.h" #include "ycbcr-rgb-cvt.h" extern const char *__progname; #define FRAMESIZE 640*480*2 static unsigned char *framebuf; static int dpipe; #define wrt(fd,buf,len) wrt_(#fd "," #buf "," #len,(fd),(buf),len) static void wrt_(const char *s, int fd, const void *buf, int len) { int n; n = write(fd,buf,len); if (n < 0) { fprintf(stderr,"write(%s): %s\n",s,strerror(errno)); exit(1); } if (n != len) { fprintf(stderr,"write(%s): wrote %d not %d\n",s,n,len); exit(1); } } static void setup_frame(void) { void *mmrv; mmrv = mmap(0,FRAMESIZE*2,PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0); if (mmrv == MAP_FAILED) { fprintf(stderr,"%s: buffer mmap (%u): %s\n",__progname,(unsigned int)(FRAMESIZE*2),strerror(errno)); exit(1); } framebuf = mmrv; bzero(framebuf,FRAMESIZE*2); } static void displayer_main(void) { unsigned char c; CVTPARAMS p; static void dpr(void *buf, int len) { int nr; nr = recv(dpipe,buf,len,MSG_WAITALL); if (nr == len) { return; } else if (nr < 0) { fprintf(stderr,"%s: displayer pipe read: %s\n",__progname,strerror(errno)); } else if (nr == 0) { fprintf(stderr,"%s: displayer pipe read EOF\n",__progname); } else if (nr < len) { fprintf(stderr,"%s: displayer pipe short read (%d, wanted %d)\n",__progname,nr,len); } else { fprintf(stderr,"%s: impossible displayer pipe read: %d\n",__progname,nr); } exit(1); } setup_X(); p.Kr = .299; p.Kb = .114; p.minY = 0; p.maxY = 255; p.maxCC = 127; reset_cvt(&p); while (1) { dpr(&c,1); display_frame(framebuf+(c*FRAMESIZE)); wrt(dpipe,&c,1); } } static void fork_displayer(void) { int p[2]; int pid; if (socketpair(AF_LOCAL,SOCK_STREAM,0,&p[0]) < 0) { fprintf(stderr,"%s: socketpair: %s\n",__progname,strerror(errno)); exit(1); } wrt(p[1],"\0\1",2); fflush(0); pid = fork(); if (pid == 0) { close(p[0]); dpipe = p[1]; displayer_main(); _exit(0); } close(p[1]); dpipe = p[0]; // fcntl(dpipe,F_SETFL,fcntl(dpipe,F_GETFL,0)|O_NONBLOCK); } static int rd(int fd, void *data, int len) { int r; unsigned char *dp; int l; dp = data; l = len; while (l > 0) { r = read(fd,dp,l); if (r < 0) { fprintf(stderr,"%s: read: %s\n",__progname,strerror(errno)); exit(1); } if (r == 0) return(0); if (r > l) abort(); dp += r; l -= r; } return(1); } int main(void); int main(void) { unsigned char bno; setup_frame(); fork_displayer(); while (1) { if (! rd(dpipe,&bno,1)) { fprintf(stderr,"%s: displayer pipe EOF\n",__progname); exit(1); } if (! rd(0,&framebuf[bno*FRAMESIZE],640*480*2)) break; wrt(dpipe,&bno,1); } return(0); }