ivcclib.jpg (28278 bytes)

Overview
Documentation
Software
Contact


IVCCLIB DOCUMENTATION

Contents:

1. Introduction
2. Installing IVCCLIB's drivers
3. Starting the IVCCLIB grabber program
4. Basic structure of an IVCCLIB program
5. Using IVCCLIB in Matlab
6. Using IVCCLIB in C
7. Using IVCCLIB in Java

Introduction

IVCCLIB works differently than most video capture environments.  An IVCCLIB program doesn't actually get its images from the capture card.  Instead, it gets the images from the computer's memory, where they have been stored by a grabber program (section 3).  So, before any IVCCLIB program can run, a grabber program has to be started to provide it with images.

Because the grabber program is taking care of moving the images from the capture card into memory, multiple IVCCLIB programs can use the captured images simultaneously.   This requires that all IVCCLIB programs be "good citizens", that is, they should never write data into the shared memory location because other programs may be trying to view that data.  I am not preventing IVCCLIB programs from doing this because I believe there may be situations when a researcher might want a program to write into that shared memory section.

A few notes on terminology:  Because of their mostly read-only nature, IVCCLIB programs tend to fit the title "Observer."  I will use this name to refer to most programs written by users using IVCCLIB.  I often use the acronym "IVCC" to stand for Intel Video Capture Card.

This document will walk you through the steps you need to follow in order to set up IVCCLIB and start writing observers.  It's only necessary to read all of sections 5,6, and 7 if you plan to use IVCCLIB in Java, C, AND Matlab.  Otherwise, I encourage you only to read the section on the language you plan to use.

Installing IVCCLIB's drivers

IVCCLIB requires a particular kernel patch that allows the capture driver to allocate a large section of memory for framegrabbing.  This patch is called "bigphysarea", and is available at http://www.uni-paderborn.de/fachbereich/AG/heiss/linux/bigphysarea.html.   Be careful-- patching a kernel isn't easy-- don't hesitate to get help on this!

After the patch is set up successfully, the drivers for your IVCC need to be installed.   Note: I didn't write the IVCC drivers-- they are a heavily modified set of drivers that have been passed around from researcher to researcher, and I believe started as Matrox Meteor drivers years ago.  I merely made several modifications to the driver to support IVCC's multiple observer feature. 

The drivers for IVCCLIB are on the software page, and must be installed with the command "insmod."  Insmod must be run by root, and only installs the driver in the current boot-session of Linux.  In order to make sure your driver is loaded everytime the system boots, I suggest you copy it into /etc/rc.d and modify your rc.local file to load the driver at system startup.  The following steps should be made as root:

First, move the driver file into the correct directory.
cp bt848.o /etc/rc.d/

Next, add the following to the end of /etc/rc.d/rc.local
/sbin/rmmod bt848
/sbin/insmod -f bt848

