aboutsummaryrefslogtreecommitdiffstats
path: root/mbone/vic/files
diff options
context:
space:
mode:
authorfenner <fenner@FreeBSD.org>1997-12-19 10:50:52 +0800
committerfenner <fenner@FreeBSD.org>1997-12-19 10:50:52 +0800
commit86fc2f677b1c200a4535f8cb3495c7d4883bdc25 (patch)
treed9b4ad9201b0b98e8e263528312e93683c72a85a /mbone/vic/files
parent18884632e0abac0fe89771de20c8c450fe57a97e (diff)
downloadfreebsd-ports-gnome-86fc2f677b1c200a4535f8cb3495c7d4883bdc25.tar.gz
freebsd-ports-gnome-86fc2f677b1c200a4535f8cb3495c7d4883bdc25.tar.zst
freebsd-ports-gnome-86fc2f677b1c200a4535f8cb3495c7d4883bdc25.zip
Add BT848 grabber support.
Submitted by: Amancio Hasty <hasty@rah.star-gate.com>
Diffstat (limited to 'mbone/vic/files')
-rw-r--r--mbone/vic/files/patch-af725
1 files changed, 725 insertions, 0 deletions
diff --git a/mbone/vic/files/patch-af b/mbone/vic/files/patch-af
new file mode 100644
index 000000000000..9d72ea29a885
--- /dev/null
+++ b/mbone/vic/files/patch-af
@@ -0,0 +1,725 @@
+--- grabber-meteor.cc.orig Sat May 18 11:44:54 1996
++++ grabber-meteor.cc Thu Dec 18 18:35:09 1997
+@@ -43,7 +43,6 @@
+ *
+ */
+
+-/*#define FRAME_CNTS /* print frame counts and fps when device stops -- debug */
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+@@ -51,14 +50,13 @@
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+ #include <sys/mman.h>
+-#ifdef FRAME_CNTS
+-#include <sys/time.h>
+-#endif
+
+ #include "grabber.h"
++#include "crdef.h"
+ #include "Tcl.h"
+ #include "device-input.h"
+ #include "module.h"
++#include "bsd-endian.h"
+
+ #include <machine/ioctl_meteor.h>
+
+@@ -72,62 +70,85 @@
+
+
+ class MeteorGrabber : public Grabber {
+- public:
+- MeteorGrabber(const char* name, const char* format);
++ public:
++ MeteorGrabber(const char* name);
+ virtual ~MeteorGrabber();
++ virtual int command(int argc, const char*const* argv);
++ virtual void fps(int);
+ virtual void start();
+ virtual void stop();
+- virtual void fps(int);
+- protected:
+- virtual int command(int argc, const char*const* argv);
+- virtual int capture();
+ virtual int grab();
++ protected:
+ void format();
+- void setsize();
++ virtual void setsize() = 0;
++ void suppress(const u_char* in, int istride);
++ virtual void saveblks(const u_char* in, int istride) = 0;
++ void set_size_meteor(int w, int h);
+
+ int video_format_; /* video input format: NTSC or PAL */
+ int dev_; /* device fd */
+ int port_; /* video input port */
+- int coder_format_; /* 411, 422, or cif */
+ u_int basewidth_; /* Height of frame to be captured */
+ u_int baseheight_; /* Width of frame to be captured */
+ u_int decimate_; /* division of base sizes */
+ volatile u_int* pyuv_; /* pointer to yuv data */
+-#ifdef FRAME_CNTS
+- struct meteor_counts cnts_; /* pointer to counters */
+- double start_time_;
+-#endif
+ };
+
+-static const int f_411 = 0; /* coder_format_s */
+-static const int f_422 = 1;
+-static const int f_cif = 2;
++class Meteor422Grabber : public MeteorGrabber {
++ public:
++ Meteor422Grabber(const char* name);
++ protected:
++ void setsize();
++ void saveblk(const u_char* in, u_char* yp, u_char* up, u_char* vp,
++ int stride, int istride);
++ void saveblks(const u_char* in, int istride);
++};
++
++class MeteorCIFGrabber : public MeteorGrabber {
++ public:
++ MeteorCIFGrabber(const char* name);
++ protected:
++ void setsize();
++ void saveblk(const u_char* in, u_char* yp, u_char* up, u_char* vp,
++ int stride, int istride);
++ void saveblks(const u_char* in, int istride);
++};
+
+ class MeteorDevice : public InputDevice {
+- public:
++ public:
+ MeteorDevice(const char* nickname, const char* devname, int free);
+ virtual int command(int argc, const char*const* argv);
+- protected:
++ protected:
+ const char* name_;
+ };
+
+ class MeteorScanner {
+- public:
++ public:
+ MeteorScanner(const int n);
+ };
++
+ static MeteorScanner find_meteor_devices(4);
+
+ MeteorScanner::MeteorScanner(const int n)
+ {
+ char* devname_template = "/dev/meteor%d";
+ char* nickname_template = "Matrox Meteor %d";
++ char* devname_template1 = "/dev/bktr%d";
++ char* nickname_template1 = "BrookTree848 %d";
++
++
+
+ for(int i = 0; i < n; i++) {
+ char *devname = new char[strlen(devname_template) + 3];
+ char *nickname = new char[strlen(nickname_template) + 3];
++ char *devname1 = new char[strlen(devname_template1) + 3];
++ char *nickname1 = new char[strlen(nickname_template1) + 3];
+
+ sprintf(nickname, nickname_template, i + 1);
+ sprintf(devname, devname_template, i);
++
++ sprintf(nickname1, nickname_template1, i + 1);
++ sprintf(devname1, devname_template1, i);
+ if(access(devname, R_OK) == 0) {
+ int fd = open(devname, O_RDONLY);
+ if(fd < 0) {
+@@ -140,7 +161,21 @@
+ delete nickname;
+ delete devname;
+ }
++
++ if(access(devname1, R_OK) == 0) {
++ int fd = open(devname1, O_RDONLY);
++ if(fd < 0) {
++ new MeteorDevice(nickname1, devname1, 0);
++ } else {
++ (void)close(fd);
++ new MeteorDevice(nickname1, devname1, 1);
++ }
++ } else {
++ delete nickname1;
++ delete devname1;
++ }
+ }
++
+ }
+
+ MeteorDevice::MeteorDevice(const char* nickname, const char *devname, int free):
+@@ -160,7 +195,10 @@
+ Tcl& tcl = Tcl::instance();
+ if ((argc == 3) && (strcmp(argv[1], "open") == 0)) {
+ TclObject* o = 0;
+- o = new MeteorGrabber(name_, argv[2]);
++ if (strcmp(argv[2], "422") == 0)
++ o = new Meteor422Grabber(name_);
++ else if (strcmp(argv[2], "cif") == 0)
++ o = new MeteorCIFGrabber(name_);
+ if (o != 0)
+ tcl.result(o->name());
+ return (TCL_OK);
+@@ -168,19 +206,8 @@
+ return (InputDevice::command(argc, argv));
+ }
+
+-MeteorGrabber::MeteorGrabber(const char* name, const char* format)
++MeteorGrabber::MeteorGrabber(const char* name)
+ {
+- coder_format_ = -1;
+- if(!strcmp(format, "411")) coder_format_ = f_411;
+- if(!strcmp(format, "422")) coder_format_ = f_422;
+- if(!strcmp(format, "cif")) coder_format_ = f_cif;
+- if(coder_format_ == -1) {
+- fprintf(stderr,
+- "vic: MeteorGrabber: unsupported format: %s\n",
+- format);
+- abort();
+- }
+-
+ dev_ = open(name, O_RDONLY);
+ if (dev_ == -1) {
+ status_ = -1;
+@@ -205,27 +232,27 @@
+ }
+ }
+
+-void MeteorGrabber::setsize()
++void MeteorGrabber::set_size_meteor(int w, int h)
+ {
+ struct meteor_geomet geom;
+
+- geom.rows = (baseheight_ / decimate_) &~0xf; /* 0xf, ugh! */
+- geom.columns = (basewidth_ / decimate_) &~0xf;
++ geom.rows = h &~0xf; /* 0xf, ugh! */
++ geom.columns = w &~0xf;
+ geom.frames = 1;
+- geom.oformat = METEOR_GEO_UNSIGNED;
+- geom.oformat |= METEOR_GEO_YUV_422;
++ geom.oformat = METEOR_GEO_UNSIGNED | METEOR_GEO_YUV_PACKED;
+ /*
+ * If we can get by with only reading even fields, then by all
+ * means do so.
+ */
+ unsigned short status;
+ ioctl(dev_, METEORSTATUS, &status);
+- if(status & METEOR_STATUS_HCLK) { /* do we have a source? */
+- /* No source, assume ntsc*/
++ if(status & METEOR_STATUS_HCLK) {
++ /* No source, assume ntsc */
+ if(geom.rows <= NTSC_HEIGHT && geom.columns <= NTSC_WIDTH)
+ geom.oformat |= METEOR_GEO_EVEN_ONLY;
+ } else {
+- if(status & METEOR_STATUS_FIDT) { /* is it pal or ntsc? */
++ /* is it pal or ntsc? */
++ if(status & METEOR_STATUS_FIDT) {
+ /* 60 hz */
+ if(geom.rows<=NTSC_HEIGHT && geom.columns<=NTSC_WIDTH)
+ geom.oformat |= METEOR_GEO_EVEN_ONLY;
+@@ -237,18 +264,6 @@
+
+ if(ioctl(dev_, METEORSETGEO, &geom) < 0)
+ perror("vic: METERSETGEO: ");
+-
+- switch(coder_format_) {
+- case f_422:
+- set_size_422(geom.columns, geom.rows);
+- break;
+- case f_cif:
+- case f_411:
+- set_size_411(geom.columns, geom.rows);
+- break;
+- }
+-
+- allocref(); /* allocate reference frame */
+ }
+
+ void MeteorGrabber::format()
+@@ -285,11 +300,6 @@
+ baseheight_ = PAL_HEIGHT * 2;
+ basewidth_ = PAL_WIDTH * 2;
+ }
+-
+- if(coder_format_ == f_cif) {
+- baseheight_ = CIF_HEIGHT * 2;
+- basewidth_ = CIF_WIDTH * 2;
+- }
+ setsize();
+ }
+
+@@ -299,15 +309,6 @@
+ format();
+ int cmd = METEOR_CAP_SINGLE;
+ ioctl(dev_, METEORCAPTUR, (char*)&cmd);
+-#ifdef FRAME_CNTS
+- cnts_.fifo_errors = 0;
+- cnts_.dma_errors = 0;
+- cnts_.frames_captured = 0;
+- cnts_.even_fields_captured = 0;
+- cnts_.odd_fields_captured = 0;
+- ioctl(dev_, METEORSCOUNT, &cnts_);
+- start_time_ = gettimeofday();
+-#endif
+
+ cmd = METEOR_CAP_CONTINOUS;
+ ioctl(dev_, METEORCAPTUR, (char*)&cmd);
+@@ -319,19 +320,6 @@
+
+ int cmd = METEOR_CAP_STOP_CONT;
+ ioctl(dev_, METEORCAPTUR, (char*)&cmd);
+-#ifdef FRAME_CNTS
+- double endtime = gettimeofday() ;
+- ioctl(dev_, METEORGCOUNT, &cnts_);
+- int diff = (int)((endtime-start_time_) * 1e-6 + 0.5);
+- printf("frames = %d, even fields = %d, odd fields = %d,\n\
+-fifo errors = %d, dma errors = %d, seconds = %d",
+- cnts_.frames_captured, cnts_.even_fields_captured,
+- cnts_.odd_fields_captured, cnts_.fifo_errors, cnts_.dma_errors,
+- diff);
+- if(diff)
+- printf(",fps = %d", cnts_.frames_captured/diff);
+- printf("\n");
+-#endif
+ Grabber::stop();
+ }
+
+@@ -345,15 +333,15 @@
+
+ int MeteorGrabber::command(int argc, const char*const* argv)
+ {
++ Tcl& tcl = Tcl::instance();
+ 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 (dec != decimate_) {
++ if ((u_int)dec != decimate_) {
+ decimate_ = dec;
+ if(running_) {
+ stop();
+@@ -362,7 +350,8 @@
+ }
+ }
+ return (TCL_OK);
+- } else if (strcmp(argv[1], "port") == 0) {
++ }
++ if (strcmp(argv[1], "port") == 0) {
+ int p = port_;
+ if(!strcmp(argv[2], "RCA")) p = METEOR_INPUT_DEV0;
+ if(!strcmp(argv[2], "Port-1")) p = METEOR_INPUT_DEV1;
+@@ -377,7 +366,8 @@
+ ioctl(dev_, METEORSINPUT, &port_);
+ }
+ return (TCL_OK);
+- } else if (strcmp(argv[1], "format") == 0 ||
++ }
++ if (strcmp(argv[1], "format") == 0 ||
+ strcmp(argv[1], "type") == 0) {
+ if (strcmp(argv[2], "auto") == 0)
+ video_format_ = METEOR_FMT_AUTOMODE;
+@@ -390,14 +380,35 @@
+ if (running_)
+ format();
+ return (TCL_OK);
+- } else if (strcmp(argv[1], "contrast") == 0) {
+- contrast(atof(argv[2]));
+- return (TCL_OK);
++ }
++ if (strcmp(argv[1], "brightness") == 0) {
++ u_char val = atoi(argv[2]);
++ ioctl(dev_, METEORSBRIG, &val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "contrast") == 0) {
++ u_char val = atoi(argv[2]);
++ ioctl(dev_, METEORSCONT, &val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "hue") == 0) {
++ char val = atoi(argv[2]);
++ ioctl(dev_, METEORSHUE, &val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "saturation") == 0) {
++ u_char val = atoi(argv[2]);
++ ioctl(dev_, METEORSCSAT, &val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "uvgain") == 0) {
++ u_char val = atoi(argv[2]);
++ ioctl(dev_, METEORSCHCV, &val);
++ return (TCL_OK);
+ }
+ } else if (argc == 2) {
+ if (strcmp(argv[1], "format") == 0 ||
+ strcmp(argv[1], "type") == 0) {
+- Tcl& tcl = Tcl::instance();
+ switch (video_format_) {
+
+ case METEOR_FMT_AUTOMODE:
+@@ -423,54 +434,316 @@
+ return (TCL_OK);
+
+ }
++ if (strcmp(argv[1], "brightness") == 0) {
++ u_char val;
++ ioctl(dev_, METEORGBRIG, &val);
++ tcl.resultf("%d", (int)val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "contrast") == 0) {
++ u_char val;
++ ioctl(dev_, METEORGCONT, &val);
++ tcl.resultf("%d", (int)val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "hue") == 0) {
++ char val;
++ ioctl(dev_, METEORGHUE, &val);
++ tcl.resultf("%d", (int)val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "saturation") == 0) {
++ u_char val;
++ ioctl(dev_, METEORGCSAT, &val);
++ tcl.resultf("%d", (int)val);
++ return (TCL_OK);
++ }
++ if (strcmp(argv[1], "uvgain") == 0) {
++ u_char val;
++ ioctl(dev_, METEORGCHCV, &val);
++ tcl.resultf("%d", (int)val);
++ return (TCL_OK);
++ }
+ }
+ return (Grabber::command(argc, argv));
+ }
+
+-int MeteorGrabber::capture()
+-{
+- if(pyuv_ == 0) return 0;
+-
+- volatile u_int* py = pyuv_;
+- volatile u_int* pu = (u_int *)((u_int)py + (u_int)framesize_);
+- volatile u_int* pv = (u_int *)((u_int)pu + (framesize_ >> 1));
+- u_int* lum = (u_int *)frame_;
+- u_int* uoff = (u_int *)((u_int)lum + (u_int)framesize_);
+- int f422 = coder_format_ == f_422;
+- u_int* voff = (u_int *)((u_int)uoff +
+- (u_int)(framesize_>>(f422?1:2)));
+- int numc = ((basewidth_/decimate_) &~0xf) >> 3;
+-
+- for (int row = 0; row < (((baseheight_/decimate_)&~0xf) >> 1); row++) {
+- for(int col = 0; col < numc; col++) {
+- *lum++ = *py++;
+- *lum++ = *py++;
+- *uoff++ = *pu++;
+- *voff++ = *pv++;
+- }
+- for(col = 0; col < numc; col++) {
+- *lum++ = *py++;
+- *lum++ = *py++;
+- if(f422) { /* only copy odd in 4:2:2 format */
+- *uoff++ = *pu++;
+- *voff++ = *pv++;
+-
+- }
+- }
+- if(!f422) { /* skip odd if 4:1:1 or cif format */
+- pu += numc;
+- pv += numc;
+- }
+- }
+- return 1;
++#define U 0
++#define Y0 1
++#define V 2
++#define Y1 3
++
++/*
++ * define these for REPLENISH macro used below
++ */
++#define DIFF4(in, frm, v) \
++ v += (in)[Y0] - (frm)[0]; \
++ v += (in)[Y1] - (frm)[1]; \
++ v += (in)[Y0+4] - (frm)[2]; \
++ v += (in)[Y1+4] - (frm)[3];
++
++#define DIFFLINE(in, frm, left, center, right) \
++ DIFF4(in + 0*8, frm + 0*4, left); \
++ DIFF4(in + 1*8, frm + 1*4, center); \
++ DIFF4(in + 2*8, frm + 2*4, center); \
++ DIFF4(in + 3*8, frm + 3*4, right); \
++ if (right < 0) \
++ right = -right; \
++ if (left < 0) \
++ left = -left; \
++ if (center < 0) \
++ center = -center;
++
++void MeteorGrabber::suppress(const u_char* devbuf, int is)
++{
++ const u_char* start = frame_ + 16 * vstart_ * outw_ + 16 * hstart_;
++ REPLENISH(devbuf, start, is, 2,
++ hstart_, hstop_, vstart_, vstop_);
+ }
+
+ int MeteorGrabber::grab()
+ {
+- if (capture() == 0)
+- return (0);
+- suppress(frame_);
+- saveblks(frame_);
+- YuvFrame f(media_ts(), frame_, crvec_, outw_, outh_);
++ if (pyuv_ == 0)
++ return 0;
++
++ int istride = inw_ * 2;
++ suppress((u_char*)pyuv_, istride);
++ saveblks((u_char*)pyuv_, istride);
++ u_int32_t ts = media_ts();
++ YuvFrame f(ts, frame_, crvec_, outw_, outh_);
+ return (target_->consume(&f));
++}
++
++Meteor422Grabber::Meteor422Grabber(const char* name)
++ : MeteorGrabber(name)
++{
++}
++
++MeteorCIFGrabber::MeteorCIFGrabber(const char* name)
++ : MeteorGrabber(name)
++{
++}
++
++void Meteor422Grabber::setsize()
++{
++ int w = basewidth_ / decimate_;
++ int h = baseheight_ / decimate_;
++ set_size_meteor(w, h);
++ set_size_422(w, h);
++}
++
++inline void
++Meteor422Grabber::saveblk(const u_char* in,
++ u_char* yp, u_char* up, u_char* vp, int stride, int istride)
++{
++ for (int i = 16; --i >= 0; ) {
++ /*
++ * Each iteration of this loop grabs 16 Ys & 8 U/Vs.
++ */
++ register u_int y0, y1, u, v;
++
++ u = in[U + 0*4] << SHIFT(24) |
++ in[U + 1*4] << SHIFT(16) |
++ in[U + 2*4] << SHIFT(8) |
++ in[U + 3*4] << SHIFT(0);
++ v = in[V + 0*4] << SHIFT(24) |
++ in[V + 1*4] << SHIFT(16) |
++ in[V + 2*4] << SHIFT(8) |
++ in[V + 3*4] << SHIFT(0);
++ y0 = in[Y0 + 0*4] << SHIFT(24) |
++ in[Y1 + 0*4] << SHIFT(16) |
++ in[Y0 + 1*4] << SHIFT(8) |
++ in[Y1 + 1*4] << SHIFT(0);
++ y1 = in[Y0 + 2*4] << SHIFT(24) |
++ in[Y1 + 2*4] << SHIFT(16) |
++ in[Y0 + 3*4] << SHIFT(8) |
++ in[Y1 + 3*4] << SHIFT(0);
++
++ ((u_int*)yp)[0] = y0;
++ ((u_int*)yp)[1] = y1;
++ ((u_int*)up)[0] = u;
++ ((u_int*)vp)[0] = v;
++
++ u = in[U + 4*4] << SHIFT(24) |
++ in[U + 5*4] << SHIFT(16) |
++ in[U + 6*4] << SHIFT(8) |
++ in[U + 7*4] << SHIFT(0);
++ v = in[V + 4*4] << SHIFT(24) |
++ in[V + 5*4] << SHIFT(16) |
++ in[V + 6*4] << SHIFT(8) |
++ in[V + 7*4] << SHIFT(0);
++ y0 = in[Y0 + 4*4] << SHIFT(24) |
++ in[Y1 + 4*4] << SHIFT(16) |
++ in[Y0 + 5*4] << SHIFT(8) |
++ in[Y1 + 5*4] << SHIFT(0);
++ y1 = in[Y0 + 6*4] << SHIFT(24) |
++ in[Y1 + 6*4] << SHIFT(16) |
++ in[Y0 + 7*4] << SHIFT(8) |
++ in[Y1 + 7*4] << SHIFT(0);
++
++ ((u_int*)yp)[2] = y0;
++ ((u_int*)yp)[3] = y1;
++ ((u_int*)up)[1] = u;
++ ((u_int*)vp)[1] = v;
++
++ in += istride;
++ yp += stride;
++ up += stride >> 1;
++ vp += stride >> 1;
++ }
++}
++
++void Meteor422Grabber::saveblks(const u_char* devbuf, int is)
++{
++ u_char* crv = crvec_;
++ int off = framesize_;
++ u_char* lum = frame_;
++ u_char* chm = lum + off;
++ off >>= 1;
++ int stride = 15 * outw_;
++ int istride = is * 15;
++ for (int y = 0; y < blkh_; ++y) {
++ for (int x = 0; x < blkw_; ++x) {
++ int s = *crv++;
++ if ((s & CR_SEND) != 0)
++ saveblk(devbuf, lum, chm, chm + off, outw_, is);
++
++ devbuf += 32;
++ lum += 16;
++ chm += 8;
++ }
++ lum += stride;
++ chm += stride >> 1;
++ devbuf += istride;
++ }
++}
++
++void MeteorCIFGrabber::setsize()
++{
++ int w = basewidth_ / decimate_;
++ int h = baseheight_ / decimate_;
++ set_size_meteor(w, h);
++ set_size_cif(w, h);
++}
++
++inline void
++MeteorCIFGrabber::saveblk(const u_char* in,
++ u_char* yp, u_char* up, u_char* vp, int stride, int istride)
++{
++ for (int i = 8; --i >= 0; ) {
++ /*
++ * Each iteration of this loop grabs 32 Ys & 16 U/Vs.
++ */
++ register u_int y0, y1, u, v;
++
++ u = in[U + 0*4] << SHIFT(24) |
++ in[U + 1*4] << SHIFT(16) |
++ in[U + 2*4] << SHIFT(8) |
++ in[U + 3*4] << SHIFT(0);
++ v = in[V + 0*4] << SHIFT(24) |
++ in[V + 1*4] << SHIFT(16) |
++ in[V + 2*4] << SHIFT(8) |
++ in[V + 3*4] << SHIFT(0);
++ y0 = in[Y0 + 0*4] << SHIFT(24) |
++ in[Y1 + 0*4] << SHIFT(16) |
++ in[Y0 + 1*4] << SHIFT(8) |
++ in[Y1 + 1*4] << SHIFT(0);
++ y1 = in[Y0 + 2*4] << SHIFT(24) |
++ in[Y1 + 2*4] << SHIFT(16) |
++ in[Y0 + 3*4] << SHIFT(8) |
++ in[Y1 + 3*4] << SHIFT(0);
++
++ ((u_int*)yp)[0] = y0;
++ ((u_int*)yp)[1] = y1;
++ ((u_int*)up)[0] = u;
++ ((u_int*)vp)[0] = v;
++
++ u = in[U + 4*4] << SHIFT(24) |
++ in[U + 5*4] << SHIFT(16) |
++ in[U + 6*4] << SHIFT(8) |
++ in[U + 7*4] << SHIFT(0);
++ v = in[V + 4*4] << SHIFT(24) |
++ in[V + 5*4] << SHIFT(16) |
++ in[V + 6*4] << SHIFT(8) |
++ in[V + 7*4] << SHIFT(0);
++ y0 = in[Y0 + 4*4] << SHIFT(24) |
++ in[Y1 + 4*4] << SHIFT(16) |
++ in[Y0 + 5*4] << SHIFT(8) |
++ in[Y1 + 5*4] << SHIFT(0);
++ y1 = in[Y0 + 6*4] << SHIFT(24) |
++ in[Y1 + 6*4] << SHIFT(16) |
++ in[Y0 + 7*4] << SHIFT(8) |
++ in[Y1 + 7*4] << SHIFT(0);
++
++ ((u_int*)yp)[2] = y0;
++ ((u_int*)yp)[3] = y1;
++ ((u_int*)up)[1] = u;
++ ((u_int*)vp)[1] = v;
++
++ in += istride;
++ yp += stride;
++ up += stride >> 1;
++ vp += stride >> 1;
++
++ /* do the 2nd (y only instead of yuv) line */
++
++ y0 = in[Y0 + 0*4] << SHIFT(24) |
++ in[Y1 + 0*4] << SHIFT(16) |
++ in[Y0 + 1*4] << SHIFT(8) |
++ in[Y1 + 1*4] << SHIFT(0);
++ y1 = in[Y0 + 2*4] << SHIFT(24) |
++ in[Y1 + 2*4] << SHIFT(16) |
++ in[Y0 + 3*4] << SHIFT(8) |
++ in[Y1 + 3*4] << SHIFT(0);
++
++ ((u_int*)yp)[0] = y0;
++ ((u_int*)yp)[1] = y1;
++
++ y0 = in[Y0 + 4*4] << SHIFT(24) |
++ in[Y1 + 4*4] << SHIFT(16) |
++ in[Y0 + 5*4] << SHIFT(8) |
++ in[Y1 + 5*4] << SHIFT(0);
++ y1 = in[Y0 + 6*4] << SHIFT(24) |
++ in[Y1 + 6*4] << SHIFT(16) |
++ in[Y0 + 7*4] << SHIFT(8) |
++ in[Y1 + 7*4] << SHIFT(0);
++
++ ((u_int*)yp)[2] = y0;
++ ((u_int*)yp)[3] = y1;
++
++ in += istride;
++ yp += stride;
++ }
++}
++
++void MeteorCIFGrabber::saveblks(const u_char* in, int is)
++{
++ u_char* crv = crvec_;
++ int off = framesize_;
++ u_char* lum = frame_;
++ u_char* chm = lum + off;
++ off >>= 2;
++
++ crv += vstart_ * blkw_ + hstart_;
++ lum += vstart_ * outw_ * 16 + hstart_ * 16;
++ chm += vstart_ * (outw_ >> 1) * 8 + hstart_ * 8;
++
++ int skip = hstart_ + (blkw_ - hstop_);
++
++ for (int y = vstart_; y < vstop_; ++y) {
++ const u_char* nin = in;
++ for (int x = hstart_; x < hstop_; ++x) {
++ int s = *crv++;
++ if ((s & CR_SEND) != 0)
++ saveblk(in, lum, chm, chm + off, outw_, is);
++
++ in += 32;
++ lum += 16;
++ chm += 8;
++ }
++ crv += skip;
++ lum += 15 * outw_ + skip * 16;
++ chm += 7 * (outw_ >> 1) + skip * 8;
++ in = nin + 16 * is;
++ }
+ }