From f5de4fdbaf8d1882ea6d50d4e564bf9655d73dca Mon Sep 17 00:00:00 2001 From: "Jordan K. Hubbard" Date: Mon, 28 Aug 1995 17:08:26 +0000 Subject: [PATCH] Man page for Matrox meteor. Submitted by: Mark Tinguely and Jim Lowe --- share/man/man4/meteor.4 | 771 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 771 insertions(+) create mode 100644 share/man/man4/meteor.4 diff --git a/share/man/man4/meteor.4 b/share/man/man4/meteor.4 new file mode 100644 index 000000000000..c4c26185e207 --- /dev/null +++ b/share/man/man4/meteor.4 @@ -0,0 +1,771 @@ +.Dd August 15, 1995 +.br +.in +0.5i +.Dt METEOR 4 +.Os FreeBSD +.Sh NAME +.Nm meteor +.Nd video capture driver +.Sh SYNOPSIS +.Nm video meteor +.Sh DESCRIPTION +The +.Xr meteor +driver provides support for a PCI +.Em video +capture. It allows the capture of 24 bit RGB, 16 bit RGB and 16 bit YUV +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 +For FreeBSD release versions 2.1 and earlier, the following patch files are also required: +.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 +deallocate all pages when closing the device. Note, the chance of +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 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 +1) Conventional read(2) interface. +.in +0.5i +.Pp +This mode is the easiest and slowest to use. This mode is great for +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 +#include + +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) { + printf("open failed: %d\n", errno); + 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) { + printf("ioctl failed: %d\n", errno); + exit(1); + } + + c = METEOR_FMT_NTSC; + + if (ioctl(i, METEORSFMT, &c) < 0) { + printf("ioctl failed: %d\n", errno); + exit(1); + } + + c = METEOR_INPUT_DEV0; + + if (ioctl(i, METEORSINPUT, &c) < 0) { + printf("ioctl failed: %d\n", errno); + exit(1); + } + + if ((c=read(i, &buf[0], SIZE)) < SIZE) { + printf("read failed %d %d %d\n", c, i, errno); + close(i); + exit(1); + } + close(i); + + if ((o = open("rgb24.ppm", O_WRONLY | O_CREAT, 0644)) < 0) { + printf("ppm open failed: %d\n", errno); + exit(1); + } + + /* make PPM header and save to file */ + strcpy(&header[0], "P6 400 300 255 "); + header[2] = header[6] = header[10] = header[14] = '\n'; + 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 +need several frames a second. The continuous capture mode is designed +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 +#include +#include +#include + +extern int errno; +#define ROWS 480 +#define COLS 640 +#define SIZE (ROW * COLS * 2) +main() +{ + struct meteor_geomet geo; + char buf[SIZE]; + char *mmbuf; + int i,c; + + if ((i = open("/dev/meteor0", O_RDONLY)) < 0) { + printf("open failed\n"); + exit(1); + } + + geo.rows = ROWS; + geo.columns = COLS; + geo.frames = 1; + geo.oformat = METEOR_GEO_RGB16 ; + + if (ioctl(i, METEORSETGEO, &geo) < 0) { + printf("ioctl failed: %d\n", errno); + exit(1); + } + + c = METEOR_FMT_NTSC; + + if (ioctl(i, METEORSFMT, &c) < 0) { + printf("ioctl failed: %d\n", errno); + exit(1); + } + + c = METEOR_INPUT_DEV0; + + if (ioctl(i, METEORSINPUT, &c) < 0) { + printf("ioctl failed: %d\n", errno); + exit(1); + } + + mmbuf=(char *)mmap((caddr_t)0, SIZE, PROT_READ, 0, i, (off_t)0); + +#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 +processes up to 32 frames. This gives the advantages of both single and +continuous capture modes. +.Pp +The kernel notifies the application of a new data by raising an +application defined signal. The driver also shares a structure with +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 +The shared structure starts on the first page after your data. The +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 +The shared structure is of type struct meteor_mem. The two most +important fields are called active and num_active_buf. active +is a bitmap of frames written by the kernel. num_active_bufs is +a count of frames marked in the active field. When a frame is read +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 +signal to activate the user application. The user application's +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 +num_active_bufs. If the threshold of number of active frames (hiwat) +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 +that the user removes them in the same order. The driver does not +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 +continuous capture mode. A special signal catcher is required to +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 +#include +#include +#include +#include + +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) { + printf("METEORCAPFRM failed %d\n", errno); + 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) { + printf("open failed\n"); + exit(1); + } + printf("test %d %d\n", errno, i); + + 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) { + printf("METEORSETGEO failed %d\n", errno); + exit(1); + } + + c = METEOR_FMT_NTSC; + + if (ioctl(i, METEORSFMT, &c) < 0) { + printf("ioctl failed: %d\n", errno); + exit(1); + } + + c = METEOR_INPUT_DEV0; + + if (ioctl(i, METEORSINPUT, &c) < 0) { + printf("ioctl failed: %d\n", errno); + 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, + 0, i, (off_t)0); + + if (data_frames == (caddr_t) -1) return (0); + + /* 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) { + printf("METEORCAPFRM failed %d\n", errno); + 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) { + printf("METEORCAPFRM failed %d\n", errno); + 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 +application should not attempt to proceed further with capturing. The +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 +number of frames in buffer. Should be 1, unless using +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 +the existing values are used. The system defaults +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 +(RBG 24 bits packed in 32 bits: +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 +is selected. It is highly recommended that a METEORSETGEO is done +before capturing data because you cannot guarantee the initial mode +the card. +.Pp +The METEORSETGEO will also attempt to reallocate a new contiguous +kernel buffer if the new geometry exceeds the old geometry. On +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 +could not allocate the contigous block. +.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 +input device. Using the DB9 connector on the Meteor card, 4 input +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 +frame has been captured. This signal will +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 +METEORGHUE and METEORSHUE are used to get and set the hue. The +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 +the device was opened. METEORSCOUNT can be used to reinitialize the +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 +1) IIC register is difficult to set. We got around that by adding a long +wait at each IIC register write. +.Pp +2) We had difficulties getting the Meteor capture card to work on systems +that used NCR chipset SCSI cards. It is possible that the Meteor and NCR SCSI +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