meteor(4)
NAME
meteor - video capture driver interface
DESCRIPTION
- The meteor driver defined a video capture interface. The
- meteor driver
is no longer in the tree, but other devices support this in - terface so the
interface portion is documented here. - Meteor Capture Modes
- The meteor capture driver has three modes of capture opera
- tion.
- 1. Conventional read(2) interface.
This mode is the easiest and slowest to use. This mode - is great for
capturing a single field at little programming cost. - In this mode, the user opens the device, sets the cap
- ture mode and
size (see: METEORSETGEO ioctl(2) call), and uses the - read(2) system
call to load the data into a buffer. - meteor_read.c; read 400x300 RGB24 into a viewable PPM
- file
- #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) {
printf("open failed: %d0, 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: %d0, errno);
exit(1); - }
- c = METEOR_FMT_NTSC;
- if (ioctl(i, METEORSFMT, &c) < 0) {
printf("ioctl failed: %d0, errno);
exit(1); - }
- c = METEOR_INPUT_DEV0;
- if (ioctl(i, METEORSINPUT, &c) < 0) {
printf("ioctl failed: %d0, errno);
exit(1); - }
- if ((c=read(i, &buf[0], SIZE)) < SIZE) {
printf("read failed %d %d %d0, c, i, - errno);
close(i);
exit(1); - }
close(i); - if ((o = open("rgb24.ppm", O_WRONLY | O_CREAT,
- 0644)) < 0) {
printf("ppm open failed: %d0, errno);
exit(1); - }
- /* make PPM header and save to file */
strcpy(&header[0], "P6 400 300 255 ");
header[2] = header[6] = header[10] = head - er[14] = '0;
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 ef - ficient */
- }
close(o);
exit(0); - }
- 2. Memory mapped single capture or unsynchronized continu
- ous capture.
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 da - ta.
- In this mode, the user opens the device, sets the cap
- ture mode and
size (see: METEORSETGEO ioctl(2) call), mmap(2)s the - frame buffer
memory into the user process space, and issues either - the singlecapture or the continuous capture call (see: METEORCAP
- TUR ioctl(2)
call) to load the data into the memory mapped buffer. - As explained in the METEORCAPTUR ioctl(2) call, the
- single frame
capture ioctl(2) will block until the capture is com - plete, the continuous capture will return immediately.
- meteor_mmap_single_continuous.c
- #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
#define SIZE (ROWS * 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 failed0);
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: %d0, errno);
exit(1); - }
- c = METEOR_FMT_NTSC;
- if (ioctl(i, METEORSFMT, &c) < 0) {
printf("ioctl failed: %d0, errno);
exit(1); - }
- c = METEOR_INPUT_DEV0;
- if (ioctl(i, METEORSINPUT, &c) < 0) {
printf("ioctl failed: %d0, errno);
exit(1); - }
- mmbuf=(char *)mmap((caddr_t)0, SIZE, PROT_READ,
MAP_SHARED, 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 im - mediately */
- /* 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);- }
- 3. Memory mapped, multi-frame ring buffer synchronize cap
- ture.
This continuous capture mode is synchronized with the- application
that processes up to 32 frames. This gives the advan - tages of both
single and continuous capture modes. - 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.
- The shared structure starts on the first page after
- your data. The
structure address can be found by calculation:
(number_rows * number_columns * pixel_depth +- 4095) &
0xfffff000 - or
((number_rows * number_columns * pixel_depth + - 4095)/4096) *
4096 - 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 sig - nal to activate
the user application. The user application's responsi - bility when
getting the signal is to check the active bitmap to de - termine 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. - 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. - 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.
- In programming for this mode, the user opens the de
- vice, sets the
geometry, mmap(2)s 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. - When specifying the geometry (see: METEORSETGEO
- ioctl(2) call), it
is important that the number of frames is set greater - than 1.
- skeleton_capture_n.c
- #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 * com - mon_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=METE - OR_CAP_STOP_FRAMES;
- if (ioctl(i, METEORCAPFRM, &capframe) <
- 0) {
printf("METEORCAPFRM failed - %d0, 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 failed0);
exit(1); - }
printf("test %d %d0, 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 %d0, er
- rno);
exit(1); - }
- c = METEOR_FMT_NTSC;
- if (ioctl(i, METEORSFMT, &c) < 0) {
printf("ioctl failed: %d0, errno);
exit(1); - }
- c = METEOR_INPUT_DEV0;
- if (ioctl(i, METEORSINPUT, &c) < 0) {
printf("ioctl failed: %d0, 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,
MAP_SHARED, - i, (off_t)0);
- if (data_frames == (caddr_t) MAP_FAILED) 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 %d0, er
- rno);
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 %d0, er
- rno);
exit(1); - }
- }
- Meteor IOCTL Call and ParametersThe meteor capture driver has ioctl(2) requests for captur
- ing, reading
card status, for setting and reading the geometry, and for - setting and
reading the attributes. - IT IS VERY IMPORTANT TO CHECK FOR ERRORS ON THESE RETURNING
IOCTLs.
- Errors indicate that something is very wrong with the
- ioctl(2) and the
application should not attempt to proceed further with cap - turing. 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.
- 1. ioctl(2) requests METEORSETGEO and METEORGETGEO
METEORSETGEO and METEORGETGEO are used to set and read- the input
size, input device, and output format for frame cap - ture.
- These ioctl(2) routines use the meteor_geomet structure
- that has the
following entries: - rows number of rows (lines high) in output image
- columns number of pixels in a row (width) in output
- image
- frames number of frames in buffer. Should be 1, un
- less using themulti-framed synchronous capture mode (METEOR
- CAPFRM) which
REQUIRES frames to be larger than 1. - Note: if rows, columns or frames is not
- changed, then the
existing values are used. The system defaults - is
640x480x1. - oformat you may choose one of the following output
- format:
METEOR_GEO_RGB16 (RGB 16 bits xrrrrrgg- gggbbbbb
default) - METEOR_GEO_RGB24 (RGB 24 bits packed in
- 32 bits:
00000000 rrrrrrrr - gggggggg bbbbbbbb)
- METEOR_GEO_YUV_PACKED (4-2-2 YUV 16 bits
- packed byte for
mat: u0 y0 v0 y1 u1 y2 - v1 y3 ...)
- 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)
- The METEORSETGEO ioctl(2) 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 guar - antee the initial mode the card.
- The METEORSETGEO will also attempt to reallocate a new
- contiguous
kernel buffer if the new geometry exceeds the old geom - etry. On
other hand, if the new geometry will fit in the exist - ing buffer, the
existing buffer is used. - If METEORSETGEO fails the ioctl(2) will return a value
- of -1 and the
external variable errno will be set to: - [EINVAL] invalid meteor_geomet structure
- pointer, rows,
columns, frames were invalid. - [ENOMEM] could not allocate the contiguous
- block.
- 2. ioctl(2) requests METEORSFMT and METEORGFMT
METEORSFMT and METEORGFMT are used to set and read the- camera input
standard format. - Possible formats are:
- METEOR_FMT_NTSC NTSC (default mode)
METEOR_FMT_PAL PAL
METEOR_FMT_SECAM SECAM
METEOR_FMT_AUTOMODE Autodetect. - 3. ioctl(2) requests METEORSINPUT and METEORGINPUT
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 se - lected with
this ioctl(2). - Possible formats are:
- METEOR_INPUT_DEV0 (default if none specified)
METEOR_INPUT_DEV_RCA (same as METEOR_INPUT_DEV0)
METEOR_INPUT_DEV1
METEOR_INPUT_DEV2
METEOR_INPUT_DEV_SVIDEO (same as METEOR_INPUT_DEV2) - 4. ioctl(2) request METEORSTATUS
METEORSTATUS is used to read the status of the Meteor- capture card
and returns the following information: - METEOR_STATUS_ID_MASK 4 bit ID of the SAA7196 scaler
- chip.
- METEOR_STATUS_DIR 0 = scaler uses internal
- source.
1 = scaler uses external data - of expansion
bus. - METEOR_STATUS_OEF 0 = even field detected.
1 = odd field detected. - METEOR_STATUS_SVP VRAM Port state:0 = inputs HFL and INCADDR in
- active.
1 = inputs HFL and INCADDR ac - tive.
- METEOR_STATUS_STTC 0 = TV horizontal time con
- stant (slow).1 = VCR horizontal time con
- stant (fast).
- METEOR_STATUS_HCLK 0 = Horizontal Phase Lock Loop
- locked.
1 = Horizontal Phase Lock Loop - unlocked.
- METEOR_STATUS_FIDT 0 = 50 Hz Field detected.
1 = 60 Hz Field detected. - METEOR_STATUS_ALTD 0 = no line alternating color
- burst
detected. - 1 = line alternating color
- burst detected
(PAL/SECAM). - METEOR_STATUS_CODE 0 = no color information de
- tected.1 = color information detect
- ed.
- 5. ioctl(2) request METEORCAPTUR
METEORCAPTUR is used to single frame capture or unsyn- chronized continuous capture.
- The single frame capture ioctl(2) request will return
- only after a
frame has been captured and transfered to the frame - buffer.
- The unsynchronized continuous capture will return imme
- diately 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.
- These ioctl(2) routines use the following settings:
- METEOR_CAP_SINGLE capture one frame
METEOR_CAP_CONTINOUS unsynchronized continuous capture
METEOR_CAP_STOP_CONT stop the unsynchronized continu - ous capture
- If METEORCAPTUR fails the ioctl(2) will return a value
- of -1 and the
external variable errno will be set to: - [EINVAL] invalid capture command value
- [ENXIO] there is not internal buffer to hold
- the frame.This indicates the previous set ge
- ometry ioctl(2)
failed. - [EIO] card is already capturing.
- 6. ioctl(2) request METEORCAPFRM
METEORCAPFRM is used for synchronous capture of multi- ple frames.
- This ioctl(2) routine uses the meteor_capture structure
- that has the
following entries: - command possible values for command are:
METEOR_CAP_STOP_FRAMES stop the capture; does- not use the
other variable in - structure.
- METEOR_CAP_N_FRAMES start the capture us
- ing the other
variables in the - structure as
inputs - 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. - lowat see below
- hiwat see below
- When a new frame is completed, the driver checks the
- current unread
frame count stored in shared variable (the shared vari - able is 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. - If METEORCAPFRM fails the ioctl(2) will return a value
- of -1 and the
external variable errno will be set to: - [EINVAL] invalid meteor_geomet structure
- pointer or bad
command. - [ENXIO] there is not internal buffer to hold
- the frame.This indicates the previous set ge
- ometry ioctl(2)
failed. - [EIO] card is already capturing.
- 7. ioctl(2) requests METEORSCHCV and METEORGCHCV
METEORSCHCV and METEORGCHCV are used to set and get the- chrominance
gain control and effects the UV output amplitude. - If METEORSCHCV or METEORGCHCV fails the ioctl(2) will
- return a value
of -1 and the external variable errno will be set to: - [EINVAL] invalid unsigned char pointer.
- 8. ioctl(2) requests METEORGHUE and METEORSHUE
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. - If METEORGHUE or METEORSHUE fails the ioctl(2) will re
- turn a value
of -1 and the external variable errno will be set to: - [EINVAL] invalid signed char pointer.
- 9. ioctl(2) requests METEORSCOUNT and METEORGCOUNT
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. - This ioctl(2) routines use the meteor_counts structure
- that has the
following entries: - fifo_errors number of FIFO errors since device was
- opened.
- dma_errors number of DMA errors since device was
- opened.
- frame_count number of frames captured since device was
- opened.
- If METEORSCOUNT or METEORGCOUNT fails the ioctl(2) will
- return a
value of -1 and the external variable errno will be set - to:
- [EINVAL] invalid meteor_counts structure
- pointer.
AUTHORS
Jim Lowe <james@miller.cs.uwm.edu>,
Mark Tinguely <tinguely@plains.nodak.edu>
BUGS
- The meteor driver no longer works at all.
- BSD August 15, 1995