5. 媒體控制器裝置¶
5.1. 媒體控制器¶
媒體控制器使用者空間 API 在 媒體控制器 uAPI 書籍中進行了文件化。本文件側重於媒體框架的核心端實現。
5.1.1. 抽象媒體裝置模型¶
發現裝置內部拓撲並在執行時對其進行配置是媒體框架的目標之一。為了實現這一目標,硬體裝置被建模為稱為實體並透過墊連線的構建塊的定向圖。
實體是基本的媒體硬體構建塊。它可以對應於各種邏輯塊,例如物理硬體裝置(例如 CMOS 感測器)、邏輯硬體裝置(片上系統圖像處理管道中的構建塊)、DMA 通道或物理聯結器。
墊是連線端點,實體可以透過該端點與其他實體進行互動。由實體產生的資料(不限於影片)從實體的輸出流向一個或多個實體輸入。墊不應與晶片邊界處的物理引腳混淆。
連結是兩個墊之間的點對點定向連線,無論是在同一實體上還是在不同實體上。資料從源墊流向接收墊。
5.1.2. 媒體裝置¶
媒體裝置由 struct media_device 例項表示,該例項在 include/media/media-device.h 中定義。結構的分配由媒體裝置驅動程式處理,通常透過將 media_device 例項嵌入到更大的驅動程式特定結構中。
驅動程式透過呼叫 media_device_init() 來初始化媒體裝置例項。在初始化媒體裝置例項後,透過宏 media_device_register() 呼叫 __media_device_register() 來註冊,並透過呼叫 media_device_unregister() 來登出。初始化的媒體裝置最終必須透過呼叫 media_device_cleanup() 來清理。
請注意,不允許登出先前未註冊的媒體裝置例項,或清理先前未初始化的媒體裝置例項。
5.1.3. 實體¶
實體由 struct media_entity 例項表示,該例項在 include/media/media-entity.h 中定義。該結構通常嵌入到更高級別的結構中,例如 v4l2_subdev 或 video_device 例項,儘管驅動程式可以直接分配實體。
驅動程式透過呼叫 media_entity_pads_init() 來初始化實體墊。
驅動程式透過呼叫 media_device_register_entity() 來註冊實體到媒體裝置,並透過呼叫 media_device_unregister_entity() 來登出。
5.1.4. 介面¶
介面由 struct media_interface 例項表示,該例項在 include/media/media-entity.h 中定義。目前,僅定義了一種型別的介面:裝置節點。此類介面由 struct media_intf_devnode 表示。
驅動程式透過呼叫 media_devnode_create() 來初始化和建立裝置節點介面,並透過呼叫 media_devnode_remove() 來刪除它們。
5.1.5. 墊¶
墊由 struct media_pad 例項表示,該例項在 include/media/media-entity.h 中定義。每個實體將其墊儲存在由實體驅動程式管理的墊陣列中。驅動程式通常將該陣列嵌入到驅動程式特定的結構中。
墊由其實體及其在墊陣列中的從 0 開始的索引標識。
這兩個資訊都儲存在 struct media_pad 中,這使得 struct media_pad 指標成為儲存和傳遞連結引用的規範方式。
墊具有描述墊功能和狀態的標誌。
MEDIA_PAD_FL_SINK 指示墊支援接收資料。MEDIA_PAD_FL_SOURCE 指示墊支援源資料。
注意
對於每個墊,必須設定 MEDIA_PAD_FL_SINK 或 MEDIA_PAD_FL_SOURCE 中的一個且只有一個。
5.1.6. 連結¶
連結由 struct media_link 例項表示,該例項在 include/media/media-entity.h 中定義。有兩種型別的連結
1. 墊到墊連結:
透過其 PAD 將兩個實體關聯起來。每個實體都有一個列表,該列表指向源自或針對其任何墊的所有連結。因此,給定的連結儲存兩次,一次在源實體中,一次在目標實體中。
驅動程式透過呼叫 media_create_pad_link() 來建立墊到墊連結,並透過 media_entity_remove_links() 刪除。
2. 介面到實體連結:
將一個介面與一個連結關聯起來。
驅動程式透過呼叫 media_create_intf_link() 來建立介面到實體連結,並透過 media_remove_intf_links() 刪除。
注意
只有在兩個端點都已建立後才能建立連結。
連結具有描述連結功能和狀態的標誌。有效值在 media_create_pad_link() 和 media_create_intf_link() 中進行了描述。
5.1.7. 圖遍歷¶
媒體框架提供 API 來遍歷媒體圖,定位連線的實體和連結。
要迭代屬於媒體裝置的所有實體,驅動程式可以使用媒體裝置 for_each_entity 宏,該宏在 include/media/media-device.h 中定義。
struct media_entity *entity;
media_device_for_each_entity(entity, mdev) {
// entity will point to each entity in turn
...
}
輔助函式可用於查詢兩個給定墊之間的連結,或透過啟用的連結連線到另一個墊的墊(media_entity_find_link()、media_pad_remote_pad_first()、media_entity_remote_source_pad_unique() 和 media_pad_remote_pad_unique())。
5.1.8. 使用計數和電源處理¶
由於驅動程式在電源管理需求方面的差異很大,媒體控制器不實現電源管理。但是,struct media_entity 包含一個 use_count 欄位,媒體驅動程式可以使用該欄位來跟蹤每個實體的使用者數量,以滿足電源管理需求。
media_entity。use_count 欄位由媒體驅動程式擁有,實體驅動程式不得觸控該欄位。對該欄位的訪問必須受到 media_device。graph_mutex 鎖的保護。
5.1.9. 連結設定¶
可以透過呼叫 media_entity_setup_link() 在執行時修改連結屬性。
5.1.10. 管道和媒體流¶
媒體流是源自一個或多個源裝置(例如感測器)的畫素或元資料流,並透過媒體實體墊流向最終接收器。該流可以在路線上透過裝置進行修改(例如,縮放或畫素格式轉換),或者可以拆分為多個分支,或者可以合併多個分支。
媒體管道是一組相互依賴的媒體流。這種相互依賴可能是由硬體引起的(例如,如果已啟用第一個流,則無法更改第二個流的配置),或者由於軟體設計而由驅動程式引起。最常見的媒體管道由一個不分支的單個流組成。
在開始流式傳輸時,驅動程式必須通知管道中的所有實體,以防止在流式傳輸期間透過呼叫 media_pipeline_start() 來修改連結狀態。
該函式會將管道的所有墊標記為流式傳輸。
pipe 引數指向的 struct media_pipeline 例項將儲存在管道的每個墊中。驅動程式應將 struct media_pipeline 嵌入到更高級別的管道結構中,然後可以透過 struct media_pad pipe 欄位訪問管道。
可以巢狀呼叫 media_pipeline_start()。對於該函式的所有巢狀呼叫,管道指標必須相同。
media_pipeline_start() 可能會返回錯誤。在這種情況下,它將清理它自己所做的任何更改。
在停止流式傳輸時,驅動程式必須使用 media_pipeline_stop() 通知實體。
如果已多次呼叫 media_pipeline_start(),則需要相同數量的 media_pipeline_stop() 呼叫來停止流式傳輸。media_entity。pipe 欄位將在上次巢狀的停止呼叫時重置為 NULL。
如果連結的任一端是流式傳輸實體,則預設情況下連結配置將失敗並顯示 -EBUSY。可以在流式傳輸時修改的連結必須使用 MEDIA_LNK_FL_DYNAMIC 標誌進行標記。
如果在流式傳輸實體上需要禁止其他操作(例如更改實體配置引數),則驅動程式可以顯式檢查媒體實體 stream_count 欄位,以確定實體是否正在流式傳輸。此操作必須在 media_device graph_mutex 持有的情況下完成。
5.1.11. 連結驗證¶
連結驗證由 media_pipeline_start() 對管道中具有接收墊的任何實體執行。 media_entity。link_validate() 回撥用於此目的。在 link_validate() 回撥中,實體驅動程式應檢查連線實體的源墊的屬性與其自身的接收墊是否匹配。匹配的實際含義取決於實體的型別(以及最終硬體的屬性)。
子系統應透過提供特定於子系統的輔助函式來促進連結驗證,以方便訪問通常需要的資訊,並最終提供一種使用驅動程式特定回撥的方式。
5.1.12. 管道遍歷¶
一旦使用 media_pipeline_start() 構建了管道,驅動程式可以使用 :c:macro:´media_pipeline_for_each_entity` 和 :c:macro:´media_pipeline_for_each_pad` 宏迭代管道中的實體或墊。迭代墊很簡單
media_pipeline_pad_iter iter;
struct media_pad *pad;
media_pipeline_for_each_pad(pipe, &iter, pad) {
/* 'pad' will point to each pad in turn */
...
}
要迭代實體,迭代器需要作為附加步驟進行初始化和清理
media_pipeline_entity_iter iter;
struct media_entity *entity;
int ret;
ret = media_pipeline_entity_iter_init(pipe, &iter);
if (ret)
...;
media_pipeline_for_each_entity(pipe, &iter, entity) {
/* 'entity' will point to each entity in turn */
...
}
media_pipeline_entity_iter_cleanup(&iter);
5.1.13. 媒體控制器裝置分配器 API¶
當媒體裝置屬於多個驅動程式時,共享媒體裝置將使用共享 struct device 作為查詢的鍵進行分配。
共享媒體裝置應保持註冊狀態,直到最後一個驅動程式登出它。此外,當所有引用都釋放時,應釋放媒體裝置。每個驅動程式在探測期間(在分配媒體裝置時)都會獲得對媒體裝置的引用。如果媒體裝置已經分配,則分配 API 會增加 refcount 並返回現有的媒體裝置。驅動程式在其斷開連線例程中呼叫 media_device_delete() 時,會將引用放回。
從 kref put 處理程式登出和清理媒體裝置,以確保媒體裝置在最後一個驅動程式登出媒體裝置之前保持註冊狀態。
驅動程式使用
驅動程式應使用適當的媒體核心例程來管理共享媒體裝置的生命週期,處理兩種狀態:1. 分配 -> 註冊 -> 刪除 2. 獲取對已註冊裝置的引用 -> 刪除
呼叫 media_device_delete() 例程以確保正確處理共享媒體裝置刪除。
驅動程式探測: 呼叫 media_device_usb_allocate() 以分配或獲取引用呼叫 media_device_register(),如果媒體 devnode 未註冊
驅動程式斷開連線: 呼叫 media_device_delete() 以釋放 media_device。釋放由 kref put 處理程式處理。
5.1.14. API 定義¶
-
struct media_entity_notify¶
媒體實體通知
定義:
struct media_entity_notify {
struct list_head list;
void *notify_data;
void (*notify)(struct media_entity *entity, void *notify_data);
};
成員
列表列表頭
notify_data呼叫回撥的輸入資料
通知回撥函式指標
描述
驅動程式可以註冊一個回撥,以便在新實體註冊到媒體裝置時採取操作。此處理程式旨在建立現有實體之間的連結,而不應建立實體並註冊它們。
-
struct media_device_ops¶
媒體裝置操作
定義:
struct media_device_ops {
int (*link_notify)(struct media_link *link, u32 flags, unsigned int notification);
struct media_request *(*req_alloc)(struct media_device *mdev);
void (*req_free)(struct media_request *req);
int (*req_validate)(struct media_request *req);
void (*req_queue)(struct media_request *req);
};
成員
link_notify連結狀態更改通知回撥。使用 graph_mutex 持有狀態呼叫此回撥。
req_alloc分配請求。如果需要分配大於
struct media_request的結構,請設定此項。 req_alloc 和 req_free 必須同時設定或同時設定為 NULL。req_free釋放請求。如果也設定了 req_alloc,請設定此項,否則保留為 NULL。
req_validate驗證請求,但不要立即排隊。呼叫此操作時會持有 req_queue_mutex 鎖。
req_queue對已驗證的請求進行排隊,不能失敗。如果排隊此請求時出現問題,則應在驅動程式內部將其標記為這樣,並且任何相關的緩衝區最終都必須以 VB2_BUF_STATE_ERROR 狀態返回到 vb2。呼叫此操作時會持有 req_queue_mutex 鎖。重要的是在所有其他物件型別排隊之後,最後對 vb2 緩衝區物件進行排隊:對緩衝區進行排隊會啟動請求處理,因此與請求(以及緩衝區)相關的所有其他物件都必須可供驅動程式使用。並且一旦緩衝區排隊,驅動程式就可以在 req_queue 退出之前完成或刪除請求中的物件。
-
struct media_device¶
媒體裝置
定義:
struct media_device {
struct device *dev;
struct media_devnode *devnode;
char model[32];
char driver_name[32];
char serial[40];
char bus_info[32];
u32 hw_revision;
u64 topology_version;
u32 id;
struct ida entity_internal_idx;
int entity_internal_idx_max;
struct list_head entities;
struct list_head interfaces;
struct list_head pads;
struct list_head links;
struct list_head entity_notify;
struct mutex graph_mutex;
struct media_graph pm_count_walk;
void *source_priv;
int (*enable_source)(struct media_entity *entity, struct media_pipeline *pipe);
void (*disable_source)(struct media_entity *entity);
const struct media_device_ops *ops;
struct mutex req_queue_mutex;
atomic_t request_id;
};
成員
dev父裝置
devnode媒體裝置節點
型號裝置型號名稱
driver_name可選裝置驅動程式名稱。如果未設定,則對
MEDIA_IOC_DEVICE_INFO的呼叫將返回dev->driver->name。例如,這是 USB 驅動程式所需要的,否則它們都將顯示為驅動程式名稱為“usb”。序列號裝置序列號(可選)
bus_info唯一且穩定的裝置位置識別符號
hw_revision硬體裝置修訂版本
topology_version用於儲存圖拓撲版本的單調計數器。每次拓撲更改時都應遞增。
id在上次註冊的圖物件上使用的唯一 ID
entity_internal_idx圖遍歷演算法使用的唯一內部實體 ID
entity_internal_idx_max分配的內部實體索引
實體已註冊實體的列表
介面已註冊介面的列表
墊已註冊墊的列表
連結已註冊連結的列表
entity_notify已註冊 entity_notify 回撥的列表
graph_mutex保護對
struct media_device資料的訪問pm_count_walk用於電源狀態步行的圖步行。使用 graph_mutex 序列化訪問。
source_priv用於啟用/停用源處理程式的驅動程式私有資料
啟用源啟用源處理程式函式指標
停用源停用源處理程式函式指標
ops操作處理程式回撥
req_queue_mutex相對於停止或啟動流式傳輸的其他操作,序列化 MEDIA_REQUEST_IOC_QUEUE ioctl。
request_id用於生成唯一請求 ID
描述
此結構表示抽象的高階媒體裝置。它允許輕鬆訪問實體並提供基本的媒體裝置級別支援。可以直接分配該結構或將其嵌入到更大的結構中。
父 dev 是物理裝置。必須在註冊媒體裝置之前設定它。
model 是透過 sysfs 匯出的描述性模型名稱。它不必是唯一的。
enable_source 是一個處理程式,用於查詢接收實體的源實體,並在源實體空閒時啟用它們之間的連結。驅動程式應在訪問源之前呼叫此處理程式。
disable_source 是一個處理程式,用於查詢接收實體的源實體並停用它們之間的連結。驅動程式應呼叫此處理程式以釋放源。
用例:查詢連線到解碼器實體的調諧器實體,並檢查它是否可用,並從 enable_source 啟用它們之間的連結,並從 disable_source 停用。
注意
預計網橋驅動程式在 media_device 註冊時或網橋驅動程式在探測期間找到 media_device 時實現並設定處理程式。網橋驅動程式使用執行 enable_source 和 disable_source 處理程式所需的資訊設定 source_priv。呼叫者應持有 graph_mutex 以訪問和呼叫 enable_source 和 disable_source 處理程式。
-
void media_device_init(struct media_device *mdev)¶
初始化媒體裝置元素
引數
struct media_device *mdev指向 struct
media_device的指標
描述
此函式在註冊之前初始化媒體裝置。媒體裝置初始化和註冊分為兩個函式,以避免競爭條件,並在媒體圖完成之前使媒體裝置可供使用者空間使用。
因此,驅動程式需要首先初始化媒體裝置,註冊媒體裝置中的任何實體,建立 pad 到 pad 的連結,然後最後透過呼叫 media_device_register() 作為最後一步來註冊媒體裝置。
呼叫者負責在註冊之前初始化媒體裝置。必須設定以下欄位
dev 必須指向父裝置
model 必須填充裝置型號名稱
如果 bus_info 欄位以“0”開頭,則 bus_info 欄位由 media_device_init() 為 PCI 和平臺裝置設定。
-
void media_device_cleanup(struct media_device *mdev)¶
清理媒體裝置元素
引數
struct media_device *mdev指向 struct
media_device的指標
描述
此函式將銷燬在 media_device_init() 中初始化的 graph_mutex。
-
int __media_device_register(struct media_device *mdev, struct module *owner)¶
註冊一個媒體裝置元素
引數
struct media_device *mdev指向 struct
media_device的指標struct module *owner應填充
THIS_MODULE
描述
使用者應該呼叫 media_device_register() 宏。
呼叫者負責在註冊之前初始化 media_device 結構。必須設定 media_device 的以下欄位
media_device.model必須用裝置的型號名稱填充,並作為以 NUL 結尾的 UTF-8 字串。裝置/型號修訂版不得儲存在此欄位中。
以下欄位是可選的
media_device.serial是一個唯一的序列號,儲存為以 NUL 結尾的 ASCII 字串。該欄位足夠大,可以以文字形式儲存 GUID。如果硬體未提供唯一的序列號,則必須將此欄位留空。
media_device.bus_info表示裝置在系統中的位置,作為以 NUL 結尾的 ASCII 字串。對於 PCI/PCIe 裝置,media_device.bus_info必須設定為“PCI:”(或“PCIe:”),後跟 pci_name() 的值。對於 USB 裝置,必須使用usb_make_path()函式。應用程式使用此欄位來區分未提供序列號的其他相同裝置。
media_device.hw_revision是驅動程式特定格式的硬體裝置修訂版。如果可能,應使用 KERNEL_VERSION() 宏格式化修訂版。
注意
成功註冊後,將建立一個名為 media[0-9]+ 的字元裝置。裝置主編號和次編號是動態的。型號名稱作為 sysfs 屬性匯出。
登出尚未註冊的媒體裝置是不安全的。
返回
成功時返回零,否則返回負錯誤程式碼。
-
media_device_register¶
media_device_register (mdev)
註冊一個媒體裝置元素
引數
mdev指向 struct
media_device的指標
描述
此宏呼叫 __media_device_register(),將 THIS_MODULE 作為 __media_device_register() 的第二個引數(owner)傳遞。
-
void media_device_unregister(struct media_device *mdev)¶
登出媒體裝置元素
-
int media_device_register_entity(struct media_device *mdev, struct media_entity *entity)¶
在先前註冊的媒體裝置中註冊媒體實體。
引數
struct media_device *mdev指向 struct
media_device的指標struct media_entity *entity指向要註冊的
media_entity結構的指標
描述
實體由唯一的正整數 ID 標識。媒體控制器框架將自動生成此類 ID。ID 不保證是連續的,並且 ID 號可能會在新核心版本上更改。因此,驅動程式和使用者空間都不應硬編碼 ID 號來引用實體,而應在需要時使用框架來查詢 ID。
應在呼叫 media_device_register_entity() 之前初始化 media_entity 名稱、型別和標誌欄位。嵌入在更高級別標準結構中的實體可以透過更高級別的框架設定其中的一些欄位。
如果裝置有 pad,則應在此函式之前呼叫 media_entity_pads_init()。否則,應在呼叫此函式之前將 media_entity.pad 和 media_entity.num_pads 置零。
實體具有描述實體功能和狀態的標誌
MEDIA_ENT_FL_DEFAULT指示給定型別的預設實體。這可以用於報告預設音訊和影片裝置或預設攝像頭感測器。
注意
驅動程式應在呼叫此函式之前設定實體功能。請注意,驅動程式不應使用值 MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN 和 MEDIA_ENT_F_UNKNOWN。
-
void media_device_unregister_entity(struct media_entity *entity)¶
登出媒體實體。
引數
struct media_entity *entity指向要登出的
media_entity結構的指標
描述
當呼叫此函式時,將自動從 media_device 登出與實體關聯的所有連結和所有 PAD。
登出實體不會更改其他實體的 ID,並且先前使用的 ID 將永遠不會重用於新註冊的實體。
登出媒體裝置時,將自動登出其所有實體。然後不需要手動實體登出。
注意
如果需要,媒體實體例項本身必須由驅動程式顯式釋放。
-
void media_device_register_entity_notify(struct media_device *mdev, struct media_entity_notify *nptr)¶
註冊媒體 entity_notify 回撥
引數
struct media_device *mdev媒體裝置
struct media_entity_notify *nptr媒體 entity_notify
描述
注意
註冊新實體時,將呼叫所有註冊的 media_entity_notify 回撥。
-
void media_device_unregister_entity_notify(struct media_device *mdev, struct media_entity_notify *nptr)¶
登出媒體實體通知回撥
引數
struct media_device *mdev媒體裝置
struct media_entity_notify *nptr媒體 entity_notify
-
void media_device_pci_init(struct media_device *mdev, struct pci_dev *pci_dev, const char *name)¶
從 PCI 裝置建立並初始化
media_device結構。
引數
struct media_device *mdev指向 struct
media_device的指標struct pci_dev *pci_dev指向 pci_dev 結構的指標
const char *name媒體裝置名稱。如果
NULL,則例程將使用 pci 裝置的預設名稱,由 pci_name() 宏給出。
-
void __media_device_usb_init(struct media_device *mdev, struct usb_device *udev, const char *board_name, const char *driver_name)¶
從 PCI 裝置建立並初始化
media_device結構。
引數
struct media_device *mdev指向 struct
media_device的指標struct usb_device *udev指向
struct usb_device的指標const char *board_name媒體裝置名稱。如果
NULL,則例程將使用 USB 產品名稱(如果可用)。const char *driver_name驅動程式的名稱。如果
NULL,則例程將使用udev->dev->driver->name給出的名稱,這通常是錯誤的做法。
描述
注意
最好呼叫 media_device_usb_init(),因為此類宏會用 KBUILD_MODNAME 填充 driver_name。
-
media_device_usb_init¶
media_device_usb_init (mdev, udev, name)
從 PCI 裝置建立並初始化
media_device結構。
引數
mdev指向 struct
media_device的指標udev指向
struct usb_device的指標name媒體裝置名稱。如果
NULL,則例程將使用 USB 產品名稱(如果可用)。
描述
此宏呼叫 media_device_usb_init(),傳遞用 KBUILD_MODNAME 填充的 media_device_usb_init() driver_name 引數。
引數
char *bus_info在其中寫入匯流排資訊(字元陣列)的變數
size_t bus_info_sizebus_info 的長度
struct device *dev相關的
struct device
描述
基於 dev 設定匯流排資訊。當前,這是為 PCI 和平臺裝置完成的。需要 dev 為非 NULL 才能執行此操作。
此函式不應從驅動程式呼叫。
-
struct media_file_operations¶
媒體裝置檔案操作
定義:
struct media_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 (*ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*open) (struct file *);
int (*release) (struct file *);
};
成員
owner應填充
THIS_MODULEread指向實現 read() 系統呼叫的函式的指標
write指向實現 write() 系統呼叫的函式的指標
poll指向實現 poll() 系統呼叫的函式的指標
ioctl指向實現 ioctl() 系統呼叫的函式的指標
compat_ioctl指向將處理在用 64 位編譯的核心上對 ioctl() 系統呼叫的 32 位使用者空間呼叫的函式的指標。
open指向實現 open() 系統呼叫的函式的指標
release指向將釋放由 open 函式分配的資源的函式的指標。
-
struct media_devnode¶
媒體裝置節點
定義:
struct media_devnode {
struct media_device *media_dev;
const struct media_file_operations *fops;
struct device dev;
struct cdev cdev;
struct device *parent;
int minor;
unsigned long flags;
void (*release)(struct media_devnode *devnode);
};
成員
media_dev指向 struct
media_device的指標fops指向具有媒體裝置操作的
media_file_operations結構的指標dev指向包含媒體控制器裝置的
device結構的指標cdevstruct cdev 指標字元裝置
parent父裝置
minor裝置節點次編號
flags標誌,
MEDIA_FLAG_*常量的組合release在 media-device.c 的
media_devnode_release()例程結束時呼叫的釋放回調。
描述
此結構表示與媒體相關的裝置節點。
parent 是物理裝置。必須由核心驅動程式或裝置驅動程式在註冊節點之前設定。
-
int media_devnode_register(struct media_device *mdev, struct media_devnode *devnode, struct module *owner)¶
註冊媒體裝置節點
引數
struct media_device *mdev我們要註冊裝置節點的
struct media_devicestruct media_devnode *devnode我們要註冊的媒體裝置節點結構
struct module *owner應填充
THIS_MODULE
描述
註冊程式碼分配次編號,並將新裝置節點註冊到核心。如果找不到空閒的次編號,或者裝置節點的註冊失敗,則返回錯誤。
成功時返回零。
請注意,如果 media_devnode_register 呼叫失敗,則不會呼叫 media_devnode 結構的 release() 回撥,因此呼叫者負責釋放任何資料。
-
void media_devnode_unregister_prepare(struct media_devnode *devnode)¶
清除媒體裝置節點註冊位
引數
struct media_devnode *devnode要準備登出的裝置節點
描述
這將清除傳遞的設備註冊位。將來的開啟呼叫將遇到錯誤。應在 media_devnode_unregister() 之前呼叫,以避免與登出和裝置檔案開啟呼叫發生競爭。
如果裝置節點從未註冊或已登出,則可以安全地呼叫此函式。
-
void media_devnode_unregister(struct media_devnode *devnode)¶
登出媒體裝置節點
引數
struct media_devnode *devnode要登出的裝置節點
描述
這將登出傳遞的裝置。將來的開啟呼叫將遇到錯誤。
-
struct media_devnode *media_devnode_data(struct file *filp)¶
返回指向
media_devnode的指標
引數
struct file *filp指向
file結構的指標
-
int media_devnode_is_registered(struct media_devnode *devnode)¶
如果
media_devnode已註冊,則返回 true;否則返回 false。
-
enum media_gobj_type¶
圖物件的型別
常量
MEDIA_GRAPH_ENTITY標識媒體實體
MEDIA_GRAPH_PAD標識媒體 pad
MEDIA_GRAPH_LINK標識媒體連結
MEDIA_GRAPH_INTF_DEVNODE透過裝置節點標識媒體核心 API 介面
-
struct media_gobj¶
定義一個圖物件。
定義:
struct media_gobj {
struct media_device *mdev;
u32 id;
struct list_head list;
};
成員
mdev指向擁有該物件的
media_device結構的指標id非零物件 ID 識別符號。ID 在 media_device 內部應該是唯一的,因為它由
MEDIA_BITS_PER_TYPE組成,用於儲存型別,再加上MEDIA_BITS_PER_ID,用於儲存 ID列表儲存在每種型別的 mdev 物件列表中的列表條目
描述
媒體圖上的所有物件都應嵌入此結構
-
struct media_entity_enum¶
媒體實體的列舉。
定義:
struct media_entity_enum {
unsigned long *bmap;
int idx_max;
};
成員
bmap點陣圖,其中每個位代表
struct media_entity->internal_idx 處的一個實體。idx_maxbmap 中的位數
-
struct media_graph¶
媒體圖遍歷狀態
定義:
struct media_graph {
struct {
struct media_entity *entity;
struct list_head *link;
} stack[MEDIA_ENTITY_ENUM_MAX_DEPTH];
struct media_entity_enum ent_enum;
int top;
};
成員
stack圖遍歷堆疊;堆疊包含有關要步行的媒體實體的路徑以及透過其到達的連結的資訊。
stack.entity指向圖中的
struct media_entity的指標。stack.link指向
struct list_head的指標。ent_enum已訪問的實體
top堆疊頂部
-
struct media_pipeline¶
媒體管道相關資訊
定義:
struct media_pipeline {
bool allocated;
struct media_device *mdev;
struct list_head pads;
int start_count;
};
成員
allocated媒體管道由框架分配和釋放
mdev管道所屬的媒體裝置
墊media_pipeline_pad 列表
start_count媒體管道啟動 - 停止計數
-
struct media_pipeline_pad¶
媒體管道的一部分的 pad
定義:
struct media_pipeline_pad {
struct list_head list;
struct media_pipeline *pipe;
struct media_pad *pad;
};
成員
列表媒體 pad pads 列表中的條目
pipepad 所屬的 media_pipeline
pad媒體 pad
描述
此結構將 pad 與媒體管道相關聯。media_pipeline_pad 的例項由 media_pipeline_start() 在構建管道時建立,並存儲在 media_pad.pads 列表中。media_pipeline_stop() 從列表中刪除條目並刪除它們。
-
struct media_pipeline_pad_iter¶
media_pipeline_for_each_pad 的迭代器
定義:
struct media_pipeline_pad_iter {
struct list_head *cursor;
};
成員
cursor當前元素
-
struct media_pipeline_entity_iter¶
media_pipeline_for_each_entity 的迭代器
定義:
struct media_pipeline_entity_iter {
struct media_entity_enum ent_enum;
struct list_head *cursor;
};
成員
ent_enum實體列舉跟蹤器
cursor當前元素
-
struct media_link¶
媒體圖的一部分的連結物件。
定義:
struct media_link {
struct media_gobj graph_obj;
struct list_head list;
union {
struct media_gobj *gobj0;
struct media_pad *source;
struct media_interface *intf;
};
union {
struct media_gobj *gobj1;
struct media_pad *sink;
struct media_entity *entity;
};
struct media_link *reverse;
unsigned long flags;
bool is_backlink;
};
成員
graph_obj嵌入式結構,包含媒體物件公共資料
列表與擁有連結的實體或介面關聯的連結列表。
{unnamed_union}anonymous
gobj0聯合的一部分。用於獲取連結的第一個 graph_object 的指標。
source聯合的一部分。僅當第一個物件 (gobj0) 是 pad 時使用。在這種情況下,它表示源 pad。
intf聯合的一部分。僅當第一個物件 (gobj0) 是介面時使用。
{unnamed_union}anonymous
gobj1聯合的一部分。用於獲取連結的第二個 graph_object 的指標。
sink聯合體的一部分。僅當第二個物件 (gobj1) 是 pad 時使用。在這種情況下,它表示 sink pad。
實體聯合體的一部分。僅當第二個物件 (gobj1) 是實體時使用。
reverse指向 pad 到 pad 連結的反向連結的指標。
flags連結標誌,如 uapi/media.h (MEDIA_LNK_FL_*) 中所定義
is_backlink指示連結是否為反向連結。
-
enum media_pad_signal_type¶
媒體 pad 中的訊號型別
常量
PAD_SIGNAL_DEFAULT預設訊號。當所有輸入或所有輸出都由 pad 編號唯一標識時,使用此訊號。
PAD_SIGNAL_ANALOGpad 包含模擬訊號。它可以是射頻、中頻、基帶訊號或子載波。調諧器輸入、IF-PLL 解調器、複合和 S-video 訊號應使用它。
PAD_SIGNAL_DV包含數字影片訊號,可以是來自模擬電視影片源的取樣位元流。在這種情況下,它通常包含 VBI 資料。
PAD_SIGNAL_AUDIO包含來自音訊子載波的中頻模擬訊號或音訊位元流。中頻訊號由調諧器提供,並由音訊 AM/FM 解碼器使用。位元流音訊由音訊解碼器提供。
-
struct media_pad¶
媒體 pad 圖物件。
定義:
struct media_pad {
struct media_gobj graph_obj;
struct media_entity *entity;
u16 index;
u16 num_links;
enum media_pad_signal_type sig_type;
unsigned long flags;
struct media_pipeline *pipe;
};
成員
graph_obj嵌入式結構,包含媒體物件公共資料
實體此 pad 所屬的實體
index實體 pads 陣列中的 Pad 索引,從 0 到 n 編號
num_links連線到此 pad 的連結數
sig_type媒體 pad 中的訊號型別
flagsPad 標誌,如 include/uapi/linux/media.h 中所定義(查詢
MEDIA_PAD_FL_*)pipe此 pad 所屬的 Pipeline。使用
media_entity_pipeline()訪問此欄位。
-
struct media_entity_operations¶
媒體實體操作
定義:
struct media_entity_operations {
int (*get_fwnode_pad)(struct media_entity *entity, struct fwnode_endpoint *endpoint);
int (*link_setup)(struct media_entity *entity,const struct media_pad *local, const struct media_pad *remote, u32 flags);
int (*link_validate)(struct media_link *link);
bool (*has_pad_interdep)(struct media_entity *entity, unsigned int pad0, unsigned int pad1);
};
成員
get_fwnode_pad基於 fwnode 端點返回 pad 編號,如果出錯,則返回負值。此操作可用於將 fwnode 對映到媒體 pad 編號。可選。
link_setup通知實體連結更改。該操作可能會返回錯誤,在這種情況下,連結設定將被取消。可選。
link_validate返回從實體角度來看連結是否有效。
media_pipeline_start()函式透過呼叫此操作來驗證所有連結。可選。has_pad_interdep返回實體的兩個 pad 是否相互依賴。如果兩個 pad 相互依賴,則它們是同一管道的一部分,啟用其中一個 pad 意味著另一個 pad 將變為“鎖定”狀態,並且不允許配置更改。保證 pad0 和 pad1 不會同時是 sink 或 source。永遠不要直接呼叫 .has_pad_interdep() 操作,始終使用 media_entity_has_pad_interdep()。可選:如果未實現該操作,則所有 pad 將被視為相互依賴。
描述
注意
這些回撥函式在持有 struct media_device.graph_mutex 互斥鎖的情況下被呼叫。
-
enum media_entity_type¶
媒體實體型別
常量
MEDIA_ENTITY_TYPE_BASE實體未嵌入在另一個子系統結構中。
MEDIA_ENTITY_TYPE_VIDEO_DEVICE實體嵌入在
struct video_device例項中。MEDIA_ENTITY_TYPE_V4L2_SUBDEV實體嵌入在
struct v4l2_subdev例項中。
描述
媒體實體物件通常不直接例項化,而是媒體實體結構由其他子系統特定的結構繼承(透過嵌入)。媒體實體型別標識實現媒體實體例項的子類結構的型別。
這允許媒體實體的執行時型別識別和安全地轉換為正確的物件型別。例如,嵌入在 v4l2_subdev 結構例項中的媒體實體結構例項將具有型別 MEDIA_ENTITY_TYPE_V4L2_SUBDEV,並且可以使用 container_of() 宏安全地轉換為 v4l2_subdev 結構。
-
struct media_entity¶
媒體實體圖物件。
定義:
struct media_entity {
struct media_gobj graph_obj;
const char *name;
enum media_entity_type obj_type;
u32 function;
unsigned long flags;
u16 num_pads;
u16 num_links;
u16 num_backlinks;
int internal_idx;
struct media_pad *pads;
struct list_head links;
const struct media_entity_operations *ops;
int use_count;
union {
struct {
u32 major;
u32 minor;
} dev;
} info;
};
成員
graph_obj包含媒體物件公共資料的嵌入式結構。
name實體名稱。
obj_type實現 media_entity 的物件的型別。
function實體主要功能,如 include/uapi/linux/media.h 中所定義(查詢
MEDIA_ENT_F_*)flags實體標誌,如 include/uapi/linux/media.h 中所定義(查詢
MEDIA_ENT_FL_*)num_padssink 和 source pad 的數量。
num_links連結總數,包括前向和反向,已啟用和已停用。
num_backlinks反向連結數
internal_idx唯一的內部實體特定編號。如果實體被登出或再次註冊,則編號將被重用。
墊Pads 陣列,其大小由 num_pads 定義。
連結資料鏈接列表。
ops實體操作。
use_count實體的使用計數。
info包含 devnode 資訊的聯合體。僅為了向後相容而保留。
info.dev包含裝置主裝置號和次裝置號資訊。
info.dev.major裝置節點主裝置號(如果裝置是 devnode)。
info.dev.minor裝置節點次裝置號(如果裝置是 devnode)。
描述
注意
use_count 引用計數絕不能為負數,但故意使用有符號整數:一個簡單的 WARN_ON(<0) 檢查可用於檢測使其變為負數的引用計數錯誤。
-
media_entity_for_each_pad¶
media_entity_for_each_pad (entity, iter)
迭代實體中的所有 pad
引數
實體pad 所屬的實體
iter迭代器 pad
描述
迭代媒體實體中的所有 pad。
-
struct media_interface¶
媒體介面圖物件。
定義:
struct media_interface {
struct media_gobj graph_obj;
struct list_head links;
u32 type;
u32 flags;
};
成員
graph_obj嵌入式圖物件
連結指向圖實體的連結列表
type介面型別,如 include/uapi/linux/media.h 中所定義(查詢
MEDIA_INTF_T_*)flags介面標誌,如 include/uapi/linux/media.h 中所定義(查詢
MEDIA_INTF_FL_*)
描述
注意
目前,沒有為 media_interface 定義任何標誌。
-
struct media_intf_devnode¶
透過裝置節點的媒體介面。
定義:
struct media_intf_devnode {
struct media_interface intf;
u32 major;
u32 minor;
};
成員
intf嵌入式介面物件
major裝置節點的主裝置號
minor裝置節點的次裝置號
-
u32 media_entity_id(struct media_entity *entity)¶
返回媒體實體圖物件 ID
引數
struct media_entity *entity指向
media_entity的指標
-
enum media_gobj_type media_type(struct media_gobj *gobj)¶
返回媒體物件型別
引數
struct media_gobj *gobj指向 struct
media_gobj圖物件的指標
-
u32 media_id(struct media_gobj *gobj)¶
返回媒體物件 ID
引數
struct media_gobj *gobj指向 struct
media_gobj圖物件的指標
-
u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id)¶
在物件 ID 上封裝型別和 ID
引數
enum media_gobj_type type物件型別,如 enum
media_gobj_type中所定義。u64 local_id下一個 ID,來自 struct
media_device.id。
-
bool is_media_entity_v4l2_video_device(struct media_entity *entity)¶
檢查實體是否為 video_device
引數
struct media_entity *entity指向實體的指標
返回
如果實體是 video_device 物件的例項,並且可以使用 container_of() 宏安全地轉換為 struct video_device,則為 true,否則為 false。
-
bool is_media_entity_v4l2_subdev(struct media_entity *entity)¶
檢查實體是否為 v4l2_subdev
引數
struct media_entity *entity指向實體的指標
返回
如果實體是 v4l2_subdev 物件的例項,並且可以使用 container_of() 宏安全地轉換為 struct v4l2_subdev,則為 true,否則為 false。
-
int media_entity_enum_init(struct media_entity_enum *ent_enum, struct media_device *mdev)¶
初始化實體列舉
引數
struct media_entity_enum *ent_enum要初始化的實體列舉
struct media_device *mdev相關的媒體裝置
返回
成功時為零,否則為負錯誤程式碼。
-
void media_entity_enum_cleanup(struct media_entity_enum *ent_enum)¶
釋放實體列舉的資源
引數
struct media_entity_enum *ent_enum要釋放的實體列舉
-
void media_entity_enum_zero(struct media_entity_enum *ent_enum)¶
清除整個列舉
引數
struct media_entity_enum *ent_enum要清除的實體列舉
-
void media_entity_enum_set(struct media_entity_enum *ent_enum, struct media_entity *entity)¶
在列舉中標記單個實體
引數
struct media_entity_enum *ent_enum實體列舉
struct media_entity *entity要標記的實體
-
void media_entity_enum_clear(struct media_entity_enum *ent_enum, struct media_entity *entity)¶
在列舉中取消標記單個實體
引數
struct media_entity_enum *ent_enum實體列舉
struct media_entity *entity要取消標記的實體
-
bool media_entity_enum_test(struct media_entity_enum *ent_enum, struct media_entity *entity)¶
測試實體是否被標記
引數
struct media_entity_enum *ent_enum實體列舉
struct media_entity *entity要測試的實體
描述
如果實體被標記,則返回 true。
-
bool media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, struct media_entity *entity)¶
測試實體是否被標記,並標記它
引數
struct media_entity_enum *ent_enum實體列舉
struct media_entity *entity要測試的實體
描述
如果實體被標記,則返回 true,並在執行此操作之前標記它。
-
bool media_entity_enum_empty(struct media_entity_enum *ent_enum)¶
測試整個列舉是否為空
引數
struct media_entity_enum *ent_enum實體列舉
返回
如果實體為空,則返回 true。
-
bool media_entity_enum_intersects(struct media_entity_enum *ent_enum1, struct media_entity_enum *ent_enum2)¶
測試兩個列舉是否相交
引數
struct media_entity_enum *ent_enum1第一個實體列舉
struct media_entity_enum *ent_enum2第二個實體列舉
返回
如果實體列舉 ent_enum1 和 ent_enum2 相交,則返回 true,否則返回 false。
-
gobj_to_entity¶
gobj_to_entity (gobj)
從包含在 gobj 中的
media_entity返回 struct 指標。
引數
gobj指向 struct
media_gobj圖物件的指標
-
gobj_to_pad¶
gobj_to_pad (gobj)
從包含在 gobj 中的
media_pad返回 struct 指標。
引數
gobj指向 struct
media_gobj圖物件的指標
-
gobj_to_link¶
gobj_to_link (gobj)
從包含在 gobj 中的
media_link返回 struct 指標。
引數
gobj指向 struct
media_gobj圖物件的指標
-
gobj_to_intf¶
gobj_to_intf (gobj)
從包含在 gobj 中的
media_interface返回 struct 指標。
引數
gobj指向 struct
media_gobj圖物件的指標
-
intf_to_devnode¶
intf_to_devnode (intf)
從包含在 intf 中的
struct media_intf_devnode返回 struct 指標。
引數
intf指向 struct
media_intf_devnode的指標
-
void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj)¶
初始化圖物件
引數
struct media_device *mdev指向包含該物件的
media_device的指標enum media_gobj_type type物件的型別
struct media_gobj *gobj指向 struct
media_gobj圖物件的指標
描述
此例程初始化媒體圖物件內的嵌入式 struct media_gobj。如果使用 media_*_create 函式呼叫,則會自動呼叫它。但是,如果物件(實體、連結、pad、介面)嵌入在其他某個物件上,則應在媒體控制器註冊物件之前呼叫此函式。
-
void media_gobj_destroy(struct media_gobj *gobj)¶
停止在媒體裝置上使用圖物件
引數
struct media_gobj *gobj指向 struct
media_gobj圖物件的指標
描述
所有例程(如 media_device_unregister())都應該呼叫此函式來移除/銷燬媒體圖物件。
-
int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads)¶
初始化實體 pad
引數
struct media_entity *entitypad 所屬的實體
u16 num_padssink 和 source pad 的總數
struct media_pad *padsnum_pads pad 的陣列。
描述
pad 陣列由實體驅動程式管理,並傳遞給 media_entity_pads_init(),其指標將儲存在 media_entity 結構中。
如果不需要 pad,驅動程式可以直接使用 0 填充 media_entity->num_pads,使用 NULL 填充 media_entity->pads,或者呼叫此函式來執行相同的操作。
由於 pad 的數量是預先知道的,因此 pad 陣列不是動態分配的,而是由實體驅動程式管理的。大多數驅動程式會將 pad 陣列嵌入到特定於驅動程式的結構中,從而避免動態分配。
驅動程式必須在呼叫 media_entity_pads_init() 之前設定 pads 陣列中每個 pad 的方向。該函式將初始化其他 pad 欄位。
-
void media_entity_cleanup(struct media_entity *entity)¶
釋放與實體關聯的資源
引數
struct media_entity *entitypad 所屬的實體
描述
此函式必須在登出實體後的清理階段呼叫(目前,它不執行任何操作)。
對已清零但尚未透過 media_entity_pad_init() 初始化的 media_entity 呼叫 media_entity_cleanup() 是有效的,並且是一個空操作。
-
int media_get_pad_index(struct media_entity *entity, u32 pad_type, enum media_pad_signal_type sig_type)¶
從實體檢索 pad 索引
引數
struct media_entity *entitypad 所屬的實體
u32 pad_typepad 的型別,即 MEDIA_PAD_FL_* pad 型別之一
enum media_pad_signal_type sig_type要搜尋的 pad 的訊號型別
描述
此輔助函式在實體內找到第一個滿足 is_sink 和 sig_type 條件的 pad 索引。
成功時,返回 pad 編號。如果未找到 pad 或媒體實體為 NULL 指標,則返回 -EINVAL。
-
int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags)¶
在兩個實體之間建立連結。
引數
struct media_entity *source指向源 pad 的
media_entity的指標。u16 source_padpad 陣列中源 pad 的編號
struct media_entity *sink指向接收端 pad 的
media_entity的指標。u16 sink_padpad 在 pads 陣列中的編號。
u32 flags連結標誌,定義在 include/uapi/linux/media.h 中 (查詢
MEDIA_LNK_FL_*)
描述
flags 的有效值
MEDIA_LNK_FL_ENABLED表示連結已啟用,可用於傳輸媒體資料。當兩個或多個連結指向同一個接收端 pad 時,一次只能啟用其中一個連結。
MEDIA_LNK_FL_IMMUTABLE表示連結的啟用狀態無法在執行時修改。如果設定了
MEDIA_LNK_FL_IMMUTABLE,則還必須設定MEDIA_LNK_FL_ENABLED,因為不可變的連結始終處於啟用狀態。
注意
在呼叫此函式之前,應事先為兩端呼叫 media_entity_pads_init() 和 media_device_register_entity()。
-
int media_create_pad_links(const struct media_device *mdev, const u32 source_function, struct media_entity *source, const u16 source_pad, const u32 sink_function, struct media_entity *sink, const u16 sink_pad, u32 flags, const bool allow_both_undefined)¶
在兩個實體之間建立連結。
引數
const struct media_device *mdev指向包含該物件的 media_device 的指標
const u32 source_function源實體的功能。僅當 source 為 NULL 時使用。
struct media_entity *source指向源 pad 的
media_entity的指標。如果為 NULL,它將使用所有與 sink_function 匹配的實體。const u16 source_padpad 陣列中源 pad 的編號
const u32 sink_function接收端實體的功能。僅當 sink 為 NULL 時使用。
struct media_entity *sink指向接收端 pad 的
media_entity的指標。如果為 NULL,它將使用所有與 sink_function 匹配的實體。const u16 sink_padpad 在 pads 陣列中的編號。
u32 flags連結標誌,定義在 include/uapi/linux/media.h 中。
const bool allow_both_undefined如果
true,則 source 和 sink 都可以為 NULL。在這種情況下,它將在所有與 source_function 匹配的實體和所有與 sink_function 匹配的實體之間建立一個交叉開關。如果false,如果 source 和 sink 都為 NULL,它將返回 0 並且不建立任何連結。
描述
flags 的有效值
MEDIA_LNK_FL_ENABLED標誌表示連結已啟用,可以用於傳輸媒體資料。如果建立了多個連結並且此標誌作為引數傳遞,則只有第一個建立的連結才具有此標誌。
MEDIA_LNK_FL_IMMUTABLE標誌表示連結的啟用狀態無法在執行時修改。如果設定了
MEDIA_LNK_FL_IMMUTABLE,則還必須設定MEDIA_LNK_FL_ENABLED,因為不可變的連結始終處於啟用狀態。
某些裝置通常具有多個相同型別的源和/或接收端實體,這些實體應連結在一起。雖然 media_create_pad_link() 逐個建立連結,但此函式旨在允許 1:n、n:1 甚至交叉開關 (n:n) 連結。
注意
在呼叫此函式之前,應事先為要連結的實體呼叫 media_entity_pads_init() 和 media_device_register_entity()。
-
void media_entity_remove_links(struct media_entity *entity)¶
刪除與實體關聯的所有連結
引數
struct media_entity *entity指向
media_entity的指標
描述
注意
當實體透過 media_device_register_entity() 取消註冊時,會自動呼叫此函式。
-
int __media_entity_setup_link(struct media_link *link, u32 flags)¶
配置媒體連結,無需鎖定
引數
struct media_link *link正在配置的連結
u32 flags連結配置標誌
描述
連結設定的大部分由透過連結連線的兩個實體處理。此函式通知兩個實體連結配置更改。
如果連結是不可變的,或者當前配置和新配置相同,則立即返回。
使用者應持有 link->source->parent->mutex。否則,應使用 media_entity_setup_link()。
-
int media_entity_setup_link(struct media_link *link, u32 flags)¶
在執行時更改連結標誌屬性
引數
struct media_link *link指向
media_link的指標u32 flags請求的新連結標誌
描述
唯一可配置的屬性是 MEDIA_LNK_FL_ENABLED 連結標誌,用於啟用/停用連結。標有 MEDIA_LNK_FL_IMMUTABLE 連結標誌的連結無法啟用或停用。
啟用或停用連結時,媒體框架會按順序為連結的源和接收端的兩個實體呼叫 link_setup 操作。如果第二個 link_setup 呼叫失敗,則會在第一個實體上進行另一個 link_setup 呼叫,以恢復原始連結標誌。
透過將 media_device.link_notify 指標設定為回撥函式,可以通知媒體裝置驅動程式連結設定操作。如果提供,則將在啟用之前和停用連結之後呼叫通知回撥。
如果任何實體的連結是非不可變的,則實體驅動程式必須實現 link_setup 操作。該操作必須配置硬體或儲存配置資訊以供以後應用。
連結配置不得對其他連結產生任何副作用。如果在接收端 pad 啟用的連結阻止在同一 pad 啟用另一個連結,則 link_setup 操作必須返回 -EBUSY,並且不能隱式停用第一個啟用的連結。
注意
連結的標誌的有效值與 media_create_pad_link() 上描述的相同,用於 pad 到 pad 連結,或者與 media_create_intf_link() 上描述的相同,用於介面到實體連結。
-
struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink)¶
查詢兩個 pad 之間的連結
引數
struct media_pad *source源 pad
struct media_pad *sink接收端 pad
返回
返回指向兩個實體之間連結的指標。如果不存在此類連結,則返回 NULL。
引數
const struct media_pad *pad連結本地端的 pad
描述
透過迭代源於或終止於該 pad 的所有連結來搜尋連線到給定 pad 的遠端 pad,直到找到啟用的連結。
返回
返回指向第一個找到的啟用連結的遠端端 pad 的指標,如果未找到任何啟用連結,則返回 NULL。
引數
const struct media_pad *padpad
描述
搜尋並透過啟用連結返回連線到 pad 的遠端 pad。如果找到多個(或沒有)遠端 pad,則返回錯誤。
唯一性約束使此輔助函式適用於一次在給定 pad 上支援單個活動源的實體。
-ENOTUNIQ - 啟用了多個連結
-ENOLINK - 未找到連線的 pad
返回
指向遠端 pad 的指標,如果發生錯誤,則指向以下錯誤指標之一
-
struct media_pad *media_entity_remote_pad_unique(const struct media_entity *entity, unsigned int type)¶
查詢連線到實體的遠端 pad
引數
const struct media_entity *entity實體
unsigned int type要查詢的 pad 型別 (MEDIA_PAD_FL_SINK 或 MEDIA_PAD_FL_SOURCE)
描述
搜尋並透過啟用連結返回連線到 entity 的 type 的遠端 pad。如果多個(或沒有)遠端 pad 符合這些條件,則返回錯誤。
唯一性約束使此輔助函式適用於一次支援單個活動源或接收端的實體。
-ENOTUNIQ - 啟用了多個連結
-ENOLINK - 未找到連線的 pad
返回
指向遠端 pad 的指標,如果發生錯誤,則指向以下錯誤指標之一
-
struct media_pad *media_entity_remote_source_pad_unique(const struct media_entity *entity)¶
查詢連線到實體的遠端源 pad
引數
const struct media_entity *entity實體
描述
搜尋並透過啟用連結返回連線到 entity 的遠端源 pad。如果多個(或沒有)遠端 pad 符合這些條件,則返回錯誤。
唯一性約束使此輔助函式適用於一次支援單個活動源的實體。
-ENOTUNIQ - 啟用了多個連結
-ENOLINK - 未找到連線的 pad
返回
指向遠端 pad 的指標,如果發生錯誤,則指向以下錯誤指標之一
引數
const struct media_pad *padpad
返回
如果 pad 是使用 media_pipeline_start() 函式啟動的管道的一部分,則為 True,否則為 false。
-
bool media_entity_is_streaming(const struct media_entity *entity)¶
測試實體是否是流式傳輸管道的一部分
引數
const struct media_entity *entity實體
返回
如果實體是使用 media_pipeline_start() 函式啟動的管道的一部分,則為 True,否則為 false。
-
struct media_pipeline *media_entity_pipeline(struct media_entity *entity)¶
獲取實體所屬的媒體管道
引數
struct media_entity *entity實體
描述
已棄用:請改用 media_pad_pipeline()。
此函式返回在使用 media_pipeline_start() 構建管道時與實體關聯的媒體管道。指標在呼叫 media_pipeline_stop() 之前仍然有效。
通常,實體可以是多個管道的一部分,當攜帶多個流時(在不同的 pad 上或在使用多路複用流的同一 pad 上)。此函式僅用於不支援多個管道的實體。
返回
實體所屬的 media_pipeline,如果實體不屬於任何管道,則為 NULL。
-
struct media_pipeline *media_pad_pipeline(struct media_pad *pad)¶
獲取 pad 所屬的媒體管道
引數
struct media_pad *padpad
描述
此函式返回在使用 media_pipeline_start() 構建管道時與 pad 關聯的媒體管道。指標在呼叫 media_pipeline_stop() 之前仍然有效。
返回
pad 所屬的 media_pipeline,如果 pad 不屬於任何管道,則為 NULL。
-
int media_entity_get_fwnode_pad(struct media_entity *entity, const struct fwnode_handle *fwnode, unsigned long direction_flags)¶
從 fwnode 獲取 pad 編號
引數
struct media_entity *entity實體
const struct fwnode_handle *fwnode指向應用於查詢 pad 的 fwnode_handle 的指標
unsigned long direction_flagspad 的預期方向,定義在 include/uapi/linux/media.h 中 (查詢
MEDIA_PAD_FL_*)
描述
此函式可用於從 fwnode 解析媒體 pad 編號。這對於使用更復雜的媒體 pad 對映的裝置非常有用。
如果實體未實現 get_fwnode_pad() 操作,則此函式會在實體中搜索與 direction_flags 匹配的第一個 pad。
返回
成功時返回 pad 編號,或返回負錯誤程式碼。
-
int media_graph_walk_init(struct media_graph *graph, struct media_device *mdev)¶
分配圖形遍歷使用的資源。
引數
struct media_graph *graph將用於遍歷圖形的媒體圖形結構
struct media_device *mdev指向包含該物件的
media_device的指標
描述
此函式已棄用,請改用 media_pipeline_for_each_pad()。
呼叫者需要在圖形遍歷期間持有 media_device graph_mutex,直到釋放圖形狀態。
成功時返回零,否則返回負錯誤程式碼。
-
void media_graph_walk_cleanup(struct media_graph *graph)¶
釋放圖形遍歷使用的資源。
-
void media_graph_walk_start(struct media_graph *graph, struct media_entity *entity)¶
從給定實體開始遍歷媒體圖形
引數
struct media_graph *graph將用於遍歷圖形的媒體圖形結構
struct media_entity *entity起始實體
描述
此函式已棄用,請改用 media_pipeline_for_each_pad()。
在使用此函式之前,必須使用 media_graph_walk_init() 分配用於遍歷圖形的資源。此函式初始化圖形遍歷結構,以遍歷從給定實體開始的實體圖形。遍歷結構不得在圖形遍歷期間由呼叫者修改。在圖形遍歷之後,必須使用 media_graph_walk_cleanup() 釋放資源。
-
struct media_entity *media_graph_walk_next(struct media_graph *graph)¶
獲取圖形中的下一個實體
引數
struct media_graph *graph媒體圖形結構
描述
此函式已棄用,請改用 media_pipeline_for_each_pad()。
執行給定媒體實體圖形的深度優先遍歷。
圖形結構必須先前已透過呼叫 media_graph_walk_start() 初始化。
返回
返回圖形中的下一個實體,如果已遍歷整個圖形,則返回 NULL。
-
int media_pipeline_start(struct media_pad *origin, struct media_pipeline *pipe)¶
將管道標記為流式傳輸
引數
struct media_pad *origin起始 pad
struct media_pipeline *pipe要分配給管道中所有 pad 的媒體管道。
描述
將透過啟用連結(直接或間接)連線到 pad origin 的所有 pad 標記為流式傳輸。給定的管道物件分配給管道中的每個 pad,並存儲在 media_pad 管道欄位中。
可以巢狀對此函式的呼叫,在這種情況下,需要相同數量的 media_pipeline_stop() 呼叫來停止流式傳輸。對於所有巢狀的 media_pipeline_start() 呼叫,管道指標必須相同。
-
int __media_pipeline_start(struct media_pad *origin, struct media_pipeline *pipe)¶
將管道標記為流式傳輸
引數
struct media_pad *origin起始 pad
struct media_pipeline *pipe要分配給管道中所有 pad 的媒體管道。
描述
.. note:: 這是 media_pipeline_start() 的非鎖定版本
引數
struct media_pad *pad起始 pad
描述
將透過啟用的連結(直接或間接)連線到給定 pad 的所有 pad 標記為非流式傳輸。media_pad pipe 欄位重置為 NULL。
如果多次呼叫 media_pipeline_start(),則需要相同次數的函式呼叫才能將流水線標記為非流式傳輸。
-
media_pipeline_for_each_pad¶
media_pipeline_for_each_pad (pipe, iter, pad)
迭代媒體流水線中的所有 pad
引數
pipe流水線
iterpad迭代器 pad
描述
迭代媒體流水線中的所有 pad。這僅在流水線已使用 media_pipeline_start() 構建並在使用 media_pipeline_stop() 銷燬之前有效。
-
int media_pipeline_entity_iter_init(struct media_pipeline *pipe, struct media_pipeline_entity_iter *iter)¶
初始化流水線實體迭代器
引數
struct media_pipeline *pipe流水線
struct media_pipeline_entity_iter *iter迭代器
描述
必須呼叫此函式以初始化迭代器,然後才能在 media_pipeline_for_each_entity() 迴圈中使用它。迭代器必須在迴圈後(包括從迴圈中斷的程式碼路徑)透過呼叫 media_pipeline_entity_iter_cleanup 來銷燬。
相同的迭代器可以在多個連續迴圈中使用,而無需銷燬和重新初始化。
返回
成功時為 0,否則為負錯誤程式碼。
-
void media_pipeline_entity_iter_cleanup(struct media_pipeline_entity_iter *iter)¶
銷燬流水線實體迭代器
引數
struct media_pipeline_entity_iter *iter迭代器
描述
必須呼叫此函式以銷燬使用 media_pipeline_entity_iter_init() 初始化的迭代器。
-
media_pipeline_for_each_entity¶
media_pipeline_for_each_entity (pipe, iter, entity)
迭代媒體流水線中的所有實體
引數
pipe流水線
iter實體迭代器實體
描述
迭代媒體流水線中的所有實體。這僅在流水線已使用 media_pipeline_start() 構建並在使用 media_pipeline_stop() 銷燬之前有效。迭代器必須在使用迭代之前使用 media_pipeline_entity_iter_init() 初始化,並在之後使用 media_pipeline_entity_iter_cleanup() 銷燬(包括從迴圈中斷的程式碼路徑)。
引數
struct media_pad *pad起始 pad
描述
media_pipeline_alloc_start() 類似於 media_pipeline_start(),但該函式不是在給定流水線上工作,而是在 pad 已經是流水線的一部分時使用現有流水線,或者分配一個新的流水線。
對 media_pipeline_alloc_start() 的呼叫必須與 media_pipeline_stop() 匹配。
-
struct media_intf_devnode *media_devnode_create(struct media_device *mdev, u32 type, u32 flags, u32 major, u32 minor)¶
建立並初始化裝置節點介面
引數
struct media_device *mdev指向 struct
media_device的指標u32 type介面型別,如 include/uapi/linux/media.h 中給出的(搜尋
MEDIA_INTF_T_*宏)。u32 flags介面標誌,如 include/uapi/linux/media.h 中定義的(搜尋
MEDIA_INTF_FL_*)u32 major裝置節點主編號。
u32 minor裝置節點次編號。
返回
- 如果成功,則返回指向新分配的
描述
注意
目前,沒有為 media_interface 定義任何標誌。
-
void media_devnode_remove(struct media_intf_devnode *devnode)¶
移除裝置節點介面
-
struct media_link *media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags)¶
建立實體和介面之間的連結
引數
struct media_entity *entity指向
media_entity的指標struct media_interface *intf指向
media_interface的指標u32 flags連結標誌,定義在 include/uapi/linux/media.h 中 (查詢
MEDIA_LNK_FL_*)
描述
flags 的有效值
MEDIA_LNK_FL_ENABLED表示介面已連線到實體硬體。這是介面的預設值。如果硬體由於使用當前正在控制硬體的其他介面而繁忙,則可以停用介面。
一個典型的例子是混合電視裝置,該裝置在給定的時間只能處理一種型別的流。因此,當數字電視正在流式傳輸時,V4L2 介面將不會啟用,因為此類裝置也無法流式傳輸模擬電視或廣播。
注意
在呼叫此函式之前,應該為介面呼叫 media_devnode_create(),並且應該為將成為連結一部分的介面呼叫 media_device_register_entity()。
-
void __media_remove_intf_link(struct media_link *link)¶
刪除單個介面連結
-
void media_remove_intf_link(struct media_link *link)¶
刪除單個介面連結
-
void __media_remove_intf_links(struct media_interface *intf)¶
移除與介面關聯的所有連結
-
void media_remove_intf_links(struct media_interface *intf)¶
移除與介面關聯的所有連結
引數
struct media_interface *intf指向
media_interface的指標
描述
注意
透過
media_device_register_entity()取消註冊實體以及透過media_devnode_remove()取消註冊實體時,會自動呼叫此函式。首選使用此方法,而不是
__media_remove_intf_links()。
-
media_entity_call¶
media_entity_call (entity, operation, args...)
在實體上呼叫
struct media_entity_operations操作
引數
實體將在其中呼叫 operation 的實體
操作操作型別。應為結構
media_entity_operations的成員名稱。args...可變引數
描述
此輔助函式將檢查 operation 是否不為 NULL。在這種情況下,它將發出對 operation(entity, args) 的呼叫。
-
struct media_link *media_create_ancillary_link(struct media_entity *primary, struct media_entity *ancillary)¶
在
media_entity的兩個例項之間建立輔助連結
引數
struct media_entity *primary指向主要
media_entity的指標struct media_entity *ancillary指向輔助
media_entity的指標
描述
在兩個實體之間建立輔助連結,表明它們表示形成單個邏輯單元的兩個連線的硬體。一個典型的例子是連線到其支援的感測器的相機鏡頭控制器。
該函式為新連結設定 MEDIA_LNK_FL_ENABLED 和 MEDIA_LNK_FL_IMMUTABLE。
-
struct media_link *__media_entity_next_link(struct media_entity *entity, struct media_link *link, unsigned long link_type)¶
遍歷
media_entity的連結
引數
struct media_entity *entity指向
media_entity的指標struct media_link *link指向
media_link的指標以儲存迭代值unsigned long link_typeMEDIA_LNK_FL_LINK_TYPE 標誌之一
描述
返回與特定連結型別匹配的實體的下一個連結。這允許遍歷實體的連結,同時保證所有返回的連結都是給定型別。
-
for_each_media_entity_data_link¶
for_each_media_entity_data_link (entity, link)
遍歷實體的資料鏈接
-
enum media_request_state¶
媒體請求狀態
常量
MEDIA_REQUEST_STATE_IDLE空閒
MEDIA_REQUEST_STATE_VALIDATING正在驗證請求,不允許狀態更改
MEDIA_REQUEST_STATE_QUEUED已排隊
MEDIA_REQUEST_STATE_COMPLETE已完成,請求已完成
MEDIA_REQUEST_STATE_CLEANING正在清理,請求正在重新初始化
MEDIA_REQUEST_STATE_UPDATING正在更新請求,即正在新增、修改或移除請求物件
NR_OF_MEDIA_REQUEST_STATE媒體請求狀態的數量,在內部用於完整性檢查
-
struct media_request¶
媒體裝置請求
定義:
struct media_request {
struct media_device *mdev;
struct kref kref;
char debug_str[TASK_COMM_LEN + 11];
enum media_request_state state;
unsigned int updating_count;
unsigned int access_count;
struct list_head objects;
unsigned int num_incomplete_objects;
wait_queue_head_t poll_wait;
spinlock_t lock;
};
成員
mdev此請求所屬的媒體裝置
kref引用計數
debug_str除錯訊息的字首(程序名稱:fd)
state請求的狀態
updating_count計算正在進行的請求更新的數量
access_count計算正在進行的請求訪問的數量
objectsstruct media_request_object 請求物件的列表
num_incomplete_objects請求中未完成物件的數量
poll_waitpoll 的等待佇列
lock序列化對此結構的訪問
-
int media_request_lock_for_access(struct media_request *req)¶
鎖定請求以訪問其物件
引數
struct media_request *req媒體請求
描述
在訪問已完成的請求之前使用。在訪問期間必須持有對請求的引用。這通常透過檔案控制代碼自動進行。完成後使用 media_request_unlock_for_access。
-
void media_request_unlock_for_access(struct media_request *req)¶
解鎖先前為訪問而鎖定的請求
引數
struct media_request *req媒體請求
描述
解鎖先前使用 media_request_lock_for_access 鎖定的請求。
-
int media_request_lock_for_update(struct media_request *req)¶
鎖定請求以更新其物件
引數
struct media_request *req媒體請求
描述
在更新請求之前使用,即在其中新增、修改或移除請求物件。在更新期間必須持有對請求的引用。這通常透過檔案控制代碼自動進行。完成後使用 media_request_unlock_for_update。
-
void media_request_unlock_for_update(struct media_request *req)¶
解鎖先前為更新而鎖定的請求
引數
struct media_request *req媒體請求
描述
解鎖先前使用 media_request_lock_for_update 鎖定的請求。
-
void media_request_get(struct media_request *req)¶
獲取媒體請求
引數
struct media_request *req媒體請求
描述
獲取媒體請求。
-
void media_request_put(struct media_request *req)¶
放置媒體請求
引數
struct media_request *req媒體請求
描述
放置媒體請求。當引用計數達到 0 時,將釋放媒體請求。
-
struct media_request *media_request_get_by_fd(struct media_device *mdev, int request_fd)¶
按 fd 獲取媒體請求
引數
struct media_device *mdev此請求所屬的媒體裝置
int request_fd請求的檔案描述符
描述
獲取由媒體裝置擁有的 request_fd 表示的請求。
如果此驅動程式不支援請求,則返回 -EBADR 錯誤指標。如果未找到請求,則返回 -EINVAL。如果找到請求,則返回指向請求的指標:呼叫者在使用完請求後必須呼叫 media_request_put。
-
int media_request_alloc(struct media_device *mdev, int *alloc_fd)¶
分配媒體請求
引數
struct media_device *mdev此請求所屬的媒體裝置
int *alloc_fd將請求的檔案描述符儲存在此 int 中
描述
分配媒體請求並將 fd 放入 alloc_fd 中。
-
struct media_request_object_ops¶
媒體請求物件操作
定義:
struct media_request_object_ops {
int (*prepare)(struct media_request_object *object);
void (*unprepare)(struct media_request_object *object);
void (*queue)(struct media_request_object *object);
void (*unbind)(struct media_request_object *object);
void (*release)(struct media_request_object *object);
};
成員
prepare驗證並準備請求物件,可選。
unprepare取消準備請求物件,可選。
queue將請求物件排隊,可選。
unbind取消繫結請求物件,可選。
releaseRelease
-
struct media_request_object¶
屬於媒體請求的不透明物件
定義:
struct media_request_object {
const struct media_request_object_ops *ops;
void *priv;
struct media_request *req;
struct list_head list;
struct kref kref;
bool completed;
};
成員
ops物件的運算
priv物件的私有指標
req此物件所屬的請求(可以為 NULL)
列表struct media_request 的物件列表條目
kref物件的引用計數,在釋放 req->lock 之前獲取
completed如果為 true,則此物件已完成。
描述
與請求相關的物件。此結構始終嵌入在另一個包含此請求物件的實際資料的結構中。
-
void media_request_object_get(struct media_request_object *obj)¶
獲取媒體請求物件
引數
struct media_request_object *obj物件
描述
獲取媒體請求物件。
-
void media_request_object_put(struct media_request_object *obj)¶
放置媒體請求物件
引數
struct media_request_object *obj物件
描述
放置媒體請求物件。一旦所有引用都消失,物件的記憶體就會被釋放。
-
struct media_request_object *media_request_object_find(struct media_request *req, const struct media_request_object_ops *ops, void *priv)¶
在請求中查詢物件
引數
struct media_request *req媒體請求
const struct media_request_object_ops *ops查詢具有此 ops 值的物件
void *priv查詢具有此私有值的物件
描述
ops 和 priv 都必須為非 NULL。
返回物件指標;如果未找到,則返回 NULL。呼叫者必須在使用完物件後呼叫 media_request_object_put()。
由於此函式需要遍歷物件列表,因此它會獲取 req->lock 自旋鎖以確保安全。
-
void media_request_object_init(struct media_request_object *obj)¶
初始化媒體請求物件
引數
struct media_request_object *obj物件
描述
初始化媒體請求物件。一旦物件沒有引用,將使用 ops 的 release 回撥釋放該物件(此函式將引用初始化為 1)。
-
int media_request_object_bind(struct media_request *req, const struct media_request_object_ops *ops, void *priv, bool is_buffer, struct media_request_object *obj)¶
將媒體請求物件繫結到請求
引數
struct media_request *req媒體請求
const struct media_request_object_ops *ops此物件的物件操作
void *priv與此物件關聯的驅動程式特定的priv指標
bool is_buffer如果物件是緩衝區物件,則設定為true。
struct media_request_object *obj物件
描述
將此物件繫結到請求,並設定物件的操作和priv值,以便以後可以使用 media_request_object_find() 找到它。
每個繫結的物件都必須在某個時間點被核心解繫結或完成,否則請求將永遠不會完成。當請求被釋放時,所有已完成的物件將由請求核心程式碼解繫結。
緩衝區物件將被新增到請求的物件列表的末尾,非緩衝區物件將被新增到列表的前面。這確保了所有緩衝區物件都在列表的末尾,並且它們所依賴的所有非緩衝區物件都首先被處理。
-
void media_request_object_unbind(struct media_request_object *obj)¶
解繫結媒體請求物件
引數
struct media_request_object *obj物件
描述
從請求中解繫結媒體請求物件。
-
void media_request_object_complete(struct media_request_object *obj)¶
將媒體請求物件標記為已完成
引數
struct media_request_object *obj物件
描述
將媒體請求物件標記為已完成。只有繫結的物件才能完成。
-
struct media_device *media_device_usb_allocate(struct usb_device *udev, const char *module_name, struct module *owner)¶
分配並返回結構體
media裝置
引數
struct usb_device *udev結構體
usb_device指標const char *module_name應該用
KBUILD_MODNAME填充struct module *owner驅動程式的結構體模組指標
THIS_MODULE。對於內建驅動程式,THIS_MODULE為 null。即使THIS_MODULE為 null,它也是安全的。
描述
當多個驅動程式共享 usb_device 和媒體裝置時,應呼叫此介面來分配媒體裝置。此介面分配 media_device 結構並呼叫 media_device_usb_init() 來初始化它。
-
void media_device_delete(struct media_device *mdev, const char *module_name, struct module *owner)¶
釋放媒體裝置。呼叫
kref_put()。
引數
struct media_device *mdev結構體
media_device指標const char *module_name應該用
KBUILD_MODNAME填充struct module *owner驅動程式的結構體模組指標
THIS_MODULE。對於內建驅動程式,THIS_MODULE為 null。即使THIS_MODULE為 null,它也是安全的。
描述
應該呼叫此介面來放置 Media Device Instance kref。