Logo Search packages:      
Sourcecode: vic version File versions

grabber-vpix.cpp

/*
 * Copyright (c) 1993-1995 Regents of the University of California.
 * All rights reserved.
 *
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and the Network Research Group at
 *      Lawrence Berkeley Laboratory.
 * 4. Neither the name of the University nor of the Laboratory may be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
 */
static const char rcsid[] =
    "@(#) $Header: /cs/research/mice/starship/src/local/CVS_repository/vic/video/grabber-vpix.cpp,v 1.1 1999/09/09 12:52:56 piers Exp $ (LBL)";

#include "config.h"
#include <fcntl.h>
//#include <sys/types.h>
#include <sys/ioctl.h>

extern "C" {
#include <vfc_lib.h>
}

#include "grabber.h"
#include "vic_tcl.h"
#include "device-input.h"
#include "module.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

/*XXX*/
#if defined(sun) && defined(__GNUC__)
#define VOLATILE register volatile
#else
/* sun's C++ compiler doesn't handle 'register volatile' correctly */
#define VOLATILE volatile
#endif


class VideoPixGrabber : public Grabber {
    public:
      VideoPixGrabber();
      virtual ~VideoPixGrabber();
      virtual void start();
    protected:
      virtual int command(int argc, const char*const* argv);
      int capture();
      virtual int grab();
      virtual void NTSCgrabSmall();
      virtual void NTSCgrabMedium();
      virtual void PALgrabSmall();
      virtual void PALgrabMedium();
      void format();
      void normalize();
      virtual void setsize();

      int format_;            /* video format: NTSC or PAL */
      int rformat_;           /* requested format, above + AUTO */
      VfcDev* vfcdev_;
      int port_;        /* videopix input port */
      u_int basewidth_;
      u_int baseheight_;
      u_int decimate_;
};

class VideoPix411Grabber : public VideoPixGrabber {
    public:
      VideoPix411Grabber();
    protected:
      virtual void NTSCgrabSmall();
      virtual void NTSCgrabMedium();
      virtual void PALgrabSmall();
      virtual void PALgrabMedium();
      virtual void setsize();
      int loff_;        /* offset from start of frame to scan */
      int coff_;        /* offset from start of frame to scan */
      int hwrap_;       /* amount to skip on each output line */
      int hskip_;       /* amount of input to throw out on each line */
};

class CIFVideoPixGrabber : public VideoPix411Grabber {
    protected:
      virtual void PALgrabSmall();
      virtual void PALgrabMedium();
      virtual void setsize();
};

class VideoPixDevice : public InputDevice {
    public:
      VideoPixDevice(const char*);
      virtual int command(int argc, const char*const* argv);
};

static VideoPixDevice vpix_device("videopix");

VideoPixDevice::VideoPixDevice(const char* name) : InputDevice(name)
{
      if (access("/dev/vfc0", R_OK) == 0)
            attributes_ = "\
format { 411 422 } \
size { small cif } \
port { Composite-1 Composite-2 S-Video}";
      else
            attributes_ = "disabled";
}

int VideoPixDevice::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 VideoPixGrabber;
                  else if (strcmp(argv[2], "411") == 0)
                        o = new VideoPix411Grabber;
                  else if (strcmp(argv[2], "cif") == 0)
                        o = new CIFVideoPixGrabber;
                  if (o != 0)
                        tcl.result(o->name());
                  return (TCL_OK);
            }
      }
      return (InputDevice::command(argc, argv));
}

VideoPixGrabber::VideoPixGrabber()
{
      /*
       * This is a horrible hack to prevent the VFC library from printing
       * error messages that we would rather not print.
       */
      int fd = dup(2);
      close(2);
      open("/dev/null", O_RDONLY);
      vfcdev_ = vfc_open("/dev/vfc0", VFC_LOCKDEV);
      dup2(fd, 2);
      close(fd);
      if (vfcdev_ == 0) {
            status_ = -1;
            return;
      }
      port_ = 1;
      /*XXX*/
      format_ = -1;
      rformat_ = VFC_AUTO;
      decimate_ = 2;
      basewidth_ = 0;
      baseheight_ = 0;
}

