裝置命名
每乙個驅動註冊乙個或多個裝置節點後他們的主裝置號都是81,而子裝置號在0~255之間。除非通過config_video_fixed_minor_ranges編譯選項編譯核心,否則子裝置號是動態分配的。而且,子裝置號分配範圍與裝置節點型別有關(video、radio等)。
很多驅動支援通過video_nr,radio_nr或vbi_nr模組設定來選擇特殊的video/radio/vbi節點號。這就允許使用者申請指定的裝置節點名稱,如/dev/video5而不是交給系統生成。當驅動支援多個同類裝置有多餘乙個裝置節點號時候,可如下:
>modprobe mydriver video_nr=0,1 radio_nr=0,1
在/etc/modules.conf中可以這樣寫:
options mydriver video_nr=0,1 radio_nr=0,1
如果在模組設定中沒有給定裝置節點號則驅動會預設進行分配。
通常情況下udev會為你在/dev下自動建立裝置節點。如果udev沒有安裝,那麼你需要使能config_video_fixed_minor_ranges核心選項,這樣就可以將子裝置號設定為裝置節點號了,即子裝置號5同樣會使裝置節點名為video5。此特性會使不同型別裝置擁有不同範圍的子裝置號。這些範圍在第四節:介面中將給出。(不繞彎子了,我這裡給直接列出來)
型別範圍
video
0~63
vbi224~255
vtx192~223
radio
64~127
sdr0~255
特殊檔案的建立(用mknod)是乙個特殊操作,而且這些裝置不能通過主裝置號和子裝置號開啟。這意味著應用程式不能掃瞄載入上的或安裝上的驅動。使用者必須敲入乙個裝置名,或者說應用程式可以嘗試使用常規的裝置名稱。
相關裝置
v4l2 api為這些功能分別建立不同的裝置節點。
v4l2 api被設計成乙個裝置節點可以支援所有功能。不過實際上這卻從來沒有奏效過:應用程式從來沒有使用過這項特性,而且許多驅動也沒有支援此特性,就算他們支援了也從來沒有被測試過。另外,在不同功能間切換裝置節點只是在使用流資料io api時需要,並不能用read()/write() api。
如今每個裝置節點只支援乙個功能。
所有這些裝置有乙個問題,就是v4l2 api並沒有提供找到相關裝置的規則。有些確實很複雜的裝置使用多**控制器來達到這個目的。但是大多數裝置並不用它,現存的一些**表示他們使用sysfs來發現相關裝置,還沒有乙個庫可以為使用多**控制器的裝置和沒使用的裝置提供乙個單一的api。如果你想來從事這個工作的話請先寫一封郵件到此郵件列表:
多重開啟
當乙個應用程式因為需要流資料而申請了記憶體空間後(通過vidioc_reqbufs或vidioc_create_bufs ioctl,或通過read()或write()函式)這個程式(檔案控制代碼)就成為了此裝置的擁有者。再不會允許對記憶體空間大小做改動的動作(vidioc_s_fmt ioctl動作),而且其他應用再不被允許申請記憶體或開始、停止資料流,一旦這樣做了會返回ebusy錯誤**。
只是開啟v4l2裝置不會允許獨佔訪問。無論對請求型別資料分配的許可權是讀還是寫,初始化資料都會發生交換,而且對檔案控制代碼來說還會改變相關屬性。應用程式可以通過使用優先順序機制請求附加特選。
共享資料流
v4l2驅動不支援多個應用通過拷貝快取的方式在同一裝置上讀寫同一資料流,或時間復用,或其他類似方式。在使用者空間使用**程式處理這種情況會更好。
功能應用程式可以使用open()和close()對v4l2裝置執行開啟和關閉操作。裝置可以通過ioctl程式設計來完成接下來的章節所講述的內容。
因為v4l2涵蓋了各種各樣的裝置,但並不是所有型別的裝置都可以使用各種api。此外,相同型別的裝置也可能擁有不同的功能以及允許省略一點複雜或並不太重要的api。
vidioc_querycap ioctl命令可以檢視核心裝置對規範的相容有效性,查詢功能和io方法都是需要裝置支援的。
從核心版本3.1開始,vidioc_querycap將會返回v4l2 api版本,通常是與核心版本匹配的。沒有必要通過vidioc_quertcap檢查乙個特殊的ioctl是否支援,如果驅動不支援v4l2會返回enotty錯誤碼。
所有v4l2驅動都必須支援vidioc_querycap,應用程式往往在開啟裝置後就執行這個ioctl。
由於這些特性不能在完全在使用者空間施行,所以v4l2定義了vidioc_g_priority和vidioc_s_priority ioctl來通過檔案描述符申請和查詢准入優先順序。驅動不支援這些ioctl的情況下,開啟乙個裝置會分配乙個中等級優先順序,這與早起版本的v4l2相容。當應用程式通過vidioc_querycap ioctl查詢完功能後可以通過vidioc_s_priority請求不同的優先順序。
如vidioc_s_input等這種會改變驅動屬性的ioctl在其他程式申請了更高的優先順序後會返回ebusy錯誤碼。
struct v4l2_input input;
int index;
if (-1 == ioctl(fd, vidioc_g_input, &index))
memset(&input, 0, sizeof(input));
input.index = index;
if (-1 == ioctl(fd, vidioc_enuminput, &input))
printf("current input: %s\n", input.name);
int index;
index = 0;
if (-1 == ioctl(fd, vidioc_s_input, &index))
應用程式通過vidioc_enumaudio和vidioc_enumaudout ioctl來列舉關於有效輸入輸出的數量和屬性。vidioc_enumaudio ioctl返回結構體v4l2_audio,同時包含當前所查詢的音訊輸入訊號狀態。
vidioc_g_audio和vidioc_g_audout ioctl會報告當前音訊輸入和輸出。這裡需要注意,vidioc_enumaudio和vidioc_enumaudout所做的並不像vidioc_g_input和vidioc_g_output只是返回索引而已。
應用程式可以通過vidioc_s_audio ioctl來選擇音訊輸入以及改變它的屬性。vidioc_s_audout ioctl應用選擇音訊輸出(目前沒有什麼可以改變的屬性)。
當裝置應用多個可選擇的音訊輸入和輸出時必須在驅動中宣告所有聲音輸入、輸出ioctl。若裝置擁有任何音訊輸入或輸入的話,驅動必須在v4l2_capability中設定v4l2_cap_audio標籤,這樣可以被vidioc_querycap ioctl查詢到。
例 1.3 當前聲音輸入相關資訊
struct v4l2_audio audio;
memset(&audio, 0, sizeof(audio));
if (-1 == ioctl(fd, vidioc_g_audio, &audio))
printf("current input: %s\n", audio.name);
例 1.4 切換到第乙個音訊輸入
struct v4l2_audio audio;
memset(&audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */
audio.index = 0;
if (-1 == ioctl(fd, vidioc_s_audio, &audio))
調諧器
調製器radio頻率
應用程式可以通過vidioc_g_frequency和vidioc_s_frequency ioctl來獲取和設定調諧器或調製器的無線頻率,其引數均為v4l2_frequency結構體。對tv和radio裝置這些ioctl使用方法一樣。當調製器或調諧器的ioctl被支援,或是當裝置是乙個radio無線裝置的話,驅動必須支援這些ioctl。
V4L2文件翻譯(一)
相關資料 裝置命名 每乙個驅動註冊乙個或多個裝置節點後他們的主裝置號都是81,而子裝置號在0 255之間。除非通過config video fixed minor ranges編譯選項編譯核心,否則子裝置號是動態分配的。而且,子裝置號分配範圍與裝置節點型別有關 video radio等 很多驅動支援...
V4L2文件翻譯(八)
struct v4l2 pix format型別 成員名描述 u32 width 寬度 畫素 u32 height 高度 畫素 若field是v4l2 field top v4l2 field bottom v4l2 field alternate之一那麼高度指的是此區域的行數,否則的話指的是此幀的...
V4L2文件翻譯(三)
裝置通常有一些使用者可設定的控制器,如亮度和飽和度等等一些會展示在圖形使用者介面的東西。但不同裝置會有不同的可用設定,而且此外其可設定值範圍 預設值在不同裝置上也不盡相同。控制ioctl提供創造乙個良好使用者介面的資訊和機制,這會讓這些控制器在任何裝置上都能正確的工作。所有控制器都需通過id值進行訪...