Video for Linux
href="Video for Linux_file/style.css" rel=stylesheet>
Video for Linux
References: A. Cox,Video4Linux Programming, 2000, available on
target=_top>http://www.kernelnewbies.org/
Video for Linux (V4L) is an abstract layer that presents a common interface
for media devices, such as cameras, tvs, audios, and tuners. It sits in the
drivers/media/video subdirectory of the kernel tree.
V4L is compiled in the kernel with the CONFIG_VIDEO_DEV
option. proc filesystem support is further added with the
CONFIG_VIDEO_PROC_FS option.
The main structure is video_device define in the header file
include/linux/videodev.h. It contains
owner, the module that own this structure;
name, the video device name (32 char max);
type, the video device type, which can be one of
VFL_TYPE_GRABBER, VFL_TYPE_VBI, VFL_TYPE_RADIO, VFL_TYPE_VTX. This field is
used by V4L to choose the driver's minor from the proper range.
hardware, the hardware type. This too is not used by V4L;
priv, a pointer to private data;
busy, a guard to ensure that the driver is open only by one
process at a time;
minor, the minor number assigned by V4L;
devfs_handle, the handle in devfs returned by
devfs_register(). as well as the pointers to the methods used
by V4L to dispatch the user application calls: open(),
close(), read(), write(), poll(),
mmap(), ioctl, and initialize. This last one is
called by V4L at initialization after it has finished with its own
initializations.
A driver that want to export its functionalities to userland via V4L must
call video_register_device(), which takes three args: a pointer to the
driver's video_device, the type of the driver, and the requested minor
(-1 for no request). When the driver wants to detach from V4L it calls
video_unregister_device() with the pointer to its video_device
structure. By registering with V4L the driver exposes to user processes only the
function video_fops, ie, open(), release(), poll(), read(), write(),
ioctl(), and mmap(). llseek() is no_llseek(). The others are forwarding to the
driver's related functions.
The most complex API is probably ioctl.
VIDIOCGCAP is used to get the driver's capabilities. The
capability includes a name, the interface type
(VID_TYPE_CAPTURE, VID_TYPE_TUNER, etc.), the number of audio/tv
channels, the number of audios devices if appropriate, and
the maximum and minimum width and height.
Capture cards that put the data on a frame buffer must be told the address
of the buffer, its size and how it is organized. The ioctl calls are
VIDIOCGFBUF and VIDIOCSFBUF, and the structure used is
video_buffer which contains a base address pointer,
width, height, depth and the number of
bytesperline.
The capture window is ruled by VIDIOCGWIN and
VIDIOCSWIN. The struct video_window contains the window
position coordinates x and y, the width and
height, the chromakey, additional capture flags, a
list of clips (clipping rectangles) and their number
(clipcount).
Overlay capture is used to instruct the hardware to capture the frames
onto the frame buffer. The device must be of type VID_TYPE_OVERLAY, and
initialized for overlay, with , and the refresh area can be clipped
with a list of rectangles (where the hardware does not refresh), or with a
mask which uses a chromakey, a colour that indicates no refresh. In the first
case the video_device must declare VID_TYPE_CLIPPING in the flags. In the
second it must be of type VID_TYPE_CHROMAKEY. If the video capture goes
directly into video memory the device is of type VID_TYPE_FRAMERAM. Before the
driver can overlay the images the video window must be set with
VIDIOCSWIN. There is also an ioctl that gets the video window
informations. Overlay capturing is activated or deactivated by the ioctl
VIDIOCCAPTURE with arg 1 or 0 respectively.
When there are several channels, it is possible to select one with
VIDIOCSCHAN and VIDIOCGCHAN. See the struct
video_channel.
Image properties are described by the video_picture structure:
brightness, hue, colour, contrast,
whiteness, depth, and palette. This last one can be
for example VIDEO_PALETTE_GREY, VIDEO_PALETTE_RGB24, VIDEO_PALETTE_RGB32.
Several other palettes are defined.
Tuners are described by the structure video_tuner and controlled
with VIDIOCGTUNER, VIDIOCSTUNER.
Audio inputs are described by the structure video_audio and
controlled with VIDIOCGAUDIO, VIDIOCSAUDIO.
Reading is possibble with the system call read(). V4L calls the
driver's read() if there is one, otherwise returns an error (EINVAL), The video
device may support also the write() system call. If not V4L return 0 on
write().
Another way to read images from the device is through the mmap
interface, which must first be set up with the mmap() system call. Next
the application gets the size of the memory buffer and offset of each frame in
the buffer with the ioctl VIDIOCMBUF call. The application issues acquisition
commands with the ioctl VIDIOCMCAPTURE call, specifying the requested frame
index. This call starts the acquisition and returns immediately. The application
waits for the completion of the acquisition with the ioctl VIDIOCSYNC. Therefore
the sequence of calls is something like int index = 0;
int newindex;
ioctl( fd, VIDIOCMCAPTURE, &index);
while ( 1 ) {
newindex = (index+1) % FRAME_NUMBER;
ioctl( fd, VIDIOCMCAPTURE, &index);
ioctl( fd, VIDIOCSYNC, &index);
// process frame "index"
index = newindex;
}
Exercise
Write a memory-based video camera driver that registers with V4L subsystem.
Check that the memory-based video camera operates properly, by writing a
graphical program that displays the frames. Here is a solution for the
driver: href="http://www.geocities.com/marco_corvi/games/lkpe/v4l/mmvideo.c">mmvideo.c
href="http://www.geocities.com/marco_corvi/games/lkpe/v4l/mmvideo_h.txt">mmvideo.h
and the href="http://www.geocities.com/marco_corvi/games/lkpe/v4l/Makefile.txt">Makefile.
Finally here is a simple application that loads an image onto the camera
memory, and displays the frames generated by the camera: href="http://www.geocities.com/marco_corvi/games/lkpe/v4l/mmvideotest_cpp.txt">mmvideotest.cpp.
It needs a few helper classes, href="http://www.geocities.com/marco_corvi/games/lkpe/v4l/mmvideoutil.tgz">mmvideoutil.tgz
(the image comes from the source Documentation) and libjpeg and libX11,
which you probably already have. Check /proc/video/mmvideo while the
application is running. Enjoy!
Marco Corvi - 2003
language=JavaScript>var PUpage="76001084"; var PUprop="geocities";
var yviContents='http://us.toto.geo.yahoo.com/toto?s=76001084&l=NE&b=1&t=1057746848';yviR='us';yfiEA(0);
geovisit();
width=1 border=0> src="Video for Linux_file/serv.gif" width=1>