6.1. V4L 和 V4L2 之間的差異

Video For Linux API 最早於 Linux 2.1 中引入,旨在統一和取代驅動開發者在前幾年獨立開發的各種電視和無線電裝置相關介面。從 Linux 2.5 開始,大幅改進的 V4L2 API 取代了 V4L API。對舊 V4L 呼叫的支援已從核心中移除,但庫 Libv4l 使用者空間庫 支援將 V4L API 系統呼叫轉換為 V4L2 呼叫。

6.1.1. 開啟和關閉裝置

出於相容性考慮,推薦用於 V4L2 影片捕獲、覆蓋、無線電和原始 VBI 捕獲裝置的字元裝置檔名與 V4L 使用的檔名保持不變。它們列在 介面 中,並在下文的 V4L 裝置型別、名稱和編號 中。

圖文電視裝置(次裝置號範圍 192-223)已在 V4L2 中移除,不再存在。目前沒有可用的硬體來處理純圖文電視。取而代之的是使用原始或切片 VBI。

V4L videodev 模組根據註冊的裝置型別,自動按載入順序為驅動程式分配次裝置號。我們建議 V4L2 驅動程式預設註冊具有相同編號的裝置,但系統管理員可以使用驅動程式模組選項分配任意次裝置號。主裝置號保持為 81。

V4L 裝置型別、名稱和編號

裝置型別

檔名

次裝置號

影片捕獲和覆蓋

/dev/video/dev/bttv0 [1], /dev/video0/dev/video63

0-63

無線電接收器

/dev/radio [2], /dev/radio0/dev/radio63

64-127

原始 VBI 捕獲

/dev/vbi, /dev/vbi0/dev/vbi31

224-255

V4L 禁止(或曾經禁止)多次開啟裝置檔案。V4L2 驅動程式可能支援多次開啟,詳情和後果請參閱 開啟和關閉裝置

V4L 驅動程式對 V4L2 ioctl 的響應是返回 EINVAL 錯誤程式碼。

6.1.2. 查詢功能

V4L 的 VIDIOCGCAP ioctl 等同於 V4L2 的 ioctl VIDIOC_QUERYCAP

struct video_capability 中的 name 欄位在 struct v4l2_capability 中變成了 cardtypecapabilities 取代。請注意,V4L2 不再像這樣區分裝置型別,最好將其視為支援影片捕獲、影片覆蓋和 VBI 捕獲等相關功能集的基本影片輸入、影片輸出和無線電裝置。有關介紹,請參閱 開啟和關閉裝置

struct video_capability type

struct v4l2_capability capabilities 標誌

目的

VID_TYPE_CAPTURE

V4L2_CAP_VIDEO_CAPTURE

支援 影片捕獲 介面。

VID_TYPE_TUNER

V4L2_CAP_TUNER

該裝置具有 調諧器或調製器

VID_TYPE_TELETEXT

V4L2_CAP_VBI_CAPTURE

支援 原始 VBI 捕獲 介面。

VID_TYPE_OVERLAY

V4L2_CAP_VIDEO_OVERLAY

支援 影片覆蓋 介面。

VID_TYPE_CHROMAKEY

struct v4l2_framebuffercapability 欄位中的 V4L2_FBUF_CAP_CHROMAKEY

是否支援色鍵覆蓋。有關覆蓋的更多資訊,請參閱 影片覆蓋介面

VID_TYPE_CLIPPING

struct v4l2_framebuffercapability 欄位中的 V4L2_FBUF_CAP_LIST_CLIPPINGV4L2_FBUF_CAP_BITMAP_CLIPPING

是否支援裁剪覆蓋影像,請參閱 影片覆蓋介面

VID_TYPE_FRAMERAM

struct v4l2_framebuffercapability 欄位中未設定 V4L2_FBUF_CAP_EXTERNOVERLAY

覆蓋是否會覆蓋幀緩衝區記憶體,請參閱 影片覆蓋介面

VID_TYPE_SCALES

-

