2.4. 影片裝置的內部表示

/dev 目錄中的實際裝置節點是使用 video_device 結構體 (v4l2-dev.h) 建立的。此結構體可以動態分配或嵌入到更大的結構體中。

要動態分配它,請使用 video_device_alloc()

struct video_device *vdev = video_device_alloc();

if (vdev == NULL)
        return -ENOMEM;

vdev->release = video_device_release;

如果將其嵌入到更大的結構體中,則必須將 release() 回撥設定為您自己的函式

struct video_device *vdev = &my_vdev->vdev;

vdev->release = my_vdev_release;

必須設定 release() 回撥,並且當影片裝置的最後一個使用者退出時會呼叫它。

預設的 video_device_release() 回撥目前只是呼叫 kfree 來釋放已分配的記憶體。

還有一個 video_device_release_empty() 函式,它不執行任何操作(為空),如果該結構體是嵌入式的,並且在釋放時無需執行任何操作,則應使用該函式。

您還應該設定 video_device 的以下欄位

  • video_device->v4l2_dev:必須設定為 v4l2_device 父裝置。

  • video_device->name:設定為具有描述性且唯一的內容。

  • video_device->vfl_dir:對於捕獲裝置,請將其設定為 VFL_DIR_RXVFL_DIR_RX 的值為 0,因此通常已經是預設值),對於輸出裝置,請設定為 VFL_DIR_TX,對於 mem2mem(編解碼器)裝置,請設定為 VFL_DIR_M2M

  • video_device->fops:設定為 v4l2_file_operations 結構體。

  • video_device->ioctl_ops:如果您使用 v4l2_ioctl_ops 來簡化 ioctl 維護(強烈建議使用此方法,並且將來可能會強制使用!),則將其設定為您的 v4l2_ioctl_ops 結構體。video_device->vfl_type 和 video_device->vfl_dir 欄位用於停用不匹配型別/dir 組合的操作。例如,VBI 操作對非 VBI 節點停用,輸出操作對捕獲裝置停用。這使得為 vbi 和影片節點提供一個 v4l2_ioctl_ops 結構體成為可能。

  • video_device->lock:如果您想在驅動程式中執行所有鎖定,則將其保留為 NULL。否則,您可以提供指向 mutex_lock 結構體的指標,並且在呼叫 video_device->unlocked_ioctl 檔案操作之前,核心會獲取此鎖並在之後釋放。有關更多詳細資訊,請參見下一節。

  • video_device->queue:指向與此裝置節點關聯的 struct vb2_queue 的指標。如果 queue 不是 NULL,並且 queue->lock 不是 NULL,則 queue->lock 用於排隊 ioctl(VIDIOC_REQBUFSCREATE_BUFSQBUFDQBUFQUERYBUFPREPARE_BUFSTREAMONSTREAMOFF),而不是上面的鎖。這樣,vb2 排隊框架不必等待其他 ioctl。此佇列指標還被 vb2 輔助函式用於檢查排隊所有權(即,是否允許呼叫它的檔案控制代碼執行該操作)。

  • video_device->prio:跟蹤優先順序。用於實現 VIDIOC_G_PRIORITYVIDIOC_S_PRIORITY。如果將其保留為 NULL,則它將使用 struct v4l2_prio_state 中的 v4l2_device。如果您想為每個(組)裝置節點擁有單獨的優先順序狀態,則可以將其指向您自己的 v4l2_prio_state 結構體。

  • video_device->dev_parent:僅當 v4l2_device 註冊時使用 NULL 作為父 device 結構體時才設定此項。這種情況僅發生在單個硬體裝置具有多個 PCI 裝置,它們都共享相同的 v4l2_device 核心時。

    cx88 驅動程式是這種情況的一個示例:一個核心 v4l2_device 結構體,但它被原始影片 PCI 裝置 (cx8800) 和 MPEG PCI 裝置 (cx8802) 使用。由於 v4l2_device 不能同時與兩個 PCI 裝置關聯,因此在沒有父裝置的情況下進行設定。但是,當初始化 struct video_device 時,您確實知道要使用哪個父 PCI 裝置,因此您可以將 dev_device 設定為正確的 PCI 裝置。

