现在的位置: 首页 > 综合 > 正文

Video4Linux2 part 2: registration and open()

2013年02月09日 ⁄ 综合 ⁄ 共 7645字 ⁄ 字号 评论关闭
文章目录

This is the second article in the LWN series on writing drivers for theVideo4Linux2 kernel interface; those who have not yet seen
the introductory article maywish to start there. This installment will look at the overall structureof a Video4Linux driver and the device registration process.

Before starting, it is worth noting that there are two resources which willprove invaluable for anybody working with video drivers:

 

  • The V4L2 API Specification. This document covers the API from the user-space point of view, but, to a great extent, V4L2 drivers implement that API directly. So most of the structures are the same,
    and the semantics of the V4L2 calls are clearly laid out. Print a copy (consider cutting out the Free Documentation License text to save trees) and keep it somewhere within easy reach.

     

  • The "vivi" driver found in the kernel source as drivers/media/video/vivi.c. It is a virtual driver, in that it generates test patterns and does not actually interface to any hardware. As such, it serves as a relatively clear illustration of how
    V4L2 drivers should be written.

To start, every V4L2 driver must include the requisite header file:

 

    #include <linux/videodev2.h>

Much of the needed information is there. When digging through the headersas a driver author, however, you'll also want to have a look atinclude/media/v4l2-dev.h, which defines many of the structures you'llbe working with.

A video driver will probably have sections which deal with the PCI or USBbus (for example); we'll not spend much time on that part of the driverhere. There is often an internal i2c interface, which
will beexamined later on in this article series. Then, there is the interface tothe V4L2 subsystem. That interface is built around
structvideo_device, which represents a V4L2 device. Covering everythingthat goes into this structure will be the topic of several articles; herewe'll just have an overview.

The name field of struct video_device is a name for thetype of device; it will appear in kernel log messages and in sysfs. Thename usually matches the name of the driver.

There are two fields to describe what type of device is being represented.The first (type) looks like a holdover from the Video4Linux1 API;it can have one of four values:

 

  • VFL_TYPE_GRABBER indicates a frame grabber device - including cameras, tuners, and such.
  • VFL_TYPE_VBI is for devices which pull information transmitted during the video blanking interval.
  • VFL_TYPE_RADIO for radio devices.
  • VFL_TYPE_VTX for videotext devices.

If your device can perform more than one of the above functions, a separateV4L2 device should be registered for each of the supported functions. InV4L2, however, any of the registered devices can be called upon to functionin any of the supported modes. What
it comes down to is that, for V4L2,there is really only need for a single device, but compatibility with theolder Video4Linux API requires that individual devices be registered foreach function.

The second field, called type2, is a bitmask describing thedevice's capabilities in more detail. It can contain any of the followingvalues:

 

  • VID_TYPE_CAPTURE: the device can capture video data.
  • VID_TYPE_TUNER: it can tune to different frequencies.
  • VID_TYPE_TELETEXT: it can grab teletext data.
  • VID_TYPE_OVERLAY: it can overlay video data directly into the frame buffer.
  • VID_TYPE_CHROMAKEY: a special form of overlay capability where the video data is only displayed where the underlying frame buffer contains pixels of a specific color.
  • VID_TYPE_CLIPPING: it can clip overlay data.
  • VID_TYPE_FRAMERAM: it uses memory located in the frame buffer device.
  • VID_TYPE_SCALES: it can scale video data.
  • VID_TYPE_MONOCHROME: it is a monochrome-only device.
  • VID_TYPE_SUBCAPTURE: it can capture sub-areas of the image.
  • VID_TYPE_MPEG_DECODER: it can decode MPEG streams.
  • VID_TYPE_MPEG_ENCODER: it can encode MPEG streams.
  • VID_TYPE_MJPEG_DECODER: it can decode MJPEG streams.
  • VID_TYPE_MJPEG_ENCODER: it can encode MJPEG streams.