VideoPixGrabber::~VideoPixGrabber()
{
      if (vfcdev_ != 0) {
            vfc_destroy(vfcdev_);
            vfcdev_ = 0;
      }
}

void VideoPixGrabber::setsize()
{
      if (format_ < 0)
            return;
      set_size_422(basewidth_ / decimate_, baseheight_ / decimate_);
      allocref();
}

void VideoPixGrabber::format()
{
      int format;
      vfc_set_port(vfcdev_, port_);
      vfc_set_format(vfcdev_, rformat_, &format);
      int w, h;
      switch (format) {

      default:
      case NO_LOCK:
            if (rformat_ == VFC_AUTO)
                  fprintf(stderr,
                  "vic: videopix sees no signal - using ntsc.\n");
            /* fall through */
      case NTSC_COLOR:
      case NTSC_NOCOLOR:
            format_ = VFC_NTSC;
            w = NTSC_WIDTH * 2;
            h = NTSC_HEIGHT * 2;
            break;

      case PAL_COLOR:
      case PAL_NOCOLOR:
            format_ = VFC_PAL;
            w = PAL_WIDTH * 2;
            h = PAL_HEIGHT * 2;
            break;
      }
      basewidth_ = w;
      baseheight_ = h;
      setsize();
}

/*XXX*/
void VideoPixGrabber::normalize()
{
      if (! running_)
            return;

      /* set the intensity map to an identity map & capture a frame. */
      int i;
      for (i = 0; i < 256; ++i)
            ynorm_[i] = u_char(i);

      capture();

      /* find the min & max y values */
      u_char* fp = frame_;
      u_int min = *fp++;
      u_int max = min;
      for (i = framesize_; --i > 0; ) {
            u_int p = *fp++;
            if (p < min)
                  min = p;
            else if (p > max)
                  max = p;
      }
      /*
       * if the range of the signal is small (i.e., all black) don't
       * do anything.  Otherwise reset the min & max based on the
       * frame & compute a new intensity map.
       */
      if (max - min < 64)
            return;

      ymin_ = min;
      ymax_ = max;
      contrast(contrast_);
}

void VideoPixGrabber::start()
{
      format();
      Grabber::start();
}

int VideoPixGrabber::command(int argc, const char*const* argv)
{
      if (argc == 3) {
            if (strcmp(argv[1], "decimate") == 0) {
                  int dec = atoi(argv[2]);
                  Tcl& tcl = Tcl::instance();
                  if (dec <= 0) {
                        tcl.resultf("%s: divide by zero", argv[0]);
                        return (TCL_ERROR);
                  }
                  if (u_int(dec) != decimate_) {
                        decimate_ = dec;
                        setsize();
                  }
                  return (TCL_OK);  
            } else if (strcmp(argv[1], "port") == 0) {
                  int p = 0;
                  if (strcmp(argv[2], "Composite-1") == 0)
                        p = VFC_PORT1;
                  else if (strcmp(argv[2], "Composite-2") == 0)
                        p = VFC_PORT2;
                  else if (strcmp(argv[2], "S-Video") == 0)
                        p = VFC_SVIDEO;
                  else {
                        Tcl& tcl = Tcl::instance();
                        tcl.resultf("%s: unknown port", argv[2]);
                        return (TCL_ERROR);
                  }
                  if (p != port_) {
                        port_ = p;
                        vfc_set_port(vfcdev_, p);
                  }
                  return (TCL_OK);  
            } else if (strcmp(argv[1], "format") == 0) {
                  if (strcmp(argv[2], "auto") == 0)
                        rformat_ = VFC_AUTO;
                  else if (strcmp(argv[2], "pal") == 0)
                        rformat_ = VFC_PAL;
                  else
                        rformat_ = VFC_NTSC;
                  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_) {

                  case VFC_AUTO:
                        tcl.result("auto");
                        break;

                  case VFC_NTSC:
                        tcl.result("ntsc");
                        break;

                  case VFC_PAL:
                        tcl.result("pal");
                        break;

                  default:
                        tcl.result("");
                        break;
                  }
                  return (TCL_OK);
                  
            }
      }
      return (Grabber::command(argc, argv));
}

#ifdef VPIX_SUN4C
typedef unsigned long long u_ll;

