libbgrab

Easy to use framegrabber library with many demo programs.

DOWNLOAD

[ libbgrab-2.1h.tar.gz (566k)]

INTRO

Author: A. Schiffler, aschiffler@cogeco.ca to contact the author.
Licenced under the GPL/MPL, see the file COPYING for details.

README


[ libbgrab ]
[ -------- ]

... is an easy to use framegrabber interface library 
     with many sample and utility programs ...


(C) A. Schiffler, 1999,2000,2001 under the dual MPL/GPL license. 

Please see source code for details.
Please see the file LICENSE.GPL for GPL info.
Please see the file LICENSE.MPL for MPL info.


[ Introduction ]
[ ------------ ]

libbgrab is a video4linux grabbing library to facilitate easy use of the
brooktree (bt848/bt878) family of framegrabber cards through a few 
function calls. 

To implement constant throughput and to avoid frame loss delays, triple 
buffering is used through local buffer copying in a separate grabbing thread.

The library consists of two parts that are usually used together:
 1. framegrabber access (bgrab.c/bgrab.h) 
 2. xwindows output (xutils.c/xutils.h)

Additional routines allow for image processing:
 3. Motion JPG compression (RTjpeg.c, RTjpeg.h, mmx.h)
 4. MMX optimized image filters (asm/*) 


[ Examples and Demo Programs ]
[ -------------------------- ]

Note: All demo programs are hardcoded for Tuner/NTSC input. You have to 
      modify the code and recompile for other inputs!

+++ testgrab

See demo program "testgrab" for a quick intro on how to use libbgrab. See
source code comments for additional usage notes. The source code will
probably have to be edited to adapt for your video input - it is just a
demoprogram! Use Q to quit with the live-video window active. Use F and D
to change channels. 

+++ glgrab (GLX only)

A very similar program uses OpenGL as output driver and maps the live 
image as a texture on a polygon - try "glgrab" for nicely scaled, 
full-screen output ... not always at full frame rates ;-). Works fine with
my Matrox G400 and Geforce2MX cards and the GLX drivers.

+++ asciigrab

Also included is a demo "asciigrab" that converts video in realtime into 
ASCII CHARACTERS - just start it in a large enough terminal ... . 
See source code for additional usage notes. This program has actually been
exhibited in the "net_condition" art exhibition at the ZKM, Karlsruhe,
Germany on a big projection screen http://www.zkm.de).

+++ delaygrab

A nice example of using MUCH memory, try "delaygrab" in which a few
seconds of video is beeing stored and shown according to a delay-map. If it
runs, try pressing the keys 1, 2 and 3 to switch effects. This effect will
be used in upcoming exhibitions at the ZKM, Karlsruhe, Germany with
temperature sensors. A similar program with a network interface was
developed for the world exhibition Expo2000, Hannover 2000 and can be found
in the "expograb" directory.

+++ zoomgrab (3Dfx Glide only)

Also included is a demo "zoomgrab" that shows a live video image at any
scale using a 3dfx graphics card (required). The numbers in "zoomdef.txt" 
define zoom scales in ONE SECOND intervals (range: 0.01 to 200.0, first 
number in line) and mixer volume settings (range: 0 to 100, second number 
in line) that will be smoothly applied to the image and the volume. See
source code for additional usage notes. This program was also part of an art
exhibition at Weimar, Germany in 1999.

+++ artcam (3Dfx Glide only)

A similar demo called "artcam" also uses glide for display. This demo
changes the colors of an image in realtime using a precalculated 
conversion table.

+++ webcam

And then there is the really complete and useful "webcam" application - see
the README in the /webcam directory for more explanation and usage 
information of this nice little utility.

+++ greydetect

A utility program called "greydetect" makes measurements of the mean
greyscale values in rectangular areas. It can be used for scientific
measurements. See the README in the /greydetect subdirectory for more info
and usage information.

+++ difftrigger

The tool program "difftrigger" can be used as a security or interface 
application to detect changes in images (i.e. from moving objects). 
See the README in the /difftrigger subdirectory for more info and usage 
information. Very similar is the application "tracker". Here the 
difference images can be used to track the motion within a rectangular
area and send it to an external program via TCP/IP.

+++ rgbmix

Yet another art-program is the demo "rgbmix". It uses three framegrabber
inputs to get b/w images and mixes them together into a single RGB color
output image. This might make it into the lobby of a big company someday. 
Any buyers ... :-)

+++ tracker

Yet another specialized tracking program is "tracker". Again this a program
that was developed for an installation and requires several other utilities
to be useful (asciireflector and reflector2midi). See the local README for 
information on this tool. If you want to see it in action, check the passage
from the Frankfurt Airport Terminal to the Trainstation June-December 2000.
Diagrams of the installation and documentation are included in the /tracker 
directory.

+++ rtjpegrecord
+++ rtjpegplay

A new addition to libbgrab for capturing live video is RTjpeg. This library 
works only on MMX capable CPUs and provides fast motion Jpeg compression
routines. The resulting format is NOT compatible with standard MPEG or JPEG
files - i.e. one needs the RTjpeg library to decompress the generated stream.
The sample applications for recording and playback can be found in the /examples
directory. Since the input video format is YUV420 and a color conversion
would be required for standard RGB X-windows screens, no output will be shown
during the recording phase. To record use "rtjpegrecord" - experiment with the 
quality settings for best results. The default setting achieves a 12:1 compression
ration at excellent image quality. To view use "rtjpegplay" on 16bit bpp screens.

See also the README files:
 RTjpeg/README
 greydetect/README
 webcam/README
 difftrigger/README
 expograb/README
 tracker/README


[ Version History ]
[ --------------- ]

See CHANGES file for what has changed.


[ Usage - Step-by-Step Programming Instructions ]
[ --------------------------------------------- ]


1. Define access structure
..........................

Define a variable with the "fgdevice" structure and use it as pointer 
to handle all accesses to the framegrabber. 

i.e.:

struct fgdevice fg;
fg_open_device(&fg,"/dev/video");


2. Open (and close) the device
..............................

Use these calls to open the device. A typical device name is /dev/video
or /dev/video0. 

int fg_open_device (struct fgdevice *fg, char *devicename);
int fg_close_device (struct fgdevice *fg);


3. Get general framegrabber information
.......................................

Use this optional call to retrieve general info and a channel list of the 
card. This can be helpful in debugging and setup of the card. The
information gets written to "stderr".

int fg_print_info(struct fgdevice *fg); 


4. Setup FPS calculation
........................

Before grabbing, one can set the update interval for frames-per-second
(FPS) calculation. The FPS is the rate of image retrieval using 
fg_get_next_image() call and can be a useful performance parameter. If
"interval" is 100, then every 100 calls to fg_get_next_image() the FPS
number available through fg_get_fps() will be updated. Useful intervalls
are 1-100.

void fg_set_fps_interval(struct fgdevice *fg, int interval);
double fg_get_fps(struct fgdevice *fg);


5. Define the setting and channel values
........................................

To configure the framegrabber for different input channels and to
programm the brightness, contrast and color settings use the following
routines. The channel setup is required.

int fg_set_channel(struct fgdevice *fg, int channel, int videomode);
int fg_get_setting(struct fgdevice *fg, int which_setting);
int fg_set_setting(struct fgdevice *fg, int which_setting, int value);

Channel defines are these:

#define CHANNEL_TUNER           0
#define CHANNEL_COMPOSITE       1
#define CHANNEL_SVIDEO          2  

The channel defines can vary from card to card. Please see the output of the
fg_print_info() call for a list of available channel of your card.

Videomode defines are these:

#define VIDEOMODE_PAL		VIDEO_MODE_PAL			
#define VIDEOMODE_NTSC		VIDEO_MODE_NTSC
#define VIDEOMODE_SECAM		VIDEO_MODE_SECAM

Setting defines are these:

#define SETTING_BRIGHTNESS	0
#define SETTING_HUE		1
#define SETTING_COLOUR		2
#define SETTING_CONTRAST	3

The value can range from 0 to 32767.

To setup a tuner frequency for TUNER input use these calls:

region=REGION_NTSC_CABLE;
channel=1;
if (fg_set_frequency (&fg, region, channel)!=0) exit(-1);


6. Start the background grabbing thread
.......................................

Now you want to initiate grabbing at a specific size and format using the
fg_start_grab_image() call. Grabbing will constantly run in a thread in the
background. All one has to do now in the main program, is to retrieve 
the latest image through the fg_get_next_image() call. The thread can be 
stopped and CPU resources freed, using the fg_stop_grab_image() call. The
thread also stopps when the program terminates.

int fg_start_grab_image (struct fgdevice *fg, int width, int height, int format);
int fg_stop_grab_image (struct fgdevice *fg);

The format settings are:

#define FORMAT_GREY		VIDEO_PALETTE_GREY
#define FORMAT_RGB565		VIDEO_PALETTE_RGB565
#define FORMAT_RGB24		VIDEO_PALETTE_RGB24
#define FORMAT_RGB32		VIDEO_PALETTE_RGB32
#define FORMAT_YUV422P		VIDEO_PALETTE_YUV422P

The widht and height settings are usually limited by the framegrabber. 
Useful values are typically 32 to 800.


7. Get new images and use them
..............................

The fg_get_next_image() blocks until a new image is available and returns
the image as a pointer. A pointer to the latest image is also stored in the
fgdevice structure. If the grabbing is not active (i.e. the thread is
not running) the routine returns a NULL pointer.
 
void * fg_get_next_image(struct fgdevice *fg);

char *curimage;
if (fg_get_next_image(&fg)!=NULL) { 
 curimage=(char *)fg.current_image;
}


8. XWindow output of the images
...............................

Normally we want to see the aquired images on the screen. To do that, the
XWindows utility routines can be used.

For following sample code shows how this can be done easily (see also
testgrab.c).

// Define structure and open window
struct xwinbuffer xwin; 
if (setup_xwinbuffer (&xwin, argv[0], WIDTH, HEIGHT, DEPTH)!=0) exit(-1); 

// ... setup framegrabber ...

// loop: get images and display them 
while (1) {
 if (fg_get_next_image(&fg)!=NULL) {
  /* Copy image to screenbuffer */
  memcpy((char *)xwin.shmimage->data,(char *)fg.current_image,fg.image_size);
  /* Draw it */
  sync_xwinbuffer(&xwin);
 } 
}