如果您使用 v4l2_ioctl_ops,則應將 video_device->unlocked_ioctl 設定為 video_ioctl2() 在您的 v4l2_file_operations 結構體中。

在某些情況下,您希望告訴核心您在 v4l2_ioctl_ops 中指定的函式應被忽略。您可以透過在呼叫 video_register_device() 之前呼叫此函式來標記此類 ioctl

如果根據外部因素(例如,正在使用的卡)您想關閉 v4l2_ioctl_ops 中的某些功能,而無需建立新的結構體,則通常需要這樣做。

v4l2_file_operations 結構體是 file_operations 的子集。主要區別在於 inode 引數被省略,因為它從未使用過。

如果需要與媒體框架整合,則必須透過呼叫 media_entity_pads_init() 初始化嵌入在 video_device 結構體(實體欄位)中的 media_entity 結構體

struct media_pad *pad = &my_vdev->pad;
int err;

err = media_entity_pads_init(&vdev->entity, 1, pad);

之前必須已初始化 pads 陣列。無需手動設定 struct media_entity 型別和名稱欄位。

當影片裝置開啟/關閉時,將自動獲取/釋放對該實體的引用。

2.4.1. ioctls 和鎖定

V4L 核心提供可選的鎖定服務。主要服務是 struct video_device 中的 lock 欄位,它是指向互斥量的指標。如果您設定此指標,則 unlocked_ioctl 將使用它來序列化所有 ioctl。

如果您正在使用 videobuf2 框架,則可以設定第二個鎖:video_device->queue->lock。如果設定,則此鎖將用於代替 video_device->lock 來序列化所有排隊 ioctl(有關這些 ioctl 的完整列表,請參見上一節)。

為排隊 ioctl 使用不同鎖的優點是,對於某些驅動程式(尤其是 USB 驅動程式),某些命令(例如設定控制元件)可能需要很長時間,因此您想為緩衝區排隊 ioctl 使用單獨的鎖。這樣,您的 VIDIOC_DQBUF 不會因為驅動程式忙於更改例如網路攝像頭的曝光而停頓。

當然,您始終可以透過將兩個鎖指標都保留為 NULL 來自己完成所有鎖定。

對於 videobuf2,如果適用,您將需要實現 wait_prepare()wait_finish() 回撥來解鎖/鎖定。如果您使用 queue->lock 指標,則可以使用輔助函式 vb2_ops_wait_prepare()vb2_ops_wait_finish()

熱插拔斷開的實現也應在呼叫 v4l2_device_disconnect 之前從 video_device 獲取鎖。如果您還使用 video_device->queue->lock,則必須首先鎖定 video_device->queue->lock,然後鎖定 video_device->lock。這樣,您可以確保在呼叫 v4l2_device_disconnect() 時沒有 ioctl 正在執行。

2.4.2. 影片設備註冊

接下來,使用 video_register_device() 註冊影片裝置。這將為您建立字元裝置。

err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
if (err) {
        video_device_release(vdev); /* or kfree(my_vdev); */
        return err;
}

如果 v4l2_device 父裝置具有非 NULL mdev 欄位,則影片裝置實體將自動在媒體裝置中註冊。

註冊哪個裝置取決於型別引數。存在以下型別

vfl_devnode_type

裝置名稱

用法

VFL_TYPE_VIDEO

/dev/videoX

用於影片輸入/輸出裝置

VFL_TYPE_VBI

/dev/vbiX

用於垂直消隱資料(即隱藏字幕、圖文電視)

VFL_TYPE_RADIO

/dev/radioX

用於無線電調諧器

VFL_TYPE_SUBDEV

