diff --git a/lib/Makefile b/lib/Makefile index ecc0981..8ed2eb7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -13,10 +13,10 @@ install: all $(CC) $(CFLAGS) -fPIC -c $< dddvb_test: dddvb_test.o - $(CC) -o dddvb_test $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi + $(CC) -o dddvb_test $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi ddzap: ddzap.o - $(CC) -o ddzap $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi + $(CC) -o ddzap $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi -lm clean: make -C ./src clean diff --git a/lib/ddzap.c b/lib/ddzap.c index 519e8b8..cf29a41 100644 --- a/lib/ddzap.c +++ b/lib/ddzap.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include char line_start[16] = ""; char line_end[16] = "\r"; @@ -22,6 +24,175 @@ uint32_t packet_errors = 0; uint8_t cc[8192] = { 0 }; +enum { IQ_RED=1, IQ_GREE, IQ_BLUE , IQ_EVIL, IQ_LOG_RED, IQ_LOG_GREEN, IQ_LOG_BLUE , IQ_LOG_EVIL , IQ_TEST, }; + +typedef struct pamdata_ +{ + unsigned char *data_points; + uint64_t *data; + int col; +} pamdata; + +int init_pamdata(pamdata *iq,int color) +{ + iq->col = 0; + if (!( iq->data=(uint64_t *) malloc(sizeof(uint64_t) *256*256))) + { + fprintf(stderr,"not enough memory\n"); + return -1; + } + memset(iq->data,0,256*256*sizeof(uint64_t)); + if (!( iq->data_points=(unsigned char *) malloc(sizeof(unsigned char) * + 256*256*3))) + { + fprintf(stderr,"not enough memory\n"); + return -1; + } + memset(iq->data_points,0,256*256*3*sizeof(char)); + iq->col = color; + return 0; +} + +static long getutime(){ + struct timespec t0; + clock_gettime(CLOCK_MONOTONIC_RAW,&t0); + return t0.tv_sec * (int)1e9 + t0.tv_nsec; +} + +void pam_coordinate_axes(pamdata *iq, unsigned char r, + unsigned char g, unsigned char b){ + int i; + for (i = 0; i < 256*3; i+=3){ + // coordinate axes + int xr = i + 256*128*3; + int yr =128*3 + i*256; + iq->data_points[xr] = r; + iq->data_points[yr] = r; + iq->data_points[xr+1] = g; + iq->data_points[yr+1] = g; + iq->data_points[xr+2] = b; + iq->data_points[yr+2] = b; + } + +} +void pam_data_convert(pamdata *iq ,uint64_t maxd) +{ + int i; + uint64_t m = 255*maxd; + double lm = log((double)m); + memset(iq->data_points,0,256*256*3*sizeof(char)); + for (i = 0; i < 256*256*3; i+=3){ + // IQ data plot + int r = i; + int g = i+1; + int b = i+2; + uint64_t odata = iq->data[i/3]; + uint64_t data = 255*iq->data[i/3]; + double lod = log((double)odata); + double q = lod/lm; + if (data){ + switch (iq->col){ + case IQ_LOG_EVIL: + if ( q < 0.25){ + iq->data_points[b] = (int)(1024.0*q); + } else { + if (q >0.5) iq->data_points[g] = (int)(255.0*q); + else + iq->data_points[r] = (int)(512.0*q); + } + break; + case IQ_LOG_RED: + iq->data_points[r] = (int)(255.0*q)&0xff; + break; + case IQ_LOG_GREEN: + iq->data_points[g] = (int)(255.0*q)&0xff; + break; + case IQ_LOG_BLUE: + iq->data_points[b] = (int)(255.0*q)&0xff; + break; + case IQ_EVIL: + if (data < m/4){ + iq->data_points[b] = ((4*data)/maxd)&0xff; + } else { + if (data >m/2) iq->data_points[g] = (data/maxd)&0xff; + else iq->data_points[r] = (2*data/maxd)&0xff; + } + break; + case IQ_TEST: + if (data < m/4){ + iq->data_points[b] = ((4*data)/maxd)&0xff; + iq->data_points[g] = ((4*data)/maxd)&0xff; + } else { + if (data >m/2) { + iq->data_points[g] = (data/maxd)&0xff; + } else { + iq->data_points[g] = (2*data/maxd)&0xff; + iq->data_points[r] = (2*data/maxd)&0xff; + } + } + break; + case IQ_RED: + iq->data_points[r] = (data/maxd)&0xff; + break; + case IQ_BLUE: + iq->data_points[b] = (data/maxd)&0xff; + break; + + default: + case IQ_GREE: + iq->data_points[g] = (data/maxd)&0xff; + break; + } + } + + } +} +#define TS_SIZE 188 +#define BSIZE 100*TS_SIZE +#define DTIME 40000000ULL +void pam_read_data (int fdin, pamdata *iq) +{ + int8_t buf[BSIZE]; + int i,j; + + long t0; + long t1; + uint64_t maxd = 0; + + t0 = getutime(); + t1 = t0; + + while ((t1 - t0) < DTIME){ + int re =0; + if ((re=read(fdin,(char *)buf, BSIZE)) < 0){ + return; + } + for (i=0; i < re; i+=TS_SIZE){ + for (j=4; jdata[ix|(qy<<8)] += 1; + uint64_t c = iq->data[ix|(qy<<8)]; + if ( c > maxd) maxd = c; + } + } + t1 = getutime(); + } + + pam_data_convert(iq, maxd); + pam_coordinate_axes(iq, 255,255 ,0); + memset(iq->data,0,256*256*sizeof(uint64_t)); +} + +void pam_write (int fd, pamdata *iq){ + char *HEAD="P7\nWIDTH 256\nHEIGHT 256\nDEPTH 3\nMAXVAL 255\nTUPLTYPE RGB\nENDHDR\n"; + int headlen = strlen(HEAD); + int we=0; + we=write(fd,HEAD,headlen); + we=write(fd,iq->data_points,256*256*3); + memset(iq->data_points,0,256*256*3*sizeof(char)); +} + void proc_ts(int i, uint8_t *buf) { uint16_t pid=0x1fff&((buf[1]<<8)|buf[2]); @@ -111,6 +282,9 @@ int main(int argc, char **argv) int odvr = 0; FILE *fout = stdout; int line = -1; + int color = 0; + pamdata iq; + while (1) { int cur_optind = optind ? optind : 1; @@ -134,16 +308,21 @@ int main(int argc, char **argv) {"tscheck", no_argument, 0, 't'}, {"tscheck_l", required_argument, 0, 'a'}, {"nodvr", no_argument , 0, 'q'}, + {"pam", no_argument , 0, 'a'}, {"help", no_argument , 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, - "c:i:f:s:d:p:hg:r:n:b:l:v:m:ota:q", + "e:c:i:f:s:d:p:hg:r:n:b:l:v:m:ota:q", long_options, &option_index); if (c==-1) break; switch (c) { + case 'e': + odvr = 2; + color = strtoul(optarg, NULL, 0); + break; case 'o': fout = stderr; if (odvr) { @@ -352,10 +531,22 @@ int main(int argc, char **argv) if ((fd = open(filename ,O_RDONLY)) < 0){ fprintf(stderr,"Error opening input file:%s\n",filename); } - if (odvr == 1){ - while(1){ - read(fd,buf,BUFFSIZE); - write(fileno(stdout),buf,BUFFSIZE); + if (odvr > 0){ + switch (odvr){ + case 1: + while(1){ + read(fd,buf,BUFFSIZE); + write(fileno(stdout),buf,BUFFSIZE); + } + break; + case 2: + fprintf(stderr,"writing pamdata\n"); + init_pamdata(&iq,color); + while(1){ + pam_read_data(fd, &iq); + pam_write(STDOUT_FILENO, &iq); + } + break; } } else { if( line >= 0 && line < 64 ){