// Close window
if (close_xwinbuffer(&xwin)!=0) exit(-1);


9. Other features and function
..............................

Two tables are initialized within the framegrabber device structure that
allow fast color conversion between the RBG565 color-space and Y8 B/W screen
formats. This can be useful when one grabs greyscale images but want to
display on a 16bit color screen (i.e. the "greydetect" utility program).

unsigned short *y8_to_rgb565;
unsigned char  *rgb565_to_y8; 

To convert a 8bit Y8 value (pixel of a B/W image) to a 16bit RGB pixel:
(unsigned short)outpixel=fg.y8_to_rgb565[(unsigned char)inpixel]

To convert a 16bit RGB pixel to a Y8 value (pixel of a B/W image);
(unsigned char)outpixel=fg.rgb565_to_y8[(unsigned short)inpixel]


[ Compilation and Running the Programs ]
[ ------------------------------------ ]

- Make sure you have the required modules for video input loaded. The
provided "loadbttv.sh" might be used to load the drivers. It probably
requires customization of tuner type (type=XX) and the card type (card=YY).
Especially the tuner needs optne manual settings.

- The include file "linux/videodev.h" has to be available.

- Create the video devices if they are not alreay there. (Run "cd /dev; 
./MAKEDEV video").  

- Edit the optimization flags setting in the "Makefile". Possible options
are for the Pentium and Athlon CPUs or a general setting (default).

- Optionally install glide libraries if you have a 3Dfx graphics card.

- Run "make clean; make" to compile. 

- Test with "testgrab" (running XWindows at depth 16 weight 565) that can be
found in the ./examples directory.

- If you have a 3Dfx graphics card and the glide libraries installed, run
"make glideprgs" in the ./examples directory. Test with "artcam".

- If you have a 3D graphics card with GL/GLX drivers installed try 
"make glprgs" in the ./examples directory. 

Most demos and testprograms have the video device and framegrabber setup
hardcoded. To get an image, one probably needs to edit the source and 
recompile. Notable exceptions are: "webcam" and "greydetect" with a
command-line interface.

- To install the assembly demos and the tracker application, get NASM and
install it (see below). Then run "make" in the ./asm and ./tracker 
directories.


[ xutil - The XWindows utility functions ]
[ -------------------------------------- ]

These functions are added to the bgrab-library to facilitate easy X-Window
creation and use. See sample programs for details.

----- IMPORTANT note on shared memory use ---------------------------------- 
Crucial is the proper closure and removal of the X-Windows shared 
memory segment in the close_xwinbuffer() function. After abnormal program
termination (i.e. programm chashes), one usually has to manually remove 
the shared-memory segment using "ipcs" (to check for the SHM ID) and 
"ipcrm shm ID" (to actually remove the segment).
The best method is to install an exit handler that calls close_xwinbuffer()
and/or quit by user request only, rather than using Ctrl-C or coredumps :-). 
----------------------------------------------------------------------------


