libfg - Video4Linux Frame Grabber interface

Introduction

The libfg library provides a simple high-level C API for controlling Video4Linux devices, including analog video cameras, TV and webcams.

Overview

Linux has support for TV tuners and frame grabbers. This is provided by the Video4Linux API, which has been around since roughly kernel 2.2. V4L is actually an interface implemented by a number of different drivers or kernel modules that support the different types of hardware. Since it is a kernel level interface, it is driven entirely by ioctl() calls, and is not particularly friendly to use. It is also not particularly well documented.

The purpose of libfg is to provide a simple, high level interface for controlling TV tuners and frame grabbers. This insulates the developer from having to fiddle around with the low-level details. An example below shows how easy it is to use. It is hoped that this will enable developers to write more applications that exploit this hardware, and create some interesting programs.

Features

The current version of libfg supports most of the major features provided by the Video4Linux API (Version 1). This includes:

  • Double-buffered capturing (depending on driver)
  • Setting a capture window (cropping)
  • Set brightness, contrast, etc (in percent)
  • Control TV tuner (in MHz)
  • Supports multiple norms (PAL, NTSC, Secam, etc)
  • Supports different frame formats (eg. RGB32, RGB24, YUV)
  • Can save frames to disk (pgm)
  • Hardware Support
  • Live GUI video viewer
  • USB cameras with v4l support

Any V4L device supported by the kernel will work with libfg. This includes capture cards, TV tuners and webcams. The most common type of hardware is probably cards based on the BT848/BT878 chipset, although plenty of others will also work. These days, TV tuner/capture cards are surprisingly affordable too. Get yours today! For more details on particular cards, consult the documentation that comes with your kernel.

We have tested libfg on the following hardware:

  • Picolo (BT878)
  • FlyVideo 98 / Chronos Video Shuttle II (BT878)
  • Logitech Webcam Express

Note on Firewire/1394 devices: it should be possible to use a Firewire camera with the loopback driver.

Kernel Support

These days, nearly all kernels come with the v4l module pre-build. In rare circumstances, you may need to build your own kernel (Shock! Horror!) if your distro doesn’t already come with the Video4Linux modules. You will need to enable at least Video4Linux, I2C (for the tuner), and the right module for your card.

License

The libfg code has been released under the Lesser GNU Public License (LGPL). This is to ensure that the code can be used in as many applications as possible (even proprietary or closed-source projects if you really must), while ensuring that improvements to the library itself get sent back to the community. Please read the license in its entirety and understand it before using the software - a copy is included in the source in the file LGPL.

Projects

Currently libfg is used in the following projects:

  • The University of Melbourne RoboCup Initiative
  • Player/Stage
  • Mezzanine

Its main application thus far has been in frame-rate (~40ms) image processing for robotics applications.

If you use libfg in your project, please let me know so I can add you to the list.

Download

For now, you can just download the source tarball (using the link below):

Documentation

API reference documentation is provided in the above tarball, in both HTML and PDF formats (thanks to Doxygen). The included samples show how to use it; it is fairly straightforward. The device is always initialised to sensible defaults, so after fg_open() returns, you can start grabbing right away.

Status

The source has not been updated in quite some time. However, there are a number of active users of the library beyond the projects listed above, and several have kindly provided patches. There is an unofficial git repository which has some patches (and extensions) applied.

I do not currently have any Video4Linux capable hardware, and are not currently working on projects that use libfg. Thus I am not in a position to make contributions and enhancements. I will be updating this page periodically with more information, and will gather the patches supplied by various users into a new source distribution.

Examples

There are two example progams included - test-capture, which exercises a number of different calls in the library, and camview. The camview program uses libsdl to perform live streaming of video images into a window.

Building

Just running make will give you a static library (.a) to link with. For now, that will have to do until I sort out dynamic linking of shared libraries and versioning and all that it entails. The README has info on how to build the Python bindings, which is pretty simple.

Sample User Code

Here is an example of how easy it is to use libfg to control your frame grabber in C:

And here is an example of the preliminary Python support. This script was used to create the image at the top of this page. (Gimp was used to convert the file from PGM to JPG and scale it down a little.)

Useful Links

Here are some links that may be useful:

8 Comments

libfg compiles flawlessly on my aspire one laptop, but it doesn't manage to capture anything from the built-in Microdia Pavilion Webcam. I know that the camera works with v4l since both ekiga and xawtv manages to use it.

This is what I get:

libfg-0.3.1$ ./test_capture
test_capture: libfg testing harness
$Revision: 1.5 $
fg_open(): set picture attributes failed: Invalid argument
libfg-0.3.1$ ./camview
camview
fg_open(): set picture attributes failed: Invalid argument
Segmentation fault

The 'invalid arguments' are what perror() outputs after running all the calls to ioctl( fg->fd, ... ) (by commenting out the free()'s and return's, I see that all ioctl-calls seem to return -1).

I'm not used to using ioctl-calls, so I don't know what this behavior really means... Do you have any idea?

Regards
Pion

Hi Pion,

Not all devices support all features, and what libfg should do is query the capabilities flags to see what settings are available before setting them. As it is now, it is very conservative and will abort if anything at all fails. So it is possible that your device simply doesn't support setting certain picture attributes, but can otherwise work fine. I suggest you change the code in fg_open to simply continue after this particular ioctl call (since it is a soft, not a hard failure) and see if you can still use it for capture after that. Since I no longer have any V4L hardware, I am unfortunately unable to test or experiment with these sorts of changes. Good luck!

:: Gavin

wow great dude!!! your code is unbelievable readable.... FYI: runs flawlessly with my low-end low priced a4tech pk635m usb-webcam on ubuntu-distro linux kernel 2.6.24-24.

Hi, thanks for your feedback! Great to hear it's working well for you, and it's handy to know which hardware and software combinations work. Good luck with your project.

:: Gavin

Hay!

Interesting library. Would it be possible to use this library to interpret some RGB565 data I've aquired from a camera? I've been trying to decode it using the Python Imaging Library, but unfortunately it doesn't support RGB565, just regular RGB.

Hi Talin,
The libfg support extends only to video capture, not to image analysis. If you wanted to use PIL, you could always write an unpacking routine to convert from RGB565 to 24-bit. It would be pretty easy to vectorise in an extension, and should run very fast.
Alternatively, you might want to look at Intel's OpenCV project at http://opencv.willowgarage.com/wiki/ which is a comprehensive C++ imaging library.
Another trick you could try is to use OpenGL to do the conversion for you by uploading the packed RGB565 texture, rendering it to an RGB888 buffer and reading back the converted texture.
Regards,
:: Gavin

Can i use the code to grab a frame from a video file?

Hi Xu, libfg is only for interfacing to video capture cards, as supported by the Video4Linux API. If you want to extract frames from video files, I suggest you look at GStreamer, which has support for a wide variety of codecs, and has APIs for reading, writing and manipulating media files.

:: Gavin

Leave a comment