4.4. 视频输出叠加接口

也称为屏幕显示 (OSD)

一些视频输出设备可以将帧缓冲区图像叠加到输出的视频信号上。应用程序可以使用此接口设置此类叠加,该接口借用了视频叠加接口的结构和 ioctl。

OSD 功能可以通过与视频输出功能相同的字符特殊文件访问。

注意

此类 /dev/video 设备的默认功能是视频捕获或输出。只有在调用VIDIOC_S_FMT ioctl 之后,才能使用 OSD 功能。

4.4.1. 查询功能

支持*视频输出叠加*接口的设备在ioctl VIDIOC_QUERYCAP ioctl 返回的 struct v4l2_capabilitycapabilities 字段中设置 V4L2_CAP_VIDEO_OUTPUT_OVERLAY 标志。

4.4.2. 帧缓冲区

与*视频叠加*接口相反,帧缓冲区通常在电视卡上实现,而不是在显卡上实现。在 Linux 上,它可以作为帧缓冲区设备 (/dev/fbN) 访问。给定一个 V4L2 设备,应用程序可以通过调用VIDIOC_G_FBUF ioctl 来查找相应的帧缓冲区设备。它返回,以及其他信息,帧缓冲区的物理地址,在 struct v4l2_framebufferbase 字段中。帧缓冲区设备 ioctl FBIOGET_FSCREENINFO 在 struct fb_fix_screeninfosmem_start 字段中返回相同的地址。FBIOGET_FSCREENINFO ioctl 和 struct fb_fix_screeninfolinux/fb.h 头文件中定义。

帧缓冲区的宽度和高度取决于当前的视频标准。在所有应用程序关闭帧缓冲区设备之前,V4L2 驱动程序可能会拒绝尝试更改视频标准(或任何其他暗示帧缓冲区大小更改的 ioctl),并返回 EBUSY 错误代码。

4.4.2.1. 示例:查找 OSD 的帧缓冲区设备

#include <linux/fb.h>

struct v4l2_framebuffer fbuf;
unsigned int i;
int fb_fd;

if (-1 == ioctl(fd, VIDIOC_G_FBUF, &fbuf)) {
    perror("VIDIOC_G_FBUF");
    exit(EXIT_FAILURE);
}

for (i = 0; i < 30; i++) {
    char dev_name[16];
    struct fb_fix_screeninfo si;

    snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);

    fb_fd = open(dev_name, O_RDWR);
    if (-1 == fb_fd) {
        switch (errno) {
        case ENOENT: /* no such file */
        case ENXIO:  /* no driver */
            continue;

        default:
            perror("open");
            exit(EXIT_FAILURE);
        }
    }

    if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &si)) {
        if (si.smem_start == (unsigned long)fbuf.base)
            break;
    } else {
        /* Apparently not a framebuffer device. */
    }

    close(fb_fd);
    fb_fd = -1;
}

/* fb_fd is the file descriptor of the framebuffer device
   for the video output overlay, or -1 if no device was found. */

4.4.3. 叠加窗口和缩放

叠加由源矩形和目标矩形控制。源矩形选择要叠加的帧缓冲区图像的子部分,目标矩形选择输出视频信号中图像将出现的区域。驱动程序可能支持或不支持缩放,以及这些矩形的任意大小和位置。此外,驱动程序可能支持为视频叠加接口定义的任何(或没有)裁剪/混合方法。

struct v4l2_window 定义了源矩形的大小、它在帧缓冲区中的位置以及用于叠加的裁剪/混合方法。要获取当前参数,应用程序将 struct v4l2_formattype 字段设置为 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY 并调用 VIDIOC_G_FMT ioctl。驱动程序会填充名为 win 的 struct v4l2_window 子结构。无法检索先前编程的裁剪列表或位图。

要编程源矩形,应用程序将 struct v4l2_formattype 字段设置为 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,初始化 win 子结构,并调用 VIDIOC_S_FMT ioctl。驱动程序会根据硬件限制调整参数,并像 VIDIOC_G_FMT 一样返回实际参数。与 VIDIOC_S_FMT 类似,VIDIOC_TRY_FMT ioctl 可用于了解驱动程序功能,而无需实际更改驱动程序状态。与 VIDIOC_S_FMT 不同,这在启用叠加后也有效。

struct v4l2_crop 定义了目标矩形的大小和位置。叠加的缩放比例由 struct v4l2_window 和 struct v4l2_crop 中给出的宽度和高度暗示。裁剪 API 以与 *视频捕获* 和 *视频叠加* 设备相同的方式应用于*视频输出*和*视频输出叠加*设备,只是反转了数据流的方向。有关更多信息,请参见图像裁剪、插入和缩放——CROP API

4.4.4. 启用叠加

没有 V4L2 ioctl 来启用或禁用叠加,但是驱动程序的帧缓冲区接口可能支持 FBIOBLANK ioctl。