You then need to make the device files in /dev.  The number of device files you should make depends on how many IVCC's you have in your system. The following commands make the necessary devices for 4 IVCC's (yes, it's possible to have 4!)   Again, you need to be root to execute these commands.

mknod /dev/bt848 c 82 0
mknod /dev/meteor c 82 0
mknod /dev/bt848-0 c 82 0
mknod /dev/bt848-1 c 82 1
mknod /dev/bt848-2 c 82 2
mknod /dev/bt848-3 c 82 3
mknod /dev/bt848-4 c 82 4
chmod a+rw /dev/bt848*
chmod a+rw /dev/meteor

mknod /dev/mmetfgrab0 c 82 0
mknod /dev/mmetfgrab1 c 82 1
mknod /dev/mmetfgrab2 c 82 2
mknod /dev/mmetfgrab3 c 82 3
mknod /dev/mmetfgrab4 c 82 4

chmod a+rw /dev/mmet*


Congratulations!  After a restart, your system should be ready to start capturing video.

Starting the IVCCLIB grabber program

As explained in the introduction, IVCCLIB observers don't actually get their images from the capture card.  A special grabber program puts images from the capture card into a shared memory location, and the IVCC driver notifies the observers when a new frame has been placed there to allow synchronization.  Before you can write an IVCCLIB program, you have to sucessfully start the grabber program.  It's also part of the downloads on the software page.

Once you've downloaded it, I suggest you place it with the card driver in /etc/rc.d/ and modify rc.local to start it every time the system starts-- you can always locate it using ps and kill it if you need to restart it.

The arguments for grabber are as follows, and will be displayed if grabber is run without any arguments.

grabber <# of IVCC's to be managed> <Source # of first IVCC> <Source # of second IVCC> ...  <Brightness> <Contrast>

Source numbers should be either 0, 1, or 2, corresponding to RCA input, SVIDEO, or INTEL-CAMERA input, respectively.  Brightness should be between # and # and contrast between # and #, typically.  Brightness and contrast are set to the same value for all IVCC's.

Executing this command:
grabber 2 1 0 50 50 &

Should result in an output that looks like this:
Thread 1 started ...
Digitizer /dev/bt848-0 is online, capturing from source 1.
Thread 2 started ...
Digitizer /dev/bt848-1 is online, capturing from source 0.

Again, I suggest you put the grabber startup command in your rc.local file similar to the way you placed the insmod command in the rc.local file above.

You can only load one grabber per IVCC-- there's really no reason to want more than one.   If you need to kill the grabber process, find its pid by typing something like:

ps auxww | grep grabber

Then kill each copy of the grabber manually with the "kill" command.

Basic structure of an IVCCLIB program

After you successfully install the IVCCLIB drivers and start the grabber process, it's time to try writing an IVCCLIB observer.  You have the choice of writing your observer in C, Java, or Matlab, but whatever you select, you program will tend to take on the same structure.

All of the real work in an IVCCLIB program gets done in its capture callback.  The callback is a function that is called every time a new frame is captured (30 frames per second), unless the callback has not completed its last execution.  In this case, the callback is not called, but will be called the next time a frame is delivered and the callback is idle. 

So, when you write an IVCCLIB observer, you spend 99% of your time writing its callback, and a tiny amount of time writing the code that informs the IVCC that your callback is interested in captured frames.  This was the goal of IVCCLIB-- to let you spend your time writing processing code instead of wasting your time with the details of getting captured frames into your program.

Deciding what language to use for your observer is really a matter of personal preference.  I am a big fan of the IVCCLIB Matlab environment-- I used it for nearly all of my masters thesis.  If you can believe it, IVCCLIB allows 30 frames per second capture into Matlab through the mex gateway, and Matlab is great for vision research if you have the image processing toolbox.  Plus, the mex gateway lets you slowly move your matlab code out into C if more performance is desired.  IVCCLIB in C is great if you're looking for high performance code, but certainly takes more work to get something working than Matlab.  IVCCLIB in Java is a new arrival, and doesn't offer high performance at all.  However, considering that there aren't many capture libraries in existence for Java, it's a step in the right direction!

Using IVCCLIB in Matlab

I believe that Matlab is the best environment for working in IVCCLIB.  Matlab offers a large number of functions that will make it possible for you to accomplish complex tasks with a single command, especially if you pick up a few toolboxes as well.   You can capture 30 frames per second of video in Matlab (no kidding!), so it's efficient enough to get you started on a real system.

Here's how to get started:

Follow the instructions to set up your machine with the IVCCLIB drivers and the grabber program.  Then, download the IVCCLIB Matlab files.  Here is a list of the files and what they are useful for:

showframe.m This is a sample callback that simply displays the video as it is passed into Matlab, as quickly as possible.  You should make a copy of this file and start editing it.  Most users will never have to edit anything but that file.
attachgrabber.m This is the command that starts the IVCCLIB Matlab system.  You shouldn't need to read or edit this file unless you want to do something really different.
m_observer.c This is the C file that handles the passing of frames of video into a callback, like showframe.m above.  You may want to edit this file if you're after high performance code-- you can do work on the image before you pass it into the Matlab callback-- you can even edit this file so that it edits the image, passes it into a Matlab callback, then edits it some more in C, then passes it into another Matlab callback, etc..
m_ivccsetup.c
m_ivccsetup.h
This file contains the commands that m_observer.c uses to talk to the video capture card, and handles the method by which m_observer.c is informed when a new frame arrives.
m_observer.mexlx This is a complied file, the result of typing "mex m_observer.c m_ivccsetup.c".  If you don't edit m_observer.c, you shouldn't need to recompile this file.
grabber.h This file contains important constants-- it's actually part of the grabber files-- make sure you keep the values in this grabber.h consistent with the values in the other grabber.h
ioctl_meteor.h Really low level constants and such for the capture card.  It's highly unlikely that you'll need to work on this file.

After you've unzipped and untarred these files (type gunzip <filename> and then tar -xf <filename>), you're ready to get started.  Make sure your grabber is running, and start Matlab in the same directory as the above files.

You should make sure everything is working correctly before you start writing code.   Type this into your matlab window:

attachgrabber(0,'showframe');

And, surprise, you'll get a huge, ugly error message about segmentation faults and all sorts of nastiness.  This is the *last* remaining skeleton in the IVCCLIB closet-- Matlab doesn't like the way I set up my memory, and throws this error ONLY on the first time you run attachgrabber after starting Matlab.  You don't need to worry about this error, just run the command again.  You'll see some messages like this:

>> attachgrabber(0,'showframe')
Observer online, attached to digitizer /dev/bt848-0.
Grabber #0 supplying images to callback showframe.

A figure should appear that starts showing you whatever the camera is looking at.   Matlab is only capable of displaying these images at about 2 frames per second, but don't worry-- you *can* capture video at 30 frames per second.  A few things might go wrong at this point:  Press control-c when you want to stop the capture process.   Control-c is the way you'll stop your system every time.  You'll see this message:

Observer break detected.. calling observershutdown().

And then you'll get your Matlab prompt back.  At least, that's the way it should all work.  Here are solutions to some possible problems:

1.  The messages appear as above, and a figure pops up, but you don't see any video in it.  This means you either don't have a camera properly connected to your capture card, or you've set your grabber to the wrong source number (see the section on the grabber above.)  The good news is that your callback IS receiving frames-- they just aren't the frames you want to be looking at.

2.  The messages appear as above, but no figure appears.  This means you probably don't have a grabber running on your system.  See the section above on the grabber to get your grabber running.  If you can see a grabber on your system by typing "ps auxww | grep grabber," try killing all of the grabber processes, starting a new grabber, and trying again. This problem can also happen occasionally if Matlab has a segmentation fault while IVCCLIB is running.  In order to correct this problem, you unfortunately have to quit Matlab and start it again before you'll be able to capture video again.

Ok, so now you have the ability to display video in (semi) real-time, and you want to write a face recognizer, or a pedestrian tracker, or a gesture recognition system-- The way to proceed is to make a copy of showframe.m into another file, say "mycb.m" and start working in that file.  Make sure you start by working entirely within the try and catch statements.. this is very important.  If you cause an error outside these statements, Matlab will crash in such a way that it doesn't give IVCCLIB to stop the observer process, and you will have to quit Matlab and restart it before you will be able to capture video successfully again. 

Your callback can call other Matlab functions, and it can leave data for you to look at after you IVCCLIB exists by creating global variables.  To do this, you must declare the variable global BOTH in your callback AND at the Matlab prompt.  For instance, while working on face recognition, I put the last face detected in a global variable so that when I stopped the system, I could look at the last detected face.

If you start feeling like your callback is running too slowly, you can move on to the next level of Matlab IVCCLIB programming.  You can begin to move time consuming computations into m_observer.c from your callback.  The function gotframe in m_observer.c is where each frame of video goes just before it is passed into your callback.  You can edit m_observer.c so that it works on the image before it is passed into your callback, and can even edit the file so that an image is passed back and forth from C to Matlab, accomplishing time consuming calculations in C, and making use of Matlab functions as needed.  In fact, you could eventually move all of your code from Matlab into m_observer.c, and stop using the mex gateway altogether.  This is part of the reason I believe that IVCCLIB in Matlab is the way to go-- you get all of the nice features of Matlab as long as you want them, and can work towards an entirely C program in the end.  Continue reading with the next section if you are interested in working towards an IVCCLIB program in C.

Using IVCCLIB in C

Again, I believe that all new users of IVCCLIB should start by using IVCCLIB in Matlab, but if you're a veteran user or don't have Matlab, IVCCLIB in C does offer high performance and an intuitive way to access real-time video.

To get started, make sure your drivers and installed and your grabber is running (read the sections at the beginning of this document.)  Then download the IVCCLIB C files from the downloads page.  After unzipping and untarring the package, you'll have these files:

writer.c A very simple C observer.  This file writes captured images to disk in sequence.  It should serve as a good framework for new observers.
c_ivccsetup.c
c_ivccsetup.h
This file contains the commands that writer.c uses to talk to the video capture card, and handles the method by which writer.c is informed when a new frame arrives.
writer The above 3 files are compiled to produce this executable
Makefile Make instructions for writer
grabber.h This file contains important constants-- it's actually part of the grabber files-- make sure you keep the values in this grabber.h consistent with the values in the other grabber.h
ioctl_meteor.h Really low level constants and such for the capture card.  It's highly unlikely that you'll need to work on this file.

Try running writer (you may need to re-make it).  Let it run for a few seconds, then press control-c.  You should see a sequence of files that look like #image#, where the first # is the grabber number and the second # is the number of the frame, i.e., 0,1,2..

If you don't see these files, make sure you have a grabber running (type ps auxww | grep grabber).  If you can see grabber processes working, you could try killing them all and restarting your grabber. 

Once you have writer working, you should make a copy of writer.c and start writing your own observer.  The function "gotframe" in writer.c is where you should make all of your changes. Some important notes:

1. You'll notice that in writer.c, the data for the captured frame is immediately copied to a separate location in memory.  This is absoultely necessary if what you plan to do with the image will take longer than 1/30th of a second, because the capture card will overwrite that location of memory every 1/30th of a second.  If your code executes very quickly, it's possible that you could finish your execution before the memory is overwritten, but copying to a separate location in memory is, in general, a good idea.   Future versions of IVCCLIB might implement a ring-buffer of captured frames, allowing an observer as long as a second before the memory will be overwritten.

2. Images are passed to the callback in a somewhat peculiar format.  It looks like this: BGRABGRABGRABGRA...  That is, blue, green, red, alpha, for each pixel.   Writer.c unshuffles this into RGBRGBRGB before writing the images to disk.

3. The NUM_ROWS and NUM_COLS constants in grabber.h are set to 480 and 640, respectively, by default.  If you want to capture at a different resolution, you will want to change these values.  However, you need to make sure the values in this grabber.h are the same as the values in the grabber.h that is compiled into your grabber program.

Using IVCCLIB in Java

This documentation was written by Mike Ross

Here is an interface I have developed that enables Java objects to interface with Jeff Norris' video-frame grabber server. The software has been compiled with JDK 1.2 (aka Java 2) for Linux, which is available in beta form from the good folks at Blackdown. As soon as a final version is available, I will update the distribution.

Although the software should be JDK 1.1.7 compatible, I recommend using Java 2 in order to take advantage of its JIT compiler. The software consists of the FrameGrabber class and the FrameGrabber.so library that implements the signal-handling necessary to interface with Jeff's code. It also contains the FrameListener interface, which allows the easy registration of callback methods that can be invoked to handle the frames.

The documentation of FrameGrabber is available here, or in the tar file.

Please Note: Currently, the software requires that FrameGrabber.so, the library containing the native code, be in the directory you invoke the JVM from (the directory you typed "java" in). I am trying to fix this problem, but have not decided upon a satisfactory solution yet.

Michael Ross