此標誌指示硬體是否可以縮放影像。V4L2 API 透過使用 VIDIOC_S_CROPVIDIOC_S_FMT ioctl 分別設定裁剪尺寸和影像大小來表示縮放因子。驅動程式返回最接近的可能尺寸。有關裁剪和縮放的更多資訊,請參閱 影像裁剪、插入和縮放 -- CROP API

VID_TYPE_MONOCHROME

-

應用程式可以使用 ioctl VIDIOC_ENUM_FMT ioctl 列舉支援的影像格式,以確定裝置是否僅支援灰度捕獲。有關影像格式的更多資訊,請參閱 影像格式

VID_TYPE_SUBCAPTURE

-

應用程式可以呼叫 VIDIOC_G_CROP ioctl 來確定裝置是否支援捕獲完整圖片的一部分(V4L2 中的“裁剪”)。如果不支援,ioctl 將返回 EINVAL 錯誤程式碼。有關裁剪和縮放的更多資訊,請參閱 影像裁剪、插入和縮放 -- CROP API

VID_TYPE_MPEG_DECODER

-

應用程式可以使用 ioctl VIDIOC_ENUM_FMT ioctl 列舉支援的影像格式,以確定裝置是否支援 MPEG 流。

VID_TYPE_MPEG_ENCODER

-

參見上文。

VID_TYPE_MJPEG_DECODER

-

參見上文。

VID_TYPE_MJPEG_ENCODER

-

參見上文。

audios 欄位被 capabilities 標誌 V4L2_CAP_AUDIO 取代,表示裝置是否有任何音訊輸入或輸出。要確定它們的數量,應用程式可以使用 VIDIOC_G_AUDIO ioctl 列舉音訊輸入。音訊 ioctl 在 音訊輸入和輸出 中描述。

maxwidthmaxheightminwidthminheight 欄位已被移除。呼叫 VIDIOC_S_FMTVIDIOC_TRY_FMT ioctl 並指定所需尺寸將返回最接近的可能尺寸,同時考慮到當前影片標準、裁剪和縮放限制。

6.1.3. 影片源

V4L 提供 VIDIOCGCHANVIDIOCSCHAN ioctl,使用 struct video_channel 列舉 V4L 裝置的影片輸入。等效的 V4L2 ioctl 是 ioctl VIDIOC_ENUMINPUTVIDIOC_G_INPUTVIDIOC_S_INPUT,它們使用 struct v4l2_input,如 影片輸入和輸出 中所討論。

計數輸入的 channel 欄位被重新命名為 index,影片輸入型別重新命名如下:

struct video_channel type

struct v4l2_input type

VIDEO_TYPE_TV

V4L2_INPUT_TYPE_TUNER

VIDEO_TYPE_CAMERA

V4L2_INPUT_TYPE_CAMERA

與表示此輸入調諧器數量的 tuners 欄位不同,V4L2 假定每個影片輸入最多連線到一個調諧器。但是,一個調諧器可以有多個輸入,即射頻聯結器,並且一個裝置可以有多個調諧器。與輸入關聯的調諧器(如果有)的索引號儲存在 struct v4l2_inputtuner 欄位中。調諧器的列舉在 調諧器和調製器 中討論。

冗餘的 VIDEO_VC_TUNER 標誌已被刪除。與調諧器關聯的影片輸入型別為 V4L2_INPUT_TYPE_TUNERVIDEO_VC_AUDIO 標誌被 audioset 欄位取代。V4L2 考慮具有多達 32 個音訊輸入的裝置。audioset 欄位中的每個設定位表示此影片輸入組合的一個音訊輸入。有關音訊輸入以及如何在其間切換的資訊,請參閱 音訊輸入和輸出

描述支援的影片標準的 norm 欄位被 std 取代。V4L 規範提到了一個標誌 VIDEO_VC_NORM,指示標準是否可以更改。此標誌是與 norm 欄位一起的後期新增,但在此期間已被移除。V4L2 對影片標準有類似但更全面的方法,有關更多資訊,請參閱 影片標準

6.1.4. 調諧