#define PIX0 (d0.i.h)
#define PIX1 (d0.i.l)
#define PIX2 (d1.i.h)
#define PIX3 (d1.i.l)
#define BW_CAPTURE_DEFS \
      union { \
            u_ll l; \
            struct { \
                  u_int h; \
                  u_int l; \
            } i; \
      } d0, d1; \
      register u_int y; \
      register u_char* ynorm = ynorm_;
#define CAPTURE_DEFS \
      BW_CAPTURE_DEFS \
      register u_short u, v;
#define NEXT4 \
      d0.l = *(volatile u_ll*)iochan; \
      d0.i.h >>= 16; \
      d0.i.l >>= 16; \
      d1.l = *(volatile u_ll*)iochan; \
      d1.i.h >>= 16; \
      d1.i.l >>= 16;
#define PRESKIP(n) \
      for (int i = ((n) - 1) / 2; --i >= 0; ) \
            *(volatile u_ll*)iochan; \
      *iochan;
#define LINESKIP(n) \
{ \
      for (int i = (n) / 2; --i >= 0; ) \
            *(volatile u_ll*)iochan;  \
}

#else
#define PIX0 (d0)
#define PIX1 (d1)
#define PIX2 (d2)
#define PIX3 (d3)
#define BW_CAPTURE_DEFS \
      register u_int y, d0, d1, d2, d3; \
      register u_char* ynorm = ynorm_;
#define CAPTURE_DEFS \
      BW_CAPTURE_DEFS \
      register u_short u, v;
#define NEXT4 \
      d0 = *iochan >> 16; \
      d1 = *iochan >> 16; \
      d2 = *iochan >> 16; \
      d3 = *iochan >> 16;
#define PRESKIP(n) \
      for (int i = (n) - 1; --i >= 0; ) \
            *iochan;
#define LINESKIP(n) \
{ \
      for (int i = (n); --i >= 0; ) \
            *iochan; \
}
#endif

#define YSTART(r) \
      y = ynorm[(r) >> 8];
#define YADD(r) \
      y <<= 8; \
      y |= ynorm[(r) >> 8];
#define UVHIGH \
      u  = (PIX0 & 0xc0) << 8; \
      u |= (PIX1 & 0xc0) << 6; \
      u |= (PIX2 & 0xc0) << 4; \
      v  = (PIX0 & 0x30) << 10; \
      v |= (PIX1 & 0x30) << 8; \
      v |= (PIX2 & 0x30) << 6;
#define UVLOW \
      u |= (PIX0 & 0xc0); \
      u |= (PIX1 & 0xc0) >> 2; \
      u |= (PIX2 & 0xc0) >> 4; \
      v |= (PIX0 & 0x30) << 2; \
      v |= (PIX1 & 0x30); \
      v |= (PIX2 & 0x30) >> 2; \
      u ^= 0x8080; v ^= 0x8080;

void VideoPixGrabber::NTSCgrabMedium()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_OSKIP_NTSC)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 1;

      for (int h = NTSC_HEIGHT; --h >= 0; ) {
            LINESKIP(16)
            for (int w = NTSC_WIDTH / 20; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  NEXT4 YSTART(PIX0) UVHIGH /*did 9, skip 1*/
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  NEXT4 YADD(PIX0)
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  YSTART(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  NEXT4 YADD(PIX0)
                  ((u_int*)lum)[3] = y;
                  ((u_short*)chm)[3] = u;
                  ((u_short*)(chm+off))[3] = v;

                  YSTART(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) /* did 9, skip 1 */
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[4] = y;
                  ((u_short*)chm)[4] = u;
                  ((u_short*)(chm+off))[4] = v;

                  lum += 4*5; chm += 2*5;
            }
      }
}

void VideoPixGrabber::NTSCgrabSmall()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_OSKIP_NTSC)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 1;

      for (int h = NTSC_HEIGHT / 2; --h >= 0; ) {
            LINESKIP(720 + 16)
            for (int w = NTSC_WIDTH / 40; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  /*after 9, skip 1*/
                  NEXT4 YSTART(PIX0) NEXT4 UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[3] = y;
                  ((u_short*)chm)[3] = u;
                  ((u_short*)(chm+off))[3] = v;

                  /*after 9, skip 1*/
                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0) NEXT4
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[4] = y;
                  ((u_short*)chm)[4] = u;
                  ((u_short*)(chm+off))[4] = v;

                  lum += 4*5; chm += 2*5;
            }
      }
}

