3.5. 緩衝區

緩衝區包含應用程式和驅動程式使用一種流式 I/O 方法交換的資料。在多平面 API 中,資料儲存在平面中,而緩衝區結構充當平面的容器。只交換指向緩衝區(平面)的指標,資料本身不復制。這些指標以及諸如時間戳或場奇偶校驗之類的元資訊儲存在結構體 v4l2_buffer 中,它是 ioctl VIDIOC_QUERYBUFVIDIOC_QBUFVIDIOC_DQBUF ioctl 的引數。在多平面 API 中,結構體 v4l2_buffer 的一些特定於平面的成員,例如每個平面的指標和大小,儲存在結構體 v4l2_plane 中。在這種情況下,結構體 v4l2_buffer 包含一個平面結構陣列。

出隊的影片緩衝區帶有時間戳。驅動程式決定在幀的哪個部分以及使用哪個時鐘獲取時間戳。請參閱 緩衝區標誌V4L2_BUF_FLAG_TIMESTAMP_MASKV4L2_BUF_FLAG_TSTAMP_SRC_MASK 掩碼中的標誌。這些標誌始終有效,並且在整個影片流中對所有緩衝區都是恆定的。這些標誌的更改可能會作為 VIDIOC_S_INPUTVIDIOC_S_OUTPUT 的副作用發生。例如,在 mem-to-mem 裝置上使用的 V4L2_BUF_FLAG_TIMESTAMP_COPY 時間戳型別是此規則的例外:時間戳源標誌從 OUTPUT 影片緩衝區複製到 CAPTURE 影片緩衝區。

3.5.1. 格式、控制元件和緩衝區之間的互動

V4L2 公開了影響緩衝區大小或資料在緩衝區中佈局方式的引數。這些引數透過格式和控制元件公開。這種控制元件的一個例子是 V4L2_CID_ROTATE 控制元件,它修改了畫素儲存在緩衝區中的方向,以及當所選格式包含行尾的填充時修改了緩衝區大小。

解釋緩衝區內容所需的一組資訊(例如,畫素格式、行步幅、平鋪方向或旋轉)在本節的其餘部分中統稱為緩衝區佈局。

可以修改緩衝區佈局的控制元件應設定 V4L2_CTRL_FLAG_MODIFY_LAYOUT 標誌。

修改影響緩衝區大小或佈局的格式或控制元件需要停止流。在流活動時嘗試進行此類修改應導致設定格式或控制元件的 ioctl 返回 EBUSY 錯誤程式碼。在這種情況下,驅動程式在呼叫 VIDIOC_QUERYCTRL()VIDIOC_QUERY_EXT_CTRL() 時,也應為流活動時此類控制元件設定 V4L2_CTRL_FLAG_GRABBED 標誌。

注意

VIDIOC_S_SELECTION() ioctl 可以根據硬體(例如,如果裝置不包含縮放器)修改格式以及選擇矩形。類似地,VIDIOC_S_INPUT()VIDIOC_S_OUTPUT()VIDIOC_S_STD()VIDIOC_S_DV_TIMINGS() ioctl 也可以修改格式和選擇矩形。當這些 ioctl 導致緩衝區大小或佈局更改時,驅動程式應像處理 VIDIOC_S_FMT() ioctl 中描述的所有情況一樣處理這種情況。

僅影響緩衝區佈局的控制元件可以在停止流時隨時修改。由於它們不影響緩衝區大小,因此無需特殊處理即可將這些控制元件與緩衝區分配同步,並且一旦流停止,V4L2_CTRL_FLAG_GRABBED 標誌將被清除。