/dev/v4l-subdevX

用於 V4L2 子裝置

VFL_TYPE_SDR

/dev/swradioX

用於軟體定義無線電 (SDR) 調諧器

VFL_TYPE_TOUCH

/dev/v4l-touchX

用於觸控感測器

最後一個引數使您可以一定程度地控制使用的裝置節點編號(即 videoX 中的 X)。通常,您會傳遞 -1 以便 v4l2 框架選擇第一個可用編號。但有時使用者想要選擇特定的節點編號。驅動程式通常允許使用者透過驅動程式模組選項選擇特定的裝置節點編號。然後將該編號傳遞給此函式,並且 video_register_device 將嘗試選擇該裝置節點編號。如果該編號已被使用,則將選擇下一個可用的裝置節點編號,並且它會向核心日誌傳送警告。

另一個用例是,如果驅動程式建立了許多裝置。在這種情況下,將不同的影片裝置放置在單獨的範圍內可能很有用。例如,影片捕獲裝置從 0 開始,影片輸出裝置從 16 開始。因此,您可以使用最後一個引數指定最小裝置節點編號,並且 v4l2 框架將嘗試選擇等於或高於您傳遞的第一個可用編號。如果失敗,它將只選擇第一個可用編號。

由於在這種情況下,您不關心有關無法選擇指定裝置節點編號的警告,因此您可以呼叫函式 video_register_device_no_warn() 代替。

每當建立裝置節點時,還會為您建立一些屬性。如果您檢視 /sys/class/video4linux,您會看到這些裝置。進入例如 video0,您將看到 'name'、'dev_debug' 和 'index' 屬性。'name' 屬性是 video_device 結構體的 'name' 欄位。'dev_debug' 屬性可用於啟用核心除錯。有關此方面的更多詳細資訊,請參見下一節。

'index' 屬性是裝置節點的索引:對於每次呼叫 video_register_device(),索引僅增加 1。您註冊的第一個影片裝置節點始終以索引 0 開始。

使用者可以設定利用 index 屬性的 udev 規則來建立奇特的裝置名稱(例如,用於 MPEG 影片捕獲裝置節點的 'mpegX')。

成功註冊裝置後,您可以使用以下欄位

如果註冊失敗,則需要呼叫 video_device_release() 以釋放已分配的 video_device 結構體,或者釋放您自己的結構體(如果 video_device 嵌入其中)。如果註冊失敗,則永遠不會呼叫 vdev->release() 回撥,也不應嘗試在註冊失敗時取消註冊裝置。

2.4.3. 影片裝置除錯

/sys/class/video4linux/<devX>/ 中的每個影片、vbi、無線電或 swradio 裝置建立的 'dev_debug' 屬性允許您啟用檔案操作的日誌記錄。

它是一個位掩碼,可以設定以下位

掩碼

描述

0x01

記錄 ioctl 名稱和錯誤程式碼。僅當同時設定了位 0x08 時,才會記錄 VIDIOC_(D)QBUF ioctl。

0x02

記錄 ioctl 名稱引數和錯誤程式碼。僅當同時設定了位 0x08 時,才會記錄 VIDIOC_(D)QBUF ioctl。

0x04

記錄檔案操作 open、release、read、write、mmap 和 get_unmapped_area。僅當同時設定了位 0x08 時,才會記錄讀寫操作。

0x08

記錄讀寫檔案操作以及 VIDIOC_QBUF 和 VIDIOC_DQBUF ioctl。

0x10

記錄 poll 檔案操作。

0x20

記錄控制操作中的錯誤和訊息。

2.4.4. 影片裝置清理

當必須刪除影片裝置節點時(在解除安裝驅動程式期間或由於 USB 裝置斷開連線時),應使用以下命令取消註冊它們

這將從 sysfs 中刪除裝置節點(導致 udev 將它們從 /dev 中刪除)。

