[Sumover-dev] [svn commit] r4447 - in vic/branches/mpeg4: tcl video
sumover-dev at cs.ucl.ac.uk
sumover-dev at cs.ucl.ac.uk
Tue May 26 13:54:03 BST 2009
Author: douglask
Date: Tue May 26 13:53:56 2009
New Revision: 4447
Added:
vic/branches/mpeg4/video/grabber-ov511.cpp
vic/branches/mpeg4/video/ov511reg.h
Modified:
vic/branches/mpeg4/configure.in
vic/branches/mpeg4/tcl/ui-grabber.tcl
vic/branches/mpeg4/video/grabber-meteor.cpp
Log:
Applied xcast6-0.2.1-vic-2.8ucl1.1.5.diff.gz video grabber patches for
FreeBSD & NetBSD available from Download files section of:
http://xcast6.sourceforge.net/
Modified: vic/branches/mpeg4/configure.in
==============================================================================
--- vic/branches/mpeg4/configure.in (original)
+++ vic/branches/mpeg4/configure.in Tue May 26 13:53:56 2009
@@ -375,7 +375,8 @@
V_OBJ_GRABBER="video/grabber-sunrise.o video/output-sunrise.o $V_OBJ_GRABBER"
fi
-if test -r /usr/include/machine/ioctl_meteor.h ; then
+if test -r /usr/include/machine/ioctl_meteor.h -o \
+ -r /usr/include/dev/ic/bt8xx.h ; then
V_OBJ_GRABBER="video/grabber-meteor.o $V_OBJ_GRABBER"
fi
@@ -424,7 +425,7 @@
V_INCLUDE_GRABBER="$V_INCLUDE_GRABBER -I$dir"
V_LIB_GRABBER="$V_LIB_GRABBER $dir/libvigrapix.a"
V_OBJ_GRABBER="video/grabber-vigra.o $V_OBJ_GRABBER"
- break
+ break
fi
done
@@ -452,7 +453,7 @@
V_INCLUDE_GRABBER="$V_INCLUDE_GRABBER -I$dir/include"
V_LIB_GRABBER="$V_LIB_GRABBER -L$dir/lib -lXext -lXvid"
V_OBJ_GRABBER="video/grabber-plx.o video/assistor-plx.o $V_OBJ_GRABBER"
- break
+ break
fi
done
@@ -554,12 +555,18 @@
V_LIB="$V_LIB -lipc"
;;
*-*-netbsd*)
+ if test "$gpl" = "yes" ; then
+ V_OBJ_GRABBER="video/grabber-ov511.o $V_OBJ_GRABBER"
+ fi
V_DEFINE="$V_DEFINE -DNetBSD"
V_STATIC=""
V_TARCMD="tar -h -c -f"
OPSYS=netbsd
;;
*-*-freebsd*)
+ if test "$gpl" = "yes" ; then
+ V_OBJ_GRABBER="video/grabber-ov511.o $V_OBJ_GRABBER"
+ fi
V_STATIC=""
V_DEFINE="$V_DEFINE -DSIGARGS=int -DFreeBSD"
if test $ipv6 = yes; then
Modified: vic/branches/mpeg4/tcl/ui-grabber.tcl
==============================================================================
--- vic/branches/mpeg4/tcl/ui-grabber.tcl (original)
+++ vic/branches/mpeg4/tcl/ui-grabber.tcl Tue May 26 13:53:56 2009
@@ -728,6 +728,39 @@
set qcamwindow(setbpp) "set qcambpp"
}
+proc build.ov511 {w} {
+ global ov511window
+
+ set f [smallfont]
+ label $w.title -text "Grabber"
+
+ frame $w.f -relief sunken -borderwidth 2
+
+ frame $w.f.s -relief flat
+
+ frame $w.f.s.l -relief flat
+ label $w.f.s.l.red -font $f -anchor w -text "Red balance"
+ label $w.f.s.l.blue -font $f -anchor w -text "Blue balance"
+ pack $w.f.s.l.red $w.f.s.l.blue -side top -fill x -expand 1
+
+ frame $w.f.s.s -relief flat
+ scale $w.f.s.s.red -orient horizontal -width 12 \
+ -relief groove -showvalue 0 -from 0 -to 255 \
+ -command "grabber set RED"
+ scale $w.f.s.s.blue -orient horizontal -width 12 \
+ -relief groove -showvalue 0 -from 0 -to 255 \
+ -command "grabber set BLUE"
+
+ pack $w.f.s.s.red $w.f.s.s.blue -side top -fill x -expand 1
+ pack $w.f.s.l $w.f.s.s -side left -fill x -expand 1
+
+ pack $w.f.s -fill x -expand 1
+ pack $w.title $w.f -fill x -expand 1
+
+ set ov511window(setred) "$w.f.s.s.red set"
+ set ov511window(setblue) "$w.f.s.s.blue set"
+}
+
#
# X11 Grabber controls
#
Modified: vic/branches/mpeg4/video/grabber-meteor.cpp
==============================================================================
--- vic/branches/mpeg4/video/grabber-meteor.cpp (original)
+++ vic/branches/mpeg4/video/grabber-meteor.cpp Tue May 26 13:53:56 2009
@@ -57,8 +57,12 @@
#include "module.h"
#include "bsd-endian.h"
-#include <machine/ioctl_meteor.h>
-#include <machine/ioctl_bt848.h>
+#if defined(__FreeBSD__)
+ #include <machine/ioctl_meteor.h>
+ #include <machine/ioctl_bt848.h>
+#elif defined(__NetBSD__)
+ #include <dev/ic/bt8xx.h>
+#endif
/*XXX*/
#define NTSC_WIDTH 320
@@ -163,7 +167,7 @@
{
if(free)
attributes_ = "\
-format {422 420} \
+format {422 420 cif} \
type {pal ntsc secam auto} \
size {large normal small cif} \
port {RCA Port-1 Port-2 Port-3 S-Video RGB}";
@@ -178,6 +182,8 @@
TclObject* o = 0;
if (strcmp(argv[2], "422") == 0)
o = new Meteor422Grabber(name_);
+ else if (strcmp(argv[2], "420") == 0)
+ o = new MeteorCIFGrabber(name_);
else if (strcmp(argv[2], "cif") == 0)
o = new MeteorCIFGrabber(name_);
if (o != 0)
Added: vic/branches/mpeg4/video/grabber-ov511.cpp
==============================================================================
--- (empty file)
+++ vic/branches/mpeg4/video/grabber-ov511.cpp Tue May 26 13:53:56 2009
@@ -0,0 +1,948 @@
+/*
+ * grabber-ov511.cpp. Copyright (C) 2001 FUJITSU LABORATORIES LTD.
+ *
+ * This program is mostly based on "vid" written by Peter S. Housel
+ * (http://ovtvid-bsd.sourceforge.net/).
+ * The "vid" program is released under GPL so this program should
+ * also be released under GPL.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Copyright information of "vid" is as follows: */
+/* Simple OV511 video capture program, version 1.0.1
+ *
+ * Copyright 2000 Peter S. Housel.
+ *
+ * Portions of this program were modeled after or adapted from the
+ * OV511 driver for Linux by Mark W. McClelland; see
+ * http://alpha.dyndns.org/ov511/ for more information.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#define class usbclass
+#include <dev/usb/usb.h>
+#undef class
+
+#if defined(__NetBSD__) && (__NetBSD_Version__ < 106000000)
+#define udi_vendorNo vendorNo
+#define udi_productNo productNo
+#define ucr_request request
+#define ucr_data data
+#define ucr_flags flags
+#define ucr_actlen actlen
+#define uai_interface_index interface_index
+#define uai_alt_no alt_no
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "grabber.h"
+#include "vic_tcl.h"
+#include "device-input.h"
+#include "module.h"
+#include "ov511reg.h"
+
+/*XXX*/
+#define NTSC_WIDTH 320
+#define NTSC_HEIGHT 240
+#define PAL_WIDTH 384
+#define PAL_HEIGHT 288
+#define CIF_WIDTH 352
+#define CIF_HEIGHT 288
+
+#define OV511_VENDOR 0x05a9
+#define OV511_PRODUCT_511 0x0511
+#define OV511_PRODUCT_511PLUS 0xa511
+
+#define OV511_MAX_CONTRAST 255
+
+class OV511Grabber : public Grabber {
+ public:
+ OV511Grabber(const char* name, int is511plus);
+ virtual ~OV511Grabber();
+ virtual void start();
+ protected:
+ virtual int command(int argc, const char*const* argv);
+ int capture();
+ virtual int grab();
+ void format();
+ void normalize();
+ virtual void setsize();
+ void contrast (double c);
+
+ int format_; /* video format: NTSC or PAL */
+ int rformat_; /* requested format, above + AUTO */
+ u_int basewidth_;
+ u_int baseheight_;
+ int decimate_;
+
+private:
+ int initDevice();
+ int regRead(int reg);
+ int regWrite(int reg, int val);
+ int i2cRead(int reg);
+ int i2cWrite(int reg, int val);
+ int init76xx();
+ int init6xx0();
+ void procData();
+ void procSegment(u_char *buf);
+ int brightness_;
+ int red_;
+ int blue_;
+ int contrast_;
+ int changed_;
+ int pktsize_;
+
+ int port_;
+ int ctlfd_;
+ int fd_;
+ int cameraid;
+
+ int is511plus_;
+ enum {
+ OV511SENSOR_7610,
+ OV511SENSOR_7620,
+ OV511SENSOR_7620AE,
+ OV511SENSOR_6620
+ } sensortype_;
+
+ enum {
+ OV511FRAME_SKIPPING,
+ OV511FRAME_READING,
+ OV511FRAME_DONE
+ } state_;
+ int segsize_;
+ int iY_, jY_;
+ int iUV_, jUV_;
+ u_char frmbuf[NTSC_WIDTH * NTSC_HEIGHT * 3 / 2];
+ u_char buf[2048];
+ int loopcnt_;
+};
+
+class CIFOV511Grabber : public OV511Grabber {
+public:
+ CIFOV511Grabber(const char* name, int is511plus)
+ : OV511Grabber(name, is511plus) {}
+
+protected:
+ virtual void setsize();
+ int loff_;
+ int coff_;
+ int hwrap_;
+ int hskip_;
+};
+
+class OV511Device : public InputDevice {
+ public:
+ OV511Device(const char*);
+ virtual int command(int argc, const char*const* argv);
+
+ int is511plus_;
+ char* devname_;
+};
+
+static OV511Device ov511_device("ov511");
+
+static const char disabled_str[] = "disabled";
+#if defined(__FreeBSD__)
+static const char ugen0_00[] = "/dev/ugen0";
+static const char ugen0_01[] = "/dev/ugen0.1";
+#elif defined(__NetBSD__)
+static const char ugen0_00[] = "/dev/ugen0.00";
+static const char ugen0_01[] = "/dev/ugen0.01";
+#endif
+
+OV511Device::OV511Device(const char* name) : InputDevice(name)
+{
+ int fd;
+ struct usb_device_info udi;
+
+ fd = open(ugen0_00, O_RDWR);
+ if (fd < 0) {
+ perror(ugen0_00);
+ attributes_ = disabled_str;
+ return;
+ }
+
+ if (ioctl(fd, USB_GET_DEVICEINFO, &udi) < 0) {
+ perror(ugen0_00);
+ close(fd);
+ attributes_ = disabled_str;
+ return;
+ }
+
+ is511plus_ = 0;
+ if (udi.udi_vendorNo == OV511_VENDOR) {
+ switch (udi.udi_productNo) {
+ case OV511_PRODUCT_511:
+ break;
+ case OV511_PRODUCT_511PLUS:
+ is511plus_ = 1;
+ break;
+ default:
+ close(fd);
+ return;
+ }
+ }
+
+ close(fd);
+ attributes_ = "\
+format {422 420 cif} \
+size {small normal cif} \
+port {default}";
+}
+
+int OV511Device::command(int argc, const char*const* argv)
+{
+ Tcl& tcl = Tcl::instance();
+ if (argc == 3) {
+ if (strcmp(argv[1], "open") == 0) {
+ TclObject* o = 0;
+ if (strcmp(argv[2], "422") == 0)
+ o = new OV511Grabber(ugen0_00, is511plus_);
+ else if (strcmp(argv[2], "420") == 0)
+ o = new CIFOV511Grabber(ugen0_00, is511plus_);
+ else if (strcmp(argv[2], "cif") == 0)
+ o = new CIFOV511Grabber(ugen0_00, is511plus_);
+ if (o != 0)
+ tcl.result(o->name());
+ return (TCL_OK);
+ }
+ }
+ return (InputDevice::command(argc, argv));
+}
+
+OV511Grabber::OV511Grabber(const char* name, int is511plus) :
+ is511plus_(is511plus)
+{
+ ctlfd_ = open(name, O_RDWR);
+ if (ctlfd_ < 0) {
+ perror("open");
+ exit(1);
+ }
+
+ if (initDevice() < 0) {
+ exit(1);
+ }
+
+ red_ = 0xb0;
+ blue_ = 0xd0;
+ contrast_ = 0xb0;
+ brightness_ = 0x70;
+ changed_ = 0;
+
+ (Tcl::instance()).evalf
+ ("if [info exists ov511window] {\n"
+ " eval \"$ov511window(setred) %d\"\n"
+ " eval \"$ov511window(setblue) %d\"\n"
+ "}\n",
+ red_, blue_);
+
+ format_ = 0;
+ decimate_ = 2;
+
+ basewidth_ = NTSC_WIDTH * decimate_;
+ baseheight_ = NTSC_HEIGHT * decimate_;
+}
+
+OV511Grabber::~OV511Grabber()
+{
+ close(ctlfd_);
+ close(fd_);
+
+}
+
+void OV511Grabber::setsize()
+{
+ set_size_422(basewidth_ / decimate_, baseheight_ / decimate_);
+ allocref();
+}
+
+void OV511Grabber::format()
+{
+ setsize();
+}
+
+/* XXX */
+void OV511Grabber::normalize()
+{
+ fprintf(stderr, "normalize \n");
+}
+
+void OV511Grabber::start()
+{
+ format();
+ Grabber::start();
+}
+
+int OV511Grabber::command(int argc, const char *const *argv)
+{
+ Tcl& tcl = Tcl::instance();
+
+ if (argc == 4) {
+ if (strcmp (argv[1], "set") == 0) {
+ changed_ = 1;
+ if (strcmp (argv[2], "BRIGHT") == 0) {
+ brightness_ = atoi(argv[3]);
+ return (TCL_OK);
+ } else if (strcmp (argv[2], "RED") == 0) {
+ red_ = atoi(argv[3]);
+ return (TCL_OK);
+ } else if (strcmp (argv[2], "BLUE") == 0) {
+ blue_ = atoi(argv[3]);
+ return (TCL_OK);
+ } else if (strcmp (argv[2], "CONT") == 0) {
+ contrast_ = atoi(argv[3]);
+ return (TCL_OK);
+ } else {
+ tcl.resultf("%s: unknown set command: %s",
+ argv[0], argv[2]);
+ return (TCL_ERROR);
+ }
+ }
+ } else if (argc == 3) {
+ if (strcmp(argv[1], "get") == 0) {
+ if (strcmp (argv[2], "BRIGHT") == 0) {
+ tcl.resultf("%d", brightness_);
+ return (TCL_OK);
+ } else if (strcmp (argv[2], "CONT") == 0) {
+ tcl.resultf ("%f", (double) contrast_ /
+ (double) OV511_MAX_CONTRAST);
+ return (TCL_OK);
+ }
+ } else if (strcmp(argv[1], "decimate") == 0) {
+ int dec = atoi(argv[2]);
+ if (dec <= 0) {
+ tcl.resultf("%s: divide by zero", argv[0]);
+ return (TCL_ERROR);
+ }
+ if (dec != decimate_) {
+ decimate_ = dec;
+ setsize();
+ }
+ return (TCL_OK);
+ } else if (strcmp(argv[1], "port") == 0) {
+ int p = atoi(argv[2]);
+ if (p != port_) {
+ port_ = p;
+ }
+ return (TCL_OK);
+ } else if (strcmp(argv[1], "format") == 0) {
+ if (running_)
+ format();
+ return (TCL_OK);
+ } else if (strcmp(argv[1], "contrast") == 0) {
+ contrast(atof(argv[2]));
+ return (TCL_OK);
+ }
+ } else if (argc == 2) {
+ if (strcmp(argv[1], "normalize") == 0) {
+ normalize();
+ return (TCL_OK);
+ } else if (strcmp(argv[1], "format") == 0) {
+ Tcl& tcl = Tcl::instance();
+ switch (format_) {
+
+ default:
+ tcl.result("");
+ break;
+ }
+ return (TCL_OK);
+
+ }
+ }
+
+ return (Grabber::command(argc, argv));
+}
+
+int OV511Grabber::grab()
+{
+ if (capture() == 0)
+ return (0);
+
+ suppress(frame_);
+ saveblks(frame_);
+ YuvFrame f(media_ts(), frame_, crvec_, outw_, outh_);
+ return (target_->consume(&f));
+}
+
+void OV511Grabber::contrast (double c)
+{
+ contrast_ = (int) (OV511_MAX_CONTRAST * c);
+}
+
+int OV511Grabber::regRead(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);
+ USETW(ur.ucr_request.wIndex, reg);
+ USETW(ur.ucr_request.wLength, 1);
+ ur.ucr_data = data;
+ ur.ucr_flags = 0;
+ ur.ucr_actlen = 0;
+
+ if (ioctl(ctlfd_, USB_DO_REQUEST, &ur) < 0) {
+ return -1;
+ }
+
+ return data[0] & 0xFF;
+}
+
+int OV511Grabber::regWrite(int reg, int val)
+{
+ struct usb_ctl_request ur;
+ unsigned char data[1024];
+
+ data[0] = val;
+
+ ur.ucr_request.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
+ ur.ucr_request.bRequest = 2;
+
+ USETW(ur.ucr_request.wValue, 0);
+ USETW(ur.ucr_request.wIndex, reg);
+ USETW(ur.ucr_request.wLength, 1);
+ ur.ucr_data = data;
+ ur.ucr_flags = 0;
+ ur.ucr_actlen = 0;
+
+ if (ioctl(ctlfd_, USB_DO_REQUEST, &ur) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int OV511Grabber::i2cRead(int reg)
+{
+ int status = 0;
+ int val = 0;
+ int retries = OV7610_I2C_RETRIES;
+
+ while (--retries >= 0) {
+ /* wait until bus idle */
+ do {
+ if ((status = regRead(OV511_REG_I2C_CONTROL)) < 0)
+ return -1;
+ } while ((status & 0x01) == 0);
+
+ /* perform a dummy write cycle to set the register */
+ if (regWrite(OV511_REG_SMA, reg) < 0)
+ return -1;
+
+ /* initiate the dummy write */
+ if(regWrite(OV511_REG_I2C_CONTROL, 0x03) < 0)
+ return -1;
+
+ /* wait until bus idle */
+ do {
+ if((status = regRead(OV511_REG_I2C_CONTROL)) < 0)
+ return -1;
+ } while ((status & 0x01) == 0);
+
+ if ((status & 0x2) == 0)
+ break;
+ }
+
+ if (retries < 0)
+ return -1;
+
+ retries = OV7610_I2C_RETRIES;
+ while (--retries >= 0) {
+ /* initiate read */
+ if(regWrite(OV511_REG_I2C_CONTROL, 0x05) < 0)
+ return -1;
+
+ /* wait until bus idle */
+ do {
+ if((status = regRead(OV511_REG_I2C_CONTROL)) < 0)
+ return -1;
+ } while ((status & 0x01) == 0);
+
+ if ((status & 0x2) == 0)
+ break;
+
+ /* abort I2C bus before retrying */
+ if (regWrite(OV511_REG_I2C_CONTROL, 0x10) < 0)
+ return -1;
+ }
+ if (retries < 0)
+ return -1;
+
+ /* retrieve data */
+ val = regRead(OV511_REG_SDA);
+
+ /* issue another read for some weird reason */
+ if (regWrite(OV511_REG_I2C_CONTROL, 0x05) < 0)
+ return -1;
+
+ return val;
+}
+
+int OV511Grabber::i2cWrite(int reg, int val)
+{
+ int status = 0;
+ int retries = OV7610_I2C_RETRIES;
+
+ while (--retries >= 0) {
+ if (regWrite(OV511_REG_SWA, reg) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_SDA, val) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_I2C_CONTROL, 0x1) < 0)
+ return -1;
+
+ /* wait until bus idle */
+ do {
+ if ((status = regRead(OV511_REG_I2C_CONTROL)) < 0)
+ return -1;
+ } while ((status & 0x01) == 0);
+
+ /* OK if ACK */
+ if ((status & 0x02) == 0)
+ return 0;
+ }
+
+ return -1;
+}
+
+int OV511Grabber::init6xx0()
+{
+ /* XXX Not implemented yet */
+ return -1;
+}
+
+int OV511Grabber::init76xx()
+{
+ int val;
+
+ if (regWrite(OV511_REG_SID, OV7610_I2C_WRITE_ID) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_SRA, OV7610_I2C_READ_ID) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_RST, 0x0) < 0)
+ return -1;
+
+ if (i2cWrite(OV7610_REG_COMA, 0x80) < 0)
+ return -1;
+
+ i2cRead(0x00);
+ while (1) {
+ if (i2cRead(OV7610_REG_MIDH) == 0x7f &&
+ i2cRead(OV7610_REG_MIDL) == 0xa2)
+ break;
+ }
+
+ val = i2cRead(OV7610_REG_COMI);
+ if (val < 0) {
+ return -1;
+ } else if ((val & 3) == 3) {
+ sensortype_ = OV511SENSOR_7610;
+ } else if ((val & 3) == 1) {
+ /*
+ * XXX Workaround for 511+/7620AE
+ * (from ov511 driver for Linux).
+ */
+ if (is511plus_)
+ sensortype_ = OV511SENSOR_7620;
+ else
+ sensortype_ = OV511SENSOR_7620AE;
+ } else if ((val & 3) == 0) {
+ sensortype_ = OV511SENSOR_7620;
+ }
+
+ if (sensortype_ == OV511SENSOR_7620) {
+ i2cWrite(OV7610_REG_EC, 0xff);
+ i2cWrite(OV7610_REG_FD, 0x06);
+ i2cWrite(OV7610_REG_COMH, 0x24);
+ i2cWrite(OV7610_REG_EHSL, 0xac);
+ i2cWrite(OV7610_REG_COMA, 0x00);
+ i2cWrite(OV7610_REG_COMH, 0x24);
+ i2cWrite(OV7610_REG_RWB, 0x85);
+ i2cWrite(OV7610_REG_COMD, 0x01);
+ i2cWrite(0x23, 0x00);
+ i2cWrite(OV7610_REG_ECW, 0x10);
+ i2cWrite(OV7610_REG_ECB, 0x8a);
+ i2cWrite(OV7610_REG_COMG, 0xe2);
+ i2cWrite(OV7610_REG_EHSH, 0x00);
+ i2cWrite(OV7610_REG_EXBK, 0xfe);
+ i2cWrite(0x30, 0x71);
+ i2cWrite(0x31, 0x60);
+ i2cWrite(0x32, 0x26);
+ i2cWrite(OV7610_REG_YGAM, 0x20);
+ i2cWrite(OV7610_REG_BADJ, 0x48);
+ i2cWrite(OV7610_REG_COMA, 0x24);
+ i2cWrite(OV7610_REG_SYN_CLK, 0x01);
+ i2cWrite(OV7610_REG_BBS, 0x24);
+ i2cWrite(OV7610_REG_RBS, 0x24);
+
+ } else {
+ i2cWrite(OV7610_REG_EC, 0xff);
+ i2cWrite(OV7610_REG_FD, 0x06);
+ i2cWrite(OV7610_REG_COMH, 0x24);
+ i2cWrite(OV7610_REG_EHSL, 0xac);
+ i2cWrite(OV7610_REG_COMA, 0x00);
+ i2cWrite(OV7610_REG_COMK, 0x81);
+ i2cWrite(OV7610_REG_COMH, 0x24); /* 0c */
+ i2cWrite(OV7610_REG_RWB, 0x85); /* lg's setting */
+ i2cWrite(OV7610_REG_COMD, 0x01);
+ i2cWrite(OV7610_REG_COME, 0x1c);
+ i2cWrite(0x23, 0x2a);
+ i2cWrite(OV7610_REG_ECW, 0x10);
+ i2cWrite(OV7610_REG_ECB, 0x8a);
+ i2cWrite(OV7610_REG_COMG, 0xc2);
+ i2cWrite(OV7610_REG_EHSH, 0x04);
+ i2cWrite(OV7610_REG_EXBK, 0xfe);
+ i2cWrite(0x30, 0x71);
+ i2cWrite(0x31, 0x60);
+ i2cWrite(0x32, 0x26);
+ i2cWrite(OV7610_REG_YGAM, 0x20);
+ i2cWrite(OV7610_REG_BADJ, 0x48);
+ i2cWrite(OV7610_REG_COMA, 0x24);
+ i2cWrite(OV7610_REG_SYN_CLK, 0x01);
+ i2cWrite(OV7610_REG_BBS, 0x24);
+ i2cWrite(OV7610_REG_RBS, 0x24);
+ }
+
+ i2cWrite(OV7610_REG_COMF, 0xa2);
+ i2cWrite(OV7610_REG_COMB, 0x01);
+ if (sensortype_ == OV511SENSOR_7620)
+ i2cWrite(OV7610_REG_COMJ, 0x91);
+ else
+ i2cWrite(OV7610_REG_COMJ, 0x93);
+
+ return 0;
+}
+
+int OV511Grabber::initDevice()
+{
+ struct usb_alt_interface alt;
+
+ /* reset the OV511 */
+ if (regWrite(OV511_REG_RST, 0x7f) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_RST, 0) < 0)
+ return -1;
+
+ /* initialize system */
+ if (regWrite(OV511_REG_EN_SYS, 0x1) < 0)
+ return -1;
+
+ /* determine the camera model */
+ if ((cameraid = regRead(OV511_REG_CID)) < 0)
+ return -1;
+
+ /* set I2C write slave ID for OV7610 */
+ if (regWrite(OV511_REG_SID, OV7610_I2C_WRITE_ID) < 0)
+ return -1;
+
+ /* set I2C read slave ID for OV7610 */
+ if (regWrite(OV511_REG_SRA, OV7610_I2C_READ_ID) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_PKSZ, 0x1) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_PKFMT, 0x0) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_RST, 0x3d) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_RST, 0x0) < 0)
+ return -1;
+
+ if (i2cWrite(OV7610_REG_COMA, 0x80) < 0) {
+ if (regWrite(OV511_REG_SID, OV6xx0_I2C_WRITE_ID) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_SRA, OV6xx0_I2C_READ_ID) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_RST, 0) < 0)
+ return -1;
+
+ if (i2cWrite(OV7610_REG_COMA, 0x80) < 0)
+ return -1;
+
+ if (init6xx0() < 0)
+ return -1;
+ } else {
+ if (init76xx() < 0)
+ return -1;
+ }
+
+ if (i2cRead(0x00) < 0)
+ return -1;
+
+ /* set YUV 4:2:0 format, Y channel LPF */
+ if (regWrite(OV511_REG_M400, 0x01) < 0)
+ return -1;
+ if (regWrite(OV511_REG_M420_YFIR, 0x03) < 0)
+ return -1;
+
+ /* disable snapshot */
+ if (regWrite(OV511_REG_SNAP, 0x0) < 0)
+ return -1;
+ /* disable compression */
+ if (regWrite(OV511_REG_CE_EN, 0x0) < 0)
+ return -1;
+
+ regWrite(OV511_REG_PXCNT, 0x27);
+ regWrite(OV511_REG_LNCNT, 0x1D);
+
+ regWrite(OV511_REG_PXDV, 0x01);
+ regWrite(OV511_REG_LNDV, 0x01);
+
+ if (is511plus_) {
+ /* set FIFO format (961-byte packets) */
+ pktsize_ = 961;
+ /* select the 961-byte alternative */
+ alt.uai_interface_index = 0;
+ alt.uai_alt_no = 7;
+ } else {
+ /* set FIFO format (993-byte packets) */
+ pktsize_ = 993;
+ /* select the 993-byte alternative */
+ alt.uai_interface_index = 0;
+ alt.uai_alt_no = 1;
+ }
+
+ if (regWrite(OV511_REG_PKSZ, (pktsize_ - 1) / 32) < 0)
+ return -1;
+ if (regWrite(OV511_REG_PKFMT, 0x03) < 0)
+ return -1;
+
+ if (ioctl(ctlfd_, USB_SET_ALTINTERFACE, &alt) < 0) {
+ perror("USB_SET_ALTINTERFACE");
+ return -1;
+ }
+
+ /* reset the device again */
+
+ if (regWrite(OV511_REG_RST, 0x3F) < 0)
+ return -1;
+
+ if (regWrite(OV511_REG_RST, 0x00) < 0)
+ return -1;
+
+ state_ = OV511FRAME_SKIPPING;
+ segsize_ = 384;
+
+ iY_ = jY_ = iUV_ = jUV_ = 0;
+
+ if ((fd_ = open(ugen0_01, O_RDONLY)) < 0) {
+ perror(ugen0_01);
+ return -1;
+ }
+
+ return 0;
+}
+
+int OV511Grabber::capture()
+{
+ int len;
+ int srcoff, dstoff, cplen;
+ int frmnm = 0;
+ int ret;
+ struct timeval tv;
+ fd_set readfds;
+
+ if (changed_) {
+ i2cWrite(OV7610_REG_RED, red_);
+ i2cWrite(OV7610_REG_BLU, blue_);
+ i2cWrite(OV7610_REG_CTR, contrast_);
+ i2cWrite(OV7610_REG_BRT, brightness_);
+ changed_ = 0;
+ }
+
+
+ loopcnt_ = 0;
+#if 0
+ state_ = OV511FRAME_SKIPPING;
+#endif
+ iY_ = jY_ = iUV_ = jUV_ = 0;
+ while (1) {
+ tv.tv_sec = tv.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(fd_, &readfds);
+ ret = select(fd_ + 1, &readfds, NULL, NULL, &tv);
+ if (ret <= 0)
+ break;
+ if ((len = read(fd_, buf, pktsize_)) != pktsize_)
+ break;
+
+ 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[pktsize_ - 1] == 0) {
+ state_ = OV511FRAME_READING;
+ loopcnt_ = 0;
+ iY_ = jY_ = iUV_ = jUV_ = 0;
+ srcoff = 9;
+ dstoff = 0;
+ cplen = pktsize_ - 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
+ && state_ == OV511FRAME_READING) {
+ // fprintf(stderr, "done\n");
+ state_ = OV511FRAME_DONE;
+ break;
+ } else {
+ frmnm = buf[pktsize_ - 1];
+ if (frmnm == 0)
+ continue;
+ state_ = OV511FRAME_READING;
+ srcoff = 0;
+ dstoff = (pktsize_ - 10) +
+ (pktsize_ - 1) *
+ (256 * loopcnt_ + frmnm - 1);
+ cplen = pktsize_ - 1;
+ if (frmnm == 255)
+ loopcnt_++;
+ }
+
+ if (dstoff + cplen < sizeof(frmbuf))
+ memcpy(&frmbuf[dstoff], &buf[srcoff], cplen);
+ }
+
+ if (state_ != OV511FRAME_DONE) {
+ return 0;
+ } else {
+ procData();
+ state_ = OV511FRAME_SKIPPING;
+ return 1;
+ }
+}
+
+void OV511Grabber::procData()
+{
+ int res;
+ u_char *p;
+
+ res = sizeof(frmbuf);
+ p = frmbuf;
+ while (res > 0) {
+ procSegment(p);
+ p += segsize_;
+ res -= segsize_;
+ }
+}
+
+#define OV511_BLKWIDTH 8
+#define OV511_BLKHEIGHT 8
+#define OV511_UVWIDTH 8
+#define OV511_UVHEIGHT 8
+#define OV511_YWIDTH 32
+#define OV511_YHEIGHT 8
+
+void OV511Grabber::procSegment(u_char *p)
+{
+ int i, j;
+ u_char *udata, *vdata, *ydata;
+ u_char *uout, *vout, *yout;
+
+ udata = p;
+ vdata = udata + (OV511_UVWIDTH * OV511_UVHEIGHT);
+ ydata = vdata + (OV511_UVWIDTH * OV511_UVHEIGHT);
+
+ yout = frame_ + (jY_ + (outh_ - inh_) / 2) * outw_
+ + iY_ + (outw_ - inw_) / 2;
+ uout = (frame_ + framesize_)
+ + (jUV_ + (outh_ - inh_) / 4) * outw_ / 2
+ + iUV_ + (outw_ - inw_) / 4;
+ vout = uout + framesize_ / 4;
+
+ /* process U/V data */
+ for (j = 0; j < OV511_BLKHEIGHT; j++) {
+ memcpy(uout + j * outw_ / 2, udata, OV511_BLKWIDTH);
+ udata += OV511_BLKWIDTH;
+ memcpy(vout + j * outw_ / 2, vdata, OV511_BLKWIDTH);
+ vdata += OV511_BLKWIDTH;
+ }
+
+ iUV_ += OV511_UVWIDTH;
+ if (iUV_ >= inw_ / 2) {
+ iUV_ = 0;
+ jUV_ += OV511_UVHEIGHT;
+ if (jUV_ >= inh_ / 2)
+ jUV_ = 0;
+ }
+
+ /* process Y data */
+ for (i = 0; i < OV511_YHEIGHT * (OV511_YWIDTH / OV511_BLKWIDTH); i++) {
+ int k;
+
+ j = i / OV511_BLKHEIGHT;
+ k = i - j * OV511_BLKHEIGHT;
+ memcpy(yout + k * outw_ + j * OV511_BLKWIDTH, ydata,
+ OV511_BLKWIDTH);
+ ydata += OV511_BLKWIDTH;
+ }
+
+ iY_ += OV511_YWIDTH;
+ if (iY_ >= inw_) {
+ iY_ = 0;
+ jY_ += OV511_YHEIGHT;
+ if (jY_ >= inh_)
+ jY_ = 0;
+ }
+
+ if (iY_ == 0 && jY_ == 0)
+ state_ = OV511FRAME_DONE;
+}
+
+
+void CIFOV511Grabber::setsize()
+{
+ if (format_ < 0)
+ return;
+
+ set_size_cif(basewidth_ / decimate_, baseheight_ / decimate_);
+ allocref();
+}
Added: vic/branches/mpeg4/video/ov511reg.h
==============================================================================
--- (empty file)
+++ vic/branches/mpeg4/video/ov511reg.h Tue May 26 13:53:56 2009
@@ -0,0 +1,146 @@
+/*
+ * Most portions of this file are taken from vid.h in "vid" written
+ * by Peter S. Housel (http://ovtvid-bsd.sourceforge.net/).
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Copyright information of "vid" is as follows: */
+/* Simple OV511 video capture program, version 1.0.1
+ *
+ * Copyright 2000 Peter S. Housel.
+ *
+ * Portions of this program were modeled after or adapted from the
+ * OV511 driver for Linux by Mark W. McClelland; see
+ * http://alpha.dyndns.org/ov511/ for more information.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _VIDEO_GRABBER_OV511_H_
+#define _VIDEO_GRABBER_OV511_H_
+
+#define OV511_REG_DLYM 0x10
+#define OV511_REG_PEM 0x11
+#define OV511_REG_PXCNT 0x12
+#define OV511_REG_LNCNT 0x13
+#define OV511_REG_PXDV 0x14
+#define OV511_REG_LNDV 0x15
+#define OV511_REG_M400 0x16
+#define OV511_REG_LSTR 0x17
+#define OV511_REG_M420_YFIR 0x18
+#define OV511_REG_SPDLY 0x19
+#define OV511_REG_SNPX 0x1A
+#define OV511_REG_SNLN 0x1B
+#define OV511_REG_SNPD 0x1C
+#define OV511_REG_SNLD 0x1D
+#define OV511_REG_SN400 0x1E
+#define OV511_REG_SNAF 0x1F
+#define OV511_REG_ENFC 0x20
+#define OV511_REG_ARCP 0x21
+#define OV511_REG_MRC 0x22
+#define OV511_REG_RFC 0x23
+#define OV511_REG_PKSZ 0x30
+#define OV511_REG_PKFMT 0x31
+#define OV511_REG_PIO 0x38
+#define OV511_REG_PDATA 0x39
+#define OV511_REG_ENTP 0x3E
+#define OV511_REG_I2C_CONTROL 0x40
+#define OV511_REG_SID 0x41
+#define OV511_REG_SWA 0x42
+#define OV511_REG_SMA 0x43
+#define OV511_REG_SRA 0x44
+#define OV511_REG_SDA 0x45
+#define OV511_REG_PSC 0x46
+#define OV511_REG_TMO 0x47
+#define OV511_REG_SPA 0x48
+#define OV511_REG_SPD 0x49
+#define OV511_REG_RST 0x50
+#define OV511_REG_CLKDIV 0x51
+#define OV511_REG_SNAP 0x52
+#define OV511_REG_EN_SYS 0x53
+#define OV511_REG_USR 0x5E
+#define OV511_REG_CID 0x5F
+#define OV511_REG_PRH_Y 0x70
+#define OV511_REG_PRH_UV 0x71
+#define OV511_REG_PRV_Y 0x72
+#define OV511_REG_PRV_UV 0x73
+#define OV511_REG_QTH_Y 0x74
+#define OV511_REG_QTH_UV 0x75
+#define OV511_REG_QTV_Y 0x76
+#define OV511_REG_QTV_UV 0x77
+#define OV511_REG_CE_EN 0x78
+#define OV511_REG_LT_EN 0x79
+
+#define OV7610_REG_GC 0x00
+#define OV7610_REG_BLU 0x01
+#define OV7610_REG_RED 0x02
+#define OV7610_REG_SAT 0x03
+#define OV7610_REG_CTR 0x05
+#define OV7610_REG_BRT 0x06
+#define OV7610_REG_BBS 0x0C
+#define OV7610_REG_RBS 0x0D
+#define OV7610_REG_GAM 0x0E
+#define OV7610_REG_RWB 0x0F
+#define OV7610_REG_EC 0x10
+#define OV7610_REG_SYN_CLK 0x11
+#define OV7610_REG_COMA 0x12
+#define OV7610_REG_COMB 0x13
+#define OV7610_REG_COMC 0x14
+#define OV7610_REG_COMD 0x15
+#define OV7610_REG_FD 0x16
+#define OV7610_REG_HS 0x17
+#define OV7610_REG_HE 0x18
+#define OV7610_REG_VS 0x19
+#define OV7610_REG_VE 0x1A
+#define OV7610_REG_PS 0x1B
+#define OV7610_REG_MIDH 0x1C
+#define OV7610_REG_MIDL 0x1D
+#define OV7610_REG_COME 0x20
+#define OV7610_REG_YOF 0x21
+#define OV7610_REG_UOF 0x22
+#define OV7610_REG_ECW 0x24
+#define OV7610_REG_ECB 0x25
+#define OV7610_REG_COMF 0x26
+#define OV7610_REG_COMG 0x27
+#define OV7610_REG_COMH 0x28
+#define OV7610_REG_COMI 0x29
+#define OV7610_REG_EHSH 0x2A
+#define OV7610_REG_EHSL 0x2B
+#define OV7610_REG_EXBK 0x2C
+#define OV7610_REG_COMJ 0x2D
+#define OV7610_REG_VOF 0x2E
+#define OV7610_REG_ABS 0x2F
+#define OV7610_REG_YGAM 0x33
+#define OV7610_REG_BADJ 0x34
+#define OV7610_REG_COML 0x35
+#define OV7610_REG_COMK 0x38
+
+#define OV7610_I2C_WRITE_ID 0x42
+#define OV7610_I2C_READ_ID 0x43
+#define OV6xx0_I2C_WRITE_ID 0xC0
+#define OV6xx0_I2C_READ_ID 0xC1
+
+#define OV7610_I2C_RETRIES 3
+#define OV7610_I2C_CLOCK_DIV 4
+
+#endif /* _VIDEO_GRABBER_OV511_H_ */
More information about the Sumover-dev
mailing list