A.) Basic screen setup and drawing routines
...........................................

int setup_xwinbuffer(struct xwinbuffer *xwin, char *prgname, int width, int height, int depth);
int sync_xwinbuffer(struct xwinbuffer *xwin);
int close_xwinbuffer (struct xwinbuffer *xwin);


B.) Keyboard and Mouse information
..................................

int keypoll_xwinbuffer (struct xwinbuffer *xwin, KeySym *key, int *button, int *mousex, *mousey);

See "Examples" section below.


C.) Simple Drawing Commands
...........................

void vline (struct xwinbuffer *xwin, int x, int y1, int y2, int color);
void hline (struct xwinbuffer *xwin, int x1, int x2, int y, int color);
void drawchar (struct xwinbuffer *xwin, int x, int y, char c, unsigned int color);
void drawstring (struct xwinbuffer *xwin, int x, int y, char *s, unsigned int color);
void drawpixel(struct xwinbuffer *xwin, int x, int y, unsigned int color);
void drawline(struct xwinbuffer *xwin, int x1, int y1, int x2, int y2, unsigned int color); 


D.) Video mode switching
........................

void videoModeChange(struct xwinbuffer *xwin, int width, int height);
void videoModeReset(struct xwinbuffer *xwin); 


Examples
........

To implement keyboard/mouse functionality use the following code fragment.