video_unregister_device() 返回後,無法執行任何新的開啟操作。但是,對於 USB 裝置,某些應用程式可能仍然打開了其中一個裝置節點。因此,在取消註冊後,所有檔案操作(當然,除了 release 之外)也將返回錯誤。

當影片裝置節點的最後一個使用者退出時,將呼叫 vdev->release() 回撥,您可以在此處執行最終清理。

如果已初始化,請不要忘記清理與影片裝置關聯的媒體實體

media_entity_cleanup (&vdev->entity);

這可以從 release 回撥中完成。

2.4.5. 輔助函式

有一些有用的輔助函式

您可以使用以下命令在 video_device 結構體中設定/獲取驅動程式私有資料

請注意,您可以安全地在呼叫 video_register_device() 之前呼叫 video_set_drvdata()

還有這個函式

返回屬於檔案結構體的 video_device。

video_devdata() 函式將 video_get_drvdata()video_devdata() 結合在一起

您可以使用以下命令從 video_device 結構體轉到 v4l2_device 結構體

struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
  • 裝置節點名稱

可以使用以下命令檢索 video_device 節點核心名稱

該名稱被使用者空間工具(例如 udev)用作提示。在可能的情況下,應使用該函式,而不是訪問 video_device::num 和 video_device::minor 欄位。

2.4.6. video_device 函式和資料結構

enum vfl_devnode_type

V4L2 裝置節點的型別

常量

VFL_TYPE_VIDEO

用於影片輸入/輸出裝置

VFL_TYPE_VBI

用於垂直消隱資料(即隱藏字幕、圖文電視)

VFL_TYPE_RADIO

用於無線電調諧器

VFL_TYPE_SUBDEV

用於 V4L2 子裝置

VFL_TYPE_SDR

用於軟體定義無線電調諧器

VFL_TYPE_TOUCH

用於觸控感測器

VFL_TYPE_MAX

VFL 型別的數量,必須始終在列舉中排在最後

enum vfl_devnode_direction

標識 struct video_device 是否對應於接收器、發射器或記憶體到記憶體裝置。

常量

VFL_DIR_RX

裝置是接收器。

VFL_DIR_TX

裝置是發射器。

VFL_DIR_M2M

裝置是記憶體到記憶體裝置。

注意

如果 enum vfl_devnode_typeVFL_TYPE_SUBDEV,則忽略。

enum v4l2_video_device_flags

struct video_device 使用的標誌

常量

V4L2_FL_REGISTERED

指示 struct video_device 已註冊。如果驅動程式想要阻止所有未來的裝置訪問,則可以清除此標誌。它由 video_unregister_device 清除。

V4L2_FL_USES_V4L2_FH

指示 file->private_data 指向 struct v4l2_fh。當呼叫 v4l2_fh_init() 時,核心會設定此標誌。所有新驅動程式都應使用它。

V4L2_FL_QUIRK_INVERTED_CROP

一些舊的 M2M 驅動程式不正確地使用了 g/s_crop/cropcap:crop 和 compose 互換了。如果設定了這個標誌,那麼選擇目標將在 v4l2-ioctl.c 中的 g/s_crop/cropcap 函式中互換。這允許這些驅動程式正確地實現選擇 API,但是舊的 crop API 仍然可以按預期工作,以保持向後相容性。永遠不要為新的驅動程式設定此標誌。

V4L2_FL_SUBDEV_RO_DEVNODE

表示影片裝置節點以只讀模式註冊。該標誌僅適用於為子設備註冊的裝置節點,當子裝置節點透過 v4l2_device_register_ro_subdev_nodes() 註冊時由核心設定,並由子裝置 ioctl 處理程式使用以限制對某些 ioctl 呼叫的訪問。

struct v4l2_prio_state

儲存優先順序狀態

定義:

struct v4l2_prio_state {
    atomic_t prios[4];
};

成員

prios

帶有元素的陣列,用於儲存陣列優先順序