V4L VIDIOCGTUNERVIDIOCSTUNER ioctl 以及 struct video_tuner 可用於列舉 V4L 電視或無線電裝置的調諧器。等效的 V4L2 ioctl 是 VIDIOC_G_TUNERVIDIOC_S_TUNER,它們使用 struct v4l2_tuner。調諧器在 調諧器和調製器 中介紹。

計數調諧器的 tuner 欄位被重新命名為 indexnamerangelowrangehigh 欄位保持不變。

指示支援的影片標準的 VIDEO_TUNER_PALVIDEO_TUNER_NTSCVIDEO_TUNER_SECAM 標誌已刪除。此資訊現在包含在關聯的 struct v4l2_input 中。目前沒有替代 VIDEO_TUNER_NORM 標誌來指示影片標準是否可以切換。用於選擇不同影片標準的 mode 欄位已被 影片標準 中描述的一整套新 ioctl 和結構取代。由於其普遍性,應提及 BTTV 驅動程式除了常規的 VIDEO_MODE_PAL (0)、VIDEO_MODE_NTSCVIDEO_MODE_SECAMVIDEO_MODE_AUTO (3) 之外,還支援多種標準,即 N/PAL Argentina、M/PAL、N/PAL 和 NTSC Japan,編號為 3-6(原文如此)。

指示立體聲接收的 VIDEO_TUNER_STEREO_ON 標誌在 rxsubchans 欄位中變為 V4L2_TUNER_SUB_STEREO。此欄位還允許檢測單聲道和雙語音訊,詳情請參閱 struct v4l2_tuner 的定義。目前沒有替代 VIDEO_TUNER_RDS_ONVIDEO_TUNER_MBS_ON 標誌。

VIDEO_TUNER_LOW 標誌在 struct v4l2_tunercapability 欄位中被重新命名為 V4L2_TUNER_CAP_LOW

用於更改調諧器頻率的 VIDIOCGFREQVIDIOCSFREQ ioctl 被重新命名為 VIDIOC_G_FREQUENCYVIDIOC_S_FREQUENCY。它們接受指向 struct v4l2_frequency 的指標,而不是無符號長整型。

6.1.5. 影像屬性

V4L2 沒有 VIDIOCGPICTVIDIOCSPICT ioctl 以及 struct video_picture 的等效項。以下欄位已被 V4L2 控制元件取代,可透過 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENUVIDIOC_G_CTRLVIDIOC_S_CTRL ioctl 訪問:

struct video_picture

V4L2 控制 ID

亮度

V4L2_CID_BRIGHTNESS

色調

V4L2_CID_HUE

色彩

V4L2_CID_SATURATION

對比度

V4L2_CID_CONTRAST

白平衡

V4L2_CID_WHITENESS

V4L 影像控制元件的範圍假定為 0 到 65535,沒有特定的重置值。V4L2 API 允許任意限制和預設值,這些值可以透過 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 進行查詢。有關控制元件的一般資訊,請參閱 使用者控制元件

影片影像的 depth(每畫素平均位數)由所選影像格式決定。V4L2 不會明確提供此類資訊,因為它假定識別該格式的應用程式會知道影像深度,而其他應用程式則無需瞭解。 palette 欄位已移至 struct v4l2_pix_format

struct video_picture palette

struct v4l2_pix_format pixfmt

VIDEO_PALETTE_GREY

V4L2_PIX_FMT_GREY

VIDEO_PALETTE_HI240

V4L2_PIX_FMT_HI240 [3]

VIDEO_PALETTE_RGB565

V4L2_PIX_FMT_RGB565

VIDEO_PALETTE_RGB555

V4L2_PIX_FMT_RGB555

VIDEO_PALETTE_RGB24

V4L2_PIX_FMT_BGR24

VIDEO_PALETTE_RGB32

V4L2_PIX_FMT_BGR32 [4]

VIDEO_PALETTE_YUV422

V4L2_PIX_FMT_YUYV

VIDEO_PALETTE_YUYV [5]

V4L2_PIX_FMT_YUYV

VIDEO_PALETTE_UYVY

V4L2_PIX_FMT_UYVY

VIDEO_PALETTE_YUV420

VIDEO_PALETTE_YUV411

V4L2_PIX_FMT_Y41P [6]

