			Application notes for the Captivator Capture Library

1.	Functions Supported

long CapConfigure( int IOBase, int IRQLevel );
long CapReset( void );
long CapGetStatus( CAP_STATUS *CapStatus );
long CapSetInput( int InputType, int InputStandard );
long CapSetFormat ( int CaptureFormat );
long CapSetDestRect( int Width, int Height);
long CapGrabOneFrame( char _huge *BufferPointer, long MaxBufferSize );
long CapConvertYUVFrameToRGB(char _huge *hpbYUVBuf, char _huge *hpbRGBBuf, 
					int iWidth, int iHeight, int iFormat, long lYUVMax);
long CapSetStreamParams( char _huge *BufferPointer, int FramesPerSecond );
long CapStreamStart( void ); 
long CapStreamStop( void ); 
long CapGetStreamStatistics(STREAMSTATS *StreamStats);
long CapSetGamma ( int iGamma );
long CapSetContrast ( int iContrast );
long CapSetSaturation ( int iSaturation );
long CapSetBrightness ( int iBrightness );


2. Synopsis of functions

long CapConfigure( int IOBase, int IRQLevel );

The CapConfigure function must be called first at the start of library usage.
It not only defines the Captivator card IO base address and hardware 
interrupt request (IRQ) level but peforms vital static initialisation. 

The parameters supplied for IOBase are the possible	bases at which the card 
can reside, namely: 0x300, 0x310, 0x320 and 0x330. The parameter supplied
for the IRQLevel is one of: 3, 5, 7, 9, 10 or 15 (decimal).

No range checking is performed and any supplied versus actual card base
discrepancy and any IRQ specification not on the above list will cause fatal 
library operation. 


long CapReset( void );

CapReset performs a software reset of the Arsenal ASIC, M2B, and 9051 DMSD,
setting the Captivator card to expect composite PAL input and to grab frames
at 160x120 resolution in VL YUV packing mode 0. This functiion should be
called immediately after CapConfigure().


long CapGetStatus( CAP_STATUS *CapStatus );

CAP_STATUS Structure													   

typedef struct _CAP_STATUS
{
	int IOBase;
	int IRQLevel;
	int InputType;
	int InputStandard;
	int CaptureFormat;
	int DestRectWidth;
	int DestRectHeight;
	int Brightness;
	int Saturation;
	int Contrast;
	int Gamma;
} CAP_STATUS, *PCAP_STATUS;

The function returns the current capture status. It is undefined until
CapReset is called.


long CapSetInput( int InputType, int InputStandard );

The CapSetInput function specifies the input video type and standard that 
the card is to expect. Parameters are:

InputType = 0 -> CVBS
		  = 1 -> SVIDEO

InputStandard = 0 -> NTSC
			  = 1 -> PAL

These numerical values are reflected in the CAP_STATUS structure.


long CapSetFormat ( int CaptureFormat );

The CapSetFormat function informs the card of the desired output frame YUV
packing mode. These formats are selected by supplying 0 to 3 to the function
and are described below:

Format 0.
									Bit
		7		6		5		4		3		2		1		0

Byte0	0		Y1.6	Y1.6	Y1.4	Y1.3	Y1.2	U6		U5
Byte1	0		Y2.6	Y2.6	Y2.4	Y2.3	Y2.2	U6		U5
Byte2	0		Y3.6	Y3.6	Y3.4	Y3.3	Y3.2	U6		U5
Byte3	0		Y4.6	Y4.6	Y4.4	Y4.3	Y4.2	U6		U5
Byte4	U4		U3		U2		V6		V5		V4		V3		V2

Format 1.
									Bit
		7		6		5		4		3		2		1		0

Byte0	0		Y1.6	Y1.6	Y1.4	Y1.3	Y1.2	Y1.1	Y1.0
Byte1	0		Y2.6	Y2.6	Y2.4	Y2.3	Y2.2	Y2.1	Y2.0
Byte2	0		Y3.6	Y3.6	Y3.4	Y3.3	Y3.2	Y3.1	Y3.0
Byte3	0		Y4.6	Y4.6	Y4.4	Y4.3	Y4.2	Y4.1	Y4.0
Byte4	0		U6		U5		U4		U3		U2		U1		U0
Byte5	0		V6		V5		V4		V3		V2		V1		V0

Format 2.
									Bit
		7		6		5		4		3		2		1		0

Byte0	0		Y1.6	Y1.6	Y1.4	Y1.3	Y1.2	U6		U5
Byte1	U4		Y2.6	Y2.6	Y2.4	Y2.3	Y2.2	U3		U2
Byte2	V4		Y3.6	Y3.6	Y3.4	Y3.3	Y3.2	V3		V2
Byte3	0		Y4.6	Y4.6	Y4.4	Y4.3	Y4.2	U6		U5

Format 3.
									Bit
		7		6		5		4		3		2		1		0

Byte0	0		Y1.6	Y1.6	Y1.4	Y1.3	Y1.2	Y1.1	Y1.0
Byte1	0		Y2.6	Y2.6	Y2.4	Y2.3	Y2.2	Y2.1	Y2.0
Byte2	0		Y3.6	Y3.6	Y3.4	Y3.3	Y3.2	Y3.1	Y3.0
Byte3	0		Y4.6	Y4.6	Y4.4	Y4.3	Y4.2	Y4.1	Y4.0