描述

注意

prios 陣列的大小與列舉 v4l2_priority 定義的優先順序型別數量匹配。

void v4l2_prio_init(struct v4l2_prio_state *global)

初始化一個 struct v4l2_prio_state

引數

struct v4l2_prio_state *global

指向 struct v4l2_prio_state 的指標

int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, enum v4l2_priority new)

更改 v4l2 檔案控制代碼優先順序

引數

struct v4l2_prio_state *global

指向裝置節點的 struct v4l2_prio_state 的指標。

enum v4l2_priority *local

指向期望的優先順序的指標,如列舉 v4l2_priority 定義的那樣

enum v4l2_priority new

請求的優先順序型別,如列舉 v4l2_priority 定義的那樣。

描述

注意

此函式應僅由 V4L2 核心使用。

void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)

為檔案控制代碼開啟實現優先順序邏輯

引數

struct v4l2_prio_state *global

指向裝置節點的 struct v4l2_prio_state 的指標。

enum v4l2_priority *local

指向期望的優先順序的指標,如列舉 v4l2_priority 定義的那樣

描述

注意

此函式應僅由 V4L2 核心使用。

void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)

為檔案控制代碼關閉實現優先順序邏輯

引數

struct v4l2_prio_state *global

指向裝置節點的 struct v4l2_prio_state 的指標。

enum v4l2_priority local

要釋放的優先順序,如列舉 v4l2_priority 定義的那樣

描述

注意

此函式應僅由 V4L2 核心使用。

enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)

返回最大優先順序,如儲存在 global 陣列中的那樣。

引數

struct v4l2_prio_state *global

指向裝置節點的 struct v4l2_prio_state 的指標。

描述

注意

此函式應僅由 V4L2 核心使用。

int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)

為檔案控制代碼關閉實現優先順序邏輯

引數

struct v4l2_prio_state *global

指向裝置節點的 struct v4l2_prio_state 的指標。

enum v4l2_priority local

期望的優先順序,如列舉 v4l2_priority local 定義的那樣

描述

注意

此函式應僅由 V4L2 核心使用。

struct v4l2_file_operations

V4L2 裝置使用的 fs 操作

定義:

struct v4l2_file_operations {
    struct module *owner;
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    __poll_t (*poll) (struct file *, struct poll_table_struct *);
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT;
    long (*compat_ioctl32) (struct file *, unsigned int, unsigned long);
#endif;
    unsigned long (*get_unmapped_area) (struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    int (*mmap) (struct file *, struct vm_area_struct *);
    int (*open) (struct file *);
    int (*release) (struct file *);
};

成員

owner

指向 struct module 的指標

read

實現 read() 系統呼叫所需的操作

write

實現 write() 系統呼叫所需的操作

poll

實現 poll() 系統呼叫所需的操作

unlocked_ioctl

實現 ioctl() 系統呼叫所需的操作

compat_ioctl32

在核心使用 64 位指令,但使用者空間使用 32 位的情況下實現 ioctl() 系統呼叫所需的操作。

get_unmapped_area

由 mmap() 系統呼叫呼叫,在 %!CONFIG_MMU 時使用

mmap

實現 mmap() 系統呼叫所需的操作

open

實現 open() 系統呼叫所需的操作

release

實現 release() 系統呼叫所需的操作

描述

注意

這些操作用於在 V4L2 驅動程式中實現 fs struct file_operations。V4L2 核心使用子系統所需的一些額外邏輯覆蓋 fs ops。

struct video_device

用於建立和管理 V4L2 裝置節點的結構。

定義:

struct video_device {
#if defined(CONFIG_MEDIA_CONTROLLER);
    struct media_entity entity;
    struct media_intf_devnode *intf_devnode;
    struct media_pipeline pipe;
#endif;
    const struct v4l2_file_operations *fops;
    u32 device_caps;
    struct device dev;
    struct cdev *cdev;
    struct v4l2_device *v4l2_dev;
    struct device *dev_parent;
    struct v4l2_ctrl_handler *ctrl_handler;
    struct vb2_queue *queue;
    struct v4l2_prio_state *prio;
    char name[64];
    enum vfl_devnode_type vfl_type;
    enum vfl_devnode_direction vfl_dir;
    int minor;
    u16 num;
    unsigned long flags;
    int index;
    spinlock_t fh_lock;
    struct list_head        fh_list;
    int dev_debug;
    v4l2_std_id tvnorms;
    void (*release)(struct video_device *vdev);
    const struct v4l2_ioctl_ops *ioctl_ops;
    unsigned long valid_ioctls[BITS_TO_LONGS(BASE_VIDIOC_PRIVATE)];
    struct mutex *lock;
};

成員

entity

struct media_entity

intf_devnode

指向 struct media_intf_devnode 的指標

pipe

struct media_pipeline

fops

指向影片裝置的 struct v4l2_file_operations 的指標

device_caps

在 v4l2_capabilities 中使用的裝置功能

dev

影片裝置的 struct device

cdev

字元裝置

v4l2_dev

指向 struct v4l2_device 父級的指標

dev_parent

指向 struct device 父級的指標

ctrl_handler

與此裝置節點關聯的控制元件處理程式。可以為 NULL。

queue

與此裝置節點關聯的 struct vb2_queue。可以為 NULL。

prio

指向帶有裝置優先順序狀態的 struct v4l2_prio_state 的指標。如果為 NULL,則將使用 v4l2_dev->prio。

name

影片裝置名稱

vfl_type

V4L 裝置型別,如 enum vfl_devnode_type 定義的那樣

vfl_dir

V4L 接收器、發射器或 m2m

minor

裝置節點“次裝置號”。如果註冊失敗,則設定為 -1

num

影片裝置節點的編號

flags

影片裝置標誌。使用位操作來設定/清除/測試標誌。包含一組 enum v4l2_video_device_flags

index

用於區分一個物理裝置上的多個索引的屬性

fh_lock

所有 v4l2_fhs 的鎖

fh_list

struct v4l2_fh 列表

dev_debug

內部裝置除錯標誌,不供驅動程式使用

tvnorms

支援的電視制式

release

影片裝置 release() 回撥

ioctl_ops

指向帶有 ioctl 回撥的 struct v4l2_ioctl_ops 的指標

valid_ioctls

包含此裝置的有效 ioctl 的點陣圖

lock

指向 struct mutex 序列化鎖的指標

描述

注意

僅當無法從 v4l2_dev 推斷出 dev_parent 時才設定。

media_entity_to_video_device

media_entity_to_video_device (__entity)

從嵌入的 struct media_entity 返回一個 struct video_device

引數

__entity

指向 struct media_entity 的指標

to_video_device

to_video_device (cd)

從嵌入的 struct device 返回一個 struct video_device

引數

cd

指向 struct device 的指標

int __video_register_device(struct video_device *vdev, enum vfl_devnode_type type, int nr, int warn_if_nr_in_use, struct module *owner)

註冊 video4linux 裝置

引數

struct video_device *vdev

要註冊的 struct video_device

enum vfl_devnode_type type

要註冊的裝置型別,如 enum vfl_devnode_type 定義的那樣

int nr

期望的裝置節點編號:(0 == /dev/video0, 1 == /dev/video1, ..., -1 == 第一個空閒的)

int warn_if_nr_in_use

如果期望的裝置節點編號已被使用,並且選擇了另一個編號,則發出警告。

struct module *owner

擁有影片裝置節點的模組

描述

註冊程式碼根據請求的型別分配次裝置號和裝置節點編號,並將新的裝置節點註冊到核心。

此函式假定 struct video_device 在分配時被清零,並且不包含任何過時的資料。

如果找不到空閒的次裝置號或裝置節點編號,或者裝置節點註冊失敗,則返回錯誤。

成功時返回 0。

注意

此函式旨在僅在 V4L2 核心中使用。驅動程式應使用 video_register_device()video_register_device_no_warn()

int video_register_device(struct video_device *vdev, enum vfl_devnode_type type, int nr)

註冊 video4linux 裝置

引數

struct video_device *vdev

要註冊的 struct video_device

enum vfl_devnode_type type

要註冊的裝置型別,如 enum vfl_devnode_type 定義的那樣

int nr

期望的裝置節點編號:(0 == /dev/video0, 1 == /dev/video1, ..., -1 == 第一個空閒的)

描述

在內部,它呼叫 __video_register_device()。請參閱其文件以獲取更多詳細資訊。

注意

如果 video_register_device 失敗,則不會呼叫 struct video_device 結構的 release() 回撥,因此呼叫者負責釋放任何資料。通常,這意味著您應該在失敗時呼叫 video_device_release()

int video_register_device_no_warn(struct video_device *vdev, enum vfl_devnode_type type, int nr)

註冊 video4linux 裝置

引數

struct video_device *vdev

要註冊的 struct video_device

enum vfl_devnode_type type

要註冊的裝置型別,如 enum vfl_devnode_type 定義的那樣

int nr

期望的裝置節點編號:(0 == /dev/video0, 1 == /dev/video1, ..., -1 == 第一個空閒的)

描述

此函式與 video_register_device() 相同,只是如果期望的裝置節點編號已被使用,則不會發出警告。

在內部,它呼叫 __video_register_device()。請參閱其文件以獲取更多詳細資訊。

注意

如果 video_register_device 失敗,則不會呼叫 struct video_device 結構的 release() 回撥,因此呼叫者負責釋放任何資料。通常,這意味著您應該在失敗時呼叫 video_device_release()

void video_unregister_device(struct video_device *vdev)

登出影片裝置。

引數

struct video_device *vdev

要註冊的 struct video_device

描述

如果 vdev == NULL 或如果 video_is_registered() 返回 false,則不執行任何操作。

struct video_device *video_device_alloc(void)

用於分配 struct video_device 的輔助函式

引數

void

沒有引數

描述

如果 -ENOMEM 則返回 NULL,如果成功,則返回 struct video_device

void video_device_release(struct video_device *vdev)

用於釋放 struct video_device 的輔助函式

引數

struct video_device *vdev

指向 struct video_device 的指標

描述

也可以用於 video_device->release()。

void video_device_release_empty(struct video_device *vdev)

用於實現 video_device->release() 回撥的輔助函式。

引數

struct video_device *vdev

指向 struct video_device 的指標

描述

此 release 函式不執行任何操作。

當 video_device 是一個靜態全域性結構時,應使用它。

注意

擁有靜態 video_device 在最佳情況下也是一個可疑的構造。

void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd)

