|
|
Intro to V4L2
2009-03-11
Foreword -- This article describes the V4L2 (Video for Linux 2) interface, along with the first steps toward developing a device driver that uses the interface. It is based on Linux 2.6.28, and may not apply to other kernel versions.
The article was contributed by Vladimir Davydov, an engineer with Promwad, an embedded development services company located in Minsk, Belarus. Promwad has used the V4L2 interface in several development projects, Davydov reports. Enjoy . . . ! by Vladimir Davydov Video For Linux (V4L) is an API that provides unified access to various video capturing devices, such as TV tuners, USB web cameras, etc. The first version of this interface was implemented in Linux 2.2, by Alan Cox. In 1999, development began on the second-generation V4L2 interface, which fixed bugs found in V4L, and supported a wider range of devices. General overview of Video4Linux2 interface (V4L2) V4L2 drivers are implemented as normal kernel modules that can be loaded by an administrator, or loaded automatically when opening a device file. Drivers use the base "videodev" kernel module, which represents the corresponding kernel interface for working with a video device. V4L2 API provides access to a device by means of standard Unix character devices. V4L2 provides the following interfaces:
Below, you can see a chart of interaction between a user application and a V4L2 driver: ![]() Chart 1: Interaction between a user application and the V4L2 driver Linux V4L2 userspace programming In this article we do not cover the issue of V4L2 application in terms of user processes, as it is quite well described in the official specification, available here. It is necessary to note that there is a wide range of free software programs with open source code for playback and recording via V4L2 interface. Here are some of them:
As noted above, V4L2 device drivers use the "videodev" base module. This module exports a set of functions for working with the V4L2 interface. Unfortunately, at the present time, there is no full description of these functions. There is the "Video for Linux Two -- Driver Writer's Guide," dated December 23rd, 1999. This document could be considered outdated, however, due to changes in V4L2's internal interface. Fortunately, the open model of Linux development provides a great number of ready drivers, which can be used as examples for examining the V4L2 interface, and for developing new drivers for video capturing devices. Source code for these V4L2 drivers is available in kernel's source code tree, in the "drivers/media/video" directory. Most interesting, from this point of view, is the VIVI driver (drivers/media/video/vivi.c). VIVI - virtual video driver VIVI is a V4L2 driver module that emulates a real video device. This driver was developed by the team of Video Technology Magazine, and was added into Linux as of the 2.6.17 kernel release. The main purpose of VIVI development is to design a working sample V4L2 driver, and also a stub driver that simplifies the development of new video drivers. Also, VIVI can be used for debugging user applications that use the V4L2 interface. VIVI code demonstrates the ideal usage of the Linux kernel interface for V4L2 drivers, and it is recommended for developers as an example, when creating new drivers. Loading the VIVI module:
V4L2 Linux kernel interface The kernel provides a set of structures and helper functions for convenient V4L2 drivers development. To use these functions one has to include the following header files:
Some important data structures To register V4L2 device it is necessary to fill three main structures: video_device, file_operations, and v4l2_ioctl_ops. Let's look closer at initializing each of these structures, using the example of the VIVI driver:
Let's look in more detail at the purposes of some fields of these structures. The video_device structure is declared in the media/v4l2-dev.h> file. It contains general information about the video device. The fops and ioctl_ops fields point at the corresponding structures file_operations and v4l2_ioctl_ops.The release field contains a pointer to the function that will be called when the video device is removed from system. In this case, this field points at the standard video_device_release function, which just releases memory allocated for the video_device structure. The tvnorms field defines a list of supported video standards. The full list of supported standards is defined in the linux/videodev2.h> header file. In our case, V4L2_STD_525_60 represents a bit mask:
The current_norm field corresponds to its name, and defines the video standard to be used by default. The file_operations structure is defined in the linux/fs.h> file, and is an important kernel structure. It contains pointers to functions, each of which implements a corresponding operation, or to NULL, if the operation is not supported. The fields of this structure are quite well described in the book Linux Device Drivers, 3rd Edition (LDD3), which you can download here.The VIVI driver defines handlers of the main system calls for the device file /dev/video: open, release, read, poll, mmap, ioctl. A specific implementation of these handlers will be considered later in the article. It is necessary to mention that the video_ioctl2 standard function is used as a handler for the ioctl call. This function performs the initial processing of an ioctl call, analyzing the command's code and calling a corresponding handler using pointers to functions specified in the v4l2_ioctl_ops structure. You can specify your own function for processing ioctl, but in that case, you will have to implement code for command analysis independently. Developers of V4L2 recommend using video_ioctl2, in order to decrease the probabilitiesof errors in driver code. The v4l2_ioctl_ops structure stores pointers to handlers of V4L2 commands transmitted by means of an ioctl system call. This structure is declared in media/v4l2-ioctl.h> file.Registering a video device As mentioned earlier, the kernel uses the video_device structure for describing video device. This structure can be created both statically and dynamically, by using the following function:
To use video_device_alloc in your code, you have to include media/v4l2-common.h>. Then for releasing memory occupied by the structure, make the following call:
A video device is registered by the following function:
The vfd parameter in the examples above is the pointer to the video device structure that you want to register. type parameter defines the type of registered device. The following values define device types: VFL_TYPE_GRABBER -- video capturing device VFL_TYPE_VTX -- teletext device VFL_TYPE_VBI -- VBI device VFL_TYPE_RADIO -- radio card The nr parameter sets the number of the registered device: 0 for /dev/video0, 1 for /dev/video1, etc. If you want to assign the first available number, then specify -1 for this parameter. To remove a video device from system, you have to call the following function:
Registering a video device in VIVI As in most Linux device drivers, there are mandatory functions for initializing and releasing the module. To understand this process, we recommend reading the LDD3 book. The VIVI driver allows registering a variable number of video devices. Currently, the maximal number of registered devices is limited by the videodev module, and is 32 devices. Let's look at modified code from the function for initializing the VIVI driver, to demonstrate registration of a video device.
Conclusion The V4L2 API provides a modern and powerful interface for working with video capturing devices. Excellent documentation on the V4L2 API and the availability of a great number of ready drivers and applications with open source code allow significant reduction of development time. In the next article we will examine structures and helper functions in the V4L interface for buffering. Useful links V4L2 home V4L2 API specification FFmpeg tools and libraries Xawtv TV application Tvtime TV application Video for Linux Two - Driver Writer's Guide MPlayer and MEncoder home The VIVI driver; a great starting point for V4L2 driver writers Linux Device Drivers, Third Edition About the author -- Vladimir Davydov works as an engineer at Promwad Innovation Company. He has more than seven years experience in network programming and Linux kernel development for multimedia applications. In 2002, he graduated from Belarusian State University of Informatics and Radioelectronics (Minsk, Belarus) with a Bachelor of Science in Computer Science, and main specialization in compute machines, complexes, systems, and networks.Related Stories:
|