影響緩衝區大小的格式和控制元件與緩衝區分配互動。處理此問題的最簡單方法是讓驅動程式始終要求重新分配緩衝區,以便更改這些格式或控制元件。在這種情況下,要執行此類更改,使用者空間應用程式應首先使用 VIDIOC_STREAMOFF() ioctl 停止影片流(如果正在執行),並使用 VIDIOC_REQBUFS() ioctl 釋放所有緩衝區(如果已分配)。釋放所有緩衝區後,將清除控制元件的 V4L2_CTRL_FLAG_GRABBED 標誌。然後可以修改格式或控制元件,然後應重新分配緩衝區並重新啟動流。一個典型的 ioctl 序列是

  1. VIDIOC_STREAMOFF

  2. VIDIOC_REQBUFS(0)

  3. VIDIOC_S_EXT_CTRLS

  4. VIDIOC_S_FMT

  5. VIDIOC_REQBUFS(n)

  6. VIDIOC_QBUF

  7. VIDIOC_STREAMON

第二個 VIDIOC_REQBUFS() 呼叫將考慮新的格式和控制元件值,以計算要分配的緩衝區大小。如果需要,應用程式還可以透過呼叫 VIDIOC_G_FMT() ioctl 來檢索大小。

注意

API 不強制執行上述控制(3.)和格式(4.)更改的順序。格式和控制元件可以根據裝置和用例以不同的順序設定,甚至可以交錯設定。例如,某些控制元件對於不同的畫素格式可能會表現不同,在這種情況下,可能需要首先設定格式。

當需要重新分配時,任何嘗試在分配緩衝區時修改影響緩衝區大小的格式或控制元件都應導致格式或控制元件設定 ioctl 返回 EBUSY 錯誤。任何嘗試排隊對於當前格式或控制元件而言太小的緩衝區都應導致 VIDIOC_QBUF() ioctl 返回 EINVAL 錯誤。

緩衝區重新分配是一項昂貴的操作。為了避免這種成本,鼓勵驅動程式允許在分配緩衝區的情況下更改影響緩衝區大小的格式或控制元件。在這種情況下,修改格式和控制元件的典型 ioctl 序列是

  1. VIDIOC_STREAMOFF

  2. VIDIOC_S_EXT_CTRLS

  3. VIDIOC_S_FMT

  4. VIDIOC_QBUF

  5. VIDIOC_STREAMON

為了使此序列正確執行,排隊的緩衝區需要足夠大,以適應新的格式或控制元件。如果當前排隊的緩衝區對於新格式而言太小,則驅動程式應返回 ENOSPC 錯誤以響應格式更改 (VIDIOC_S_FMT()) 或控制元件更改 (VIDIOC_S_CTRL()VIDIOC_S_EXT_CTRLS())。作為一種簡化,如果當前已排隊任何緩衝區,則允許驅動程式從這些 ioctl 返回 EBUSY 錯誤,而無需檢查排隊緩衝區的大小。

此外,如果正在排隊的緩衝區對於當前格式或控制元件而言太小,則驅動程式應從 VIDIOC_QBUF() ioctl 返回 EINVAL 錯誤。這些要求共同確保排隊的緩衝區始終足夠大,以適應配置的格式和控制元件。

使用者空間應用程式可以透過首先設定所需的控制元件值,然後嘗試所需的格式,來查詢給定格式和控制元件所需的緩衝區大小。VIDIOC_TRY_FMT() ioctl 將返回所需的緩衝區大小。

  1. VIDIOC_S_EXT_CTRLS(x)

  2. VIDIOC_TRY_FMT()

  3. VIDIOC_S_EXT_CTRLS(y)

  4. VIDIOC_TRY_FMT()

然後可以使用 VIDIOC_CREATE_BUFS() ioctl 根據查詢的大小分配緩衝區(例如,透過分配一組足夠大的緩衝區以適應所有所需的格式和控制元件,或者透過為每個用例分配單獨的一組大小合適的緩衝區)。

型別 v4l2_buffer

3.5.2. struct v4l2_buffer

struct v4l2_buffer

__u32

index

緩衝區的編號,由應用程式設定,但在呼叫 VIDIOC_DQBUF 時除外,此時由驅動程式設定。該欄位的範圍可以從零到使用 ioctl VIDIOC_REQBUFS ioctl(struct v4l2_requestbuffers count)分配的緩衝區數量,加上使用 ioctl VIDIOC_CREATE_BUFS 分配的任何緩衝區減一。