標記給定的命令未實現。不應使用核心鎖定

引數

struct video_device *vdev

指向 struct video_device 的指標

unsigned int cmd

ioctl 命令

描述

此函式允許驅動程式僅提供一個 v4l2_ioctl_ops 結構,但根據實際找到的特定卡停用 ioctl。

注意

必須在 video_register_device 之前呼叫此函式。另請參閱 determine_valid_ioctls() 的註釋。

void *video_get_drvdata(struct video_device *vdev)

struct video_device 獲取私有資料。

引數

struct video_device *vdev

指向 struct video_device 的指標

描述

返回指向私有資料的指標

void video_set_drvdata(struct video_device *vdev, void *data)

struct video_device 設定私有資料。

引數

struct video_device *vdev

指向 struct video_device 的指標

void *data

私有資料指標

struct video_device *video_devdata(struct file *file)

struct file 獲取 struct video_device

引數

struct file *file

指向 struct file 的指標

void *video_drvdata(struct file *file)

使用 struct filestruct video_device 獲取私有資料。

引數

struct file *file

指向 struct file 的指標

描述

此函式結合了 video_get_drvdata()video_devdata(),因為這非常常用。

const char *video_device_node_name(struct video_device *vdev)

返回影片裝置名稱

引數

struct video_device *vdev

