4.4. 影片輸出疊加介面

也稱為螢幕顯示 (OSD)

一些影片輸出裝置可以將幀緩衝區影像疊加到輸出影片訊號上。應用程式可以使用此介面設定此類疊加,該介面借鑑了影片疊加介面的結構和 ioctl。

OSD 功能可透過與影片輸出功能相同的字元特殊檔案訪問。

注意

此類 /dev/video 裝置的預設功能是影片捕獲或輸出。OSD 功能僅在呼叫 VIDIOC_S_FMT ioctl 後才可用。

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。