Another field initialized by all V4L2 drivers is minor, which isthe desired minor number for the device. Usually this field will be set to-1, which causes the Video4Linux subsystem to allocate a minor number atregistration time.

There are also three distinct sets of function pointers found withinstruct video_device. The first, consisting of a single function,is the
release() method. If a device lacks a release()function, the kernel will complain (your editor was amused to note that itrefers offending programmers to an LWN article). The
release()function is important: for various reasons, references to avideo_device structure can remain long after that last videoapplication has closed its file descriptor. Those references can remainafter the device has been unregistered.
For this reason, it is not safe tofree the structure until the release() method has been called.So, often, this function consists of a simple
kfree() call.

The video_device structure contains within it afile_operations structure with the usual function pointers. Videodrivers will always need
open() and release() operations;note that this release() is called whenever the device isclosed, not when it can be freed as with the other function with the samename described above. There will often be a
read() orwrite() method, depending on whether the device performs input oroutput; note, however, that for streaming video devices, there are otherways of transferring data. Most devices which handle streaming video datawill need to implement
poll() and mmap(). Andevery V4l2 device needs an ioctl() method - but they canuse
video_ioctl2(), which is provided by the V4L2 subsystem.

The third set of methods, stored in the video_device structureitself, makes up the core of the V4L2 API. There are several dozen ofthem, handling various device configuration operations, streaming I/O, andmore.

Finally, a useful field to know from the beginning is debug.Setting it to either (or both - it's a bitmask) of
V4L2_DEBUG_IOCTL andV4L2_DEBUG_IOCTL_ARG will yield a fair amount of debugging outputwhich can help a befuddled programmer figure out why a driver and anapplication are failing to understand each other.

 

Video device registration

Once the video_device structure has been set up, it should beregistered with:

 

    int video_register_device(struct video_device *vfd, int type, int nr);

Here, vfd is the device structure, type is the same valuefound in its
type field, and nr is, again, the desiredminor number (or -1 for dynamic allocation). The return value should bezero; a negative error code indicates that something went badly wrong. Asalways, one should be aware that the device's methods
can be calledimmediately once the device is registered; do not callvideo_register_device() until everything is ready to go.

A device can be unregistered with:

 

    void video_unregister_device(struct video_device *vfd);

Stay tuned for the next article in this series, which will begin to look atthe implementation of some of these methods.

 

open() and release()

Every V4L2 device will need an open() method, which will have theusual prototype:

 

    int (*open)(struct inode *inode, struct file *filp);

The first thing an open() method will normally do is to locate aninternal device corresponding to the given
inode; this is done bykeying on the minor number stored in inode. A certain amount ofinitialization can be performed; this can also be a good time to power upthe hardware if it has a power-down option.

The V4L2 specification defines some conventions which are relevant here.One is that, by design, all V4L2 devices can have multiple open filedescriptors at any given time. The purpose here is to allow oneapplication to display (or generate) video data while
another one, perhaps,tweaks control values. So, while certain V4L2 operations (actually readingand writing video data, in particular) can be madeexclusive to a single file descriptor, the device as a whole should supportmultiple open descriptors.

Another convention worth mentioning is that the open() methodshould not, in general, make changes to the operating parameters currentlyset in the hardware. It should be possible to run a command-line programwhich configures a camera according to
a certain set of desires(resolution, video format, etc.), then run an entirely separate applicationto, for example, capture a frame from the camera. This mode would not workif the camera's settings were reset in the middle, so a V4L2 driver shouldendeavor
to keep existing settings until an application explicitly resetsthem.

The release() method performs any needed cleanup. Since videodevices can have multiple open file descriptors,
release() willneed to decrement a counter and check before doing anything radical. Ifthe just-closed file descriptor was being used to transfer data, it maynecessary to shut down the DMA engine and perform other cleanups.

The next installment in this series will start into the long process ofquerying device capabilities and configuring operating modes. Stay tuned.

抱歉!评论已关闭.