指向 struct video_device 的指標

描述

返回裝置名稱字串

int video_is_registered(struct video_device *vdev)

如果 struct video_device 已註冊,則返回 true。

引數

struct video_device *vdev

指向 struct video_device 的指標

struct dentry *v4l2_debugfs_root(void)

返回頂級“v4l2”debugfs 目錄的 dentry

引數

void

沒有引數

描述

如果此目錄尚不存在,則將建立它。

int video_device_pipeline_start(struct video_device *vdev, struct media_pipeline *pipe)

將管道標記為流式傳輸

引數

struct video_device *vdev

啟動影片裝置

struct media_pipeline *pipe

要分配給管道中所有實體的媒體管道。

描述

將透過啟用的連結(直接或間接)連線到給定影片裝置的所有實體標記為流式傳輸。給定的管道物件分配給管道中的每個 pad,並存儲在 media_pad pipe 欄位中。

可以巢狀對此函式的呼叫,在這種情況下,需要相同數量的 video_device_pipeline_stop() 呼叫才能停止流式傳輸。對於 video_device_pipeline_start() 的所有巢狀呼叫,管道指標必須相同。

影片裝置必須包含單個 pad。

這是 media_pipeline_start() 的一個便捷封裝。

int __video_device_pipeline_start(struct video_device *vdev, struct media_pipeline *pipe)

將管道標記為流式傳輸

引數

struct video_device *vdev

啟動影片裝置

struct media_pipeline *pipe

要分配給管道中所有實體的媒體管道。

描述

..note:: 這是 video_device_pipeline_start() 的非鎖定版本

影片裝置必須包含單個 pad。

這是 __media_pipeline_start() 的一個便捷封裝。

void video_device_pipeline_stop(struct video_device *vdev)

將管道標記為非流式傳輸

引數

struct video_device *vdev

啟動影片裝置

描述

將透過啟用的連結(直接或間接)連線到給定影片裝置的所有實體標記為非流式傳輸。media_pad pipe 欄位被重置為 NULL

如果多次呼叫 media_pipeline_start(),則需要相同數量的對該函式的呼叫才能將管道標記為非流式傳輸。

影片裝置必須包含單個 pad。

這是 media_pipeline_stop() 的一個便捷封裝。

void __video_device_pipeline_stop(struct video_device *vdev)

將管道標記為非流式傳輸

引數

struct video_device *vdev

啟動影片裝置

描述

注意

這是 media_pipeline_stop() 的非鎖定版本

影片裝置必須包含單個 pad。

這是 __media_pipeline_stop() 的一個便捷封裝。

int video_device_pipeline_alloc_start(struct video_device *vdev)

將管道標記為流式傳輸

引數

struct video_device *vdev

啟動影片裝置

描述

video_device_pipeline_alloc_start() 類似於 video_device_pipeline_start(),但該函式不是在給定的管道上工作,而是將在影片裝置已經是管道的一部分時使用現有管道,或者分配一個新的管道。

video_device_pipeline_alloc_start() 的呼叫必須與 video_device_pipeline_stop() 匹配。

struct media_pipeline *video_device_pipeline(struct video_device *vdev)

獲取影片裝置所屬的媒體管道

引數

struct video_device *vdev

影片裝置

描述

此函式返回在透過 video_device_pipeline_start() 構造管道時與影片裝置關聯的媒體管道。指標在呼叫 video_device_pipeline_stop() 之前仍然有效。

影片裝置必須包含單個 pad。

這是 media_entity_pipeline() 的一個便捷封裝。

返回

影片裝置所屬的 media_pipeline,如果影片裝置不屬於任何管道,則返回 NULL。