// Sample keyboard polling
// ...
 KeySym key;
 int button;
 int x,y;
// ...
  /* Poll keyboard */
  if (keypoll_xwinbuffer (&xwin, &key, &button, &x, &y)) {
     /* Check for mouse button press */
     if (button) {
      printf ("Mouse was pressed at coordinate (%i,%i)\n",x,y);
     }
     /* Check for keyboard press +/
     switch (key) {
      case XK_Home:
       break;
      case XK_Left:
       break;
      case XK_Right:
       break;
      case XK_Up:
       break;
      case XK_Down:
       break;
//     ...
      case XK_q:
       break; 
     }
    }


[ Assembly Image Processing Routines]
[-----------------------------------]

Experimental MMX assembly routines for image processing tasks have been
added as of version 2.1. They require the installation of the NASM compiler.

The NASM homepage with links for RPMs and source archives of NASM is here:
http://www.web-sites.co.uk/nasm/

Once installed, the documentation for NASM 0.98 can be found here:
file:/usr/doc/nasm-0.98/html/nasmdoc0.html

To compile the routines use:
	make assembly

A demo program that uses the one of the assembly routines is called 
'testabsdiff' and can be compiled within the /examples directory using:
	make asmprgs

Another program that relies on the assembly routines is 'tracker'.


[ Bugs & TO-DO List ]
[ ----------------- ]

I've got several 2.2 and 2.3 beta source trees hanging around, but my new 
job doesn't leave me much time. Maybe later ...

- TO-DO: Webcam appliction with support for logging and/or statistics.
- TO-DO: Webcam with multipart-mime support.
- TO-DO: Generic command line setup for all programs.
- TO-DO: Assembly image-transfer routines that do color conversion.

Please send suggestions and bug reports to aschiffler@cogeco.ca.