void VideoPixGrabber::PALgrabMedium()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_ESKIP_PAL)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 1;

      for (int h = PAL_HEIGHT; --h >= 0; ) {
            LINESKIP(16)
            for (int w = PAL_WIDTH / 24; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX1) UVLOW   /*dup 11th*/
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  YSTART(PIX2) NEXT4 YADD(PIX0) UVHIGH
                  YADD(PIX2) NEXT4 YADD(PIX0) UVLOW
                  ((u_int*)lum)[3] = y;
                  ((u_short*)chm)[3] = u;
                  ((u_short*)(chm+off))[3] = v;

                  YSTART(PIX2) NEXT4 YADD(PIX0) UVHIGH
                  YADD(PIX2) NEXT4 YADD(PIX0) UVLOW
                  ((u_int*)lum)[4] = y;
                  ((u_short*)chm)[4] = u;
                  ((u_short*)(chm+off))[4] = v;

                  YSTART(PIX2) NEXT4 YADD(PIX0) UVHIGH
                  YADD(PIX2) YADD(PIX3) UVLOW         /*dup 11th*/
                  ((u_int*)lum)[5] = y;
                  ((u_short*)chm)[5] = u;
                  ((u_short*)(chm+off))[5] = v;

                  lum += 4*6; chm += 2*6;
            }
      }
}

void VideoPixGrabber::PALgrabSmall()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_ESKIP_PAL)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 1;

      for (int h = PAL_HEIGHT / 2; --h >= 0; ) {
            LINESKIP(720 + 16)
            for (int w = PAL_WIDTH / 24; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW YADD(PIX2)   /*dup 11th*/
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  lum += 4*3; chm += 2*3;
            }
      }
}

int VideoPixGrabber::capture()
{
      int cmd = CAPTRCMD;
      if (ioctl(vfcdev_->vfc_fd, VFCSCTRL, (char*)&cmd) == -1)
            return (0);

      switch (format_ | (decimate_ << 1)) {

      case VFC_PAL | (2 << 1):
            PALgrabMedium();
            break;

      case VFC_PAL | (4 << 1):
            PALgrabSmall();
            break;

      case VFC_NTSC | (2 << 1):
            NTSCgrabMedium();
            break;

      case VFC_NTSC | (4 << 1):
            NTSCgrabSmall();
            break;

      default:
            return (0);
      }
      return (1);
}

int VideoPixGrabber::grab()
{
      if (capture() == 0)
            return (0);
      suppress(frame_);
      saveblks(frame_);
      YuvFrame f(media_ts(), frame_, crvec_, outw_, outh_);
      return (target_->consume(&f));
}

VideoPix411Grabber::VideoPix411Grabber()
      : loff_(0), coff_(0), hwrap_(0), hskip_(0)
{
}

void VideoPix411Grabber::setsize()
{
      if (format_ < 0)
            return;
      set_size_411(basewidth_ / decimate_, baseheight_ / decimate_);
      allocref();
      loff_ = 0;
      coff_ = 0;
      hskip_ = 0;
      hwrap_ = 0;
}

void CIFVideoPixGrabber::setsize()
{
      if (format_ < 0)
            return;
      set_size_cif(basewidth_ / decimate_, baseheight_ / decimate_);
      /*XXX*/
      vstart_ = 0;
      vstop_ = blkh_;
      hstart_ = 1;
      hstop_ = blkw_ - 1;

      allocref();

      int voff = (outh_ - inh_) / 2;
      hwrap_ = outw_ - inw_;
      int hoff = hwrap_ / 2;
      loff_ = outw_ * voff + hoff;
      coff_ = (outw_ >> 1) * (voff >> 1) + (hoff >> 1);
}

