V4L2 第四部分:输入输出

Video4Linux2 part 4: inputs and outputs

V4L2 第四部分:输入输出

This is the fourth article in the irregular LWN series on writing video drivers for Linux. Those who have not yet read the introductory article may want to start there. This week's episode describes how an application can determine which inputs and outputs are available on a given adapter and select between them.

这是写Linux视频驱动系列文章的第四篇。那些还没有看过简介篇的可以先去看一下。这周我们讲应用程序如何在给定的适配器上决定哪个输入输出是可用的,并选择它们。

 

In many cases, a video adapter does not provide a lot of input and output options. A camera controller, for example, may provide the camera and little else. In other cases, however, the situation is more complicated. A TV card might have multiple inputs corresponding to different connectors on the board; it could even have multiple tuners capable of functioning independently. Sometimes those inputs have different characteristics; some might be able to tune to a wider range of video standards than others. The same holds for outputs.

很多情况下,一个视频适配器并不提供很多输入输出选项。例如:摄像头控制器,通常只提供摄像头和一点其他东西。然而,也有一些情况,情形相对复杂一点。一个电视卡上面可能有多个连接器,可能有多个输入。有的输入有不同的特性,有的可能覆盖的视频标准。视频输出也是一样。

 

Clearly, for an application to be able to make full use of a video adapter, it must be able to find out about the available inputs and outputs, and it must be able to select the one it wishes to operate with. To that end, the Video4Linux2 API offers three different ioctl() calls for dealing with inputs, and an equivalent three for outputs. Drivers should implement all three (for each functionality supported by the hardware), even though, for simple hardware, the corresponding code can be quite simple. Drivers should also provide reasonable defaults on startup. What a driver should not do, however, is reset input and output information when an application exits; as with other video parameters, these settings should be left unchanged between opens.

显而易见,为了让应用程序能够重复的利用视频适配器,一定要找出所有可用的输入和输出,一定要能够选择要操作哪一个。最后,V4L2 API提供了三个不同ioctl()调用处理输入,同样也有三个ioctl()调用处理输出。对应于硬件提供的三种功能,驱动要实现三种ioctl(),即使,代码可能很少很简单。驱动应该启动时提供一个合理的默认值。驱动不应该做的是:应用程序退出时重设了输入和输出配置;和其他视频参数一样,这些参数应该保持不变。

 

Video standards

视频标准

Before we can get into the details of inputs and outputs, however, we must have a look at video standards. These standards describe how a video signal is formatted for transmission - resolution, frame rates, etc. These standards are usually set by regulatory authorities in each country. There are three major types of video standard used in the world: NTSC (used in North America, primarily), PAL (much of Europe, Africa, and Asia), and SECAM (France, Russia, parts of Africa). There are, however, variations in the standards from one country to the next, and some devices are more flexible than others in the variants they can work with.

在我们深入输入输出的细节之前,我们一定要审视一下视频标准。视频标准描述了视频信号如何格式化用来传输-解析度,帧率,等等。这些标准通常是由每个国家的管理部门制定的。世界上主要有三种视频标准:NTSC(主要用在北美),PAL(欧洲的大部分,非洲,和亚洲),和SECAM(法国,俄罗斯,和非洲的部分)。然而,标准内部也有变种,一个国家可能跟另外一个就不同,某些设备也就在参数上面更加灵活。

The V4L2 layer represents video standards with the type v4l2_std_id, which is a 64-bit mask. Each standard variant is then one bit in the mask. So "standard" NTSC is V4L2_STD_NTSC_M, value 0x1000, but the Japanese variant is V4L2_STD_NTSC_M_JP (0x2000). If a device can handle all variants of NTSC, it can set a standard type of V4L2_STD_NTSC, which has all of the relevant bits set. Similar sets of bits exist for the variants of PAL and SECAM. See this page for a complete list. 