VIDEO_PALETTE_RAW

[7]

VIDEO_PALETTE_YUV422P

V4L2_PIX_FMT_YUV422P

VIDEO_PALETTE_YUV411P

V4L2_PIX_FMT_YUV411P [8]

VIDEO_PALETTE_YUV420P

V4L2_PIX_FMT_YVU420

VIDEO_PALETTE_YUV410P

V4L2_PIX_FMT_YVU410

V4L2 影像格式在 影像格式 中定義。影像格式可以使用 VIDIOC_S_FMT ioctl 選擇。

6.1.6. 音訊

VIDIOCGAUDIOVIDIOCSAUDIO ioctl 以及 struct video_audio 用於列舉 V4L 裝置的音訊輸入。等效的 V4L2 ioctl 是 VIDIOC_G_AUDIOVIDIOC_S_AUDIO,它們使用 struct v4l2_audio,如 音訊輸入和輸出 中所討論。

計數音訊輸入的 audio “通道號”欄位被重新命名為 index

VIDIOCSAUDIO 上,mode 欄位選擇 VIDEO_SOUND_MONOVIDEO_SOUND_STEREOVIDEO_SOUND_LANG1VIDEO_SOUND_LANG2 音訊解調模式中的一種。噹噹前音訊標準是 BTSC 時,VIDEO_SOUND_LANG2 指的是 SAP,而 VIDEO_SOUND_LANG1 則毫無意義。V4L 規範中也未記錄,無法查詢所選模式。在 VIDIOCGAUDIO 上,驅動程式在此欄位中返回實際接收到的音訊節目。在 V4L2 API 中,此資訊分別儲存在 struct v4l2_tunerrxsubchansaudmode 欄位中。有關調諧器的更多資訊,請參閱 調諧器和調製器。與音訊模式相關,struct v4l2_audio 還報告這是否是單聲道或立體聲輸入,無論來源是否是調諧器。

以下欄位已被 V4L2 控制元件取代,可透過 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENUVIDIOC_G_CTRLVIDIOC_S_CTRL ioctl 訪問:

struct video_audio

V4L2 控制 ID

音量

V4L2_CID_AUDIO_VOLUME

低音

V4L2_CID_AUDIO_BASS

高音

V4L2_CID_AUDIO_TREBLE

平衡

V4L2_CID_AUDIO_BALANCE

為了確定驅動程式支援哪些控制元件,V4L 提供了 flags VIDEO_AUDIO_VOLUMEVIDEO_AUDIO_BASSVIDEO_AUDIO_TREBLEVIDEO_AUDIO_BALANCE。在 V4L2 API 中,ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 報告是否支援相應的控制元件。因此,VIDEO_AUDIO_MUTABLEVIDEO_AUDIO_MUTE 標誌被布林型 V4L2_CID_AUDIO_MUTE 控制元件取代。

所有 V4L2 控制元件都有一個 step 屬性,取代了 struct video_audiostep 欄位。V4L 音訊控制元件的範圍假定為 0 到 65535,沒有特定的重置值。V4L2 API 允許任意限制和預設值,這些值可以透過 ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL 和 VIDIOC_QUERYMENU ioctl 進行查詢。有關控制元件的一般資訊,請參閱 使用者控制元件

6.1.7. 幀緩衝區覆蓋

VIDIOCGFBUFVIDIOCSFBUF 等效的 V4L2 ioctl 是 VIDIOC_G_FBUFVIDIOC_S_FBUF。struct video_bufferbase 欄位保持不變,只是 V4L2 定義了一個標誌來指示非破壞性覆蓋,而不是 NULL 指標。所有其他欄位都移至 struct v4l2_framebuffer 的 struct v4l2_pix_format fmt 子結構中。depth 欄位被 pixelformat 取代。有關 RGB 格式及其各自顏色深度的列表,請參閱 RGB 格式

V4L2 不使用特殊的 ioctl VIDIOCGWINVIDIOCSWIN,而是使用通用資料格式協商 ioctl VIDIOC_G_FMTVIDIOC_S_FMT。它們接受指向 struct v4l2_format 的指標作為引數。此處使用的是 fmt 聯合體的 win 成員,即 struct v4l2_window

