mirror of
https://git.FreeBSD.org/ports.git
synced 2024-10-19 19:59:43 +00:00
Add BT848 grabber support.
Submitted by: Amancio Hasty <hasty@rah.star-gate.com>
This commit is contained in:
parent
61c8e9cd6e
commit
6832892b30
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=9131
725
mbone/vic/files/patch-af
Normal file
725
mbone/vic/files/patch-af
Normal file
@ -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;
|
||||
+ }
|
||||
}
|
725
multimedia/vic/files/patch-af
Normal file
725
multimedia/vic/files/patch-af
Normal file
@ -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;
|
||||
+ }
|
||||
}
|
Loading…
Reference in New Issue
Block a user