__u32

type

緩衝區的型別,與 struct v4l2_format type 或 struct v4l2_requestbuffers type 相同,由應用程式設定。請參閱 v4l2_buf_type

__u32

bytesused

緩衝區中資料佔用的位元組數。它取決於協商的資料格式,並且對於壓縮的可變大小資料(如 JPEG 影像)可能會隨每個緩衝區而變化。當 type 指的是捕獲流時,驅動程式必須設定此欄位;當它指的是輸出流時,應用程式必須設定此欄位。對於多平面格式,此欄位將被忽略,而是使用 planes 指標。

__u32

flags

由應用程式或驅動程式設定的標誌,請參閱 緩衝區標誌

__u32

field

指示緩衝區中影像的場序,請參閱 v4l2_field。當緩衝區包含 VBI 資料時,不使用此欄位。當 type 指的是捕獲流時,驅動程式必須設定它;當它指的是輸出流時,應用程式必須設定它。

struct timeval

timestamp

對於捕獲流,這是捕獲第一個資料位元組的時間,由相關時鐘 ID 的 clock_gettime() 函式返回;請參閱 緩衝區標誌 中的 V4L2_BUF_FLAG_TIMESTAMP_*。對於輸出流,驅動程式將實際傳送出最後一個數據位元組的時間儲存在 timestamp 欄位中。這允許應用程式監視影片和系統時鐘之間的漂移。對於使用 V4L2_BUF_FLAG_TIMESTAMP_COPY 的輸出流,應用程式必須填寫時間戳,該時間戳將由驅動程式複製到捕獲流。

struct v4l2_timecode

timecode

flags 中設定了 V4L2_BUF_FLAG_TIMECODE 標誌時,此結構包含幀時間碼。在 V4L2_FIELD_ALTERNATE 模式下,頂部和底部場包含相同的時間碼。時間碼旨在幫助影片編輯,通常記錄在錄影帶上,但也嵌入在諸如 MPEG 之類的壓縮格式中。此欄位獨立於 timestampsequence 欄位。

__u32

sequence

由驅動程式設定,按順序計數幀(不是場!)。為輸入和輸出裝置設定此欄位。

V4L2_FIELD_ALTERNATE 模式下,頂部和底部場具有相同的序列號。計數從零開始,包括丟棄或重複的幀。丟棄的幀由輸入裝置接收,但由於缺少可用緩衝區空間而無法儲存。重複的幀由輸出裝置再次顯示,因為應用程式沒有及時傳遞新資料。

注意

這可能會計數透過 USB 接收的幀,而無需考慮由於有限的壓縮吞吐量或匯流排頻寬而被遠端硬體丟棄的幀。這些裝置透過不列舉任何影片標準來識別,請參閱 影片標準

__u32

memory

必須由應用程式和/或驅動程式根據所選的 I/O 方法設定此欄位。請參閱 v4l2_memory

union {

m

__u32

offset

對於單平面 API,並且當 memoryV4L2_MEMORY_MMAP 時,這是緩衝區相對於裝置記憶體起始位置的偏移量。該值由驅動程式返回,並且作為 mmap() 函式的引數,對應用程式沒有用處。有關詳細資訊,請參閱 流式 I/O(記憶體對映)

unsigned long

userptr

對於單平面 API,並且當 memoryV4L2_MEMORY_USERPTR 時,這是指向虛擬記憶體中緩衝區(強制轉換為 unsigned long 型別)的指標,由應用程式設定。有關詳細資訊,請參閱 流式 I/O(使用者指標)

struct v4l2_plane

*planes

使用多平面 API 時,包含指向 struct v4l2_plane 陣列的使用者空間指標。陣列的大小應放在此 struct v4l2_buffer 結構的 length 欄位中。

int

fd

對於單平面 API,並且當 memoryV4L2_MEMORY_DMABUF 時,這是與 DMABUF 緩衝區關聯的檔案描述符。

}

__u32

length