void VideoPix411Grabber::NTSCgrabMedium()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_OSKIP_NTSC)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 2;

      lum += loff_;
      chm += coff_;

      int hwrap = hwrap_;
      for (int h = NTSC_HEIGHT; h > 0; h -= 2) {
            LINESKIP(16)
            int w;
            for (w = NTSC_WIDTH / 20; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  NEXT4 YSTART(PIX0) UVHIGH /*did 9, skip 1*/
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  NEXT4 YADD(PIX0)
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  YSTART(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  NEXT4 YADD(PIX0)
                  ((u_int*)lum)[3] = y;
                  ((u_short*)chm)[3] = u;
                  ((u_short*)(chm+off))[3] = v;

                  YSTART(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) /* did 9, skip 1 */
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[4] = y;
                  ((u_short*)chm)[4] = u;
                  ((u_short*)(chm+off))[4] = v;

                  lum += 4*5; chm += 2*5;
            }
            lum += hwrap;
            chm += hwrap >> 1;

            LINESKIP(16)
            for (w = NTSC_WIDTH / 20; --w >= 0; ) {
                  BW_CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  ((u_int*)lum)[0] = y;

                  NEXT4 YSTART(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  ((u_int*)lum)[1] = y;

                  NEXT4 YSTART(PIX0) /*did 9, skip 1*/
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0)
                  ((u_int*)lum)[2] = y;

                  YSTART(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0)
                  ((u_int*)lum)[3] = y;

                  YSTART(PIX2)
                  NEXT4 YADD(PIX0) /* did 9, skip 1 */
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  ((u_int*)lum)[4] = y;

                  lum += 4*5;
            }
            lum += hwrap;
      }
}

void VideoPix411Grabber::NTSCgrabSmall()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_OSKIP_NTSC)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 2;

      lum += loff_;
      chm += coff_;

      int hwrap = hwrap_;
      for (int h = NTSC_HEIGHT / 2; h > 0; h -= 2) {
            LINESKIP(720 + 16)
            int w;
            for (w = NTSC_WIDTH / 40; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  /*after 9, skip 1*/
                  NEXT4 YSTART(PIX0) NEXT4 UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[3] = y;
                  ((u_short*)chm)[3] = u;
                  ((u_short*)(chm+off))[3] = v;

                  /*after 9, skip 1*/
                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0) NEXT4
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0)
                  ((u_int*)lum)[4] = y;
                  ((u_short*)chm)[4] = u;
                  ((u_short*)(chm+off))[4] = v;

                  lum += 4*5; chm += 2*5;
            }
            lum += hwrap;
            chm += hwrap >> 1;

            LINESKIP(720 + 16)
            for (w = NTSC_WIDTH / 40; --w >= 0; ) {
                  BW_CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0)
                  ((u_int*)lum)[0] = y;

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0)
                  ((u_int*)lum)[1] = y;

                  /*after 9, skip 1*/
                  NEXT4 YSTART(PIX0) NEXT4 NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0)
                  ((u_int*)lum)[2] = y;

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0)
                  ((u_int*)lum)[3] = y;

                  /*after 9, skip 1*/
                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0) NEXT4
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0)
                  ((u_int*)lum)[4] = y;

                  lum += 4*5;
            }
            lum += hwrap;
      }
}

void VideoPix411Grabber::PALgrabMedium()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_ESKIP_PAL)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 2;

      for (int h = PAL_HEIGHT / 2; --h >= 0; ) {
            LINESKIP(16)
            int w;
            for (w = PAL_WIDTH / 24; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX1) UVLOW   /*dup 11th*/
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  YSTART(PIX2) NEXT4 YADD(PIX0) UVHIGH
                  YADD(PIX2) NEXT4 YADD(PIX0) UVLOW
                  ((u_int*)lum)[3] = y;
                  ((u_short*)chm)[3] = u;
                  ((u_short*)(chm+off))[3] = v;

                  YSTART(PIX2) NEXT4 YADD(PIX0) UVHIGH
                  YADD(PIX2) NEXT4 YADD(PIX0) UVLOW
                  ((u_int*)lum)[4] = y;
                  ((u_short*)chm)[4] = u;
                  ((u_short*)(chm+off))[4] = v;

                  YSTART(PIX2) NEXT4 YADD(PIX0) UVHIGH
                  YADD(PIX2) YADD(PIX3) UVLOW         /*dup 11th*/
                  ((u_int*)lum)[5] = y;
                  ((u_short*)chm)[5] = u;
                  ((u_short*)(chm+off))[5] = v;

                  lum += 4*6; chm += 2*6;
            }
            LINESKIP(16)
            for (w = PAL_WIDTH / 24; --w >= 0; ) {
                  BW_CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  ((u_int*)lum)[0] = y;

                  NEXT4 YSTART(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  ((u_int*)lum)[1] = y;

                  NEXT4 YSTART(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX1)   /*dup 11th*/
                  ((u_int*)lum)[2] = y;

                  YSTART(PIX2) NEXT4 YADD(PIX0)
                  YADD(PIX2) NEXT4 YADD(PIX0)
                  ((u_int*)lum)[3] = y;

                  YSTART(PIX2) NEXT4 YADD(PIX0)
                  YADD(PIX2) NEXT4 YADD(PIX0)
                  ((u_int*)lum)[4] = y;

                  YSTART(PIX2) NEXT4 YADD(PIX0)
                  YADD(PIX2) YADD(PIX3)         /*dup 11th*/
                  ((u_int*)lum)[5] = y;

                  lum += 4*6;
            }
      }
}

