/* * Video spigot grab routines. * Copyright (c) Jim Lowe, 1995. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. 2. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Version 1.2, Feb 17, 1995 */ #ifdef SPIGOT #include #include #include #include #include #include #include #include #include #include "sized_types.h" #include "vid_image.h" #include "vid_util.h" #include "vid_code.h" #include "spigot_grab.h" extern Tcl_Interp *interp; static int width=320, height=240, vtof=10, xmit_color=1; static unsigned short * yuv_data_addr = (unsigned short *)0; static unsigned char status; #define SPIGOT_DEV "/dev/spigot" static int Spigot_Grab(register uint8 *y_data, register int8 *uv_data) { register int x, y; register unsigned short d0, d1, d2, d3; register int8 u, v; register int format; int tmp; if(yuv_data_addr == (unsigned short *)0) return 1; if(width == 640) tmp = 1; else tmp=0; format = saa7191_getv("OFTS"); (void)spigot_start_xfer(1); for(y=0; y> 8) & 0xff)^0x80; *uv_data++ = ((d0 >> 8) & 0xff)^0x80; *uv_data++ = ((d3 >> 8) & 0xff)^0x80; *uv_data++ = ((d2 >> 8) & 0xff)^0x80; } else { /* YUV 4:1:1 */ /* * Data comes from the saa7191 * in the format: * Y0 u[7:6]v[7:6]0[3:0] * Y1 u[5:4]v[5:4]0[3:0] * Y2 u[3:2]v[3:2]0[3:0] * Y3 u[1:0]v[1:0]0[3:0] */ u =(((d1 >> 8) & 0xc0) | ((d0 >> 10) & 0x30) | ((d3 >> 12) & 0x0c) | ((d2 >> 14) & 0x03)) ^0x80; v =(((d1 >> 6) & 0xc0) | ((d0 >> 8) & 0x30) | ((d3 >> 10) & 0x0c) | ((d2 >> 12) & 0x03)) ^0x80; *uv_data++ = u; *uv_data++ = v; *uv_data++ = u; *uv_data++ = v; } } } } spigot_stop_xfer(); return 1; } /* * Set spigot register. */ #define NAME 0 #define GETSET 1 #define CMD 2 #define VALUE 3 int SpigotCmd(ClientData clientdata, Tcl_Interp *interp, int ac, char *av[]) { int set; int data; static char buf[50]; if(ac < 3) { interp->result = "wrong # arguments"; return TCL_ERROR; } set = 0; /* default to get command */ if(strcmp(av[GETSET], "set") == 0) { if(ac != 4) { interp->result = "wrong # arguments"; return TCL_ERROR; } set = 1; data = atoi(av[VALUE]); } else if (ac != 3) { interp->result = "wrong # arguments"; return TCL_ERROR; } if(strcmp(av[CMD], "VTOF") == 0) { if(set) { if(data < 0 || data > 15) { interp->result = "Bad value"; return TCL_ERROR; } vtof = data; spigot_set_capture_size(width, vtof); return TCL_OK; } else { sprintf(buf, "%d", vtof); interp->result = buf; return TCL_OK; } } if (set) { if(saa7191_setv(av[CMD], data)) { return TCL_OK; } else { interp->result = "Bad value"; return TCL_ERROR; } } else { data = saa7191_getv(av[CMD]); sprintf(buf, "%d", data); interp->result = buf; return TCL_OK; } } int Spigot_Probe(void) { if((yuv_data_addr=spigot_open(SPIGOT_DEV))==(unsigned short *)0) return 0; Tcl_CreateCommand(interp, "spigot", SpigotCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); status = spigot_status(); if(status & SPIGOT_60HZ) return VID_SMALL|VID_MEDIUM|VID_LARGE|VID_GREYSCALE|VID_COLOR; else return VID_SMALL|VID_MEDIUM|VID_GREYSCALE|VID_COLOR; } char * Spigot_Attach(void) { saa7191_init(NULL, 0); #ifdef SPIGOT_EXPERT return ".grabControls.spigote"; #else return ".grabControls.spigot"; #endif } void Spigot_Detach(void) { } grabproc_t * Spigot_Start(int framerate, int config, reconfigproc_t *reconfig) { grabproc_t *grabber; int xmit_size; if((yuv_data_addr=spigot_open(SPIGOT_DEV))==(unsigned short *)0) return; grabber=Spigot_Grab; xmit_size = config & VID_SIZEMASK; xmit_color = config & VID_COLOR; status = spigot_status(); switch (status & (SPIGOT_COLOR|SPIGOT_60HZ|SPIGOT_NO_HORIZONTAL_LOCK)) { default: fprintf(stderr, "Warning: no video signal found!\n"); case 2: /* NTSC no color */ case 3: /* NTSC color */ switch (xmit_size) { case VID_SMALL: width = NTSC_WIDTH/2; height = NTSC_HEIGHT/2; break; case VID_MEDIUM: width = NTSC_WIDTH; height = NTSC_HEIGHT; break; case VID_LARGE: width = NTSC_WIDTH*2; height = NTSC_HEIGHT*2; break; } break; case 0: /* PAL no color */ case 1: /* PAL color */ switch (xmit_size) { case VID_SMALL: width = PAL_WIDTH/2; height = PAL_HEIGHT/2; break; case VID_MEDIUM: width = PAL_WIDTH; height = PAL_HEIGHT; break; case VID_LARGE: width = PAL_WIDTH*2; height = PAL_HEIGHT*2; break; } break; } (*reconfig)(xmit_color, width, height); spigot_set_capture_size(width, vtof); return grabber; } void Spigot_Stop(void) { yuv_data_addr = (unsigned short *)0; #ifdef notdef (void)spigot_close(); #endif } #endif