單平面 API 的緩衝區大小(不是有效負載),以位元組為單位。這是由驅動程式根據對 ioctl VIDIOC_REQBUFS 和/或 ioctl VIDIOC_CREATE_BUFS 的呼叫設定的。對於多平面 API,應用程式將其設定為 planes 陣列中的元素數。驅動程式將填寫該陣列中有效元素的實際數量。

__u32

reserved2

用於將來擴充套件的佔位符。驅動程式和應用程式必須將其設定為 0。

__u32

request_fd

要將緩衝區排隊到的請求的檔案描述符。如果設定了標誌 V4L2_BUF_FLAG_REQUEST_FD,則會將緩衝區排隊到此請求。如果未設定該標誌,則將忽略此欄位。

V4L2_BUF_FLAG_REQUEST_FD 標誌和此欄位僅由 ioctl VIDIOC_QBUF 使用,並且被其他將 v4l2_buffer 作為引數的 ioctl 忽略。

對於除 VIDIOC_QBUF 之外的任何 ioctl,應用程式不應設定 V4L2_BUF_FLAG_REQUEST_FD

如果裝置不支援請求,則將返回 EBADR。如果支援請求但給出了無效的請求檔案描述符,則將返回 EINVAL

型別 v4l2_plane

3.5.3. struct v4l2_plane

__u32

bytesused

平面中資料佔用的位元組數(其有效負載)。當 type 指的是捕獲流時,驅動程式必須設定此欄位;當它指的是輸出流時,應用程式必須設定此欄位。

注意

請注意,實際影像資料從 data_offset 開始,它可能不是 0。

__u32

length

平面(而非其有效負載)的大小,以位元組為單位。 該值由驅動程式根據對 ioctl VIDIOC_REQBUFS 和/或 ioctl VIDIOC_CREATE_BUFS 的呼叫進行設定。

union {

m

__u32

mem_offset

當包含的結構體 v4l2_buffer 中的記憶體型別為 V4L2_MEMORY_MMAP 時,該值應傳遞給 mmap(),類似於結構體 v4l2_buffer 中的 offset 欄位。

unsigned long

userptr

當包含的結構體 v4l2_buffer 中的記憶體型別為 V4L2_MEMORY_USERPTR 時,這是一個使用者空間指標,指向應用程式為此平面分配的記憶體。

int

fd

當包含的結構體 v4l2_buffer 中的記憶體型別為 V4L2_MEMORY_DMABUF 時,這是一個與 DMABUF 緩衝區關聯的檔案描述符,類似於結構體 v4l2_buffer 中的 fd 欄位。

}

__u32

data_offset

平面中影片資料的偏移量(以位元組為單位)。 當 type 指的是捕獲流時,驅動程式必須設定此欄位;當指的是輸出流時,應用程式必須設定此欄位。

注意

該 data_offset 包含在 bytesused 中。因此,平面中影像的大小為 bytesused-data_offset,偏移量為從平面開始的 data_offset

__u32

reserved[11]

保留供將來使用。 驅動程式和應用程式應將其歸零。

type v4l2_buf_type

3.5.4. enum v4l2_buf_type

V4L2_BUF_TYPE_VIDEO_CAPTURE

1

單平面影片捕獲流的緩衝區,請參閱 影片捕獲介面

V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE

9

多平面影片捕獲流的緩衝區,請參閱 影片捕獲介面

V4L2_BUF_TYPE_VIDEO_OUTPUT

2

單平面影片輸出流的緩衝區,請參閱 影片輸出介面

V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE

10

多平面影片輸出流的緩衝區,請參閱 影片輸出介面

V4L2_BUF_TYPE_VIDEO_OVERLAY

3

影片覆蓋的緩衝區,請參閱 影片覆蓋介面

V4L2_BUF_TYPE_VBI_CAPTURE

4

原始 VBI 捕獲流的緩衝區,請參閱 原始 VBI 資料介面

V4L2_BUF_TYPE_VBI_OUTPUT

5

原始 VBI 輸出流的緩衝區,請參閱 原始 VBI 資料介面

