2.15. V4L2 控制¶
2.15.1. 簡介¶
V4L2 控制 API 看起來很簡單,但在驅動程式中正確實現很快就會變得非常困難。但是,處理控制元件所需的許多程式碼實際上並不是特定於驅動程式的,可以轉移到 V4L 核心框架。
畢竟,驅動程式開發人員唯一感興趣的部分是
如何新增控制元件?
如何設定控制元件的值?(即 s_ctrl)
偶爾
如何獲取控制元件的值?(即 g_volatile_ctrl)
如何驗證使用者建議的控制元件值?(即 try_ctrl)
其餘的都可以集中處理。
建立控制框架是為了在中心位置實現 V4L2 規範中關於控制的所有規則。並儘可能地方便驅動程式開發人員。
請注意,控制框架依賴於 V4L2 驅動程式的 v4l2_device 結構和子裝置驅動程式的 struct v4l2_subdev 的存在。
2.15.2. 框架中的物件¶
有兩個主要物件
v4l2_ctrl 物件描述了控制元件的屬性並跟蹤控制元件的值(包括當前值和建議的新值)。
v4l2_ctrl_handler 是跟蹤控制元件的物件。它維護一個它擁有的 v4l2_ctrl 物件列表,以及一個對控制元件的引用列表,可能引用其他處理程式擁有的控制元件。
2.15.3. V4L2 和子裝置驅動程式的基本用法¶
準備驅動程式
#include <media/v4l2-ctrls.h>
1.1) 將處理程式新增到驅動程式的頂層結構
對於 V4L2 驅動程式
struct foo_dev {
...
struct v4l2_device v4l2_dev;
...
struct v4l2_ctrl_handler ctrl_handler;
...
};
對於子裝置驅動程式
struct foo_dev {
...
struct v4l2_subdev sd;
...
struct v4l2_ctrl_handler ctrl_handler;
...
};
1.2) 初始化處理程式
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
第二個引數是一個提示,告訴函式期望此處理程式處理多少個控制元件。它將基於此資訊分配一個雜湊表。這只是一個提示。
1.3) 將控制元件處理程式掛鉤到驅動程式中
對於 V4L2 驅動程式
foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler;
對於子裝置驅動程式
foo->sd.ctrl_handler = &foo->ctrl_handler;
1.4) 在最後清理處理程式
v4l2_ctrl_handler_free(&foo->ctrl_handler);
新增控制元件
您可以透過呼叫 v4l2_ctrl_new_std() 新增非選單控制元件
struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, s32 min, s32 max, u32 step, s32 def);
選單和整數選單控制元件透過呼叫 v4l2_ctrl_new_std_menu() 新增
struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, s32 max, s32 skip_mask, s32 def);
帶有特定於驅動程式的選單的選單控制元件透過呼叫 v4l2_ctrl_new_std_menu_items() 新增
struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
s32 skip_mask, s32 def, const char * const *qmenu);
標準複合控制元件可以透過呼叫 v4l2_ctrl_new_std_compound() 新增
struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops, u32 id,
const union v4l2_ctrl_ptr p_def);
帶有特定於驅動程式的選單的整數選單控制元件可以透過呼叫 v4l2_ctrl_new_int_menu() 新增
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, s32 max, s32 def, const s64 *qmenu_int);
這些函式通常在 v4l2_ctrl_handler_init() 之後立即呼叫
static const s64 exp_bias_qmenu[] = {
-2, -1, 0, 1, 2
};
static const char * const test_pattern[] = {
"Disabled",
"Vertical Bars",
"Solid Black",
"Solid White",
};
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
V4L2_CID_CONTRAST, 0, 255, 1, 128);
v4l2_ctrl_new_std_menu(&foo->ctrl_handler, &foo_ctrl_ops,
V4L2_CID_POWER_LINE_FREQUENCY,
V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
v4l2_ctrl_new_int_menu(&foo->ctrl_handler, &foo_ctrl_ops,
V4L2_CID_EXPOSURE_BIAS,
ARRAY_SIZE(exp_bias_qmenu) - 1,
ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
exp_bias_qmenu);
v4l2_ctrl_new_std_menu_items(&foo->ctrl_handler, &foo_ctrl_ops,
V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
0, test_pattern);
...
if (foo->ctrl_handler.error) {
int err = foo->ctrl_handler.error;
v4l2_ctrl_handler_free(&foo->ctrl_handler);
return err;
}
v4l2_ctrl_new_std() 函式返回指向新控制元件的 v4l2_ctrl 指標,但如果不需要在控制元件操作之外訪問該指標,則無需儲存它。
v4l2_ctrl_new_std() 函式將根據控制元件 ID 填充大多數字段,但最小值、最大值、步長和預設值除外。這些值在最後四個引數中傳遞。這些值是特定於驅動程式的,而控制元件屬性(如型別、名稱、標誌)都是全域性的。控制元件的當前值將設定為預設值。
v4l2_ctrl_new_std_menu() 函式非常相似,但它用於選單控制元件。由於選單控制元件的最小值始終為 0,因此沒有 min 引數,並且沒有步長,而是一個 skip_mask 引數:如果位 X 為 1,則跳過選單項 X。
v4l2_ctrl_new_int_menu() 函式建立一個新的標準整數選單控制元件,其中選單中包含特定於驅動程式的項。它與 v4l2_ctrl_new_std_menu 的不同之處在於,它沒有掩碼引數,而是將有符號 64 位整數陣列作為最後一個引數,該陣列構成精確的選單項列表。
v4l2_ctrl_new_std_menu_items() 函式與 v4l2_ctrl_new_std_menu 非常相似,但採用了一個額外的引數 qmenu,它是特定於驅動程式的選單,用於其他標準的選單控制元件。此控制元件的一個很好的示例是捕獲/顯示/感測器裝置的測試模式控制元件,該控制元件具有生成測試模式的功能。這些測試模式是特定於硬體的,因此選單的內容會因裝置而異。
請注意,如果出現問題,該函式將返回 NULL 或錯誤,並將 ctrl_handler->error 設定為錯誤程式碼。如果 ctrl_handler->error 已設定,則它只會返回並且不執行任何操作。如果 v4l2_ctrl_handler_init 無法分配內部資料結構,則也是如此。
這使得初始化處理程式並新增所有控制元件,並在最後僅檢查錯誤程式碼變得容易。節省了大量重複的錯誤檢查。
建議按升序控制元件 ID 順序新增控制元件:這樣會稍微快一些。
(可選)強制初始控制元件設定
v4l2_ctrl_handler_setup(&foo->ctrl_handler);
這將無條件地為所有控制元件呼叫 s_ctrl。實際上,這會將硬體初始化為預設控制元件值。建議這樣做,因為這可以確保內部資料結構和硬體都同步。
最後:實現
v4l2_ctrl_ops
static const struct v4l2_ctrl_ops foo_ctrl_ops = {
.s_ctrl = foo_s_ctrl,
};
通常您只需要 s_ctrl
static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
write_reg(0x123, ctrl->val);
break;
case V4L2_CID_CONTRAST:
write_reg(0x456, ctrl->val);
break;
}
return 0;
}
呼叫控制元件操作時,v4l2_ctrl 指標作為引數。新的控制元件值已經過驗證,因此您需要做的就是實際更新硬體暫存器。
你完成了!這對於我們擁有的大多數驅動程式來說已經足夠了。無需驗證控制元件值,或實現 QUERYCTRL、QUERY_EXT_CTRL 和 QUERYMENU。並且自動支援 G/S_CTRL 以及 G/TRY/S_EXT_CTRLS。
注意
其餘部分處理更高階的控制元件主題和場景。實際上,上述基本用法對於大多數驅動程式來說已經足夠了。
2.15.4. 繼承子裝置控制元件¶
當透過呼叫 v4l2_device_register_subdev() 向 V4L2 驅動程式註冊子裝置,並且設定了 v4l2_subdev 和 v4l2_device 的 ctrl_handler 欄位時,子裝置的控制元件也會自動在 V4L2 驅動程式中可用。如果子裝置驅動程式包含 V4L2 驅動程式中已存在的控制元件,則會跳過這些控制元件(因此 V4L2 驅動程式始終可以覆蓋子裝置控制元件)。
這裡發生的是 v4l2_device_register_subdev() 呼叫 v4l2_ctrl_add_handler(),將子裝置的控制元件新增到 v4l2_device 的控制元件中。
2.15.5. 訪問控制元件值¶
以下聯合在控制框架內部用於訪問控制元件值
union v4l2_ctrl_ptr {
s32 *p_s32;
s64 *p_s64;
char *p_char;
void *p;
};
v4l2_ctrl 結構包含以下欄位,可用於訪問當前值和新值
s32 val;
struct {
s32 val;
} cur;
union v4l2_ctrl_ptr p_new;
union v4l2_ctrl_ptr p_cur;
如果控制元件具有簡單的 s32 型別,則
&ctrl->val == ctrl->p_new.p_s32
&ctrl->cur.val == ctrl->p_cur.p_s32
對於所有其他型別,請使用 ctrl->p_cur.p<something>。基本上,val 和 cur.val 欄位可以被視為別名,因為它們經常被使用。
在控制元件操作中,您可以自由使用這些。val 和 cur.val 不言自明。p_char 指標指向長度為 ctrl->maximum + 1 的字元緩衝區,並且始終以 0 結尾。
除非控制元件被標記為 volatile,否則 p_cur 欄位指向當前快取的控制元件值。當您建立新控制元件時,此值與預設值相同。呼叫 v4l2_ctrl_handler_setup() 後,此值將傳遞到硬體。通常,呼叫此函式是一個好主意。
每當設定新值時,該新值都會自動快取。這意味著大多數驅動程式不需要實現 g_volatile_ctrl() 操作。例外情況是對於返回易失性暫存器的控制元件,例如訊號強度讀數,該讀數會持續變化。在這種情況下,您將需要像這樣實現 g_volatile_ctrl
static int foo_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->val = read_reg(0x123);
break;
}
}
請注意,您也在 g_volatile_ctrl 中使用“新值”聯合。通常,需要實現 g_volatile_ctrl 的控制元件是隻讀控制元件。如果它們不是,則當控制元件更改時,不會生成 V4L2_EVENT_CTRL_CH_VALUE。
要將控制元件標記為 volatile,您必須設定 V4L2_CTRL_FLAG_VOLATILE
ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
if (ctrl)
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
對於 try/s_ctrl,將填充新值(即使用者傳遞的值),您可以在 try_ctrl 中修改它們或在 s_ctrl 中設定它們。“cur”聯合包含當前值,您也可以使用它(但不能更改!)。
如果 s_ctrl 返回 0 (OK),則控制框架會將新的最終值複製到“cur”聯合中。
在 g_volatile/s/try_ctrl 中,您可以訪問同一處理程式擁有的所有控制元件的值,因為持有處理程式的鎖。如果您需要訪問其他處理程式擁有的控制元件的值,則必須非常小心,不要引入死鎖。
在控制元件操作之外,您必須透過輔助函式來安全地獲取或設定驅動程式中的單個控制元件值
s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
這些函式像 VIDIOC_G/S_CTRL ioctl 一樣透過控制框架。但是,不要在控制元件操作 g_volatile/s/try_ctrl 中使用它們,因為這將導致死鎖,因為這些輔助函式也會鎖定處理程式。
您也可以自己獲取處理程式鎖
mutex_lock(&state->ctrl_handler.lock);
pr_info("String value is '%s'\n", ctrl1->p_cur.p_char);
pr_info("Integer value is '%s'\n", ctrl2->cur.val);
mutex_unlock(&state->ctrl_handler.lock);
2.15.7. 自定義控制元件¶
可以使用 v4l2_ctrl_new_custom() 建立特定於驅動程式的控制元件
static const struct v4l2_ctrl_config ctrl_filter = {
.ops = &ctrl_custom_ops,
.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
.name = "Spatial Filter",
.type = V4L2_CTRL_TYPE_INTEGER,
.flags = V4L2_CTRL_FLAG_SLIDER,
.max = 15,
.step = 1,
};
ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_filter, NULL);
最後一個引數是 priv 指標,可以設定為特定於驅動程式的私有資料。
v4l2_ctrl_config 結構還有一個用於設定 is_private 標誌的欄位。
如果未設定 name 欄位,則框架將假定這是一個標準控制元件,並將相應地填充 name、type 和 flags 欄位。
2.15.8. 活動和抓取的控制元件¶
如果控制元件之間存在更復雜的關係,則可能需要啟用和停用控制元件。例如,如果 Chroma AGC 控制元件已開啟,則 Chroma Gain 控制元件處於非活動狀態。也就是說,您可以設定它,但只要自動增益控制處於開啟狀態,硬體就不會使用該值。通常,使用者介面可以停用此類輸入欄位。
您可以使用 v4l2_ctrl_activate() 設定“active”狀態。預設情況下,所有控制元件都是活動的。請注意,框架不檢查此標誌。它純粹是為了 GUI。該函式通常從 s_ctrl 中呼叫。
另一個標誌是“grabbed”標誌。抓取的控制元件意味著您無法更改它,因為它正在被某些資源使用。典型的例子是 MPEG 位元率控制元件,在捕獲正在進行時無法更改。
如果使用 v4l2_ctrl_grab() 將控制元件設定為“grabbed”,則如果嘗試設定此控制元件,框架將返回 -EBUSY。v4l2_ctrl_grab() 函式通常在驅動程式啟動或停止流式傳輸時呼叫。
2.15.9. 控制元件叢集¶
預設情況下,所有控制元件都與其他控制元件無關。但在更復雜的場景中,您可以獲得從一個控制元件到另一個控制元件的依賴關係。在這種情況下,您需要“叢集”它們
struct foo {
struct v4l2_ctrl_handler ctrl_handler;
#define AUDIO_CL_VOLUME (0)
#define AUDIO_CL_MUTE (1)
struct v4l2_ctrl *audio_cluster[2];
...
};
state->audio_cluster[AUDIO_CL_VOLUME] =
v4l2_ctrl_new_std(&state->ctrl_handler, ...);
state->audio_cluster[AUDIO_CL_MUTE] =
v4l2_ctrl_new_std(&state->ctrl_handler, ...);
v4l2_ctrl_cluster(ARRAY_SIZE(state->audio_cluster), state->audio_cluster);
從現在開始,只要設定(或“獲取”或“嘗試”)屬於同一叢集的一個或多個控制元件,只會呼叫第一個控制元件(在本例中為“volume”)的控制元件操作。您有效地建立了一個新的複合控制元件。類似於 C 中“struct”的工作方式。
因此,當使用 V4L2_CID_AUDIO_VOLUME 作為引數呼叫 s_ctrl 時,您應該設定屬於 audio_cluster 的所有兩個控制元件
static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME: {
struct v4l2_ctrl *mute = ctrl->cluster[AUDIO_CL_MUTE];
write_reg(0x123, mute->val ? 0 : ctrl->val);
break;
}
case V4L2_CID_CONTRAST:
write_reg(0x456, ctrl->val);
break;
}
return 0;
}
在上面的示例中,對於 VOLUME 的情況,以下內容是等效的
ctrl == ctrl->cluster[AUDIO_CL_VOLUME] == state->audio_cluster[AUDIO_CL_VOLUME]
ctrl->cluster[AUDIO_CL_MUTE] == state->audio_cluster[AUDIO_CL_MUTE]
實際上,像這樣使用叢集陣列會變得非常麻煩。因此,改為使用以下等效方法
struct {
/* audio cluster */
struct v4l2_ctrl *volume;
struct v4l2_ctrl *mute;
};
匿名結構用於清楚地“叢集”這兩個控制元件指標,但它沒有其他用途。效果與建立具有兩個控制元件指標的陣列相同。因此,您可以只做
state->volume = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
state->mute = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
v4l2_ctrl_cluster(2, &state->volume);
在 foo_s_ctrl 中,您可以直接使用這些指標:state->mute->val。
請注意,叢集中的控制元件可能為 NULL。例如,如果由於某種原因從未新增靜音(因為硬體不支援該特定功能),則靜音將為 NULL。因此,在這種情況下,我們有一個包含 2 個控制元件的叢集,其中實際上只例項化了 1 個控制元件。唯一的限制是叢集的第一個控制元件必須始終存在,因為它是叢集的“主”控制元件。主控制元件是識別叢集並提供指向用於該叢集的 v4l2_ctrl_ops 結構的指標的控制元件。
顯然,叢集陣列中的所有控制元件都必須初始化為有效控制元件或 NULL。
在極少數情況下,您可能想知道叢集的哪些控制元件實際上是由使用者顯式設定的。為此,您可以檢查每個控制元件的“is_new”標誌。例如,在音量/靜音叢集的情況下,如果使用者僅為靜音呼叫 VIDIOC_S_CTRL,則會設定靜音控制元件的“is_new”標誌。如果使用者為靜音和音量控制元件呼叫 VIDIOC_S_EXT_CTRLS,則兩個控制元件的“is_new”標誌都將為 1。
從 v4l2_ctrl_handler_setup() 呼叫時,“is_new”標誌始終為 1。
2.15.10. 使用自動叢集處理自動增益/增益型別控制元件¶
一種常見的控制元件叢集型別是處理“auto-foo/foo”型別的控制元件。典型的例子是自動增益/增益、自動曝光/曝光、自動白平衡/紅色平衡/藍色平衡。在所有情況下,您都有一個控制元件,用於確定另一個控制元件是由硬體自動處理,還是在使用者的手動控制下。
如果叢集處於自動模式,則應將手動控制元件標記為非活動和易失性。讀取易失性控制元件時,g_volatile_ctrl 操作應返回硬體的自動模式自動設定的值。
如果叢集設定為手動模式,則手動控制元件應再次變為活動狀態,並且清除易失性標誌(因此在手動模式下不再呼叫 g_volatile_ctrl)。此外,在切換到手動模式之前,會將自動模式確定的當前值複製為新的手動值。
最後,應為自動控制元件設定 V4L2_CTRL_FLAG_UPDATE,因為更改該控制元件會影響手動控制元件的控制元件標誌。
為了簡化此操作,引入了 v4l2_ctrl_cluster 的特殊變體
void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
u8 manual_val, bool set_volatile);
前兩個引數與 v4l2_ctrl_cluster 相同。第三個引數告訴框架哪個值將叢集切換到手動模式。最後一個引數將可選地為非自動控制元件設定 V4L2_CTRL_FLAG_VOLATILE。如果為 false,則手動控制元件永遠不會易失性。如果硬體不為您提供讀回自動模式確定的值的選項,您通常會使用它(例如,如果自動增益開啟,則硬體不允許您獲取當前增益值)。
假定叢集的第一個控制元件是“自動”控制元件。
使用此函式將確保您無需處理所有複雜的標誌和 volatile 處理。
2.15.11. VIDIOC_LOG_STATUS 支援¶
此ioctl允許您將驅動程式的當前狀態轉儲到核心日誌中。 v4l2_ctrl_handler_log_status(ctrl_handler, prefix) 可用於將給定處理程式擁有的控制元件的值轉儲到日誌中。您也可以提供字首。如果字首未以空格結尾,則將為您新增“: ”。
2.15.12. 不同影片節點的不同的處理程式¶
通常,V4L2驅動程式只有一個控制處理程式,該處理程式對於所有影片節點都是全域性的。但是您也可以為不同的影片節點指定不同的控制處理程式。您可以透過手動設定 struct video_device 的 ctrl_handler 欄位來實現。
如果沒有涉及子裝置,則沒有問題,但是如果存在子裝置,則需要阻止子裝置控制元件自動合併到全域性控制處理程式。您只需將 struct v4l2_device 中的 ctrl_handler 欄位設定為 NULL 來實現這一點。現在 v4l2_device_register_subdev() 將不再合併子裝置控制元件。
新增每個子裝置後,您將必須手動呼叫 v4l2_ctrl_add_handler 以將子裝置的控制處理程式 (sd->ctrl_handler) 新增到所需的控制處理程式。此控制處理程式可能特定於 video_device 或 video_device 的子集。例如:無線電裝置節點只有音訊控制元件,而影片和 vbi 裝置節點共享音訊和影片控制元件的相同控制處理程式。
如果您希望一個處理程式(例如,用於無線電裝置節點)具有另一個處理程式的子集(例如,用於影片裝置節點),則應首先將控制元件新增到第一個處理程式,將其他控制元件新增到第二個處理程式,最後將第一個處理程式新增到第二個。例如
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_VOLUME, ...);
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler, NULL);
v4l2_ctrl_add_handler() 的最後一個引數是一個篩選函式,允許您篩選要新增哪些控制元件。如果要新增所有控制元件,請將其設定為 NULL。
或者,您可以將特定控制元件新增到處理程式
volume = v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_AUDIO_VOLUME, ...);
v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_BRIGHTNESS, ...);
v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_CONTRAST, ...);
您不應該做的是為兩個處理程式製作兩個相同的控制元件。例如
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_AUDIO_MUTE, ...);
這將是不好的,因為使無線電靜音不會更改影片靜音控制元件。規則是為您可以轉動的每個硬體“旋鈕”設定一個控制元件。
2.15.13. 查詢控制元件¶
通常,您自己建立了控制元件,並且可以將 struct v4l2_ctrl 指標儲存到您自己的結構中。
但是有時您需要從您不擁有的另一個處理程式中找到一個控制元件。例如,如果您必須從子裝置找到音量控制。
您可以透過呼叫 v4l2_ctrl_find 來實現這一點
struct v4l2_ctrl *volume;
volume = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_AUDIO_VOLUME);
由於 v4l2_ctrl_find 會鎖定處理程式,因此您必須小心在哪裡使用它。例如,這不是一個好主意
struct v4l2_ctrl_handler ctrl_handler;
v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
...以及在 video_ops.s_ctrl 中
case V4L2_CID_BRIGHTNESS:
contrast = v4l2_find_ctrl(&ctrl_handler, V4L2_CID_CONTRAST);
...
當框架呼叫 s_ctrl 時,ctrl_handler.lock 已經被佔用,因此嘗試從同一處理程式中找到另一個控制元件將導致死鎖。
建議不要從控制元件操作內部使用此函式。
2.15.14. 防止控制元件繼承¶
當使用 v4l2_ctrl_add_handler 將一個控制處理程式新增到另一個時,預設情況下,一個處理程式中的所有控制元件都會合併到另一個。但是,子裝置可能具有對於某些高階嵌入式系統有意義的低階控制元件,但在消費級硬體中使用時沒有意義。在這種情況下,您希望將這些低階控制元件保留在子裝置本地。您可以透過簡單地將控制元件的“is_private”標誌設定為 1 來實現這一點
static const struct v4l2_ctrl_config ctrl_private = {
.ops = &ctrl_custom_ops,
.id = V4L2_CID_...,
.name = "Some Private Control",
.type = V4L2_CTRL_TYPE_INTEGER,
.max = 15,
.step = 1,
.is_private = 1,
};
ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_private, NULL);
現在,當呼叫 v4l2_ctrl_add_handler 時,將跳過這些控制元件。
2.15.15. V4L2_CTRL_TYPE_CTRL_CLASS 控制元件¶
GUI 可以使用此型別的控制元件來獲取控制元件類的名稱。功能齊全的 GUI 可以建立一個帶有多個選項卡的對話方塊,每個選項卡包含屬於特定控制元件類的控制元件。可以透過查詢 ID 為 <control class | 1> 的特殊控制元件來找到每個選項卡的名稱。
驅動程式不必關心這一點。每當新增屬於新控制元件類的第一個控制元件時,框架將自動新增此型別的控制元件。
2.15.16. 新增通知回撥¶
有時,當子裝置驅動程式中的控制元件發生更改時,平臺或橋接驅動程式需要收到通知。您可以透過呼叫此函式來設定通知回撥
void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl,
void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv);
每當給定的控制元件更改值時,將呼叫通知回撥,其中包含指向控制元件的指標和與 v4l2_ctrl_notify 一起傳遞的 priv 指標。請注意,呼叫通知函式時會保持控制元件的處理程式鎖。
每個控制處理程式只能有一個通知函式。任何嘗試設定另一個通知函式的嘗試都會導致 WARN_ON。
2.15.17. v4l2_ctrl 函式和資料結構¶
-
union v4l2_ctrl_ptr¶
指向控制元件值的指標。
定義:
union v4l2_ctrl_ptr {
s32 *p_s32;
s64 *p_s64;
u8 *p_u8;
u16 *p_u16;
u32 *p_u32;
char *p_char;
struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation;
struct v4l2_ctrl_fwht_params *p_fwht_params;
struct v4l2_ctrl_h264_sps *p_h264_sps;
struct v4l2_ctrl_h264_pps *p_h264_pps;
struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
struct v4l2_ctrl_h264_decode_params *p_h264_decode_params;
struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights;
struct v4l2_ctrl_vp8_frame *p_vp8_frame;
struct v4l2_ctrl_hevc_sps *p_hevc_sps;
struct v4l2_ctrl_hevc_pps *p_hevc_pps;
struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
struct v4l2_ctrl_vp9_compressed_hdr *p_vp9_compressed_hdr_probs;
struct v4l2_ctrl_vp9_frame *p_vp9_frame;
struct v4l2_ctrl_hdr10_cll_info *p_hdr10_cll;
struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
struct v4l2_area *p_area;
struct v4l2_ctrl_av1_sequence *p_av1_sequence;
struct v4l2_ctrl_av1_tile_group_entry *p_av1_tile_group_entry;
struct v4l2_ctrl_av1_frame *p_av1_frame;
struct v4l2_ctrl_av1_film_grain *p_av1_film_grain;
struct v4l2_rect *p_rect;
void *p;
const void *p_const;
};
成員
p_s32指向 32 位有符號值的指標。
p_s64指向 64 位有符號值的指標。
p_u8指向 8 位無符號值的指標。
p_u16指向 16 位無符號值的指標。
p_u32指向 32 位無符號值的指標。
p_char指向字串的指標。
p_mpeg2_sequence指向 MPEG2 序列結構的指標。
p_mpeg2_picture指向 MPEG2 圖片結構的指標。
p_mpeg2_quantisation指向 MPEG2 量化資料結構的指標。
p_fwht_params指向 FWHT 無狀態引數結構的指標。
p_h264_sps指向
struct v4l2_ctrl_h264_sps的指標。p_h264_pps指向
struct v4l2_ctrl_h264_pps的指標。p_h264_scaling_matrixp_h264_slice_paramsp_h264_decode_paramsp_h264_pred_weightsp_vp8_frame指向 VP8 幀引數結構的指標。
p_hevc_sps指向 HEVC 序列引數集結構的指標。
p_hevc_pps指向 HEVC 圖片引數集結構的指標。
p_hevc_slice_params指向 HEVC 切片引數結構的指標。
p_vp9_compressed_hdr_probs指向 VP9 幀壓縮標頭機率結構的指標。
p_vp9_frame指向 VP9 幀引數結構的指標。
p_hdr10_cll指向 HDR10 內容亮度級別結構的指標。
p_hdr10_mastering指向 HDR10 母版顯示結構的指標。
p_area指向區域的指標。
p_av1_sequence指向 AV1 序列結構的指標。
p_av1_tile_group_entry指向 AV1 圖塊組條目結構的指標。
p_av1_frame指向 AV1 幀結構的指標。
p_av1_film_grain指向 AV1 膠片顆粒結構的指標。
p_rect指向矩形的指標。
p指向複合值的指標。
p_const指向常量複合值的指標。
-
union v4l2_ctrl_ptr v4l2_ctrl_ptr_create(void *ptr)¶
從 void 指標返回 v4l2_ctrl_ptr 的幫助函式
引數
void *ptrvoid 指標
-
struct v4l2_ctrl_ops¶
驅動程式必須提供的控制元件操作。
定義:
struct v4l2_ctrl_ops {
int (*g_volatile_ctrl)(struct v4l2_ctrl *ctrl);
int (*try_ctrl)(struct v4l2_ctrl *ctrl);
int (*s_ctrl)(struct v4l2_ctrl *ctrl);
};
成員
g_volatile_ctrl獲取此控制元件的新值。通常僅與 volatile(並且通常是隻讀的)控制元件相關,例如返回當前訊號強度的控制元件,該控制元件會不斷變化。如果未設定,則將返回當前快取的值。
try_ctrl測試控制元件的值是否有效。僅當通常的 min/max/step 檢查不足時才相關。
s_ctrl實際設定新的控制元件值。s_ctrl 是強制性的。呼叫這些操作時,ctrl->handler->lock 處於保持狀態,因此沒有其他人可以訪問該處理程式擁有的控制元件。
-
struct v4l2_ctrl_type_ops¶
驅動程式必須提供的控制元件型別操作。
定義:
struct v4l2_ctrl_type_ops {
bool (*equal)(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2);
void (*init)(const struct v4l2_ctrl *ctrl, u32 from_idx, union v4l2_ctrl_ptr ptr);
void (*minimum)(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr);
void (*maximum)(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr);
void (*log)(const struct v4l2_ctrl *ctrl);
int (*validate)(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr ptr);
};
成員
equal如果所有 ctrl->elems 陣列元素都相等,則返回 true。
init從 from_idx 初始化陣列元素的值到 ctrl->elems。
minimum將值設定為控制元件的最小值。
maximum將值設定為控制元件的最大值。
log記錄該值。
validate驗證 ctrl->new_elems 陣列元素的值。成功時返回 0,否則返回負值。
-
v4l2_ctrl_notify_fnc¶
Typedef:用於帶有當控制元件值發生更改時應呼叫的函式的通知引數的 typedef。
語法
void v4l2_ctrl_notify_fnc (struct v4l2_ctrl *ctrl, void *priv)
引數
struct v4l2_ctrl *ctrl指向 struct
v4l2_ctrl的指標void *priv控制元件私有資料
說明
此 typedef 定義用作 v4l2_ctrl_notify() 的引數,並作為 struct v4l2_ctrl_handler 的引數。
-
struct v4l2_ctrl¶
控制元件結構。
定義:
struct v4l2_ctrl {
struct list_head node;
struct list_head ev_subs;
struct v4l2_ctrl_handler *handler;
struct v4l2_ctrl **cluster;
unsigned int ncontrols;
unsigned int done:1;
unsigned int is_new:1;
unsigned int has_changed:1;
unsigned int is_private:1;
unsigned int is_auto:1;
unsigned int is_int:1;
unsigned int is_string:1;
unsigned int is_ptr:1;
unsigned int is_array:1;
unsigned int is_dyn_array:1;
unsigned int has_volatiles:1;
unsigned int call_notify:1;
unsigned int manual_mode_value:8;
const struct v4l2_ctrl_ops *ops;
const struct v4l2_ctrl_type_ops *type_ops;
u32 id;
const char *name;
enum v4l2_ctrl_type type;
s64 minimum, maximum, default_value;
u32 elems;
u32 elem_size;
u32 new_elems;
u32 dims[V4L2_CTRL_MAX_DIMS];
u32 nr_of_dims;
union {
u64 step;
u64 menu_skip_mask;
};
union {
const char * const *qmenu;
const s64 *qmenu_int;
};
unsigned long flags;
void *priv;
void *p_array;
u32 p_array_alloc_elems;
s32 val;
struct {
s32 val;
} cur;
union v4l2_ctrl_ptr p_def;
union v4l2_ctrl_ptr p_min;
union v4l2_ctrl_ptr p_max;
union v4l2_ctrl_ptr p_new;
union v4l2_ctrl_ptr p_cur;
};
成員
node列表節點。
ev_subs控制元件事件訂閱列表。
handler擁有該控制元件的處理程式。
cluster指向群集陣列的開頭。
ncontrols群集陣列中的控制元件數量。
done內部標誌:為每個已處理的控制元件設定。
is_new當用戶為此控制元件指定新值時設定。從
v4l2_ctrl_handler_setup()呼叫時也會設定。驅動程式不應設定此標誌。has_changed噹噹前值與新值不同時設定。驅動程式不應使用此標誌。
is_private如果設定,則此控制元件對其處理程式是私有的,並且不會新增到任何其他處理程式。驅動程式可以設定此標誌。
is_auto如果設定,則此控制元件選擇其他群整合員是處於“自動”模式還是“手動”模式。這用於自動增益/增益型別群集。驅動程式不應直接設定此標誌。
is_int如果設定,則此控制元件具有簡單的整數值(即,它使用 ctrl->val)。
is_string如果設定,則此控制元件的型別為
V4L2_CTRL_TYPE_STRING。is_ptr如果設定,則此控制元件是一個數組和/或型別 >=
V4L2_CTRL_COMPOUND_TYPES和/或型別V4L2_CTRL_TYPE_STRING。換句話說,struct v4l2_ext_control使用欄位 p 來指向資料。is_array如果設定,則此控制元件包含 N 維陣列。
is_dyn_array如果設定,則此控制元件包含動態大小的 1 維陣列。如果設定了此項,則也會設定 is_array。
has_volatiles如果設定,則群集的一個或多個成員是 volatile 的。驅動程式不應觸控此標誌。
call_notify如果設定,則每當控制元件的值更改時,呼叫處理程式的通知函式。
manual_mode_value如果設定了 is_auto 標誌,則這是 auto 控制元件的值,用於確定該控制元件是否處於手動模式。因此,如果 auto 控制元件的值等於此值,則整個群集都處於手動模式。驅動程式不應直接設定此標誌。
ops控制元件操作。
type_ops控制元件型別操作。
id控制元件 ID。
name控制元件名稱。
type控制元件型別。
minimum控制元件的最小值。
maximum控制元件的最大值。
default_value控制元件的預設值。
elemsN 維陣列中的元素數。
elem_size控制元件的大小(以位元組為單位)。
new_elemsp_new 中的元素數。除了動態陣列之外,這與 elems 相同。在動態陣列中,它在 1 到 p_array_alloc_elems 的範圍內。
dims每個維度的大小。
nr_of_dimsdims 中的維度數。
{unnamed_union}anonymous
step非選單控制元件的控制元件步長值。
menu_skip_mask選單控制元件的控制元件跳過掩碼。這使得跳過無效的選單項變得容易。如果設定了位 X,則跳過選單項 X。當然,這僅適用於 <= 32 個選單項的選單。沒有選單接近該數字,因此這沒問題。如果我們需要更多,則必須將其擴充套件到 u64 或位陣列。
{unnamed_union}anonymous
qmenu所有選單項的 const char * 陣列。空字串 (“”) 的陣列條目對應於不存在的選單項(這是對上述 menu_skip_mask 的補充)。最後一個條目必須為 NULL。僅當 type 為
V4L2_CTRL_TYPE_MENU時使用。qmenu_int帶有整數選單項的 64 位整數陣列。陣列的大小必須等於選單大小,例如:
。僅當 type 為 V4L2_CTRL_TYPE_INTEGER_MENU時使用。flags控制元件的標誌。
priv控制元件的私有指標。供驅動程式使用。控制元件框架不會觸及它。請注意,刪除控制元件時不會釋放此指標。如果需要這樣做,則可以新增一個新的內部位欄位來告訴框架釋放此指標。
p_array指向已分配陣列的指標。僅當 is_array 為 true 時才有效。
p_array_alloc_elems當前值和新值的已分配陣列中的元素數。因此,p_array 實際上針對 2 * p_array_alloc_elems * elem_size 進行了大小調整。僅當 is_array 為 true 時才有效。
val控制元件的新 s32 值。
cur用於儲存當前值的結構。
cur.val控制元件的當前值,如果 type 透過 u32 整數表示(請參閱
enum v4l2_ctrl_type)。p_def控制元件的預設值透過聯合表示,該聯合提供了透過指標訪問控制元件型別的標準方法(僅適用於複合控制元件)。
p_min控制元件的最小值透過聯合表示,該聯合提供了透過指標訪問控制元件型別的標準方法(僅適用於複合控制元件)。
p_max控制元件的最大值透過聯合表示,該聯合提供了透過指標訪問控制元件型別的標準方法(僅適用於複合控制元件)。
p_new控制元件的新值透過聯合表示,該聯合提供了透過指標訪問控制元件型別的標準方法。
p_cur控制元件的當前值透過聯合表示,該聯合提供了透過指標訪問控制元件型別的標準方法。
-
struct v4l2_ctrl_ref¶
控制元件引用。
定義:
struct v4l2_ctrl_ref {
struct list_head node;
struct v4l2_ctrl_ref *next;
struct v4l2_ctrl *ctrl;
struct v4l2_ctrl_helper *helper;
bool from_other_dev;
bool req_done;
bool p_req_valid;
bool p_req_array_enomem;
u32 p_req_array_alloc_elems;
u32 p_req_elems;
union v4l2_ctrl_ptr p_req;
};
成員
node排序列表的列表節點。
next雜湊的單鏈接列表節點。
ctrl實際的控制元件資訊。
helper指向輔助結構的指標。在
v4l2-ctrl.c的prepare_ext_ctrls函式中內部使用。from_other_dev如果為真,則表示 ctrl 是在
struct v4l2_ctrl_handler之外的另一個裝置中定義的。req_done內部標誌:如果包含此控制元件引用的控制元件處理程式繫結到媒體請求,則在應用該控制元件時設定此標誌。這可以防止從具有多個控制元件的叢集中應用控制元件兩次(當應用叢集的第一個控制元件時,它們都會被應用)。
p_req_valid如果設定,則 p_req 包含請求的控制元件值。
p_req_array_enomem如果設定,則 p_req 無效,因為分配陣列空間失敗。嘗試讀取此值將導致 ENOMEM。僅當 ctrl->is_array 為 true 時有效。
p_req_array_alloc_elems為陣列分配的元素數量。僅當 p_req_valid 和 ctrl->is_array 為 true 時有效。
p_req_elemsp_req 中的元素數量。 這與 ctrl->elems 相同,除了動態陣列。 在這種情況下,它在 1 到 p_req_array_alloc_elems 的範圍內。 僅當 p_req_valid 為 true 時有效。
p_req如果包含此控制元件引用的控制元件處理程式繫結到媒體請求,則此指標指向在執行請求時必須應用的控制元件的值,或者指向請求完成時的控制元件的值。 如果 p_req_valid 為 false,則表示從未為此請求設定過此控制元件,並且在此請求應用時控制元件不會更新。
說明
每個控制元件處理程式都有一個這些引用的列表。 list_head 用於儲存按控制元件 ID 排序的所有控制元件的列表,而 next 指標用於將控制元件連結到雜湊桶中。
-
struct v4l2_ctrl_handler¶
控制元件處理程式跟蹤所有控制元件:包括處理程式擁有的控制元件和從其他處理程式繼承的控制元件。
定義:
struct v4l2_ctrl_handler {
struct mutex _lock;
struct mutex *lock;
struct list_head ctrls;
struct list_head ctrl_refs;
struct v4l2_ctrl_ref *cached;
struct v4l2_ctrl_ref **buckets;
v4l2_ctrl_notify_fnc notify;
void *notify_priv;
u16 nr_of_buckets;
int error;
bool request_is_queued;
struct list_head requests;
struct list_head requests_queued;
struct media_request_object req_obj;
};
成員
_lock“lock” 的預設值。
lock用於控制對此處理程式及其控制元件的訪問的鎖。 可能在初始化後立即被使用者替換。
ctrls此處理程式擁有的控制元件列表。
ctrl_refs控制元件引用列表。
cached上次找到的控制元件引用。 通常需要多次使用相同的控制元件,因此這是一個簡單的最佳化。
buckets用於雜湊的桶。 允許快速查詢控制元件。
notify每當控制元件值更改時呼叫的通知回撥。 請注意,呼叫通知函式時,將持有處理程式的鎖!
notify_priv作為引數傳遞給 v4l2_ctrl 通知回撥。
nr_of_buckets陣列中的桶總數。
error第一次控制元件新增失敗的錯誤程式碼。
request_is_queued如果請求已排隊,則為 True。
requests用於跟蹤開啟的控制元件處理程式請求物件的列表。 對於父控制元件處理程式 (req_obj.ops == NULL),這是列表頭。 刪除父控制元件處理程式時,必須取消繫結並放置所有這些請求,因為它們引用了父控制元件處理程式。
requests_queued已排隊請求的列表。 這決定了應用這些控制元件的順序。 請求完成後,將從該列表中刪除。
req_objstruct media_request_object,用於連結到struct media_request。 此請求物件具有引用計數。
-
struct v4l2_ctrl_config¶
控制元件配置結構。
定義:
struct v4l2_ctrl_config {
const struct v4l2_ctrl_ops *ops;
const struct v4l2_ctrl_type_ops *type_ops;
u32 id;
const char *name;
enum v4l2_ctrl_type type;
s64 min;
s64 max;
u64 step;
s64 def;
union v4l2_ctrl_ptr p_def;
union v4l2_ctrl_ptr p_min;
union v4l2_ctrl_ptr p_max;
u32 dims[V4L2_CTRL_MAX_DIMS];
u32 elem_size;
u32 flags;
u64 menu_skip_mask;
const char * const *qmenu;
const s64 *qmenu_int;
unsigned int is_private:1;
};
成員
ops控制元件操作。
type_ops控制元件型別 ops。 僅複合控制元件需要。
id控制元件 ID。
name控制元件名稱。
type控制元件型別。
min控制元件的最小值。
max控制元件的最大值。
step非選單控制元件的控制元件步長值。
def控制元件的預設值。
p_def複合控制元件的控制元件預設值。
p_min複合控制元件的控制元件最小值。
p_max複合控制元件的控制元件最大值。
dims每個維度的大小。
elem_size控制元件的大小(以位元組為單位)。
flags控制元件的標誌。
menu_skip_mask選單控制元件的控制元件跳過掩碼。 這使得跳過無效的選單項變得容易。 如果設定了位 X,則跳過選單項 X。 當然,這僅適用於具有 <= 64 個選單項的選單。 沒有接近該數量的選單,所以這沒問題。 如果我們確實需要更多,那麼必須將其擴充套件到位陣列。
qmenu所有選單項的 const char * 陣列。 空字串 (“”) 的陣列條目對應於不存在的選單項(這是對上面 menu_skip_mask 的補充)。 最後一個條目必須為 NULL。
qmenu_intV4L2_CTRL_TYPE_INTEGER_MENU 型別的所有選單項的 const s64 整數陣列。
is_private如果設定,則此控制元件是其處理程式私有的,並且不會新增到任何其他處理程式。
-
void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags)¶
根據控制元件 ID 填充控制元件欄位。
引數
u32 id控制元件的 ID
const char **name要用控制元件名稱的字串填充的指標
enum v4l2_ctrl_type *type用於儲存控制元件型別的指標
s64 *min用於儲存控制元件最小值的指標
s64 *max用於儲存控制元件最大值的指標
u64 *step用於儲存控制元件步長的指標
s64 *def用於儲存控制元件預設值的指標
u32 *flags用於儲存要在控制元件上使用的標誌的指標
說明
這適用於所有標準 V4L2 控制元件。 對於非標準控制元件,它只會填充給定的引數,並且 name 內容將設定為 NULL。
此函式將覆蓋 name、type 和 flags 的內容。 min、max、step 和 def 的內容可能會根據型別進行修改。
注意
不要在驅動程式中使用! 它僅在內部用於向後相容的控制元件處理。 一旦所有驅動程式都轉換為使用新的控制元件框架,該函式將不再匯出。
-
int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, unsigned int nr_of_controls_hint, struct lock_class_key *key, const char *name)¶
初始化控制元件處理程式。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
unsigned int nr_of_controls_hint提示此處理程式預計引用的控制元件數量。 這是總數,因此包括任何繼承的控制元件。 它不必精確,但如果它偏離太遠,那麼你要麼浪費記憶體(分配了太多的桶),要麼控制元件查詢變得更慢(分配的桶不夠,因此有更多的慢速列表查詢)。 不過,它總是會工作。
struct lock_class_key *key如果設定了 CONFIG_LOCKDEP,則由鎖驗證器使用。
const char *name如果設定了 CONFIG_LOCKDEP,則由鎖驗證器使用。
說明
注意
永遠不要直接使用此呼叫,始終使用隱藏 key 和 name 引數的 v4l2_ctrl_handler_init() 宏。
返回值
如果無法分配桶,則返回錯誤。 此錯誤也將儲存在 hdl->error 中。
-
v4l2_ctrl_handler_init¶
v4l2_ctrl_handler_init (hdl, nr_of_controls_hint)
輔助函式,用於建立靜態 struct
lock_class_key並呼叫v4l2_ctrl_handler_init_class()
引數
hdl控制元件處理程式。
nr_of_controls_hint提示此處理程式預計引用的控制元件數量。 這是總數,因此包括任何繼承的控制元件。 它不必精確,但如果它偏離太遠,那麼你要麼浪費記憶體(分配了太多的桶),要麼控制元件查詢變得更慢(分配的桶不夠,因此有更多的慢速列表查詢)。 不過,它總是會工作。
說明
此輔助函式建立靜態 struct lock_class_key 並呼叫 v4l2_ctrl_handler_init_class(),為鎖驗證器提供適當的名稱。
使用此輔助函式來初始化控制元件處理程式。
-
void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)¶
釋放處理程式擁有的所有控制元件並釋放控制元件列表。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
說明
如果 hdl == NULL,則不執行任何操作。
引數
struct v4l2_ctrl *ctrl要鎖定的控制元件。
引數
struct v4l2_ctrl *ctrl要解鎖的控制元件。
-
int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)¶
為屬於處理程式的所有控制元件呼叫 s_ctrl op,以將硬體初始化為當前的控制元件值。 呼叫者負責代表
__v4l2_ctrl_handler_setup()獲取控制元件處理程式互斥鎖。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
說明
按鈕控制元件將被跳過,只讀控制元件也是如此。
如果 hdl == NULL,則這隻會返回 0。
-
int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)¶
為屬於處理程式的所有控制元件呼叫 s_ctrl op,以將硬體初始化為當前的控制元件值。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
說明
按鈕控制元件將被跳過,只讀控制元件也是如此。
如果 hdl == NULL,則這隻會返回 0。
-
void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, const char *prefix)¶
記錄處理程式擁有的所有控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
const char *prefix記錄控制元件值時要使用的字首。 如果字首不以空格結尾,則將在字首後新增“: ”。 如果 prefix == NULL,則不使用字首。
說明
與 VIDIOC_LOG_STATUS 一起使用。
如果 hdl == NULL,則不執行任何操作。
-
struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_config *cfg, void *priv)¶
分配並初始化新的自定義 V4L2 控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
const struct v4l2_ctrl_config *cfg控制元件的配置資料。
void *priv控制元件的特定於驅動程式的私有資料。
說明
如果無法分配 v4l2_ctrl 結構,則返回 NULL,並將 hdl->error 設定為錯誤程式碼(如果尚未設定)。
-
struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, s64 min, s64 max, u64 step, s64 def)¶
分配並初始化新的標準 V4L2 非選單控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
const struct v4l2_ctrl_ops *ops控制元件操作。
u32 id控制元件 ID。
s64 min控制元件的最小值。
s64 max控制元件的最大值。
u64 step控制元件的步長值
s64 def控制元件的預設值。
說明
如果無法分配 v4l2_ctrl 結構,或者控制元件 ID 未知,則返回 NULL,並將 hdl->error 設定為適當的錯誤程式碼(如果尚未設定)。
如果 id 引用選單控制元件,則此函式將返回 NULL。
新增選單控制元件時,請使用 v4l2_ctrl_new_std_menu()。
分配並初始化一個新的標準 V4L2 選單控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
const struct v4l2_ctrl_ops *ops控制元件操作。
u32 id控制元件 ID。
u8 max控制元件的最大值。
u64 mask選單控制元件的控制元件跳過掩碼。 這使得跳過無效的選單項變得容易。 如果設定了位 X,則跳過選單項 X。 當然,這僅適用於具有 <= 64 個選單項的選單。 沒有接近該數量的選單,所以這沒問題。 如果我們確實需要更多,那麼必須將其擴充套件到位陣列。
u8 def控制元件的預設值。
說明
與 v4l2_ctrl_new_std() 相同,但 min 設定為 0,並且 mask 值決定了要跳過哪些選單項。
如果 id 指的是非選單控制元件,則此函式將返回 NULL。
使用特定於驅動程式的選單建立一個新的標準 V4L2 選單控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
const struct v4l2_ctrl_ops *ops控制元件操作。
u32 id控制元件 ID。
u8 max控制元件的最大值。
u64 mask選單控制元件的控制元件跳過掩碼。 這使得跳過無效的選單項變得容易。 如果設定了位 X,則跳過選單項 X。 當然,這僅適用於具有 <= 64 個選單項的選單。 沒有接近該數量的選單,所以這沒問題。 如果我們確實需要更多,那麼必須將其擴充套件到位陣列。
u8 def控制元件的預設值。
const char * const *qmenu新的選單。
說明
與 v4l2_ctrl_new_std_menu() 相同,但 qmenu 將是此控制元件的特定於驅動程式的選單。
-
struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, const union v4l2_ctrl_ptr p_def, const union v4l2_ctrl_ptr p_min, const union v4l2_ctrl_ptr p_max)¶
分配並初始化一個新的標準 V4L2 複合控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
const struct v4l2_ctrl_ops *ops控制元件操作。
u32 id控制元件 ID。
const union v4l2_ctrl_ptr p_def控制元件的預設值。
const union v4l2_ctrl_ptr p_min控制元件的最小值。
const union v4l2_ctrl_ptr p_max控制元件的最大值。
說明
與 v4l2_ctrl_new_std() 相同,但支援複合控制元件。要填充 p_def、p_min 和 p_max 欄位,請使用 v4l2_ctrl_ptr_create() 將指標轉換為 const union v4l2_ctrl_ptr。如果您希望複合控制元件的預設值、最小值或最大值全為零,請使用 v4l2_ctrl_ptr_create(NULL)。如果複合控制元件未設定 V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX 標誌,則它沒有最小值和最大值。在這種情況下,只需對 p_min 和 p_max 引數使用 v4l2_ctrl_ptr_create(NULL)。
建立一個新的標準 V4L2 整數選單控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
const struct v4l2_ctrl_ops *ops控制元件操作。
u32 id控制元件 ID。
u8 max控制元件的最大值。
u8 def控制元件的預設值。
const s64 *qmenu_int控制元件的選單項。
說明
與 v4l2_ctrl_new_std_menu() 相同,但 mask 設定為 0,並且它額外接受一個整數陣列作為引數,用於確定選單項。
如果 id 指的是非整數選單控制元件,則此函式將返回 NULL。
-
v4l2_ctrl_filter¶
Typedef:用於定義新增控制元件處理程式時要使用的篩選器函式的 Typedef。
語法
bool v4l2_ctrl_filter (const struct v4l2_ctrl *ctrl)
引數
const struct v4l2_ctrl *ctrl指向 struct
v4l2_ctrl的指標。
-
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, struct v4l2_ctrl_handler *add, v4l2_ctrl_filter filter, bool from_other_dev)¶
將處理程式 add 中的所有控制元件新增到處理程式 hdl。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
struct v4l2_ctrl_handler *add您想要將其控制元件新增到 hdl 控制元件處理程式的控制元件處理程式。
v4l2_ctrl_filter filter此函式將篩選應新增哪些控制元件。
bool from_other_dev如果為 true,則 add 中的控制元件是在與 hdl 不同的裝置中定義的。
說明
如果兩個處理程式中的任何一個是指標,則不執行任何操作。如果 filter 為 NULL,則新增所有控制元件。否則,僅新增 filter 返回 true 的那些控制元件。如果發生錯誤,hdl->error 將設定為錯誤程式碼(如果尚未設定)。
引數
const struct v4l2_ctrl *ctrl要篩選的控制元件。
說明
這將為任何對無線電裝置節點有效的控制元件返回 true。這些控制元件是所有的 V4L2_CID_AUDIO_* 使用者控制元件和所有的 FM 發射器類控制元件。
此函式要與 v4l2_ctrl_add_handler() 一起使用。
引數
unsigned int ncontrols此叢集中控制元件的數量。
struct v4l2_ctrl **controls大小為 ncontrols 的叢集控制元件陣列。
-
void v4l2_ctrl_auto_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls, u8 manual_val, bool set_volatile)¶
將叢集中的所有控制元件標記為屬於該叢集,並將其設定為進行 autofoo/foo 型別處理。
引數
unsigned int ncontrols此叢集中控制元件的數量。
struct v4l2_ctrl **controls大小為 ncontrols 的叢集控制元件陣列。第一個控制元件必須是“自動”控制元件(例如,自動增益、自動曝光等)。
u8 manual_val叢集中第一個控制元件的值,該值等於手動設定。
bool set_volatile如果為 true,則除第一個自動控制元件之外的所有控制元件都將是易失的。
說明
用於控制元件組,其中一個控制元件選擇某個自動功能,而其他控制元件僅在自動功能關閉(手動模式)時才處於活動狀態。典型示例:自動增益與增益、自動白平衡與紅色和藍色平衡等。
此類控制元件的行為如下
當 autofoo 控制元件設定為自動時,任何手動控制元件都將設定為不活動狀態,並且任何讀取都將呼叫 g_volatile_ctrl(如果控制元件標記為易失)。
當 autofoo 控制元件設定為手動時,任何手動控制元件都將標記為活動狀態,並且任何讀取都將只返回當前值,而無需透過 g_volatile_ctrl。
此外,如果 autofoo 處於自動模式,此函式將在 autofoo 控制元件上設定 V4L2_CTRL_FLAG_UPDATE 標誌,並在 foo 控制元件上設定 V4L2_CTRL_FLAG_INACTIVE。
-
struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)¶
查詢具有給定 ID 的控制元件。
引數
struct v4l2_ctrl_handler *hdl控制元件處理程式。
u32 id要查詢的控制元件 ID。
說明
如果 hdl == NULL,則它也將返回 NULL。將鎖定處理程式,因此請勿從 v4l2_ctrl_ops 內部使用。
引數
struct v4l2_ctrl *ctrl要(取消)啟用的控制元件。
bool active如果控制元件應變為活動狀態,則為 True。
說明
這將自動設定或清除 V4L2_CTRL_FLAG_INACTIVE 標誌。如果 ctrl == NULL,則不執行任何操作。這通常會從 s_ctrl op 中呼叫。之後將生成 V4L2_EVENT_CTRL 事件。
此函式假定控制元件處理程式已鎖定。
引數
struct v4l2_ctrl *ctrl要(取消)啟用的控制元件。
bool grabbed如果控制元件應變為已抓取狀態,則為 True。
說明
這將自動設定或清除 V4L2_CTRL_FLAG_GRABBED 標誌。如果 ctrl == NULL,則不執行任何操作。之後將生成 V4L2_EVENT_CTRL 事件。這通常會在驅動程式中啟動或停止流式傳輸時呼叫。
此函式假定控制元件處理程式已由呼叫方鎖定。
引數
struct v4l2_ctrl *ctrl要(取消)啟用的控制元件。
bool grabbed如果控制元件應變為已抓取狀態,則為 True。
說明
這將自動設定或清除 V4L2_CTRL_FLAG_GRABBED 標誌。如果 ctrl == NULL,則不執行任何操作。之後將生成 V4L2_EVENT_CTRL 事件。這通常會在驅動程式中啟動或停止流式傳輸時呼叫。
此函式假定控制元件處理程式未鎖定,並將自行獲取鎖定。
-
int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, s64 min, s64 max, u64 step, s64 def)¶
v4l2_ctrl_modify_range()的未鎖定變體
引數
struct v4l2_ctrl *ctrl要更新的控制元件。
s64 min控制元件的最小值。
s64 max控制元件的最大值。
u64 step控制元件的步長值
s64 def控制元件的預設值。
說明
動態更新控制元件的範圍。 這適用於控制元件型別 INTEGER、BOOLEAN、MENU、INTEGER MENU 和 BITMASK。 對於選單控制元件,step 值被解釋為 menu_skip_mask。
如果某個範圍引數對於此控制元件型別無效,則返回錯誤。
呼叫者負責代表 __v4l2_ctrl_modify_range() 獲取控制元件處理程式互斥鎖。
引數
struct v4l2_ctrl *ctrl要更新的控制元件。
s64 min控制元件的最小值。
s64 max控制元件的最大值。
u64 step控制元件的步長值
s64 def控制元件的預設值。
說明
動態更新控制元件的範圍。 這適用於控制元件型別 INTEGER、BOOLEAN、MENU、INTEGER MENU 和 BITMASK。 對於選單控制元件,step 值被解釋為 menu_skip_mask。
如果某個範圍引數對於此控制元件型別無效,則返回錯誤。
此函式假定控制元件處理程式未鎖定,並將自行獲取鎖定。
引數
struct v4l2_ctrl *ctrl要更新的控制元件。
u32 dims[V4L2_CTRL_MAX_DIMS]控制元件的新尺寸。
說明
動態更新陣列控制元件的尺寸。 陣列的元素將重置為其預設值,即使尺寸未更改也是如此。
如果 dims 對此控制元件無效,則返回錯誤。
呼叫者負責代表 __v4l2_ctrl_modify_dimensions() 獲取控制元件處理程式互斥鎖。
注意
在掛起的請求中使用同一控制元件時呼叫此函式未經測試。 它應該可以工作(具有錯誤控制元件大小的請求將靜默刪除該控制元件),但這會非常令人困惑。
引數
struct v4l2_ctrl *ctrl要更新的控制元件。
u32 dims[V4L2_CTRL_MAX_DIMS]控制元件的新尺寸。
說明
動態更新陣列控制元件的尺寸。 陣列的元素將重置為其預設值,即使尺寸未更改也是如此。
如果 dims 對此控制元件型別無效,則返回錯誤。
此函式假定控制元件處理程式未鎖定,並將自行獲取鎖定。
注意
在掛起的請求中使用同一控制元件時呼叫此函式未經測試。 它應該可以工作(具有錯誤控制元件大小的請求將靜默刪除該控制元件),但這會非常令人困惑。
-
void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)¶
用於設定控制元件的通知回撥的函式。
引數
struct v4l2_ctrl *ctrl控制元件。
v4l2_ctrl_notify_fnc notify回撥函式。
void *priv回撥私有控制代碼,作為引數傳遞給回撥。
說明
此函式為控制元件設定回撥函式。 如果 ctrl 為 NULL,則它將不執行任何操作。 如果 notify 為 NULL,則將刪除通知回撥。
只能有一個通知。 如果已經存在另一個通知,則會發出 WARN_ON 並且該函式將不執行任何操作。
-
const char *v4l2_ctrl_get_name(u32 id)¶
獲取控制元件的名稱
引數
u32 id控制元件 ID。
說明
此函式返回給定控制元件 ID 的名稱;如果它不是已知的控制元件,則返回 NULL。
獲取控制元件的選單字串陣列
引數
u32 id控制元件 ID。
說明
此函式返回給定控制元件 ID 的以 NULL 結尾的選單字串陣列名稱;如果它不是已知的選單控制元件,則返回 NULL。
獲取控制元件的整數選單陣列
引數
u32 id控制元件 ID。
u32 *len整數陣列的大小。
說明
此函式返回給定控制元件 ID 的整數陣列;如果它不是已知的整數選單控制元件,則返回 NULL。
引數
struct v4l2_ctrl *ctrl控制元件。
說明
這透過控制框架安全地返回控制元件的值。 此函式將鎖定控制元件的處理程式,因此無法從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於整數型別控制元件。
-
int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)¶
v4l2_ctrl_s_ctrl()的未鎖定變體。
引數
struct v4l2_ctrl *ctrl控制元件。
s32 val新值。
說明
這透過控制框架安全地設定控制元件的新值。 此函式假定控制元件的處理程式已鎖定,允許從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於整數型別控制元件。
引數
struct v4l2_ctrl *ctrl控制元件。
s32 val新值。
說明
這透過控制框架安全地設定控制元件的新值。 此函式將鎖定控制元件的處理程式,因此無法從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於整數型別控制元件。
引數
struct v4l2_ctrl *ctrl控制元件。
說明
這透過控制框架安全地返回控制元件的值。 此函式將鎖定控制元件的處理程式,因此無法從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於 64 位整數型別控制元件。
-
int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)¶
v4l2_ctrl_s_ctrl_int64()的未鎖定變體。
引數
struct v4l2_ctrl *ctrl控制元件。
s64 val新值。
說明
這透過控制框架安全地設定控制元件的新值。 此函式假定控制元件的處理程式已鎖定,允許從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於 64 位整數型別控制元件。
引數
struct v4l2_ctrl *ctrl控制元件。
s64 val新值。
說明
這透過控制框架安全地設定控制元件的新值。 此函式將鎖定控制元件的處理程式,因此無法從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於 64 位整數型別控制元件。
-
int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)¶
v4l2_ctrl_s_ctrl_string()的未鎖定變體。
引數
struct v4l2_ctrl *ctrl控制元件。
const char *s新字串。
說明
這透過控制框架安全地設定控制元件的新字串。 此函式假定控制元件的處理程式已鎖定,允許從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於字串型別控制元件。
引數
struct v4l2_ctrl *ctrl控制元件。
const char *s新字串。
說明
這透過控制框架安全地設定控制元件的新字串。 此函式將鎖定控制元件的處理程式,因此無法從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於字串型別控制元件。
-
int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl, enum v4l2_ctrl_type type, const void *p)¶
用於設定複合控制元件的未鎖定變體
引數
struct v4l2_ctrl *ctrl控制元件。
enum v4l2_ctrl_type type資料的型別。
const void *p新的複合有效負載。
說明
這透過控制框架安全地設定控制元件的新複合有效負載。 此函式假定控制元件的處理程式已鎖定,允許從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於複合型別控制元件。
-
int v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl, enum v4l2_ctrl_type type, const void *p)¶
用於從驅動程式中設定複合控制元件的輔助函式。
引數
struct v4l2_ctrl *ctrl控制元件。
enum v4l2_ctrl_type type資料的型別。
const void *p新的複合有效負載。
說明
這透過控制框架安全地設定控制元件的新複合有效負載。 此函式將鎖定控制元件的處理程式,因此無法從 v4l2_ctrl_ops 函式中使用它。
此函式僅適用於複合型別控制元件。
-
void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)¶
要用作
struct v4l2_subscribed_event_opsreplace() 的回撥的函式
引數
struct v4l2_event *old指向具有報告事件的
v4l2_event結構的指標;const struct v4l2_event *new指向具有已修改事件的
v4l2_event結構體的指標;
-
void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)¶
用作
struct v4l2_subscribed_event_opsmerge()的回撥函式
引數
const struct v4l2_event *old指向具有報告事件的
v4l2_event結構的指標;struct v4l2_event *new指向具有已合併事件的
v4l2_event結構體的指標;
引數
struct file *file指向
struct file的指標void *fh未使用。保留它只是為了與
struct v4l2_ioctl_ops.vidioc_log_status 期望的引數相容。
說明
可用作僅轉儲與檔案控制代碼關聯的所有控制元件的 vidioc_log_status 函式。
引數
struct v4l2_fh *fh指向
struct v4l2_fh的指標const struct v4l2_event_subscription *sub指向
struct v4l2_event_subscription的指標
說明
可用作僅訂閱控制事件的 vidioc_subscribe_event 函式。
-
__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)¶
用作 poll() 回撥的函式,它只輪詢控制事件。
引數
struct file *file指向
struct file的指標struct poll_table_struct *wait指向 struct poll_table_struct 的指標
-
int v4l2_ctrl_request_setup(struct media_request *req, struct v4l2_ctrl_handler *parent)¶
用於在請求中應用控制值的輔助函式
引數
struct media_request *req請求
struct v4l2_ctrl_handler *parent父控制元件處理程式(
media_request_object_find()中的'priv')
說明
這是一個輔助函式,用於使用請求中包含的控制元件值呼叫控制元件處理程式的 s_ctrl 回撥。請注意,這種在請求中應用控制元件值的方法僅適用於記憶體到記憶體裝置。
-
void v4l2_ctrl_request_complete(struct media_request *req, struct v4l2_ctrl_handler *parent)¶
完成控制元件處理程式請求物件
引數
struct media_request *req請求
struct v4l2_ctrl_handler *parent父控制元件處理程式(
media_request_object_find()中的'priv')
說明
該函式應在每個可能具有與之關聯的請求物件的控制元件處理程式上呼叫,即支援請求的驅動程式的控制元件處理程式。
該函式首先獲取控制元件處理程式中任何易失性控制元件的值,並將它們附加到請求。然後,該函式完成請求物件。
-
struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, struct v4l2_ctrl_handler *parent)¶
在請求中查詢控制元件處理程式
引數
struct media_request *req請求
struct v4l2_ctrl_handler *parent父控制元件處理程式(
media_request_object_find()中的'priv')
說明
該函式在請求中查詢控制元件處理程式。如果未找到,則可能返回 NULL。完成後,您必須使用返回的處理程式指標呼叫v4l2_ctrl_request_hdl_put()。
如果請求不處於 VALIDATING 或 QUEUED 狀態,則此函式將始終返回 NULL。
請注意,在 VALIDATING 狀態下,req_queue_mutex 被持有,因此無法從請求中新增或刪除物件。
在 QUEUED 狀態下,將由驅動程式來確保這一點。
-
void v4l2_ctrl_request_hdl_put(struct v4l2_ctrl_handler *hdl)¶
放置控制元件處理程式
-
struct v4l2_ctrl *v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)¶
查詢具有給定 ID 的控制元件。
引數
struct v4l2_ctrl_handler *hdl請求中的控制元件處理程式。
u32 id要查詢的控制元件的 ID。
說明
如果此控制元件是請求的一部分,則此函式返回指向該控制元件的指標,否則返回 NULL。
-
int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)¶
用於實現VIDIOC_QUERYCTRL ioctl 的輔助函式
引數
struct v4l2_ctrl_handler *hdlstruct v4l2_queryctrl *qc
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
-
void v4l2_query_ext_ctrl_to_v4l2_queryctrl(struct v4l2_queryctrl *to, const struct v4l2_query_ext_ctrl *from)¶
將 qec 轉換為 qe。
引數
struct v4l2_queryctrl *to要寫入的 v4l2_queryctrl。
const struct v4l2_query_ext_ctrl *from要從中讀取的 v4l2_query_ext_ctrl。
說明
此函式是一個輔助函式,用於將 v4l2_query_ext_ctrl 轉換為 v4l2_queryctrl。
-
int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)¶
用於實現VIDIOC_QUERY_EXT_CTRL ioctl 的輔助函式
引數
struct v4l2_ctrl_handler *hdlstruct v4l2_query_ext_ctrl *qc
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
用於實現VIDIOC_QUERYMENU ioctl 的輔助函式
引數
struct v4l2_ctrl_handler *hdlstruct v4l2_querymenu *qm
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
-
int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl)¶
用於實現VIDIOC_G_CTRL ioctl 的輔助函式
引數
struct v4l2_ctrl_handler *hdlstruct v4l2_control *ctrl指向
struct v4l2_control的指標
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
-
int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl)¶
用於實現VIDIOC_S_CTRL ioctl 的輔助函式
引數
struct v4l2_fh *fh指向
struct v4l2_fh的指標struct v4l2_ctrl_handler *hdlstruct v4l2_control *ctrl指向
struct v4l2_control的指標
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
-
int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, struct media_device *mdev, struct v4l2_ext_controls *c)¶
用於實現 VIDIOC_G_EXT_CTRLS ioctl 的輔助函式
引數
struct v4l2_ctrl_handler *hdlstruct video_device *vdev指向
struct video_device的指標struct media_device *mdev指向
struct media_device的指標struct v4l2_ext_controls *c指向
struct v4l2_ext_controls的指標
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
-
int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, struct media_device *mdev, struct v4l2_ext_controls *c)¶
用於實現 VIDIOC_TRY_EXT_CTRLS ioctl 的輔助函式
引數
struct v4l2_ctrl_handler *hdlstruct video_device *vdev指向
struct video_device的指標struct media_device *mdev指向
struct media_device的指標struct v4l2_ext_controls *c指向
struct v4l2_ext_controls的指標
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
-
int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, struct video_device *vdev, struct media_device *mdev, struct v4l2_ext_controls *c)¶
用於實現 VIDIOC_S_EXT_CTRLS ioctl 的輔助函式
引數
struct v4l2_fh *fh指向
struct v4l2_fh的指標struct v4l2_ctrl_handler *hdlstruct video_device *vdev指向
struct video_device的指標struct media_device *mdev指向
struct media_device的指標struct v4l2_ext_controls *c指向
struct v4l2_ext_controls的指標
說明
如果 hdl == NULL,則它們都將返回 -EINVAL。
-
int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub)¶
用作
struct v4l2_subdev_core_opssubscribe_event 函式的輔助函式,該函式僅訂閱控制事件。
引數
struct v4l2_subdev *sd指向
struct v4l2_subdev的指標struct v4l2_fh *fh指向
struct v4l2_fh的指標struct v4l2_event_subscription *sub指向
struct v4l2_event_subscription的指標
-
int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd)¶
記錄子裝置控制控制代碼擁有的所有控制元件。
引數
struct v4l2_subdev *sd指向
struct v4l2_subdev的指標
-
int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ctrl_ops, const struct v4l2_fwnode_device_properties *p)¶
註冊裝置屬性的控制元件
引數
struct v4l2_ctrl_handler *hdl指向要在其上註冊控制元件的
struct v4l2_ctrl_handler的指標const struct v4l2_ctrl_ops *ctrl_ops指向用於註冊控制元件的
struct v4l2_ctrl_ops的指標const struct v4l2_fwnode_device_properties *p
說明
如果屬性已設定為某個值,則此函式使用 p 引數中包含的屬性值註冊與裝置屬性關聯的控制元件。
當前解析並註冊以下 v4l2 控制元件: - V4L2_CID_CAMERA_ORIENTATION - V4L2_CID_CAMERA_SENSOR_ROTATION;
呼叫方已使用 hdl 控制控制代碼註冊的控制元件不會被覆蓋。呼叫方應先註冊他們想要自己處理的控制元件,然後再呼叫此函式。
返回值
成功時返回 0,失敗時返回負錯誤程式碼。
-
bool v4l2_ctrl_type_op_equal(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2)¶
預設的 v4l2_ctrl_type_ops equal 回撥。
引數
const struct v4l2_ctrl *ctrlv4l2_ctrl 指標。
union v4l2_ctrl_ptr ptr1一個 v4l2 控制值。
union v4l2_ctrl_ptr ptr2一個 v4l2 控制值。
返回值
如果值相等,則為 true;否則為 false。
-
void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, union v4l2_ctrl_ptr ptr)¶
預設的 v4l2_ctrl_type_ops init 回撥。
引數
const struct v4l2_ctrl *ctrlv4l2_ctrl 指標。
u32 from_idx起始元素索引。
union v4l2_ctrl_ptr ptrv4l2 控制值。
返回值
void
引數
const struct v4l2_ctrl *ctrlv4l2_ctrl 指標。
返回值
void
-
int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr ptr)¶
預設的 v4l2_ctrl_type_ops validate 回撥。
引數
const struct v4l2_ctrl *ctrlv4l2_ctrl 指標。
union v4l2_ctrl_ptr ptrv4l2 控制值。
返回值
成功時返回 0,失敗時返回負錯誤程式碼。