struct video_windowxywidthheight 欄位已移至 struct v4l2_window 的 struct v4l2_rect 子結構 w 中。chromakeyclipsclipcount 欄位保持不變。struct video_clip 被重新命名為 struct v4l2_clip,它也包含一個 struct v4l2_rect,但其語義仍然相同。

VIDEO_WINDOW_INTERLACE 標誌已刪除。取而代之的是,應用程式必須將 field 欄位設定為 V4L2_FIELD_ANYV4L2_FIELD_INTERLACEDVIDEO_WINDOW_CHROMAKEY 標誌已移至 struct v4l2_framebuffer 中,並以新名稱 V4L2_FBUF_FLAG_CHROMAKEY 存在。

在 V4L 中,將點陣圖指標儲存在 clips 中並將 clipcount 設定為 VIDEO_CLIP_BITMAP (-1) 會請求點陣圖裁剪,使用固定大小為 1024 × 625 位的點陣圖。Struct v4l2_window 為此目的有一個單獨的 bitmap 指標欄位,點陣圖大小由 w.widthw.height 決定。

啟用或停用覆蓋的 VIDIOCCAPTURE ioctl 已重新命名為 ioctl VIDIOC_OVERLAY

6.1.8. 裁剪

為了僅捕獲完整圖片的一部分,V4L 定義了使用 struct video_captureVIDIOCGCAPTUREVIDIOCSCAPTURE ioctl。等效的 V4L2 ioctl 是 VIDIOC_G_CROPVIDIOC_S_CROP,它們使用 struct v4l2_crop,以及相關的 ioctl VIDIOC_CROPCAP ioctl。這是一個相當複雜的問題,詳情請參閱 影像裁剪、插入和縮放 -- CROP API

struct v4l2_cropxywidthheight 欄位已移至 struct v4l2_rect 子結構 c 中。decimation 欄位已刪除。在 V4L2 API 中,縮放因子由裁剪矩形的大小以及捕獲或覆蓋影像的大小隱式決定。

用於分別僅捕獲奇數或偶數場的 VIDEO_CAPTURE_ODDVIDEO_CAPTURE_EVEN 標誌已替換為 struct v4l2_pix_format 和 struct v4l2_window 中名為 field 的欄位中的 V4L2_FIELD_TOPV4L2_FIELD_BOTTOM。這些結構用於使用 VIDIOC_S_FMT ioctl 選擇捕獲或覆蓋格式。

6.1.9. 讀取影像,記憶體對映

6.1.9.1. 使用讀方法捕獲

使用 read() 函式從 V4L 或 V4L2 裝置讀取影像之間沒有本質區別,但 V4L2 驅動程式不要求支援此 I/O 方法。應用程式可以透過 ioctl VIDIOC_QUERYCAP ioctl 確定該函式是否可用。所有與應用程式交換資料的 V4L2 裝置都必須支援 select()poll() 函式。

為了選擇影像格式和大小,V4L 提供了 VIDIOCSPICTVIDIOCSWIN ioctl。V4L2 使用通用資料格式協商 ioctl VIDIOC_G_FMTVIDIOC_S_FMT。它們接受指向 struct v4l2_format 的指標作為引數,此處使用的是其 fmt 聯合體中名為 pix 的 struct v4l2_pix_format

有關 V4L2 讀介面的更多資訊,請參閱 讀/寫

6.1.9.2. 使用記憶體對映捕獲

應用程式可以透過將裝置記憶體中的緩衝區(或更常見的是僅將分配在支援 DMA 的系統記憶體中的緩衝區)對映到其地址空間來從 V4L 裝置讀取資料。這避免了讀方法的資料複製開銷。V4L2 也支援記憶體對映,但有一些不同。

V4L

V4L2

必須在分配緩衝區之前選擇影像格式,使用 VIDIOC_S_FMT ioctl。如果沒有選擇格式,驅動程式可能會使用上一個(可能由另一個應用程式請求的)格式。

應用程式無法更改緩衝區數量。它內建在驅動程式中,除非它有一個模組選項可以在驅動程式模組載入時更改數量。