void VideoPix411Grabber::PALgrabSmall()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_ESKIP_PAL)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 2;

      for (int h = PAL_HEIGHT / 2; h > 0; h -= 2) {
            LINESKIP(720 + 16)
            int w;
            for (w = PAL_WIDTH / 24; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW YADD(PIX2)   /*dup 11th*/
                  ((u_int*)lum)[2] = y;
                  ((u_short*)chm)[2] = u;
                  ((u_short*)(chm+off))[2] = v;

                  lum += 4*3; chm += 2*3;
            }

            LINESKIP(720 + 16)
            for (w = PAL_WIDTH / 24; --w >= 0; ) {
                  BW_CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[0] = y;

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[1] = y;

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) YADD(PIX2)   /*dup 11th*/
                  ((u_int*)lum)[2] = y;

                  lum += 4*3;
            }
      }
}

void CIFVideoPixGrabber::PALgrabMedium()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_ESKIP_PAL)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 2;

      for (int h = PAL_HEIGHT / 2; --h >= 0; ) {
            LINESKIP(16)
            int w;
            for (w = CIF_WIDTH / 8; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) YADD(PIX2) UVHIGH
                  NEXT4 YADD(PIX0) YADD(PIX2) UVLOW
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  lum += 4*2; chm += 2*2;
            }
            LINESKIP(16)
            for (w = CIF_WIDTH / 8; --w >= 0; ) {
                  BW_CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  ((u_int*)lum)[0] = y;

                  NEXT4 YSTART(PIX0) YADD(PIX2)
                  NEXT4 YADD(PIX0) YADD(PIX2)
                  ((u_int*)lum)[1] = y;

                  lum += 4*2;
            }
      }
}

void CIFVideoPixGrabber::PALgrabSmall()
{
      VOLATILE u_int* iochan = (u_int*)vfcdev_->vfc_port1;
      PRESKIP(VFC_ESKIP_PAL)

      u_char* lum = frame_;
      int off = framesize_;
      u_char* chm = frame_ + off;
      off >>= 2;

      for (int h = PAL_HEIGHT / 4; --h > 0; ) {
            LINESKIP(720 + 16)
            int w;
            for (w = CIF_WIDTH / 16; --w >= 0; ) {
                  CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[0] = y;
                  ((u_short*)chm)[0] = u;
                  ((u_short*)(chm+off))[0] = v;

                  NEXT4 YSTART(PIX0) UVHIGH NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) UVLOW NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[1] = y;
                  ((u_short*)chm)[1] = u;
                  ((u_short*)(chm+off))[1] = v;

                  lum += 4*2; chm += 2*2;
            }

            LINESKIP(720 + 16)
            for (w = CIF_WIDTH / 16; --w >= 0; ) {
                  BW_CAPTURE_DEFS

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[0] = y;

                  NEXT4 YSTART(PIX0) NEXT4 YADD(PIX0)
                  NEXT4 YADD(PIX0) NEXT4 YADD(PIX0) 
                  ((u_int*)lum)[1] = y;

                  lum += 4*2;
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index