123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- $OpenBSD: patch-vid_c,v 1.4 2016/04/26 18:06:26 jca Exp $
- --- vid.c.orig Mon May 8 06:59:03 2000
- +++ vid.c Tue Apr 26 15:50:06 2016
- @@ -37,7 +37,7 @@
-
- #include <dev/usb/usb.h>
-
- -#include <pnm.h>
- +#include <netpbm/pnm.h>
-
- #include "vid.h"
-
- @@ -48,15 +48,15 @@ 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;
- + ur.ucr_request.bmRequestType = UT_READ_VENDOR_INTERFACE;
- + ur.ucr_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;
- + 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,15 +72,15 @@ ov511_reg_write(int fd, int reg, int val) {
-
- data[0] = val;
-
- - ur.request.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- - ur.request.bRequest = 2;
- + ur.ucr_request.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- + ur.ucr_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;
- + 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;
- @@ -213,16 +213,23 @@ main(int argc, char *argv[]) {
- char dev[FILENAME_MAX]; /* for constructing device names */
- char isocdev[FILENAME_MAX]; /* for constructing endpoint 1 device names */
- char *devname = NULL; /* device name */
- + char *p = NULL; /* for string ops */
- + int slen = -1; /* string length holder */
- + int plen = -1; /* string length holder */
- int len = -1; /* isochronous input read length */
- struct vidstate vs; /* current read state */
- int small = 0; /* use 320x240 */
- int frmnm = 0; /* cyclic frame number key */
- + int isplus; /* bridge is OV511+ if true, else OV511 */
- + int is20; /* sensor is OV7620 if true, else OV7610 */
- + int bufsize; /* size of packet buffer */
-
- +
- /* pnm_init(&argc, argv); */ /* required for PNM programs? */
-
- while(++argv, --argc) {
- if(strcmp(*argv, "--version") == 0) {
- - fprintf(stderr, "OV511 capture program version " VERSION
- + fprintf(stderr, "OV511/OV511+ capture program version " VERSION
- "\nCopyright 2000 Peter S. Housel"
- "\nThis program is free software; "
- "you may redistribute it under the terms of"
- @@ -235,7 +242,7 @@ main(int argc, char *argv[]) {
- exit(0);
- } else if(strcmp(*argv, "--help") == 0) {
- fprintf(stderr, "usage: vid [options]\n"
- - "Capture an image frame from an OV511-based USB video camera\n"
- + "Capture an image frame from an OV511/OV511+ based USB video camera\n"
- "and write image data to standard output in PNM format\n\n"
- "--version print program version information\n"
- "--usage summarize command line options\n"
- @@ -243,6 +250,7 @@ main(int argc, char *argv[]) {
- "--small capture as 320x240 image (default is 640x480)\n"
- "-d device, --device-name=device\n"
- " specify OV511 ugen device\n");
- + fprintf(stderr, "example: vid | pnmtojpeg > ~/public_html/mywebcam.jpg\n");
- exit(0);
- } else if(strcmp(*argv, "--small") == 0) {
- small = 1;
- @@ -287,18 +295,21 @@ main(int argc, char *argv[]) {
- exit(1);
- }
-
- - if(udi.vendorNo != 0x05A9 || udi.productNo != 0x0511) {
- - fprintf(stderr, "device %s is not an OmniVision OV511\n", devname);
- + if(udi.udi_vendorNo != 0x05A9 ||
- + (udi.udi_productNo != 0x0511 && udi.udi_productNo != 0xa511)) {
- + fprintf(stderr, "device %s is not an OmniVision OV511/OV511+\n", devname);
- exit(1);
- }
- } else {
- int i = 0;
- for(i = 0; i < 15; ++i) {
- - sprintf(dev, "/dev/ugen%d", i);
- + snprintf(dev, sizeof(dev), "/dev/ugen%d.00", i);
- if((fd = open(dev, O_RDWR)) < 0)
- continue;
- - if(ioctl(fd, USB_GET_DEVICEINFO, &udi) < 0
- - || udi.vendorNo != 0x05A9 || udi.productNo != 0x0511) {
- + 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;
- @@ -308,12 +319,15 @@ main(int argc, char *argv[]) {
- }
-
- if(fd < 0) {
- - fprintf(stderr, "vid: couldn't locate an OV511 device\n");
- + fprintf(stderr, "vid: couldn't locate an OV511/OV511+ device\n");
- exit(1);
- }
-
- devname = dev;
- }
- +
- + isplus = udi.udi_productNo == 0xa511;
- + bufsize = (isplus ? 961 : 993);
-
- /* reset the OV511 */
- if(ov511_reg_write(fd, OV511_REG_RST, 0x7f) < 0)
- @@ -398,24 +412,57 @@ main(int argc, char *argv[]) {
- if(ov511_reg_write(fd, OV511_REG_CE_EN, 0x0) < 0)
- exit(1);
-
- - ov511_i2c_write(fd, OV7610_REG_RWB, 0x5);
- - ov511_i2c_write(fd, OV7610_REG_EC, 0xFF);
- - ov511_i2c_write(fd, OV7610_REG_COMB, 0x01);
- - ov511_i2c_write(fd, OV7610_REG_FD, 0x06);
- - ov511_i2c_write(fd, OV7610_REG_COME, 0x1c);
- - ov511_i2c_write(fd, OV7610_REG_COMF, 0x90);
- - ov511_i2c_write(fd, OV7610_REG_ECW, 0x2e);
- - ov511_i2c_write(fd, OV7610_REG_ECB, 0x7C);
- - ov511_i2c_write(fd, OV7610_REG_COMH, 0x24);
- - ov511_i2c_write(fd, OV7610_REG_EHSH, 0x04);
- - ov511_i2c_write(fd, OV7610_REG_EHSL, 0xAC);
- - ov511_i2c_write(fd, OV7610_REG_EXBK, 0xFE);
- - ov511_i2c_write(fd, OV7610_REG_COMJ, 0x93);
- - ov511_i2c_write(fd, OV7610_REG_BADJ, 0x48);
- - ov511_i2c_write(fd, OV7610_REG_COMK, 0x81);
- + /* This returns 0 if we have an OV7620 sensor */
- + if((is20 = ov511_i2c_read(fd, OV7610_REG_COMI)) < 0)
- + exit(1);
- + is20 = !is20;
-
- - ov511_i2c_write(fd, OV7610_REG_GAM, 0x04);
- + /* set up the OV7610/OV7620 */
- + if(is20) {
- + ov511_i2c_write(fd, OV7610_REG_EC, 0xff);
- + ov511_i2c_write(fd, OV7610_REG_FD, 0x06);
- + ov511_i2c_write(fd, OV7610_REG_COMH, 0x24);
- + ov511_i2c_write(fd, OV7610_REG_EHSL, 0xac);
- + ov511_i2c_write(fd, OV7610_REG_COMA, 0x00);
- + ov511_i2c_write(fd, OV7610_REG_COMH, 0x24);
- + ov511_i2c_write(fd, OV7610_REG_RWB, 0x85);
- + ov511_i2c_write(fd, OV7610_REG_COMD, 0x01);
- + ov511_i2c_write(fd, 0x23, 0x00);
- + ov511_i2c_write(fd, OV7610_REG_ECW, 0x10);
- + ov511_i2c_write(fd, OV7610_REG_ECB, 0x8a);
- + ov511_i2c_write(fd, OV7610_REG_COMG, 0xe2);
- + ov511_i2c_write(fd, OV7610_REG_EHSH, 0x00);
- + ov511_i2c_write(fd, OV7610_REG_EXBK, 0xfe);
- + ov511_i2c_write(fd, 0x30, 0x71);
- + ov511_i2c_write(fd, 0x31, 0x60);
- + ov511_i2c_write(fd, 0x32, 0x26);
- + ov511_i2c_write(fd, OV7610_REG_YGAM, 0x20);
- + ov511_i2c_write(fd, OV7610_REG_BADJ, 0x48);
- + ov511_i2c_write(fd, OV7610_REG_COMA, 0x24);
- + ov511_i2c_write(fd, OV7610_REG_SYN_CLK, 0x01);
- + ov511_i2c_write(fd, OV7610_REG_BBS, 0x24);
- + ov511_i2c_write(fd, OV7610_REG_RBS, 0x24);
- + } 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);
- + ov511_i2c_write(fd, OV7610_REG_FD, 0x06);
- + ov511_i2c_write(fd, OV7610_REG_COME, 0x1c);
- + ov511_i2c_write(fd, OV7610_REG_COMF, 0x90);
- + ov511_i2c_write(fd, OV7610_REG_ECW, 0x2e);
- + ov511_i2c_write(fd, OV7610_REG_ECB, 0x7C);
- + ov511_i2c_write(fd, OV7610_REG_COMH, 0x24);
- + ov511_i2c_write(fd, OV7610_REG_EHSH, 0x04);
- + ov511_i2c_write(fd, OV7610_REG_EHSL, 0xAC);
- + ov511_i2c_write(fd, OV7610_REG_EXBK, 0xFE);
- + ov511_i2c_write(fd, OV7610_REG_COMJ, 0x93);
- + ov511_i2c_write(fd, OV7610_REG_BADJ, 0x48);
- + ov511_i2c_write(fd, OV7610_REG_COMK, 0x81);
-
- + ov511_i2c_write(fd, OV7610_REG_GAM, 0x04);
- + }
- +
- +
- if(small) {
- vs.width = 320;
- vs.height = 240;
- @@ -442,14 +489,14 @@ main(int argc, char *argv[]) {
- ov511_reg_write(fd, OV511_REG_LNDV, 0x00);
-
- /* set FIFO format (993-byte packets) */
- - if(ov511_reg_write(fd, OV511_REG_PKSZ, 0x1F) < 0)
- + if(ov511_reg_write(fd, OV511_REG_PKSZ, bufsize/32) < 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;
- + alt.uai_interface_index = 0;
- + alt.uai_alt_no = (isplus ? 7 : 1);
- if(ioctl(fd, USB_SET_ALTINTERFACE, &alt) < 0) {
- perror("USB_SET_ALTINTERFACE");
- exit(1);
- @@ -468,43 +515,62 @@ main(int argc, char *argv[]) {
- vs.xels = pnm_allocarray(vs.width, vs.height);
-
- /* open the isochronous endpoint (endpoint 1) */
- - sprintf(isocdev, "%s.1", devname);
- + /* first we need to construct the endpoint device from */
- + /* the given device */
- + p = strchr(devname, '.');
- + slen = strlen(devname);
- + if(p == NULL) {
- + /* there is no dot, just append the isoc endpoint */
- + /* this is horribly contrived and needs some work, */
- + /* at this point OpenBSD doesn't use /dev/ugenX so */
- + /* it will get fixed if soon */
- + snprintf(isocdev, sizeof(isocdev), "%s.01", devname);
- + } else {
- + /* there is a dot */
- + plen = strlen(p);
- + snprintf(isocdev, sizeof(isocdev), "%s", devname);
- + isocdev[slen - plen] = NULL;
- + snprintf(isocdev, sizeof(isocdev), "%s.01", isocdev);
- + }
- +
- if((isoc = open(isocdev, O_RDONLY)) < 0) {
- perror(isocdev);
- exit(1);
- }
-
- /* read, looking for start and end frames */
- - while(vs.state != DONE && (len = read(isoc, &buf, 993)) >= 0) {
- + while(vs.state != DONE && (len = read(isoc, &buf, bufsize)) >= 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) {
- + && (buf[8] & 0x80) == 0 && buf[bufsize-1] == 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);
- + procdata(&vs, buf + 9, bufsize - 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
- + && (buf[8] & 0x80) == 0x80 && buf[bufsize-1] == 0
- && vs.state == READING) {
- vs.state = DONE;
- } else if(vs.state == READING) {
- - procdata(&vs, buf, 993 - 1);
- + procdata(&vs, buf, bufsize - 1);
-
- /* abort the capture and start over if packets come in out-of-order */
- - if(buf[992] != frmnm && buf[992] != 1) {
- + if(buf[bufsize-1] != frmnm && buf[bufsize-1] != 1) {
- vs.state = SKIPPING;
- }
- - frmnm = buf[992] + 1;
- + frmnm = buf[bufsize-1] + 1;
- if(frmnm == 256)
- frmnm = 1;
- - } else if(buf[992] != 0) {
- - frmnm = buf[992] + 1;
- + } else if(buf[bufsize-1] != 0) {
- + frmnm = buf[bufsize-1] + 1;
- if(frmnm == 256)
- frmnm = 1;
- }
- }
-
- + /* reset and close the OV511 */
- + ov511_reg_write(fd, OV511_REG_RST, 0x7f);
- close(isoc);
- close(fd);
-
|