V4L2_BUF_TYPE_SLICED_VBI_CAPTURE

6

切片 VBI 捕獲流的緩衝區,請參閱 切片 VBI 資料介面

V4L2_BUF_TYPE_SLICED_VBI_OUTPUT

7

切片 VBI 輸出流的緩衝區,請參閱 切片 VBI 資料介面

V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY

8

影片輸出覆蓋 (OSD) 的緩衝區,請參閱 影片輸出覆蓋介面

V4L2_BUF_TYPE_SDR_CAPTURE

11

軟體定義無線電 (SDR) 捕獲流的緩衝區,請參閱 軟體定義無線電介面 (SDR)

V4L2_BUF_TYPE_SDR_OUTPUT

12

軟體定義無線電 (SDR) 輸出流的緩衝區,請參閱 軟體定義無線電介面 (SDR)

V4L2_BUF_TYPE_META_CAPTURE

13

元資料捕獲的緩衝區,請參閱 元資料介面

V4L2_BUF_TYPE_META_OUTPUT

14

元資料輸出的緩衝區,請參閱 元資料介面

3.5.5. 緩衝區標誌

V4L2_BUF_FLAG_MAPPED

0x00000001

該緩衝區位於裝置記憶體中,並且已對映到應用程式的地址空間中,有關詳細資訊,請參閱 流式 I/O (記憶體對映)。 呼叫 ioctl VIDIOC_QUERYBUFioctl VIDIOC_QBUF, VIDIOC_DQBUFVIDIOC_DQBUF ioctl 時,驅動程式會設定或清除此標誌。 由驅動程式設定。

V4L2_BUF_FLAG_QUEUED

0x00000002

在內部,驅動程式維護兩個緩衝區佇列,一個傳入佇列和一個傳出佇列。 設定此標誌後,該緩衝區當前位於傳入佇列中。緩衝區填充(捕獲裝置)或顯示(輸出裝置)後,它會自動移至傳出佇列。 呼叫 VIDIOC_QUERYBUF ioctl 時,驅動程式會設定或清除此標誌。 在(成功)呼叫 VIDIOC_QBUFioctl 之後,它始終設定為已設定,並在 VIDIOC_DQBUF 之後始終清除。

V4L2_BUF_FLAG_DONE

0x00000004

設定此標誌後,該緩衝區當前位於傳出佇列中,可以從驅動程式中出隊。 呼叫 VIDIOC_QUERYBUF ioctl 時,驅動程式會設定或清除此標誌。 呼叫 VIDIOC_QBUFVIDIOC_DQBUF 之後,它始終會被清除。 當然,一個緩衝區不能同時位於兩個佇列中,V4L2_BUF_FLAG_QUEUEDV4L2_BUF_FLAG_DONE 標誌是互斥的。 但是,它們可以都被清除,那麼該緩衝區將處於“已出隊”狀態,也就是說,它位於應用程式域中。

V4L2_BUF_FLAG_ERROR

0x00000040

設定此標誌後,緩衝區已成功出隊,但資料可能已損壞。 這是可恢復的,流式傳輸可以像往常一樣繼續,並且可以正常重複使用該緩衝區。 呼叫 VIDIOC_DQBUF ioctl 時,驅動程式會設定此標誌。

V4L2_BUF_FLAG_IN_REQUEST

0x00000080

此緩衝區是尚未排隊的請求的一部分。

V4L2_BUF_FLAG_KEYFRAME

0x00000008

呼叫 VIDIOC_DQBUF ioctl 時,驅動程式會設定或清除此標誌。 當緩衝區包含壓縮影像時,影片捕獲裝置可能會設定該標誌,該壓縮影像是一個關鍵幀(或欄位),即可自行解壓縮。 也稱為 I 幀。 當 type 指的是輸出流時,應用程式可以設定此位。

V4L2_BUF_FLAG_PFRAME

0x00000010

V4L2_BUF_FLAG_KEYFRAME 類似,此標誌預測幀或欄位,其中僅包含與先前關鍵幀的差異。 當 type 指的是輸出流時,應用程式可以設定此位。