The numerical values for the formats are reflected in the CAP_STATUS 
structure.


long CapSetDestRect ( int Width, int Height);

The CapSetDestRect function specifies the output frame size. Any size is 
possible up to the maximum of 640x480 although supplied parameters must
be rounded to a multiple of four pixels in both dimensions. NO range 
checking is performed, values outside the horizontal and vertical maxima
can lead to unpredictable behaviour and lockup scenarios.


long CapGrabOneFrame ( char _huge *BufferPointer, long MaxBufferSize );

The function transfers a frame of YUV data of the specified resolution from
the Captivator card to the user suplied buffer pointed to by the huge pointer
BufferPointer. The user must ensure that the buffer to receive the data is
of an adequate size. The function will transfer no more than MaxBufferSize
bytes irrespective of image size. Note that one YUV pixel is equivalent to
one RGB pixel and that only in capture formats 2 and 3 are four YUV pixels
represented in 4 bytes (these modes are effectively one byte per pixel). In
modes 0 and 1, 4 YUV pixels are encoded in 5 and 6 bytes respectively,
yielding the following formulae to calculate the required byte buffer
size to hold a frame of width W and height H:

Formats 2 and 3

MaxBufferSize = W * H


Format 0

MaxBufferSize = (W * H * 5)	/ 4


Format 1

MaxBufferSize = (W * H * 6)	/ 4


long CapConvertYUVFrameToRGB(char _huge *hpbYUVBuf, char _huge *hpbRGBBuf, 
					int iWidth, int iHeight, int iFormat, long lYUVMax);

This function converts the YUV data buffer pointed to by hpbYUVBuf to a 24bit
RGB data frame and places the RGB data in the buffer indicated by hpbRGBBuf.
The user must supply the width, height, capture format and number of bytes 
comprising the YUV image.

The conversion process creates a DIB-like arrangement of RGB data, namely,
data is stored one byte per RGB component in BGR order with the YUV image 
data inverted (YUV image line 0 at end of RGB buffer, etc). Following the
restrictions on DIB data formats, the required size for the RGB buffer can
be determined for an image of width W and height H via:

MaxSize = (H * ((W + 3) & ~3)) * 3

 
long CapSetStreamParams( char _huge *BufferPointer, int FramesPerSecond );

STREAMBUF Structure.

typedef struct _STREAMBUF
{
	char InUse;
	char _huge *NPtr;
	char Buf[1];
} STREAMBUF;

This function supplies the first of a potentially circular linked list of 
stream buffers to the library, along with the application-desired capture 
rate in the FramesPerSecond parameter. 

As with the CapGrabOneFrame() function, the user must supply buffers that
are large enough to hold the YUV data (dependent on the width, height and
format). The asynchronous nature of streaming requires some form of 
semaphoring between library and application. This is achieved via the InUse
streambuffer structure element. A zero value of InUse, indicates to the
Library that the buffer is free to receive captured data. The Library sets
two flags in the InUse element; BUFFER_FILLING during the capture process
and BUFFER_FULL at its termination alowing the application to then process
the YUV data and to set InUse to zero to free up the buffer.

The Library streaming process uses the NPtr structure element to ascertain
the next buffer to fill. If only one buffer is provided by the application
(NOT recommended) the NPtr element must point to the start of the buffer. 
If multiple buffers are used the NPtr elements provide the linkage between 
buffers; the last buffer NPtr should reference the start of the first buffer.


long CapStreamStart( void ); 

The streaming process is started. This function hooks the indicated IRQ
and enables the 8259 PIC, it is essential that the companion function 
CapStreamStop be called to unhook the IRQ and reset the PIC.


long CapStreamStop( void ); 

Stops the streamed capture.


long CapGetStreamStatistics(STREAMSTATS *StreamStats);

STREAMSTATS structure.

typedef struct _STREAMSTATS
{
	long lError;
	long lFramesSkipped;
   	long lFramesDropped;
	long lFramesCaptured;
	long lFrameCount;
} STREAMSTATS, *PSTREAMSTATS;

Function retrieves the latest stream operation statistics. The streaming
process as implemented here can incur two error conditions:-

(1) If, to maintain the specified framerate the capture process must start
	but no buffer is available an IOERR_DRV_NO_BUFFER error is reported in
	the stream stats.

(2) If the capture process cannot read the data from the Captivator card
	rapidly enough before another capture interrupt is received an 
	IOERR_DRV_DATA_OVERRUN error is reported.

Each of these errors increment the lFramesDropped element. The lFramesSkipped
element is not incremented by error, it increases by a valid skipping
of a frame when the requested frame rate is lower than the source frame rate.


long CapSetGamma ( int iGamma );
long CapSetContrast ( int iContrast );
long CapSetSaturation ( int iSaturation );
long CapSetBrightness ( int iBrightness );

These functions act in the YUV domain, changing the above factors for the 
data returned by the streamed and single frame captures. The functions take
a range of 0 to 200, (again no range checking is performed, BEWARE) a 
nominal value of 100 being the library reset default. The Gamma function
supplied here provides data corrected for screens with gammas of 0 to 2.0.


The Capture library provides CAP.H, which defines these functions and structs.


Marc Stevens
24/JUN/93






