1997-03-07 02:50:01 +00:00
|
|
|
.\"
|
1999-08-28 00:22:10 +00:00
|
|
|
.\" $FreeBSD$
|
1997-03-07 02:50:01 +00:00
|
|
|
.\"
|
1995-09-06 03:34:52 +00:00
|
|
|
.Dd August 15, 1995
|
|
|
|
.br
|
|
|
|
.in +0.5i
|
1996-12-29 20:36:04 +00:00
|
|
|
.Dt METEOR 4 i386
|
1995-09-06 03:34:52 +00:00
|
|
|
.Os FreeBSD
|
|
|
|
.Sh NAME
|
|
|
|
.Nm meteor
|
|
|
|
.Nd video capture driver
|
|
|
|
.Sh SYNOPSIS
|
|
|
|
.Nm video meteor
|
|
|
|
.Sh DESCRIPTION
|
|
|
|
The
|
1997-02-05 15:07:37 +00:00
|
|
|
.Nm meteor
|
1995-09-06 03:34:52 +00:00
|
|
|
driver provides support for a PCI
|
|
|
|
.Em video
|
2000-03-03 14:05:08 +00:00
|
|
|
capture.
|
|
|
|
It allows the capture of 24 bit RGB, 16 bit RGB and 16 bit YUV
|
1995-09-06 03:34:52 +00:00
|
|
|
output formats.
|
|
|
|
.Pp
|
|
|
|
.Sh Meteor Driver Installation
|
|
|
|
To use the Matrox Meteor card in your system, you need a computer
|
|
|
|
that support the PCI (preferably the Type 2 or better) interface bus.
|
|
|
|
It is recommended that the system has as more than 16 MB of RAM since this
|
|
|
|
capture card directly deposits the image to system RAM.
|
|
|
|
.Pp
|
|
|
|
The files required for Matrox Meteor card are:
|
|
|
|
.br
|
|
|
|
.in +0.5i
|
|
|
|
/sys/pci/meteor.c
|
|
|
|
.br
|
|
|
|
/sys/i386/include/ioctl_meteor.h (also known as:
|
|
|
|
.br
|
|
|
|
/usr/include/machine/ioctl_meteor.h)
|
|
|
|
.br
|
|
|
|
.in -0.5i
|
1997-03-21 20:14:15 +00:00
|
|
|
For
|
2000-11-14 11:20:58 +00:00
|
|
|
.Fx
|
1997-03-21 20:14:15 +00:00
|
|
|
release versions 2.1 and earlier, the following patch files are also required:
|
1995-09-06 03:34:52 +00:00
|
|
|
.br
|
|
|
|
.in +0.5i
|
|
|
|
meteor/usr/sys/i386/i386/conf.patch
|
|
|
|
.br
|
|
|
|
meteor/usr/sys/conf/files.patch
|
|
|
|
.br
|
|
|
|
meteor/sys/i386/conf/LINT.patch
|
|
|
|
.br
|
|
|
|
These files are available for anonymous ftp at:
|
|
|
|
.br
|
|
|
|
.in +0.5i
|
|
|
|
ftp://joy.cs.ndsu.nodak.edu/pub/meteor.tgz
|
|
|
|
.br
|
|
|
|
.in -1.0i
|
|
|
|
.Pp
|
|
|
|
1) In the configuration file, add the line (as shown in
|
|
|
|
meteor/usr/sys/i386/conf/LINT.patch):
|
|
|
|
.Pp
|
|
|
|
.Em device meteor0
|
|
|
|
.Pp
|
|
|
|
2) There is also a couple of optional parameters you may use
|
|
|
|
.Pp
|
|
|
|
.Em options "METEOR_ALLOC_PAGES=xxx"
|
|
|
|
specifies the number of contiguous pages to allocate when successfully
|
|
|
|
probed. The default number of pages allocated by the kernel is 151.
|
|
|
|
This means that there are (151*4096) bytes available for use.
|
|
|
|
.Pp
|
|
|
|
.Em options METEOR_DEALLOC_PAGES
|
2000-03-03 14:05:08 +00:00
|
|
|
deallocate all pages when closing the device.
|
|
|
|
Note, the chance of
|
1995-09-06 03:34:52 +00:00
|
|
|
contiguously re-allocating new pages are very small. The default
|
|
|
|
behavior is to not deallocate pages.
|
|
|
|
.Pp
|
|
|
|
.Em options "METEOR_DEALLOC_ABOVE=xxx"
|
|
|
|
deallocate all pages above the specified number. The default action is
|
|
|
|
to not deallocate above any pages.
|
|
|
|
.Pp
|
|
|
|
3) Make and install the kernel.
|
|
|
|
.Pp
|
|
|
|
4) Make the special file name:
|
|
|
|
.Pp
|
|
|
|
.Em mknod /dev/meteor0 c <major> 0
|
|
|
|
The major number is determined by the placement of the device in conf.c.
|
|
|
|
The patch supplied with the driver will make the major number 67.
|
|
|
|
.Pp
|
|
|
|
.Sh Meteor Capture Modes
|
|
|
|
The Meteor capture driver has three modes of capture operation.
|
|
|
|
.Pp
|
2000-05-31 21:33:15 +00:00
|
|
|
1) Conventional
|
|
|
|
.Xr read 2
|
|
|
|
interface.
|
1995-09-06 03:34:52 +00:00
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
2000-03-03 14:05:08 +00:00
|
|
|
This mode is the easiest and slowest to use.
|
|
|
|
This mode is great for
|
1995-09-06 03:34:52 +00:00
|
|
|
capturing a single field at little programming cost.
|
|
|
|
.Pp
|
|
|
|
In this mode, the user opens the device, set the capture mode
|
|
|
|
and size (See: METEORSETGEO ioctl call), and uses the read system
|
|
|
|
call to load the data into a buffer.
|
|
|
|
.Pp
|
|
|
|
meteor_read.c; read 400x300 RGB24 into a viewable PPM file
|
|
|
|
.Pp
|
|
|
|
.in -0.5i
|
|
|
|
.nf
|
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#include <machine/ioctl_meteor.h>
|
|
|
|
|
|
|
|
extern int errno;
|
|
|
|
#define ROWS 300
|
|
|
|
#define COLS 400
|
|
|
|
#define SIZE (ROWS * COLS * 4)
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
struct meteor_geomet geo;
|
|
|
|
char buf[SIZE],b[4],header[16],*p;
|
|
|
|
int i,o,c;
|
|
|
|
|
|
|
|
if ((i = open("/dev/meteor0", O_RDONLY)) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("open failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
/* set up the capture type and size */
|
|
|
|
geo.rows = ROWS;
|
|
|
|
geo.columns = COLS;
|
|
|
|
geo.frames = 1;
|
|
|
|
geo.oformat = METEOR_GEO_RGB24 ;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSETGEO, &geo) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
c = METEOR_FMT_NTSC;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSFMT, &c) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
c = METEOR_INPUT_DEV0;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSINPUT, &c) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((c=read(i, &buf[0], SIZE)) < SIZE) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("read failed %d %d %d\\n", c, i, errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
close(i);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
close(i);
|
|
|
|
|
|
|
|
if ((o = open("rgb24.ppm", O_WRONLY | O_CREAT, 0644)) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ppm open failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make PPM header and save to file */
|
|
|
|
strcpy(&header[0], "P6 400 300 255 ");
|
1999-05-04 21:03:22 +00:00
|
|
|
header[2] = header[6] = header[10] = header[14] = '\\n';
|
1995-09-06 03:34:52 +00:00
|
|
|
write (o, &header[0], 15);
|
|
|
|
/* save the RGB data to PPM file */
|
|
|
|
for (p = &buf[0]; p < &buf[SIZE]; ) {
|
|
|
|
b[2] = *p++; /* blue */
|
|
|
|
b[1] = *p++; /* green */
|
|
|
|
b[0] = *p++; /* red */
|
|
|
|
*p++; /* NULL byte */
|
|
|
|
write(o,&b[0], 3); /* not very efficient */
|
|
|
|
}
|
|
|
|
close(o);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
.if
|
|
|
|
.Pp
|
|
|
|
2) Memory mapped single capture or unsynchronized continuous capture.
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
The single capture mode is designed for conferencing tools such as nv.
|
|
|
|
These tools need to control the starting of the image capture and also
|
2000-03-03 14:05:08 +00:00
|
|
|
need several frames a second.
|
|
|
|
The continuous capture mode is designed
|
1995-09-06 03:34:52 +00:00
|
|
|
for applications that want free-running data.
|
|
|
|
.Pp
|
|
|
|
In this mode, the user opens the device, set the capture mode
|
|
|
|
and size (See: METEORSETGEO ioctl call), memory maps the frame buffer
|
|
|
|
memory into the user process space, and issues either the
|
|
|
|
single-capture or the continuous capture call (See: METEORCAPTUR ioctl
|
|
|
|
call) to load the data into the memory mapped buffer.
|
|
|
|
.Pp
|
|
|
|
As explained in the METEORCAPTUR ioctl call, the single frame capture
|
|
|
|
ioctl will block until the capture is complete, the continuous capture
|
|
|
|
will return immediately.
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
meteor_mmap_single_continuous.c
|
|
|
|
.Pp
|
|
|
|
.nf
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#include <machine/ioctl_meteor.h>
|
|
|
|
|
|
|
|
extern int errno;
|
|
|
|
#define ROWS 480
|
|
|
|
#define COLS 640
|
2000-10-17 08:27:18 +00:00
|
|
|
#define SIZE (ROWS * COLS * 2)
|
1995-09-06 03:34:52 +00:00
|
|
|
main()
|
|
|
|
{
|
|
|
|
struct meteor_geomet geo;
|
|
|
|
char buf[SIZE];
|
|
|
|
char *mmbuf;
|
|
|
|
int i,c;
|
|
|
|
|
|
|
|
if ((i = open("/dev/meteor0", O_RDONLY)) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("open failed\\n");
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
geo.rows = ROWS;
|
|
|
|
geo.columns = COLS;
|
|
|
|
geo.frames = 1;
|
|
|
|
geo.oformat = METEOR_GEO_RGB16 ;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSETGEO, &geo) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
c = METEOR_FMT_NTSC;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSFMT, &c) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
c = METEOR_INPUT_DEV0;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSINPUT, &c) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
1997-01-16 21:58:40 +00:00
|
|
|
mmbuf=(char *)mmap((caddr_t)0, SIZE, PROT_READ,
|
|
|
|
MAP_SHARED, i, (off_t)0);
|
1995-09-06 03:34:52 +00:00
|
|
|
|
|
|
|
#ifdef SINGLE_MODE
|
|
|
|
/* single frame capture */
|
|
|
|
c = METEOR_CAP_SINGLE ;
|
|
|
|
ioctl(i, METEORCAPTUR, &c); /* wait for the frame */
|
|
|
|
|
|
|
|
/* directly access the frame buffer array data in mmbuf */
|
|
|
|
#else
|
|
|
|
/* continuous frame capture */
|
|
|
|
c = METEOR_CAP_CONTINOUS ;
|
|
|
|
ioctl(i, METEORCAPTUR, &c); /* returns immediately */
|
|
|
|
|
|
|
|
/* directly access the frame buffer array data in mmbuf */
|
|
|
|
|
|
|
|
c = METEOR_CAP_STOP_CONT ;
|
|
|
|
ioctl(i, METEORCAPTUR, &c); /* close will also stop capture */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
close(i);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
.if
|
|
|
|
.Pp
|
|
|
|
3) Memory mapped, multi-frame ring buffer synchronize capture.
|
|
|
|
.Pp
|
|
|
|
.in +0.5i
|
|
|
|
This continuous capture mode is synchronized with the application that
|
2000-03-03 14:05:08 +00:00
|
|
|
processes up to 32 frames.
|
|
|
|
This gives the advantages of both single and
|
1995-09-06 03:34:52 +00:00
|
|
|
continuous capture modes.
|
|
|
|
.Pp
|
|
|
|
The kernel notifies the application of a new data by raising an
|
2000-03-03 14:05:08 +00:00
|
|
|
application defined signal.
|
|
|
|
The driver also shares a structure with
|
1995-09-06 03:34:52 +00:00
|
|
|
the application that allows them to communicate which frame has been
|
|
|
|
written by the kernel and which frame has been read by the application.
|
|
|
|
.Pp
|
2000-03-03 14:05:08 +00:00
|
|
|
The shared structure starts on the first page after your data.
|
|
|
|
The
|
1995-09-06 03:34:52 +00:00
|
|
|
structure address can be found by calculation:
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
(number_rows * number_columns * pixel_depth + 4095) & 0xfffff000
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
or
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
((number_rows * number_columns * pixel_depth + 4095)/4096) * 4096
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
2000-03-03 14:05:08 +00:00
|
|
|
The shared structure is of type struct meteor_mem.
|
|
|
|
The two most
|
1995-09-06 03:34:52 +00:00
|
|
|
important fields are called active and num_active_buf. active
|
|
|
|
is a bitmap of frames written by the kernel. num_active_bufs is
|
2000-03-03 14:05:08 +00:00
|
|
|
a count of frames marked in the active field.
|
|
|
|
When a frame is read
|
1995-09-06 03:34:52 +00:00
|
|
|
in by the driver, the num_active_bufs count is tested, if this
|
|
|
|
count is below the threshold of number of active frames (value
|
|
|
|
in meteor_mem's hiwat variable), the bit representing frame
|
|
|
|
number in the buffer is stored in the active variable, the
|
|
|
|
num_active_bufs is incremented, the kernel then raises the specified
|
2000-03-03 14:05:08 +00:00
|
|
|
signal to activate the user application.
|
|
|
|
The user application's
|
1995-09-06 03:34:52 +00:00
|
|
|
responsibility when getting the signal is to check the active bitmap
|
|
|
|
to determine the lowest active frame, use the data as the application
|
|
|
|
desires, clear the bitmap entry for that frame, and decrement the
|
2000-03-03 14:05:08 +00:00
|
|
|
num_active_bufs.
|
|
|
|
If the threshold of number of active frames (hiwat)
|
1995-09-06 03:34:52 +00:00
|
|
|
has been exceeded, no new frames or signal from the kernel will occur
|
|
|
|
until the num_active_bufs is less than or equal to lowat.
|
|
|
|
.Pp
|
|
|
|
The driver loads the frames in a round-robin fashion. it is expected
|
2000-03-03 14:05:08 +00:00
|
|
|
that the user removes them in the same order.
|
|
|
|
The driver does not
|
1995-09-06 03:34:52 +00:00
|
|
|
check to see if the frame is already active.
|
|
|
|
.Pp
|
|
|
|
The frame_size and number of frames in the buffer are also provided
|
|
|
|
to the meteor_mem structure, but changing these fields in the
|
|
|
|
application will not change the operation of the driver.
|
|
|
|
.Pp
|
|
|
|
In programming for this mode, the user opens the device, sets the
|
|
|
|
geometry, mmaps the data/common control structure, then starts the
|
2000-03-03 14:05:08 +00:00
|
|
|
continuous capture mode.
|
|
|
|
A special signal catcher is required to
|
1995-09-06 03:34:52 +00:00
|
|
|
process the frames as they are read by the kernel.
|
|
|
|
.Pp
|
|
|
|
When specifying the geometry (See: ioctl METEORSETGEO), it
|
|
|
|
is important that the number of frames is set greater than 1.
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
skeleton_capture_n.c
|
|
|
|
.Pp
|
|
|
|
.nf
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#include <sys/signal.h>
|
|
|
|
#include <machine/ioctl_meteor.h>
|
|
|
|
|
|
|
|
int video; /* made global if you wish to stop capture in signal handler */
|
|
|
|
caddr_t data_frames;
|
|
|
|
struct meteor_mem *common_mem;
|
|
|
|
extern int errno;
|
|
|
|
|
|
|
|
#define FRAME_MAX
|
|
|
|
|
|
|
|
void
|
|
|
|
usr2_catcher()
|
|
|
|
{
|
|
|
|
#ifdef SIGNAL_STOP
|
|
|
|
struct meteor_capframe capframe; /* for ioctl */
|
|
|
|
#endif
|
|
|
|
char *frame;
|
|
|
|
|
|
|
|
/* find frame */
|
|
|
|
frame = (char *) (data_frames + sig_cnt * common_mem->frame_size) ;
|
|
|
|
|
|
|
|
/* add frame processing here */
|
|
|
|
/* deactivate frame */
|
|
|
|
common_mem->active &= ~(1 << (sig_cnt % 16));
|
|
|
|
common_mem->num_active_bufs--;
|
|
|
|
|
|
|
|
/* process next frame on next interrupt */
|
|
|
|
sig_cnt = ((sig_cnt+1) % FRAME_MAX);
|
|
|
|
|
|
|
|
#ifdef SIGNAL_STOP
|
|
|
|
if (some_condition_requiring_stopping) {
|
|
|
|
capframe.command=METEOR_CAP_STOP_FRAMES;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORCAPFRM, &capframe) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("METEORCAPFRM failed %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
struct meteor_geomet geo;
|
|
|
|
int height, width, depth, frames, size;
|
|
|
|
struct meteor_capframe capframe;
|
|
|
|
|
|
|
|
if ((i = open("/dev/meteor0", O_RDONLY)) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("open failed\\n");
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("test %d %d\\n", errno, i);
|
1995-09-06 03:34:52 +00:00
|
|
|
|
|
|
|
height = geo.rows = 120;
|
|
|
|
width= geo.columns = 320;
|
|
|
|
frames = geo.frames = FRAME_MAX;
|
|
|
|
depth = 2; /* 2 bytes per pixel for RGB*/
|
|
|
|
|
|
|
|
|
|
|
|
geo.oformat = METEOR_GEO_RGB16;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSETGEO, &geo) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("METEORSETGEO failed %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
c = METEOR_FMT_NTSC;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSFMT, &c) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
c = METEOR_INPUT_DEV0;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORSINPUT, &c) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("ioctl failed: %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
size = ((width*height*depth*frames+4095)/4096)*4096;
|
|
|
|
/* add one page after data for meteor_mem */
|
|
|
|
data_frames = mmap((caddr_t)0, size + 4096, PROT_READ | PROT_WRITE,
|
1997-01-16 21:58:40 +00:00
|
|
|
MAP_SHARED, i, (off_t)0);
|
1995-09-06 03:34:52 +00:00
|
|
|
|
1997-01-16 21:58:40 +00:00
|
|
|
if (data_frames == (caddr_t) MAP_FAILED) return (0);
|
1995-09-06 03:34:52 +00:00
|
|
|
|
|
|
|
/* common_mem is located at page following data */
|
|
|
|
common_mem = (struct meteor_mem *) (y + size);
|
|
|
|
|
|
|
|
signal(SIGUSR2, usr2_catcher); /* catch new frame message */
|
|
|
|
|
|
|
|
capframe.command=METEOR_CAP_N_FRAMES;
|
|
|
|
capframe.signal=SIGUSR2;
|
|
|
|
capframe.lowat=12; /* must be < hiwat */
|
|
|
|
capframe.hiwat=14; /* must be < FRAME_MAX */
|
|
|
|
|
|
|
|
/* start the sync capture */
|
|
|
|
if (ioctl(i, METEORCAPFRM, &capframe) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("METEORCAPFRM failed %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this is the background working area, or you can sleep */
|
|
|
|
|
|
|
|
|
|
|
|
/* to stop capture */
|
|
|
|
capframe.command=METEOR_CAP_STOP_FRAMES;
|
|
|
|
|
|
|
|
if (ioctl(i, METEORCAPFRM, &capframe) < 0) {
|
1999-05-04 21:03:22 +00:00
|
|
|
printf("METEORCAPFRM failed %d\\n", errno);
|
1995-09-06 03:34:52 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.if
|
|
|
|
.Pp
|
|
|
|
.Sh Meteor IOCTL Call and Parameters
|
|
|
|
.Pp
|
|
|
|
The Meteor capture driver has ioctl requests for capturing, reading card
|
|
|
|
status, for setting and reading the geometry, and for setting and reading the
|
|
|
|
attributes.
|
|
|
|
.Pp
|
|
|
|
IT IS VERY IMPORTANT TO CHECK FOR ERRORS ON THESE RETURNING IOCTLs.
|
|
|
|
Errors indicate that something is very wrong with the ioctl and the
|
2000-03-03 14:05:08 +00:00
|
|
|
application should not attempt to proceed further with capturing.
|
|
|
|
The
|
1995-09-06 03:34:52 +00:00
|
|
|
meteor capture driver still makes attempts to stop the next capture step if
|
|
|
|
an error occurred in a previous step but was ignored by the application
|
|
|
|
programmer.
|
|
|
|
.Pp
|
|
|
|
1) ioctl requests METEORSETGEO and METEORGETGEO
|
|
|
|
.in +0.5i
|
|
|
|
METEORSETGEO and METEORGETGEO are used to set and read the input
|
|
|
|
size, input device, and output format for frame capture.
|
|
|
|
.Pp
|
|
|
|
These ioctl routines use the meteor_geomet structure that has the
|
|
|
|
following entries:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width columns
|
|
|
|
.It Dv rows
|
|
|
|
number of rows (lines high) in output image
|
|
|
|
.It Dv columns
|
|
|
|
number of pixels in a row (width) in output image
|
|
|
|
.It Dv frames
|
2000-03-03 14:05:08 +00:00
|
|
|
number of frames in buffer.
|
|
|
|
Should be 1, unless using
|
1995-09-06 03:34:52 +00:00
|
|
|
the multi-framed synchronous capture mode (METEORCAPFRM)
|
|
|
|
which REQUIRES frames to be larger than 1.
|
|
|
|
.Pp
|
|
|
|
Note: if rows, columns or frames is not changed, then
|
2000-03-03 14:05:08 +00:00
|
|
|
the existing values are used.
|
|
|
|
The system defaults
|
1995-09-06 03:34:52 +00:00
|
|
|
is 640x480x1.
|
|
|
|
.It Dv oformat
|
|
|
|
you may choose one of the following output format:
|
|
|
|
.Bl -tag -width METEOR_GEO_YUV_PACKED
|
|
|
|
.It Dv METEOR_GEO_RGB16
|
|
|
|
RGB 16 bits xrrrrrgg gggbbbbb default)
|
|
|
|
.It Dv METEOR_GEO_RGB24
|
2000-10-28 23:25:41 +00:00
|
|
|
(RGB 24 bits packed in 32 bits:
|
1995-09-06 03:34:52 +00:00
|
|
|
00000000 rrrrrrrr gggggggg bbbbbbbb)
|
|
|
|
.It Dv METEOR_GEO_YUV_PACKED
|
|
|
|
(4-2-2 YUV 16 bits packed. byte format:
|
|
|
|
u0 y0 v0 y1 u1 y2 v1 y3 ...)
|
|
|
|
.It Dv METEOR_GEO_YUV_PLANER
|
|
|
|
(4-2-2 YUV 16 bits planer format:
|
|
|
|
rows * columns bytes of y
|
|
|
|
rows * column / 4 bytes of even u
|
|
|
|
rows * column / 4 bytes of even v
|
|
|
|
rows * column / 4 bytes of odd u
|
|
|
|
rows * column / 4 bytes of odd v)
|
|
|
|
.El
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
The METEORSETGEO ioctl will fail if more than one entry from a category
|
2000-03-03 14:05:08 +00:00
|
|
|
is selected.
|
|
|
|
It is highly recommended that a METEORSETGEO is done
|
1995-09-06 03:34:52 +00:00
|
|
|
before capturing data because you cannot guarantee the initial mode
|
|
|
|
the card.
|
|
|
|
.Pp
|
|
|
|
The METEORSETGEO will also attempt to reallocate a new contiguous
|
2000-03-03 14:05:08 +00:00
|
|
|
kernel buffer if the new geometry exceeds the old geometry.
|
|
|
|
On
|
1995-09-06 03:34:52 +00:00
|
|
|
other hand, if the new geometry will fit in the existing buffer,
|
|
|
|
the existing buffer is used.
|
|
|
|
.Pp
|
|
|
|
If METEORSETGEO fails the ioctl() will return a value of -1 and the
|
|
|
|
external variable errno will be set to:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width EINVAL
|
|
|
|
.It Dv EINVAL
|
|
|
|
invalid meteor_geomet structure pointer, rows, columns,
|
|
|
|
frames were invalid.
|
|
|
|
.It Dv ENOMEM
|
1998-06-08 06:12:02 +00:00
|
|
|
could not allocate the contiguous block.
|
1995-09-06 03:34:52 +00:00
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
2) ioctl requests METEORSFMT and METEORGFMT
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
METEORSFMT and METEORGFMT are used to set and read the camera input
|
|
|
|
standard format.
|
|
|
|
.Pp
|
|
|
|
Possible formats are:
|
|
|
|
.Bl -tag -width METEOR_FMT_AUTOMODE
|
|
|
|
.It Dv METEOR_FMT_NTSC
|
|
|
|
NTSC (default mode)
|
|
|
|
.It Dv METEOR_FMT_PAL
|
|
|
|
PAL
|
|
|
|
.It Dv METEOR_FMT_SECAM
|
|
|
|
SECAM
|
|
|
|
.It Dv METEOR_FMT_AUTOMODE
|
|
|
|
Autodetect.
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
3) ioctl requests METEORSINPUT and METEORGINPUT
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
METEORSINPUT and METEORGINPUT are used to set and read the camera
|
2000-03-03 14:05:08 +00:00
|
|
|
input device.
|
|
|
|
Using the DB9 connector on the Meteor card, 4 input
|
1995-09-06 03:34:52 +00:00
|
|
|
devices can be connected and an input camera can be selected with this
|
|
|
|
ioctl.
|
|
|
|
.Pp
|
|
|
|
Possible formats are:
|
|
|
|
.Bl -tag -width METEOR_INPUT_DEV_SVIDEO
|
|
|
|
.It Dv METEOR_INPUT_DEV0
|
|
|
|
(default if none specified)
|
|
|
|
.It Dv METEOR_INPUT_DEV_RCA
|
|
|
|
(same as METEOR_INPUT_DEV0)
|
|
|
|
.It Dv METEOR_INPUT_DEV1
|
|
|
|
.It Dv METEOR_INPUT_DEV2
|
|
|
|
.It Dv METEOR_INPUT_DEV_SVIDEO
|
|
|
|
(same as METEOR_INPUT_DEV2)
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
4) ioctl request METEORSTATUS
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
METEORSTATUS is used to read the status of the Meteor capture card
|
|
|
|
and returns the following information:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width METEOR_STATUS_ID_MASK
|
|
|
|
.It Dv METEOR_STATUS_ID_MASK
|
|
|
|
4 bit ID of the SAA7196 scaler chip.
|
|
|
|
.It Dv METEOR_STATUS_DIR
|
|
|
|
0 = scaler uses internal source.
|
|
|
|
.br
|
|
|
|
1 = scaler uses external data of expansion bus.
|
|
|
|
.It Dv METEOR_STATUS_OEF
|
|
|
|
0 = even field detected.
|
|
|
|
.br
|
|
|
|
1 = odd field detected.
|
|
|
|
.It Dv METEOR_STATUS_SVP
|
|
|
|
VRAM Port state:
|
|
|
|
.br
|
|
|
|
0 = inputs HFL and INCADDR inactive.
|
|
|
|
.br
|
|
|
|
1 = inputs HFL and INCADDR active.
|
|
|
|
.It Dv METEOR_STATUS_STTC
|
|
|
|
0 = TV horizontal time constant (slow).
|
|
|
|
.br
|
|
|
|
1 = VCR horizontal time constant (fast).
|
|
|
|
.It Dv METEOR_STATUS_HCLK
|
|
|
|
0 = Horizontal Phase Lock Loop locked.
|
|
|
|
.br
|
|
|
|
1 = Horizontal Phase Lock Loop unlocked.
|
|
|
|
.It Dv METEOR_STATUS_FIDT
|
|
|
|
0 = 50 Hz Field detected.
|
|
|
|
.br
|
|
|
|
1 = 60 Hz Field detected.
|
|
|
|
.It Dv METEOR_STATUS_ALTD
|
|
|
|
0 = no line alternating color burst detected.
|
|
|
|
.br
|
|
|
|
1 = line alternating color burst detected
|
|
|
|
(PAL/SECAM).
|
|
|
|
.It Dv METEOR_STATUS_CODE
|
|
|
|
0 = no color information detected.
|
|
|
|
.br
|
|
|
|
1 = color information detected.
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
5) ioctl request METEORCAPTUR
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
METEORCAPTUR is used to single frame capture or unsynchronized
|
|
|
|
continuous capture.
|
|
|
|
.Pp
|
|
|
|
The single frame capture ioctl request will return only after a
|
|
|
|
frame has been captured and transfered to the frame buffer.
|
|
|
|
.Pp
|
|
|
|
The unsynchronized continuous capture will return immediately and
|
|
|
|
data is directly deposited into the buffer when it is available.
|
|
|
|
Since this is unsynchronized, it is possible the data is being
|
|
|
|
written by the kernel while being read by the application.
|
|
|
|
.Pp
|
|
|
|
These ioctl routines use the following settings:
|
|
|
|
following entries:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width METEOR_CAP_CONTINOUS
|
|
|
|
.It Dv METEOR_CAP_SINGLE
|
|
|
|
capture one frame
|
|
|
|
.It Dv METEOR_CAP_CONTINOUS
|
|
|
|
unsynchronized continuous capture
|
|
|
|
.It Dv METEOR_CAP_STOP_CONT
|
|
|
|
stop the unsynchronized continuous
|
|
|
|
capture
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
If METEORCAPTUR fails the ioctl() will return a value of -1 and the
|
|
|
|
external variable errno will be set to:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width EINVAL
|
|
|
|
.It Dv EINVAL
|
|
|
|
invalid capture command value
|
|
|
|
.It Dv ENXIO
|
|
|
|
there is not internal buffer to hold the frame.
|
|
|
|
this indicates the previous set geometry ioctl failed.
|
|
|
|
.It Dv EIO
|
|
|
|
card is already capturing.
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
6) ioctl request METEORCAPFRM
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
METEORCAPFRM is used for synchronous capture of multiple frames.
|
|
|
|
.Pp
|
|
|
|
This ioctl routines use the meteor_capture structure that has the
|
|
|
|
following entries:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width command
|
|
|
|
.It Dv command
|
|
|
|
possible values for command are:
|
|
|
|
.Bl -tag -width METEOR_CAP_STOP_FRAMES
|
|
|
|
.It Dv METEOR_CAP_STOP_FRAMES stop the capture does not use the
|
|
|
|
other variable in structure.
|
|
|
|
.It Dv METEOR_CAP_N_FRAMES start the capture using the other
|
|
|
|
variables in the structure as inputs
|
|
|
|
.El
|
|
|
|
.It Dv signal
|
|
|
|
signal to send to application when a new
|
2000-03-03 14:05:08 +00:00
|
|
|
frame has been captured.
|
|
|
|
This signal will
|
1995-09-06 03:34:52 +00:00
|
|
|
only be raised if the captured frame is saved.
|
|
|
|
.It Dv lowat
|
|
|
|
see below
|
|
|
|
.It Dv hiwat
|
|
|
|
see below
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
When a new frame is completed, the driver checks the current unread
|
|
|
|
frame count stored in shared variable (the shared variable are stored
|
|
|
|
in the meteor_mem structure) num_active_buf, if the count is larger
|
|
|
|
than hiwat, the driver will not store any new frames and will not
|
|
|
|
send capture signal to the user application until the num_active_buf
|
|
|
|
is lower than lowat.
|
|
|
|
.Pp
|
|
|
|
If METEORCAPFRM fails the ioctl() will return a value of -1 and the
|
|
|
|
external variable errno will be set to:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width EINVAL
|
|
|
|
.It Dv EINVAL
|
|
|
|
invalid meteor_geomet structure pointer or bad command.
|
|
|
|
.It Dv ENXIO
|
|
|
|
there is not internal buffer to hold the frame.
|
|
|
|
this indicates the previous set geometry ioctl failed.
|
|
|
|
.It Dv EIO
|
|
|
|
card is already capturing.
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
7) ioctl requests METEORSCHCV and METEORGCHCV
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
METEORSCHCV and METEORGCHCV are used to set and get the chrominance
|
|
|
|
gain control and effects the UV output amplitude.
|
|
|
|
.Pp
|
|
|
|
If METEORSCHCV or METEORGCHCV fails the ioctl() will return a value
|
|
|
|
of -1 and the external variable errno will be set to:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width EINVAL
|
|
|
|
.It Dv EINVAL
|
|
|
|
EINVAL
|
|
|
|
invalid unsigned char pointer.
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
8) ioctl requests METEORGHUE and METEORSHUE
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
2000-03-03 14:05:08 +00:00
|
|
|
METEORGHUE and METEORSHUE are used to get and set the hue.
|
|
|
|
The
|
1995-09-06 03:34:52 +00:00
|
|
|
signed character has legal values are from +127 which represent
|
|
|
|
+178.6 degrees to -128 which represents -180 degrees.
|
|
|
|
.Pp
|
|
|
|
If METEORGHUE or METEORSHUE fails the ioctl() will return a value of
|
|
|
|
-1 and the external variable errno will be set to:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width EINVAL
|
|
|
|
.It Dv EINVAL
|
|
|
|
invalid signed char pointer.
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
9) ioctl requests METEORSCOUNT and METEORGCOUNT
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
|
|
|
METEORGCOUNT is used to get the count of frame errors, DMA errors and
|
|
|
|
count of the number of frames captured that have occurred since
|
2000-03-03 14:05:08 +00:00
|
|
|
the device was opened.
|
|
|
|
METEORSCOUNT can be used to reinitialize the
|
1995-09-06 03:34:52 +00:00
|
|
|
counters.
|
|
|
|
.Pp
|
|
|
|
This ioctl routines use the meteor_counts structure that has the
|
|
|
|
following entries:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width frame_count
|
|
|
|
.It Dv fifo_errors
|
|
|
|
number of FIFO errors since device was opened.
|
|
|
|
.It Dv dma_errors number of DMA errors since device was opened.
|
|
|
|
|
|
|
|
.It Dv frame_count number of frames captured since device was opened.
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
If METEORSCOUNT or METEORGCOUNT fails the ioctl() will return a value
|
|
|
|
of -1 and the external variable errno will be set to:
|
|
|
|
.Bl -tag -width EINVAL
|
|
|
|
.It Dv EINVAL
|
|
|
|
invalid meteor_counts structure pointer.
|
|
|
|
.El
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
.Sh Known Bugs:
|
|
|
|
.in +0.5i
|
|
|
|
.Pp
|
2000-03-03 14:05:08 +00:00
|
|
|
1) IIC register is difficult to set.
|
|
|
|
We got around that by adding a long
|
1995-09-06 03:34:52 +00:00
|
|
|
wait at each IIC register write.
|
|
|
|
.Pp
|
|
|
|
2) We had difficulties getting the Meteor capture card to work on systems
|
2000-03-03 14:05:08 +00:00
|
|
|
that used NCR chipset SCSI cards.
|
|
|
|
It is possible that the Meteor and NCR SCSI
|
1995-09-06 03:34:52 +00:00
|
|
|
could work together using the newer TRITON motherboards.
|
|
|
|
.in -0.5i
|
|
|
|
.Pp
|
|
|
|
.Sh Authors:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width Mark_Tinguely
|
|
|
|
.It Dv Jim Lowe
|
|
|
|
(james@miller.cs.uwm.edu)
|
|
|
|
.It Dv Mark Tinguely
|
|
|
|
(tinguely@plains.nodak.edu)
|
|
|
|
.El
|