V4L2层使用类型v4l2_std_id代表视频标准,这是个64位掩码。每种标准的变种是掩码的一位。因此标准NTSC是 V4L2_STD_NTSC_M,值为0x1000,而NTSC的日本变种是V4L2_STD_NTSC_M_JP (0x2000)。如果一个设备能够处理NTSC标准的所有变种,它可以设置V4L2_STD_NTSC,它是整个变种集合。相似的情况也存在于PAL和SECAM。查看这个网页里的完整列表。

For user space, V4L2 provides an ioctl() command (VIDIOC_ENUMSTD) which allows an application to query which standards are implemented by a device. The driver does not need to answer those queries directly, however; instead, it simply sets the tvnorm field of the video_device structure with all of the standards that it supports. The V4L2 layer will then split out the supported standards for the application. The VIDIOC_G_STD command, used to query which standard is active at the moment, is also handled in the V4L2 layer by returning the value in the current_norm field of the video_device structure. The driver should, at startup, initialize current_norm to reflect reality; some applications will get confused if no standard is set, even though they have not set one.

对用户空间来说,V4L2提供了ioctl()命令(VIDIOC_ENUMSTD),允许应用程序查询设备实现了哪些标准。驱动不必直接回答这些查询,它只是简单的设置了video_device结构体中的tvnorm成员,表示了自己所支持的所有标准。V4L2层会扩展它,然后交给应用程序。VIDIOC_G_STD命令,用来查询当前激活的标准,同样的,也是通过video_device的current_norm成员返回,然后由V4L2层处理,交给应用程序。驱动启动的时候,应该初始化current_norm;否则,如果没有设置任何标准,应用程序可能就糊涂了,即使它们还没有设置这个值。

 

When an application wishes to request a specific standard, it will issue a VIDIOC_S_STD call, which is passed through to the driver via:

int (*vidioc_s_std) (struct file *file, void *private_data, v4l2_std_id std);

The driver should program the hardware to use the given standard and return zero (or a negative error code). The V4L2 layer will handle setting current_norm to the new value.

应用程序需要请求某个特定标准是,它需要发布一个VIDIOC_S_STD调用,通过下面这个函数指针传入驱动:

int (*vidioc_s_std) (struct file *file, void *private_data, v4l2_std_id std);

驱动应该让硬件使用给定的标准,并且返回0(或者负值表示错误码)。V4L2层将会把该值设置给current_norm。

 

The application may want to know what kind of signal the hardware actually sees on its input. The answer can be found with VIDIOC_QUERYSTD, which reaches the driver as:

int (*vidioc_querystd) (struct file *file, void *private_data, v4l2_std_id *std);

The driver should fill in this field in the greatest detail possible. If the hardware does not provide much information, the std field should indicate any of the standards which might be present.

应用程序可能想要知道硬件会实际输出什么标准。可以通过VIDIOC_QUERYSTD方法获取答案,到驱动这边是个函数指针:

int (*vidioc_querystd) (struct file *file, void *private_data, v4l2_std_id *std);

驱动应该尽可能的填写这个变量std。如果硬件不能提供信息,那么std变量应该能够表示可能会出现任何一种标准。

 

There is one more point worth noting here: all video devices must support (or at least claim to support) at least one standard. Video standards make little sense for camera devices, which are not tied to any specific regulatory regime. But there is no standard for "I'm a camera and can do almost anything you want." So the V4L2 layer has a number of camera drivers which claim to return PAL or NTSC data.

还有一点,虽然不值一提:所有的视频设备必需支持一种标准,或者至少宣称支持一种标准。视频标准对摄像设备来说没什么意义,它不会绑定任何一专门的政治体制。但是也没有一种说法:我是一个摄像头,我可以做你想要的任何事情。因此V4L2层有一些摄像驱动宣称返回PAL数据或者NTSC数据。

 

Inputs

A video acquisition application will start by enumerating the available inputs with the VIDIOC_ENUMINPUT command. Within the V4L2 layer, that command will be turned into a call to the driver's corresponding callback:

int (*vidioc_enum_input)(struct file *file, void *private_data, struct v4l2_input *input);

In this call, file corresponds to the open video device, and private_data is the private field set by the driver. The input structure is where the real information is passed; it has several fields of interest:

1. __u32 index: the index number of the input the application is interested in; this is the only field which will be set by user space. Drivers should assign index numbers to inputs, starting at zero and going up from there. An application wanting to know about all available inputs will call VIDIOC_ENUMINPUT with index numbers starting at zero and incrementing from there; once the driver returns EINVAL the application knows that it has exhausted the list. Input number zero should exist for all input-capable devices.

2. __u8 name[32]: the name of the input, as set by the driver. In simple cases, it can simply be "Camera" or some such; if the card has multiple inputs, the name used here should correspond to what is printed by the connector.

3. __u32 type: the type of input. There are currently only two: V4L2_INPUT_TYPE_TUNER and V4L2_INPUT_TYPE_CAMERA.

4. __u32 audioset: describes which audio inputs can be associated with this video input. Audio inputs are enumerated by index number just like video inputs (we'll get to audio in another installment), but not all combinations of audio and video can be selected. This field is a bitmask with a bit set for each audio input which works with the video input being enumerated. If no audio inputs are supported, or if only a single input can be selected, the driver can simply leave this field as zero.

5. __u32 tuner: if this input is a tuner (type is set to V4L2_INPUT_TYPE_TUNER), this field will contain an index number corresponding to the tuner device. Enumeration and control of tuners will be covered in a future installment too.

6. v4l2_std_id std: describes which video standard(s) are supported by the device.

7. __u32 status: gives the status of the input. The full set of flags can be found in the V4L2 documentation; in short, each bit set in status describes a problem. These can include no power, no signal, no synchronization lock, or the presence of Macrovision, among other unfortunate events.

8. __u32 reserved[4]: reserved fields. Drivers should set them to zero.

Normally, the driver will set all of the fields above and return zero. If index is outside the range of supported inputs, -EINVAL should be returned instead; there is not much else that can go wrong in this call.

When the application wants to change the current input, the driver will receive a call to its vidioc_s_input() callback:

int (*vidioc_s_input) (struct file *file, void *private_data, unsigned int index);

The index value has the same meaning as before - it identifies which input is of interest. The driver should program the hardware to use that input and return zero. Other possible return values are -EINVAL (for a bogus index number) or -EIO (for hardware trouble). Drivers should implement this callback even if they only support a single input.

There is also a callback to query which input is currently active:

int (*vidioc_g_input) (struct file *file, void *private_data, unsigned int *index);

Here, the driver sets *index to the index number of the currently active input.

Outputs

The process for enumerating and selecting outputs is very similar to that for inputs, so the description here will be a little more brief. The callback for output enumeration looks like this:

int (*vidioc_enumoutput) (struct file *file, void *private_data, struct v4l2_output *output);

The fields of the v4l2_output structure are:

1. __u32 index: the index value corresponding to the output. This index works the same way as the input index: it starts at zero and goes up from there.

2. __u8 name[32]: the name of the output. 

3. __u32 type: the type of the output. The supported output types are  V4L2_OUTPUT_TYPE_MODULATOR for an analog TV modulator, V4L2_OUTPUT_TYPE_ANALOG for basic analog video output, and V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY for analog VGA overlay devices. 

4. __u32 audioset: the set of audio outputs which can operate with this video output. 

5. __u32 modulator: the index of the modulator associated with this device (for those of type V4L2_OUTPUT_TYPE_MODULATOR). 

6. v4l2_std_id std: the video standards supported by this output.

7. __u32 reserved[4]: reserved fields, should be set to zero. 

There are callbacks for getting and setting the current output setting; they mirror the input callbacks:

int (*vidioc_g_output) (struct file *file, void *private_data, unsigned int *index);
int (*vidioc_s_output) (struct file *file, void *private_data, unsigned int index);

Any device which supports video output should have all three output callbacks defined, even if there is only one possible output.

With these methods in place, a V4L2 application can determine which inputs and outputs are available on a given device and choose between them. The task of determining just what kind of video data flows through those inputs and outputs is rather more complicated, however. The next installment in this series will begin to look at video data formats and how to negotiate a format with user space.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值