V4L2_BUF_FLAG_BFRAME

0x00000020

V4L2_BUF_FLAG_KEYFRAME 類似,此標誌一個雙向預測幀或欄位,其中僅包含當前幀與前面和後面的關鍵幀之間的差異,以指定其內容。 當 type 指的是輸出流時,應用程式可以設定此位。

V4L2_BUF_FLAG_TIMECODE

0x00000100

timecode 欄位有效。 呼叫 VIDIOC_DQBUF ioctl 時,驅動程式會設定或清除此標誌。 當 type 指的是輸出流時,應用程式可以設定此位和相應的 timecode 結構。

V4L2_BUF_FLAG_PREPARED

0x00000400

該緩衝區已準備好進行 I/O,並且可以由應用程式排隊。 呼叫 VIDIOC_QUERYBUFVIDIOC_PREPARE_BUFVIDIOC_QBUFVIDIOC_DQBUF ioctl 時,驅動程式會設定或清除此標誌。

V4L2_BUF_FLAG_NO_CACHE_INVALIDATE

0x00000800

不必使此緩衝區的快取失效。 通常,如果 CPU 不會接觸緩衝區中捕獲的資料,則應用程式應使用此標誌,相反,可能會將緩衝區傳遞給支援 DMA 的硬體單元以進行進一步處理或輸出。 除非佇列用於 記憶體對映 流式 I/O 並報告 V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS 功能,否則將忽略此標誌。

V4L2_BUF_FLAG_NO_CACHE_CLEAN

0x00001000

不必為此緩衝區清理快取。 通常,如果此緩衝區中的資料不是由 CPU 建立而是由某些支援 DMA 的單元建立的,在這種情況下未使用快取,則應用程式應將此標誌用於輸出緩衝區。 除非佇列用於 記憶體對映 流式 I/O 並報告 V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS 功能,否則將忽略此標誌。

V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF

0x00000200

僅當設定了結構體 v4l2_requestbuffers 標誌 V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF 時才有效。 它通常與無狀態解碼器一起使用,其中多個輸出緩衝區各自解碼為解碼幀的一部分。 應用程式可以在對輸出緩衝區進行排隊時設定此標誌,以防止驅動程式在解碼輸出緩衝區之後對捕獲緩衝區進行出隊(即,捕獲緩衝區是“保留的”)。 如果此輸出緩衝區的時間戳與前一個輸出緩衝區的時間戳不同,則表示新幀的開始,並且先前保留的捕獲緩衝區將出隊。

V4L2_BUF_FLAG_LAST

0x00100000

硬體生成的最後一個緩衝區。 當呼叫 ioctl VIDIOC_QUERYBUFVIDIOC_DQBUF ioctl 時,mem2mem 編解碼器驅動程式會在捕獲佇列上設定此標誌。 由於硬體限制,最後一個緩衝區可能為空。 在這種情況下,無論格式如何,驅動程式都會將 bytesused 欄位設定為 0。 隨後對 VIDIOC_DQBUF ioctl 的任何呼叫都不會再阻塞,而是返回 EPIPE 錯誤程式碼。

V4L2_BUF_FLAG_REQUEST_FD

0x00800000

request_fd 欄位包含有效的檔案描述符。

V4L2_BUF_FLAG_TIMESTAMP_MASK

0x0000e000

用於以下時間戳型別的掩碼。 要測試時間戳型別,請透過對緩衝區標誌和時間戳掩碼執行邏輯與運算來遮蔽掉不屬於時間戳型別的位。

V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN

0x00000000

未知時間戳型別。 Linux 3.9 之前的驅動程式使用此型別,並且它可能是單調的(請參見下文)或即時的(掛鐘時間)。 單調時鐘在嵌入式系統中很受歡迎,而大多數驅動程式都使用即時時鐘。 兩種型別的時間戳都可透過使用時鐘 ID CLOCK_MONOTONICCLOCK_REALTIMEclock_gettime() 在使用者空間中使用。

V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC

0x00002000