ioctl VIDIOC_REQBUFS ioctl 分配所需數量的緩衝區,這是初始化序列中的一個必需步驟。

驅動程式將所有緩衝區對映為一塊連續的記憶體區域。VIDIOCGMBUF ioctl 可用於查詢緩衝區數量、每個緩衝區相對於虛擬檔案起始處的偏移量以及使用的總記憶體量,這些資訊可用作 mmap() 函式的引數。

緩衝區是單獨對映的。每個緩衝區的偏移量和大小可以使用 ioctl VIDIOC_QUERYBUF ioctl 確定。

VIDIOCMCAPTURE ioctl 準備一個緩衝區用於捕獲。它還確定此緩衝區的影像格式。如果未檢測到影片訊號,ioctl 會立即返回,最終返回 EAGAIN 錯誤程式碼。當驅動程式支援多個緩衝區時,應用程式可以多次呼叫 ioctl,從而有多個未完成的捕獲請求。

VIDIOCSYNC ioctl 暫停執行,直到某個特定緩衝區被填充。

驅動程式維護一個輸入佇列和一個輸出佇列。ioctl VIDIOC_QBUF, VIDIOC_DQBUF 將任何空緩衝區入隊到輸入佇列。已填充的緩衝區使用 VIDIOC_DQBUF ioctl 從輸出佇列中出隊。要等待填充的緩衝區可用,可以使用此函式、select()poll()。在將一個或多個緩衝區入隊後,必須呼叫一次 ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF ioctl 以開始捕獲。其對應項 VIDIOC_STREAMOFF 停止捕獲並從兩個佇列中取出所有緩衝區。應用程式可以透過 ioctl VIDIOC_ENUMINPUT ioctl 查詢訊號狀態(如果已知)。

有關記憶體對映和示例的更深入討論,請參閱 流 I/O (記憶體對映)

6.1.10. 讀取原始 VBI 資料

最初 V4L API 沒有指定原始 VBI 捕獲介面,僅將裝置檔案 /dev/vbi 保留用於此目的。唯一支援此介面的驅動程式是 BTTV 驅動程式,實際上它定義了 V4L VBI 介面。從裝置讀取會得到一個具有以下引數的原始 VBI 影像:

struct v4l2_vbi_format

V4L, BTTV 驅動程式

取樣率

28636363 Hz NTSC(或任何其他 525 行標準);35468950 Hz PAL 和 SECAM(625 行標準)

偏移量

?

每行樣本數

2048

樣本格式

V4L2_PIX_FMT_GREY。最後四個位元組(一個機器位元組序整數)包含一個幀計數器。

起始[]

10, 273 NTSC; 22, 335 PAL 和 SECAM

計數[]

16, 16 [9]

標誌

0

V4L 規範中未記錄,在 Linux 2.3 中,增加了使用 struct vbi_formatVIDIOCGVBIFMTVIDIOCSVBIFMT ioctl 來確定 VBI 影像引數。這些 ioctl 僅與 原始 VBI 資料介面 中指定的 V4L2 VBI 介面部分相容。

不存在 offset 欄位,sample_format 應該是 VIDEO_PALETTE_RAW,等同於 V4L2_PIX_FMT_GREY。其餘欄位可能與 struct v4l2_vbi_format 等效。

顯然,只有 Zoran (ZR 36120) 驅動程式實現了這些 ioctl。其語義與 V4L2 中指定的語義有兩種不同之處。引數在 open() 時重置,並且如果引數無效,VIDIOCSVBIFMT 總是返回 EINVAL 錯誤程式碼。

6.1.11. 雜項

V4L2 沒有 VIDIOCGUNIT ioctl 的等效項。應用程式可以透過重新開啟裝置並請求 VBI 資料來查詢與影片捕獲裝置關聯的 VBI 裝置(反之亦然)。詳情請參閱 開啟和關閉裝置

目前沒有替代 VIDIOCKEY 和用於微碼程式設計的 V4L 函式的方案。MPEG 壓縮和播放裝置的新介面已在 擴充套件控制元件 API 中記錄。