*** Makefile.org Mon May 8 13:59:03 2000 --- Makefile Fri May 17 00:32:04 2002 *************** *** 4,17 **** VERSION = 1.0.1 ! CFLAGS = -O CPPFLAGS = -I/usr/local/include LIBS = -L/usr/local/lib -lpnm default: vid ! vid: vid.c vid.h ! $(CC) $(CPPFLAGS) $(CFLAGS) -o vid vid.c $(LIBS) dist: vid-$(VERSION).tar.gz --- 4,18 ---- VERSION = 1.0.1 ! #CFLAGS = -O CPPFLAGS = -I/usr/local/include + CFLAGS = -O -DSAA7111A=1 -DOV511PLUS=1 -DUSECOMPRESS=0 $(CPPFLAGS) LIBS = -L/usr/local/lib -lpnm default: vid ! vid: vid.o ov511_decomp.o ! $(CC) -o vid vid.o ov511_decomp.o $(LIBS) dist: vid-$(VERSION).tar.gz *************** *** 21,23 **** --- 22,30 ---- cp vid.c vid.h Makefile README COPYING ChangeLog vid-$(VERSION) tar czvf vid-$(VERSION).tar.gz vid-$(VERSION) rm -rf vid-$(VERSION) + + clean: + rm vid *.o + + vid.o: vid.c vid.h Makefile + ov511_decomp.o: ov511_decomp.c Makefile *** vid.c.org Mon May 8 13:59:03 2000 --- vid.c Fri May 17 00:57:01 2002 *************** *** 43,62 **** #define VERSION "1.0.1 (2000-05-07)" static int ov511_reg_read(int fd, int reg) { struct usb_ctl_request ur; unsigned char data[1024]; ! ur.request.bmRequestType = UT_READ_VENDOR_INTERFACE; ! ur.request.bRequest = 2; ! USETW(ur.request.wValue, 0); /* unused */ ! USETW(ur.request.wIndex, reg); /* index */ ! USETW(ur.request.wLength, 1); /* payload len in bytes */ ! ur.data = data; ! ur.flags = 0; ! ur.actlen = 0; if(ioctl(fd, USB_DO_REQUEST, &ur) < 0) { return -1; --- 43,107 ---- #define VERSION "1.0.1 (2000-05-07)" + /* for tuner support */ + + #define FREQFACTOR 16 + + #define OFFSET 6.00 + #define IF_FREQ 45.75 + static int jpnbcst[] = { + 62, (int)(IF_FREQ * FREQFACTOR), 0, + 13, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), + 8, (int)(193.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), + 4, (int)(171.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), + 1, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), + 0 + }; + #undef IF_FREQ + #undef OFFSET + + #define TBL_CHNL jpnbcst[ x ] + #define TBL_BASE_FREQ jpnbcst[ x + 1 ] + #define TBL_OFFSET jpnbcst[ x + 2 ] + static int + frequency_lookup( int channel ) + { + int x; + + /* check for "> MAX channel" */ + x = 0; + if ( channel > TBL_CHNL ) + return( -1 ); + + /* search the table for data */ + for ( x = 3; TBL_CHNL; x += 3 ) { + if ( channel >= TBL_CHNL ) { + return( TBL_BASE_FREQ + + ((channel - TBL_CHNL) * TBL_OFFSET) ); + } + } + + /* not found, must be below the MIN channel */ + return( -1 ); + } + #undef TBL_OFFSET + #undef TBL_BASE_FREQ + #undef TBL_CHNL + static int ov511_reg_read(int fd, int reg) { struct usb_ctl_request ur; unsigned char data[1024]; ! ur.ucr_request.bmRequestType = UT_READ_VENDOR_INTERFACE; ! ur.ucr_request.bRequest = 2; ! USETW(ur.ucr_request.wValue, 0); /* unused */ ! USETW(ur.ucr_request.wIndex, reg); /* index */ ! USETW(ur.ucr_request.wLength, 1); /* payload len in bytes */ ! ur.ucr_data = data; ! ur.ucr_flags = 0; ! ur.ucr_actlen = 0; if(ioctl(fd, USB_DO_REQUEST, &ur) < 0) { return -1; *************** *** 72,86 **** data[0] = val; ! ur.request.bmRequestType = UT_WRITE_VENDOR_INTERFACE; ! ur.request.bRequest = 2; ! USETW(ur.request.wValue, 0); /* unused */ ! USETW(ur.request.wIndex, reg); /* index */ ! USETW(ur.request.wLength, 1); /* payload len in bytes */ ! ur.data = data; ! ur.flags = 0; ! ur.actlen = 0; if(ioctl(fd, USB_DO_REQUEST, &ur) < 0) { return -1; --- 117,131 ---- data[0] = val; ! ur.ucr_request.bmRequestType = UT_WRITE_VENDOR_INTERFACE; ! ur.ucr_request.bRequest = 2; ! USETW(ur.ucr_request.wValue, 0); /* unused */ ! USETW(ur.ucr_request.wIndex, reg); /* index */ ! USETW(ur.ucr_request.wLength, 1); /* payload len in bytes */ ! ur.ucr_data = data; ! ur.ucr_flags = 0; ! ur.ucr_actlen = 0; if(ioctl(fd, USB_DO_REQUEST, &ur) < 0) { return -1; *************** *** 156,161 **** --- 201,243 ---- } static int + ov511_i2c_read2(int fd) { + int status = 0; + int val = 0; + int retries = OV7610_I2C_RETRIES; + + while(--retries >= 0) { + /* initiate read */ + if(ov511_reg_write(fd, OV511_REG_I2C_CONTROL, 0x05) < 0) + return -1; + + /* wait until bus idle */ + do { + if((status = ov511_reg_read(fd, OV511_REG_I2C_CONTROL)) < 0) + return -1; + } while ((status & 0x01) == 0); + + if((status & 0x2) == 0) + break; + + /* abort I2C bus before retrying */ + if(ov511_reg_write(fd, OV511_REG_I2C_CONTROL, 0x10) < 0) + return -1; + } + if(retries < 0) + return -1; + + /* retrieve data */ + val = ov511_reg_read(fd, OV511_REG_SDA); + + /* issue another read for some weird reason */ + if(ov511_reg_write(fd, OV511_REG_I2C_CONTROL, 0x05) < 0) + return -1; + + return val; + } + + static int ov511_i2c_write(int fd, int reg, int val) { int status = 0; int retries = OV7610_I2C_RETRIES; *************** *** 184,189 **** --- 266,423 ---- return -1; } + int + settv(int fd, int ch) + { + int control = 0xce; + int band; + int frequency, N; + + /* set I2C write slave ID for FI1236MK2(tuner) */ + if(ov511_reg_write(fd, OV511_REG_SID, FI1236MK2_I2C_WRITE_ID) < 0) + exit(1); + if(ov511_reg_write(fd, OV511_REG_SRA, FI1236MK2_I2C_READ_ID) < 0) + exit(1); + + if(ov511_i2c_read2(fd) < 0) + exit(1); + + frequency = frequency_lookup(ch); + + if ( frequency < (160 * FREQFACTOR ) ) + band = 0xa0; + else if ( frequency < (454 * FREQFACTOR ) ) + band = 0x90; + else + band = 0x30; + + N = frequency + (int)(45.75 * 16); + + fprintf(stderr, "tuner = %02x %02x\n", (N >> 8) & 0x7f, N & 0xff); + + ov511_i2c_write(fd, (N >> 8) & 0x7f, N & 0xff); + // if(ov511_i2c_read2(fd) < 0) + // exit(1); + + ov511_i2c_write(fd, control, band); + // if(ov511_i2c_read2(fd) < 0) + // exit(1); + + /* reset the OV511 */ + if(ov511_reg_write(fd, OV511_REG_RST, 0x03) < 0) + exit(1); + + return 1; + } + + /* Compression stuff */ + + #define OV511_QUANTABLESIZE 64 + #define OV518_QUANTABLESIZE 32 + + #define OV511_YQUANTABLE { \ + 0, 1, 1, 2, 2, 3, 3, 4, \ + 1, 1, 1, 2, 2, 3, 4, 4, \ + 1, 1, 2, 2, 3, 4, 4, 4, \ + 2, 2, 2, 3, 4, 4, 4, 4, \ + 2, 2, 3, 4, 4, 5, 5, 5, \ + 3, 3, 4, 4, 5, 5, 5, 5, \ + 3, 4, 4, 4, 5, 5, 5, 5, \ + 4, 4, 4, 4, 5, 5, 5, 5 \ + } + + #define OV511_UVQUANTABLE { \ + 0, 2, 2, 3, 4, 4, 4, 4, \ + 2, 2, 2, 4, 4, 4, 4, 4, \ + 2, 2, 3, 4, 4, 4, 4, 4, \ + 3, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4 \ + } + + #define ENABLE_Y_QUANTABLE 1 + #define ENABLE_UV_QUANTABLE 1 + + static unsigned char yQuanTable511[] = OV511_YQUANTABLE; + static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE; + + static int + ov511_upload_quan_tables(int fd) + { + unsigned char *pYTable = yQuanTable511; + unsigned char *pUVTable = uvQuanTable511; + unsigned char val0, val1; + int i, rc, reg = OV511_REG_LT_V; + + for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) + { + if (ENABLE_Y_QUANTABLE) + { + val0 = *pYTable++; + val1 = *pYTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = ov511_reg_write(fd, reg, val0); + if (rc < 0) + return rc; + } + + if (ENABLE_UV_QUANTABLE) + { + val0 = *pUVTable++; + val1 = *pUVTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = ov511_reg_write(fd, reg + OV511_QUANTABLESIZE/2, val0); + if (rc < 0) + return rc; + } + + reg++; + } + + return 0; + } + + int tmpsize = 0; + u_char tmpbuf[1024*128]; /* isochronous input read buffer */ + + framecpy(u_char *buffer, int offset, int size) + { + int b, in = 0, allzero, copied=0; + + if (offset) { + memmove(tmpbuf + tmpsize, + buffer + offset, 32 - offset); + tmpsize += 32 - offset; // Bytes out + in = 32; + } + + while (in < size - 1) { + allzero = 1; + for (b = 0; b < 32; b++) { + if (buffer[in + b]) { + allzero = 0; + break; + } + } + + if (allzero) { + /* Don't copy it */ + } else { + memmove(tmpbuf + tmpsize, + &buffer[in], 32); + tmpsize += 32; + } + + in += 32; + } + } + struct vidstate { enum {SKIPPING, READING, DONE} state; int width, height; /* image dimensions */ *************** *** 194,205 **** int iY, jY; /* current horizontal/vertical Y coords */ int iUV, jUV; /* current horizontal/vertical UV coords */ ! u_char buf[2048]; /* segment data being processed */ int residue; /* left over from last processing run */ }; static void procdata(struct vidstate *vsp, u_char *data, size_t len); static void progsegment(struct vidstate *vsp, u_char *data); static void postproc(struct vidstate *vsp); --- 428,444 ---- int iY, jY; /* current horizontal/vertical Y coords */ int iUV, jUV; /* current horizontal/vertical UV coords */ ! // u_char buf[2048]; /* segment data being processed */ ! u_char buf[1024*512]; /* segment data being processed */ int residue; /* left over from last processing run */ }; + #if !(USECOMPRESS) static void procdata(struct vidstate *vsp, u_char *data, size_t len); static void progsegment(struct vidstate *vsp, u_char *data); + #else + static void procdata(struct vidstate *vsp, u_char *data); + #endif static void postproc(struct vidstate *vsp); *************** *** 210,215 **** --- 449,455 ---- struct usb_alt_interface alt; /* interface/alternate selection */ int cid = -1; /* OV511 camera ID */ u_char buf[1024]; /* isochronous input read buffer */ + u_char tmpbuf2[1024*512]; /* isochronous input read buffer */ char dev[FILENAME_MAX]; /* for constructing device names */ char isocdev[FILENAME_MAX]; /* for constructing endpoint 1 device names */ char *devname = NULL; /* device name */ *************** *** 217,222 **** --- 457,465 ---- struct vidstate vs; /* current read state */ int small = 0; /* use 320x240 */ int frmnm = 0; /* cyclic frame number key */ + int channel = 1; + int input = 0; + int fifosize; /* pnm_init(&argc, argv); */ /* required for PNM programs? */ *************** *** 268,273 **** --- 511,531 ---- " [-d device] [--device-name=device]\n"); exit(1); } + } else if((*argv)[0] == '-' && (*argv)[1] == 'c') { + if((*argv)[2] != '\0') { + channel = atoi(*argv + 2); + } else if(argc > 0) { + channel = atoi(*++argv); + --argc; + } else { + fprintf(stderr, "usage: vid [--version] [--usage] [--help] [--small]\n" + " [-d device] [--device-name=device]\n"); + exit(1); + } + } else if((*argv)[0] == '-' && (*argv)[1] == 't') { + input = 1; + } else if((*argv)[0] == '-' && (*argv)[1] == 's') { + input = 2; } else { fprintf(stderr, "usage: vid [--version] [--usage] [--help] [--small]\n" " [-d device] [--device-name=device]\n"); *************** *** 287,293 **** exit(1); } ! if(udi.vendorNo != 0x05A9 || udi.productNo != 0x0511) { fprintf(stderr, "device %s is not an OmniVision OV511\n", devname); exit(1); } --- 545,552 ---- exit(1); } ! if(udi.udi_vendorNo != 0x05A9 || (udi.udi_productNo != 0x0511 && ! udi.udi_productNo != 0xa511)) { fprintf(stderr, "device %s is not an OmniVision OV511\n", devname); exit(1); } *************** *** 298,304 **** if((fd = open(dev, O_RDWR)) < 0) continue; if(ioctl(fd, USB_GET_DEVICEINFO, &udi) < 0 ! || udi.vendorNo != 0x05A9 || udi.productNo != 0x0511) { close(fd); fd = -1; continue; --- 557,564 ---- if((fd = open(dev, O_RDWR)) < 0) continue; if(ioctl(fd, USB_GET_DEVICEINFO, &udi) < 0 ! || udi.udi_vendorNo != 0x05A9 || (udi.udi_productNo != 0x0511 && ! udi.udi_productNo != 0xa511)) { close(fd); fd = -1; continue; *************** *** 314,320 **** devname = dev; } ! /* reset the OV511 */ if(ov511_reg_write(fd, OV511_REG_RST, 0x7f) < 0) exit(1); --- 574,593 ---- devname = dev; } ! ! #if 0 ! { int i; ! for(i=0x10;i<=0x23; ++i) ! printf("%02x = %02x\n", i, ov511_reg_read(fd, i)); ! for(i=0x30;i<=0x31; ++i) ! printf("%02x = %02x\n", i, ov511_reg_read(fd, i)); ! for(i=0x50;i<=0x53; ++i) ! printf("%02x = %02x\n", i, ov511_reg_read(fd, i)); ! ! return 0; ! } ! #endif ! /* reset the OV511 */ if(ov511_reg_write(fd, OV511_REG_RST, 0x7f) < 0) exit(1); *************** *** 343,348 **** --- 616,624 ---- case 5: /* fprintf(stderr, "vid: Puretek PT-6007\n"); */ break; + case 6: + /* fprintf(stderr, "vid: Lifeview USB Life TV (NTSC)\n"); */ + break; case 21: /* fprintf(stderr, "vid: Creative Labs WebCam 3\n"); */ break; *************** *** 362,368 **** fprintf(stderr, "vid: Camera custom ID %d not recognized\n", cid); exit(1); } ! /* set I2C write slave ID for OV7601 */ if(ov511_reg_write(fd, OV511_REG_SID, OV7610_I2C_WRITE_ID) < 0) exit(1); --- 638,687 ---- fprintf(stderr, "vid: Camera custom ID %d not recognized\n", cid); exit(1); } ! ! #if 0 ! { ! int i; ! for(i = 0; i <= 0xff; ++i) { ! if(ov511_reg_write(fd, OV511_REG_SID, i) < 0) ! exit(1); ! if(ov511_reg_write(fd, OV511_REG_SRA, i+1) < 0) ! exit(1); ! if(i % 16 == 0) ! fprintf(stderr, "%1x : ", i >> 4); ! fprintf(stderr, "%02x ", ov511_i2c_read2(fd)); ! ++i; ! if(i % 16 == 15) ! fprintf(stderr, "\n"); ! } ! } ! #endif ! ! if(input == 1) ! settv(fd, channel); ! ! /* set I2C write slave ID for PT2313L(audio) */ ! if(ov511_reg_write(fd, OV511_REG_SID, PT2313L_I2C_WRITE_ID) < 0) ! ! /* set I2C read slave ID for PT2313L(audio) */ ! if(ov511_reg_write(fd, OV511_REG_SRA, PT2313L_I2C_READ_ID) < 0) ! exit(1); ! ! // ov511_i2c_read2(fd); ! ! ov511_i2c_write(fd, 0x24, 0x43); ! ov511_i2c_write(fd, 0x80, 0xa0); ! ov511_i2c_write(fd, 0xc0, 0xe0); ! ! #if SAA7111A ! /* set I2C write slave ID for SAA7111A */ ! if(ov511_reg_write(fd, OV511_REG_SID, SAA7111A_I2C_WRITE_ID) < 0) ! exit(1); ! ! /* set I2C read slave ID for SAA7111A */ ! if(ov511_reg_write(fd, OV511_REG_SRA, SAA7111A_I2C_READ_ID) < 0) ! exit(1); ! #else /* set I2C write slave ID for OV7601 */ if(ov511_reg_write(fd, OV511_REG_SID, OV7610_I2C_WRITE_ID) < 0) exit(1); *************** *** 370,375 **** --- 689,695 ---- /* set I2C read slave ID for OV7601 */ if(ov511_reg_write(fd, OV511_REG_SRA, OV7610_I2C_READ_ID) < 0) exit(1); + #endif if(ov511_reg_write(fd, OV511_REG_PKSZ, 0x1) < 0) exit(1); *************** *** 398,403 **** --- 718,769 ---- if(ov511_reg_write(fd, OV511_REG_CE_EN, 0x0) < 0) exit(1); + #if SAA7111A + /* Horizontal sync be gin */ + ov511_i2c_write(fd, 0x06, 0xce); + /* Horizontal sync stop */ + ov511_i2c_write(fd, 0x07, 0x00); + /* Format/Delay control */ + /* ov511_i2c_write(fd, 0x10, 0x44); /* YUV 422 16 bits */ + ov511_i2c_write(fd, 0x10, 0x44); /* YUV 422 16 bits */ + ov511_i2c_write(fd, 0x0e, 0x01); + ov511_i2c_write(fd, 0x00, 0x00); + ov511_i2c_write(fd, 0x01, 0x00); + ov511_i2c_write(fd, 0x03, 0x23); + ov511_i2c_write(fd, 0x04, 0x00); + ov511_i2c_write(fd, 0x05, 0x00); + ov511_i2c_write(fd, 0x08, 0xc8); + ov511_i2c_write(fd, 0x09, 0x01); + + /* Luminace brightness control = 128(CCIR level) */ + /* ov511_i2c_write(fd, 0x0a, 0x80);*/ + ov511_i2c_write(fd, 0x0a, 0x95); + /* Luminace contrast control = 1.0 */ + /* ov511_i2c_write(fd, 0x0b, 0x40);*/ + ov511_i2c_write(fd, 0x0b, 0x48); + /* Chrominance saturation control = 1.0(CCIR level) */ + ov511_i2c_write(fd, 0x0c, 0x50); + /* Chrominance hue control = 0 */ + ov511_i2c_write(fd, 0x0d, 0x00); + ov511_i2c_write(fd, 0x0f, 0x00); + /* COLO = 0; VIPB = 0; OEHV = 1; OEVC = 1; + COMPO = 0; FECO = 0; CM99 = 0; GPW = 0 */ + ov511_i2c_write(fd, 0x11, 0x0c); + ov511_i2c_write(fd, 0x12, 0x00); + ov511_i2c_write(fd, 0x13, 0x00); + ov511_i2c_write(fd, 0x14, 0x00); + ov511_i2c_write(fd, 0x15, 0x00); + ov511_i2c_write(fd, 0x16, 0x00); + ov511_i2c_write(fd, 0x17, 0x00); + if(input == 0) + ov511_i2c_write(fd, 0x02, 0xc0); /* Mode 0 */ + else if(input == 1) + ov511_i2c_write(fd, 0x02, 0xc2); /* Mode 2 */ + else + ov511_i2c_write(fd, 0x02, 0xc7); /* Mode 7 */ + + fprintf(stderr, "SAA7111A status = %02x\n", ov511_i2c_read(fd, 0x1f)); + #else ov511_i2c_write(fd, OV7610_REG_RWB, 0x5); ov511_i2c_write(fd, OV7610_REG_EC, 0xFF); ov511_i2c_write(fd, OV7610_REG_COMB, 0x01); *************** *** 415,462 **** ov511_i2c_write(fd, OV7610_REG_COMK, 0x81); ov511_i2c_write(fd, OV7610_REG_GAM, 0x04); if(small) { vs.width = 320; vs.height = 240; ! ov511_reg_write(fd, OV511_REG_PXCNT, 0x27); ! ov511_reg_write(fd, OV511_REG_LNCNT, 0x1D); ov511_i2c_write(fd, OV7610_REG_SYN_CLK, 0x01); ov511_i2c_write(fd, OV7610_REG_COMA, 0x04); ov511_i2c_write(fd, OV7610_REG_COMC, 0x24); ov511_i2c_write(fd, OV7610_REG_COML, 0x9e); } else { vs.width = 640; vs.height = 480; ! ov511_reg_write(fd, OV511_REG_PXCNT, 0x4F); ! ov511_reg_write(fd, OV511_REG_LNCNT, 0x3D); ov511_i2c_write(fd, OV7610_REG_SYN_CLK, 0x06); ov511_i2c_write(fd, OV7610_REG_HE, 0x3a + (640>>2)); ov511_i2c_write(fd, OV7610_REG_VE, 5 + (480>>1)); ov511_i2c_write(fd, OV7610_REG_COMA, 0x24); ov511_i2c_write(fd, OV7610_REG_COMC, 0x04); ov511_i2c_write(fd, OV7610_REG_COML, 0x1e); } ov511_reg_write(fd, OV511_REG_PXDV, 0x00); ov511_reg_write(fd, OV511_REG_LNDV, 0x00); /* set FIFO format (993-byte packets) */ if(ov511_reg_write(fd, OV511_REG_PKSZ, 0x1F) < 0) exit(1); if(ov511_reg_write(fd, OV511_REG_PKFMT, 0x03) < 0) exit(1); /* select the 993-byte alternative */ ! alt.interface_index = 0; ! alt.alt_no = 1; if(ioctl(fd, USB_SET_ALTINTERFACE, &alt) < 0) { perror("USB_SET_ALTINTERFACE"); exit(1); } /* reset the device again */ ! if(ov511_reg_write(fd, OV511_REG_RST, 0x3F) < 0) exit(1); --- 781,876 ---- ov511_i2c_write(fd, OV7610_REG_COMK, 0x81); ov511_i2c_write(fd, OV7610_REG_GAM, 0x04); + #endif + + #if SAA7111A + ov511_reg_write(fd, OV511_REG_DLYM, 0x00); + ov511_reg_write(fd, OV511_REG_PEM, 0x00); + #endif if(small) { vs.width = 320; vs.height = 240; ! ov511_reg_write(fd, OV511_REG_PXCNT, (vs.width >> 3) - 1); ! ov511_reg_write(fd, OV511_REG_LNCNT, (vs.height >> 3) - 1); ! #if SAA7111A ! #else ov511_i2c_write(fd, OV7610_REG_SYN_CLK, 0x01); ov511_i2c_write(fd, OV7610_REG_COMA, 0x04); ov511_i2c_write(fd, OV7610_REG_COMC, 0x24); ov511_i2c_write(fd, OV7610_REG_COML, 0x9e); + #endif } else { vs.width = 640; vs.height = 480; ! ov511_reg_write(fd, OV511_REG_PXCNT, (vs.width >> 3) - 1); ! ov511_reg_write(fd, OV511_REG_LNCNT, (vs.height >> 3) - 1); ! #if SAA7111A ! #else ov511_i2c_write(fd, OV7610_REG_SYN_CLK, 0x06); ov511_i2c_write(fd, OV7610_REG_HE, 0x3a + (640>>2)); ov511_i2c_write(fd, OV7610_REG_VE, 5 + (480>>1)); ov511_i2c_write(fd, OV7610_REG_COMA, 0x24); ov511_i2c_write(fd, OV7610_REG_COMC, 0x04); ov511_i2c_write(fd, OV7610_REG_COML, 0x1e); + #endif } + #if USECOMPRESS + ov511_upload_quan_tables(fd); + ov511_reg_write(fd, OV511_REG_CE_EN, 0x07); + ov511_reg_write(fd, OV511_REG_LT_EN, 0x03); + #endif + ov511_reg_write(fd, OV511_REG_PXDV, 0x00); ov511_reg_write(fd, OV511_REG_LNDV, 0x00); + #if OV511PLUS + ov511_reg_write(fd, OV511_REG_ENFC, 0xFF); + #endif + + #if OV511PLUS + /* set FIFO format (961-byte packets) */ + if(ov511_reg_write(fd, OV511_REG_PKSZ, 0x1E) < 0) + exit(1); + if(ov511_reg_write(fd, OV511_REG_PKFMT, 0xFF) < 0) + exit(1); + fifosize = 961; + #else /* set FIFO format (993-byte packets) */ if(ov511_reg_write(fd, OV511_REG_PKSZ, 0x1F) < 0) exit(1); if(ov511_reg_write(fd, OV511_REG_PKFMT, 0x03) < 0) exit(1); + fifosize = 993; + #endif /* select the 993-byte alternative */ ! alt.uai_interface_index = 0; ! #if OV511PLUS ! alt.uai_alt_no = 7; ! #else ! alt.uai_alt_no = 1; ! #endif if(ioctl(fd, USB_SET_ALTINTERFACE, &alt) < 0) { perror("USB_SET_ALTINTERFACE"); exit(1); } + + #if OV511PLUS + if(ov511_reg_write(fd, OV511_REG_SNAP, 0x01) < 0) + exit(1); + if(ov511_reg_write(fd, OV511_REG_SNAP, 0x03) < 0) + exit(1); + if(ov511_reg_write(fd, OV511_REG_SNAP, 0x01) < 0) + exit(1); + /* if(ov511_reg_write(fd, OV511_REG_EN_SYS, 0x01) < 0) + exit(1);*/ + #endif + /* reset the device again */ ! if(ov511_reg_write(fd, OV511_REG_RST, 0x3F) < 0) exit(1); *************** *** 474,509 **** exit(1); } /* read, looking for start and end frames */ ! while(vs.state != DONE && (len = read(isoc, &buf, 993)) >= 0) { if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 ! && (buf[8] & 0x80) == 0 && buf[992] == 0 && vs.state == SKIPPING) { vs.state = READING; vs.iY = vs.jY = vs.iUV = vs.jUV = 0; vs.residue = 0; ! procdata(&vs, buf + 9, 993 - 10); } else if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 ! && (buf[8] & 0x80) == 0x80 && buf[992] == 0 && vs.state == READING) { vs.state = DONE; } else if(vs.state == READING) { ! procdata(&vs, buf, 993 - 1); ! /* abort the capture and start over if packets come in out-of-order */ ! if(buf[992] != frmnm && buf[992] != 1) { vs.state = SKIPPING; } ! frmnm = buf[992] + 1; if(frmnm == 256) frmnm = 1; ! } else if(buf[992] != 0) { ! frmnm = buf[992] + 1; if(frmnm == 256) frmnm = 1; } } close(isoc); close(fd); --- 888,986 ---- exit(1); } + /* + {int i; + for(i = 0; i < 121*6*5; ++i) { + vs.state = SKIPPING; + */ + /* read, looking for start and end frames */ ! while(vs.state != DONE && (len = read(isoc, &buf, fifosize)) >= 0) { ! ! fprintf(stderr, "buf[8] = %02x buf[9] = %d buf[10] = %d buf[%d] = %02x buf[%d] = %02x\n", ! buf[8], buf[9], buf[10], ! fifosize-2, buf[fifosize-2], fifosize-1, buf[fifosize-1]); ! ! #if !(USECOMPRESS) if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 ! && (buf[8] & 0x80) == 0 && buf[fifosize-1] == 0 && vs.state == SKIPPING) { vs.state = READING; vs.iY = vs.jY = vs.iUV = vs.jUV = 0; vs.residue = 0; ! procdata(&vs, buf + 9, fifosize - 10); } else if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 ! && (buf[8] & 0x80) == 0x80 && buf[fifosize-1] == 0 && vs.state == READING) { vs.state = DONE; } else if(vs.state == READING) { ! procdata(&vs, buf, fifosize - 1); /* abort the capture and start over if packets come in out-of-order */ ! if(buf[fifosize-1] != frmnm && buf[fifosize-1] != 1) { vs.state = SKIPPING; } ! frmnm = buf[fifosize-1] + 1; if(frmnm == 256) frmnm = 1; ! } else if(buf[fifosize-1] != 0) { ! frmnm = buf[fifosize-1] + 1; if(frmnm == 256) frmnm = 1; } + #else + if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 + && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 + && (buf[8] & 0x48) == 0x48 && buf[fifosize-1] == 0 && vs.state == SKIPPING) { + vs.state = READING; + framecpy(buf, 9, len - 1); + } else if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 + && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 + && (buf[8] & 0xc8) == 0xc8 && vs.state == READING) { + framecpy(buf, 11, len - 1); + { + FILE *fp; + fp = fopen("rawdata.dat", "w"); + fwrite(tmpbuf, 1, tmpsize, fp); + fclose(fp); + } + fprintf(stderr, "tmpsize = %d\n", tmpsize); + len = Decompress420(tmpbuf, tmpbuf2, vs.width, vs.height, tmpsize); + fprintf(stderr, "Decomp = %d\n", len); + procdata(&vs, tmpbuf2); + + { + int i; + fprintf(stderr, "Y dump\n"); + for(i = 0; i < 128; ++i) { + fprintf(stderr, "%02x ", tmpbuf2[i]); + if(i % 16 == 15) + fprintf(stderr, "\n"); + } + fprintf(stderr, "U dump\n"); + for(i = 0; i < 32; ++i) { + fprintf(stderr, "%02x ", tmpbuf2[76800+i]); + if(i % 16 == 15) + fprintf(stderr, "\n"); + } + fprintf(stderr, "V dump\n"); + for(i = 0; i < 32; ++i) { + fprintf(stderr, "%02x ", tmpbuf2[96000+i]); + if(i % 16 == 15) + fprintf(stderr, "\n"); + } + } + + vs.state = DONE; + } else if(vs.state == READING) { + framecpy(buf, 0, len - 1); + } + #endif } + fprintf(stderr, "len = %d done = %d\n", len, vs.state == DONE); + /* + }} + */ close(isoc); close(fd); *************** *** 517,522 **** --- 994,1000 ---- exit(0); } + #if !(USECOMPRESS) static void procdata(struct vidstate *vsp, u_char *data, size_t datalen) { size_t len = vsp->residue + datalen; *************** *** 579,585 **** int i, j, k; u_char *Up = data, *Vp = data + 64, *Yp = data + 128; xel *xp; ! for(j = 0; j < 8; ++j) { xp = vsp->xels[vsp->jUV + j * 2] + vsp->iUV; --- 1057,1065 ---- int i, j, k; u_char *Up = data, *Vp = data + 64, *Yp = data + 128; xel *xp; ! /* ! fprintf(stderr, "%02x %02x\n", *Up, *Vp); ! */ for(j = 0; j < 8; ++j) { xp = vsp->xels[vsp->jUV + j * 2] + vsp->iUV; *************** *** 604,609 **** --- 1084,1121 ---- } } } + #else + static void procdata(struct vidstate *vsp, u_char *data) { + int i, j, k; + u_char *Up = data + 76800, *Vp = data + 96000, *Yp = data; + xel *xp; + /* + fprintf(stderr, "%02x %02x\n", *Up, *Vp); + */ + for(j = 0; j < vsp->height/2; ++j) { + // xp = vsp->xels[vsp->jUV + j * 2] + vsp->iUV; + xp = vsp->xels[j*2]; + + for(i = 0; i < vsp->width/2; ++i) { + PPM_ASSIGN(*xp, *Up, PPM_GETG(*xp), *Vp); + Up++; + Vp++; + xp += 2; + } + } + + for(j = 0; j < vsp->height; ++j) { + // xp = vsp->xels[vsp->jY + j] + vsp->iY; + xp = vsp->xels[j]; + + for(i = 0; i < vsp->width; ++i) { + PPM_ASSIGN(xp[0], PPM_GETR(xp[0]), Yp[0], PPM_GETB(xp[0])); + Yp++; + xp++; + } + } + } + #endif #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16))) *************** *** 615,624 **** --- 1127,1143 ---- const double brightness = 1.0; /* 0->black; 1->full scale */ const double saturation = 1.0; /* 0->greyscale; 1->full color */ const double fixScale = brightness * 256 * 256; + #if 0 const int rvScale = (int)(1.402 * saturation * fixScale); const int guScale = (int)(-0.344136 * saturation * fixScale); const int gvScale = (int)(-0.714136 * saturation * fixScale); const int buScale = (int)(1.772 * saturation * fixScale); + #else + const int rvScale = (int)(1.371 * saturation * fixScale); + const int guScale = (int)(-0.336 * saturation * fixScale); + const int gvScale = (int)(-0.698 * saturation * fixScale); + const int buScale = (int)(1.732 * saturation * fixScale); + #endif const int yScale = (int)(fixScale); for(j = 0; j < vsp->height; j += 2) { *************** *** 637,653 **** int r = rvScale * v; int g = guScale * u + gvScale * v; int b = buScale * u; ! PPM_ASSIGN(xp[0], LIMIT(r+yTL), LIMIT(g+yTL), LIMIT(b+yTL)); PPM_ASSIGN(xp[1], LIMIT(r+yTR), LIMIT(g+yTR), LIMIT(b+yTR)); PPM_ASSIGN(xq[0], LIMIT(r+yBL), LIMIT(g+yBL), LIMIT(b+yBL)); PPM_ASSIGN(xq[1], LIMIT(r+yBR), LIMIT(g+yBR), LIMIT(b+yBR)); ! xp += 2; xq += 2; } } - if(vsp->width > 400) { for(j = 0; j < vsp->height - 1; ++j) { xp = vsp->xels[j]; --- 1156,1176 ---- int r = rvScale * v; int g = guScale * u + gvScale * v; int b = buScale * u; ! /* ! fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n", ! yTL, yTR, yBL, yBR, u, v); ! */ PPM_ASSIGN(xp[0], LIMIT(r+yTL), LIMIT(g+yTL), LIMIT(b+yTL)); PPM_ASSIGN(xp[1], LIMIT(r+yTR), LIMIT(g+yTR), LIMIT(b+yTR)); PPM_ASSIGN(xq[0], LIMIT(r+yBL), LIMIT(g+yBL), LIMIT(b+yBL)); PPM_ASSIGN(xq[1], LIMIT(r+yBR), LIMIT(g+yBR), LIMIT(b+yBR)); ! /* ! printf("%02x %02x %02x\n", LIMIT(r+yTR),LIMIT(g+yTR),LIMIT(b+yTR)); ! */ xp += 2; xq += 2; } } if(vsp->width > 400) { for(j = 0; j < vsp->height - 1; ++j) { xp = vsp->xels[j]; *** vid.h.org Mon May 8 13:59:03 2000 --- vid.h Fri May 17 00:56:32 2002 *************** *** 49,54 **** --- 49,55 ---- #define OV511_REG_QTV_UV 0x77 #define OV511_REG_CE_EN 0x78 #define OV511_REG_LT_EN 0x79 + #define OV511_REG_LT_V 0x80 #define OV7610_REG_GC 0x00 #define OV7610_REG_BLU 0x01 *************** *** 99,101 **** --- 100,112 ---- #define OV7610_I2C_RETRIES 3 #define OV7610_I2C_CLOCK_DIV 4 + + #define SAA7111A_I2C_WRITE_ID 0x48 + #define SAA7111A_I2C_READ_ID 0x49 + + #define FI1236MK2_I2C_WRITE_ID 0xC2 + #define FI1236MK2_I2C_READ_ID 0xC3 + + #define PT2313L_I2C_WRITE_ID 0x4A + #define PT2313L_I2C_READ_ID 0x4B + *** /home/mori/src/ov511-1.50/ov511_decomp.c Mon Dec 24 19:32:52 2001 --- ov511_decomp.c Thu May 9 11:45:28 2002 *************** *** 23,28 **** --- 23,29 ---- * */ + #if !(__FreeBSD__) #include /* Begin module versioning code */ *************** *** 88,93 **** --- 89,95 ---- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10) MODULE_LICENSE("GPL"); #endif + #endif static void DecompressYHI(unsigned char *pIn, *************** *** 1169,1175 **** --- 1171,1179 ---- int numpix = w * h; int rc; + #if !(__FreeBSD__) PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize); + #endif rc = Decompress400HiNoMMX(pIn, pOut, w, h, inSize); *************** *** 1185,1191 **** --- 1189,1199 ---- * Output format is planar YUV420 * Returns uncompressed data length if success, or zero if error */ + #if !(__FreeBSD__) static int + #else + int + #endif Decompress420(unsigned char *pIn, unsigned char *pOut, int w, *************** *** 1195,1201 **** --- 1203,1211 ---- int numpix = w * h; int rc; + #if !(__FreeBSD__) PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize); + #endif rc = Decompress420HiNoMMX(pIn, pOut, w, h, inSize); *************** *** 1229,1234 **** --- 1239,1245 ---- return (numpix * 3 / 2); } + #if !(__FreeBSD__) static void DecompLock(void) { *************** *** 1276,1278 **** --- 1287,1290 ---- module_init(decomp_init); module_exit(decomp_exit); + #endif