緩衝區時間戳取自 CLOCK_MONOTONIC 時鐘。 要在 V4L2 之外訪問同一時鐘,請使用 clock_gettime()

V4L2_BUF_FLAG_TIMESTAMP_COPY

0x00004000

CAPTURE 緩衝區時間戳取自相應的 OUTPUT 緩衝區。 此標誌僅適用於 mem2mem 裝置。

V4L2_BUF_FLAG_TSTAMP_SRC_MASK

0x00070000

用於以下時間戳源的掩碼。 時間戳源定義了時間戳相對於幀的獲取時間點。 flags 欄位與 V4L2_BUF_FLAG_TSTAMP_SRC_MASK 之間的邏輯“與”運算會生成時間戳源的值。 當 type 指的是輸出流並且設定了 V4L2_BUF_FLAG_TIMESTAMP_COPY 時,應用程式必須設定時間戳源。

V4L2_BUF_FLAG_TSTAMP_SRC_EOF

0x00000000

幀結束。 當接收到幀的最後一個畫素或已傳輸幀的最後一個畫素時,將獲取緩衝區時間戳。 實際上,軟體生成的時間戳通常會在接收或傳輸最後一個畫素之後的一小段時間內從時鐘讀取,具體取決於系統及其中的其他活動。

V4L2_BUF_FLAG_TSTAMP_SRC_SOE

0x00010000

曝光開始。 緩衝區時間戳是在幀的曝光開始時獲取的。 這僅對 V4L2_BUF_TYPE_VIDEO_CAPTURE 緩衝區型別有效。

3.5.6. enum v4l2_memory

V4L2_MEMORY_MMAP

1

該緩衝區用於 記憶體對映 I/O。

V4L2_MEMORY_USERPTR

2

該緩衝區用於 使用者指標 I/O。

V4L2_MEMORY_OVERLAY

3

[待辦]

V4L2_MEMORY_DMABUF

4

該緩衝區用於 DMA 共享緩衝區 I/O。

3.5.7. 時間碼

v4l2_buffer_timecode 結構旨在儲存 SMPTE 12M 或類似的時間碼。(timeval 時間戳儲存在結構 v4l2_buffer timestamp 欄位中。)

type v4l2_timecode

3.5.7.1. struct v4l2_timecode

__u32

type

時間碼基於的幀速率,請參閱 時間碼型別

__u32

flags

時間碼標誌,請參閱 時間碼標誌

__u8

frames

幀計數,0 ... 23/24/29/49/59,具體取決於時間碼的型別。

__u8

seconds

秒數,0 ... 59。這是一個二進位制數,而不是 BCD 數字。

__u8

minutes

分鐘數,0 ... 59。這是一個二進位制數,而不是 BCD 數字。

__u8

hours

小時數,0 ... 29。這是一個二進位制數,而不是 BCD 數字。

__u8

userbits[4]

時間碼中的“使用者組”位。

3.5.7.2. 時間碼型別

V4L2_TC_TYPE_24FPS

1

每秒 24 幀,即電影。

V4L2_TC_TYPE_25FPS

2

每秒 25 幀,即 PAL 或 SECAM 影片。

V4L2_TC_TYPE_30FPS

3

每秒 30 幀,即 NTSC 影片。

V4L2_TC_TYPE_50FPS

4

V4L2_TC_TYPE_60FPS

5

3.5.7.3. 時間碼標誌

V4L2_TC_FLAG_DROPFRAME

0x0001

表示 29.97 fps 素材中用於計算幀的“丟幀”語義。 設定後,從每分鐘開始,從計數中省略幀號 0 和 1,但 0、10、20、30、40、50 分鐘除外。

V4L2_TC_FLAG_COLORFRAME

0x0002

“彩色幀”標誌。

V4L2_TC_USERBITS_field

0x000C

“二進位制組標誌”的欄位掩碼。

V4L2_TC_USERBITS_USERDEFINED

0x0000

未指定的格式。

V4L2_TC_USERBITS_8BITCHARS

0x0008

8 位 ISO 字元。