轉自:https://blog.csdn.net/airk000/article/details/23218903php
https://www.kernel.org/doc/Documentation/zh_CN/video4linux/v4l2-framework.txt
http://linuxtv.org/downloads/v4l-dvb-apis/html
V4L2驅動之內核模塊形式存在,能夠被系統管理員手動加載或當發現設備時自動加載。驅動被編入videodev模塊,其提供幫助函數以及在此文檔的一個經常使用應用接口描述。linux
每個驅動註冊一個或多個設備節點後他們的主設備號都是81,而子設備號在0~255之間。除非經過CONFIG_VIDEO_FIXED_MINOR_RANGES編譯選項編譯內核,不然子設備號是動態分配的。並且,子設備號分配範圍與設備節點類型有關(video、radio等)。ios
不少驅動支持經過video_nr,radio_nr或vbi_nr模塊設置來選擇特殊的video/radio/vbi節點號。這就容許用戶申請指定的設備節點名稱,如/dev/video5而不是交給系統生成。當驅動支持多個同類設備有多餘一個設備節點號時候,可以下:編程
>modprobe mydriver video_nr=0,1 radio_nr=0,1
在/etc/modules.conf中能夠這樣寫:api
options mydriver video_nr=0,1 radio_nr=0,1
若是在模塊設置中沒有給定設備節點號則驅動會默認進行分配。緩存
一般狀況下udev會爲你在/dev下自動建立設備節點。若是udev沒有安裝,那麼你須要使能CONFIG_VIDEO_FIXED_MINOR_RANGES內核選項,這樣就能夠將子設備號設定爲設備節點號了,即子設備號5一樣會使設備節點名爲video5。此特性會使不一樣類型設備擁有不一樣範圍的子設備號。這些範圍在第四節:接口中將給出。(不繞彎子了,我這裏給直接列出來)ide
類型 | 範圍 |
---|---|
video | 0~63 |
vbi | 224~255 |
vtx | 192~223 |
radio | 64~127 |
SDR | 0~255 |
特殊文件的建立(用mknod)是一個特殊操做,並且這些設備不能經過主設備號和子設備號打開。這意味着應用程序不能掃描加載上的或安裝上的驅動。用戶必須敲入一個設備名,或者說應用程序能夠嘗試使用常規的設備名稱。函數
設備能夠支持好幾個功能,如視頻捕捉、VBI捕捉以及無線廣播。測試
V4L2 API爲這些功能分別建立不一樣的設備節點。
V4L2 API被設計成一個設備節點能夠支持全部功能。不過實際上這卻歷來沒有奏效過:應用程序歷來沒有使用過這項特性,並且許多驅動也沒有支持此特性,就算他們支持了也歷來沒有被測試過。另外,在不一樣功能間切換設備節點只是在使用流數據IO API時須要,並不能用read()/write() API。
現在每一個設備節點只支持一個功能。
除了視頻輸入、輸出外硬件還可能同時支持聲音取樣和播放。若是這樣的話,這些功能要以ALSA PCM設備形式存在。
全部這些設備有一個問題,就是V4L2 API並無提供找到相關設備的規則。有些確實很複雜的設備使用多媒體控制器來達到這個目的。可是大多數設備並不用它,現存的一些代碼表示他們使用sysfs來發現相關設備,尚未一個庫能夠爲使用多媒體控制器的設備和沒使用的設備提供一個單一的API。若是你想來從事這個工做的話請先寫一封郵件到此郵件列表:http://www.linuxtv.org/lists.php
V4L2設備能夠被打開超過一次。一旦驅動支持這樣作,用戶就能夠像這樣使用:開啓一個錶盤程序來控制好比亮度或聲音音量,而後另外一個程序來捕捉視頻和音頻。換句話說,就是錶盤程序至關於ALSA聲音混合程序。只是打開一個V4L2設備並不會改變設備的狀態。
當一個應用程序由於須要流數據而申請了內存空間後(經過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錯誤碼。
能夠經過不一樣的ioctl查詢其餘特性,如經過VIDIOC_ENUMINPUT查詢設備視頻鏈接器的數量、類型及名字。儘管API的目的主要是抽象,VIDIOC_QUERYCAP ioctl仍然容許驅動透過特殊應用程序來實現個性化。
全部V4L2驅動都必須支持VIDIOC_QUERYCAP,應用程序每每在打開設備後就執行這個ioctl。
當多個應用程序共享同一個設備時,須要給他們分配不一樣的優先級。相反的一個視頻錄製應用程序執行如rm -rf /這類命令可能會阻塞其餘程序改變視頻控制或切換當前TV頻道。另外一個目的是容許低優先級應用程序工做在後臺,這樣用戶控制程序就能夠優先並可以在稍後自動恢復設備控制。
因爲這些特性不能在徹底在用戶空間施行,因此V4L2定義了VIDIOC_G_PRIORITY和VIDIOC_S_PRIORITY ioctl來經過文件描述符申請和查詢准入優先級。驅動不支持這些ioctl的狀況下,打開一個設備會分配一箇中等級優先級,這與早起版本的V4L2兼容。當應用程序經過VIDIOC_QUERYCAP ioctl查詢完功能後能夠經過VIDIOC_S_PRIORITY請求不一樣的優先級。
如VIDIOC_S_INPUT等這種會改變驅動屬性的ioctl在其餘程序申請了更高的優先級後會返回EBUSY錯誤碼。
視頻輸入輸出一個設備的物理連線。如RF連線(天線、電纜),視頻連線,或RGB連線。視頻和VBI捕捉設備須要輸入,而視頻和VBI輸出設備須要輸出,至少各一個。Radio無限通信設備並無視頻輸入輸出。
應用程序能夠經過VIDIOC_ENUMINPUT和VIDIOC_ENUMOUTPUT ioctl來查看有效輸入和輸出的數量和屬性。VIDIOC_ENUMINPUT ioctl會返回v4l2_input結構體,也會返回被查詢的視頻輸入設備的狀態信息。
VIDIOC_G_INPUT和VIDIOC_G_OUTPUT ioctl將會返回當前視頻輸入或輸出的索引。應用程序能夠經過VIDIOC_S_INPUT和VIDIOC_S_OUTPUT ioctl來選擇不一樣輸入或輸出。設備若擁有一個或多個的輸入、輸出,則必須在驅動中聲明全部的輸入、輸出ioctl。
例 1.1 當前視頻輸入的信息
例 1.2 切換到第一個視頻輸入
音頻輸入和輸出是設備的物理連線。視頻捕捉設備會有輸入,輸出設備會有輸出,零個或每一個多個。Radio無線通信設備沒有聲音輸入和輸出。他們都會擁有正好一個調諧器,事實上就是一個聲源,可是API只將視頻輸入或輸出與調諧器關聯起來,而radio設備沒有。TV卡上用來接收聲音信號給聲卡的鏈接器並不被視爲是聲音輸出。
聲音和視頻輸入輸出是相互關聯的。選擇一個視頻源的同時也會選擇一個聲音源。當視頻和聲音的源是一個調諧器的時候這就最明顯不過了。未來聲音連機器將會和一個以上的視頻輸入或輸出結合。假設有兩個混合的視頻輸入和兩個音頻輸入存在,就會有最多四種有效組合。關於視頻和聲音的聯繫在結構體v4l2_input或v4l2_output的audioset中有所體現,每一位表明一個索引號,從0開始。
應用程序經過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 當前聲音輸入相關信息
例 1.4 切換到第一個音頻輸入
視頻輸入設備能夠擁有一個或多個調諧器來解調一個RF信號。每一個調諧器關聯一個或多個視頻輸入,這依賴於調諧器的RF連線數量。經過VIDIOC_ENUMINPUT ioctl返回的v4l2_input結構體中中的type成員是V4L2_INPUT_TYPE_TUNER,tuner成員包含了調諧器的索引號。
Radio無線通信輸入設備有一個調諧器,索引號爲0,沒有任何視頻輸入。
應用程序能夠經過VIDIOC_G_TUNER和VIDIOC_S_TUNER ioctl來查詢和改變調諧器屬性。噹噹前視頻或radio輸入被查詢時,VIDIOC_G_TUNER所返回的v4l2_tuner結構體也包含了信號狀態信息。注意,當擁有一個以上調諧器的時候,VIDIOC_S_TUNER並不會切換當前調諧器。使用哪一個調諧器只由當前視頻輸入決定。若設備擁有一個或以上的調諧器的時候,必須支持這些ioctl,且要在v4l2_capability結構體中設置V4L2_CAP_TUNER標籤。
視頻輸出設備能夠有一個或以上的調製器,調製TV天線接收或者視頻錄製的視頻信號。每一個調製器可跟一個或多個視頻輸出關聯,這取決於調製器上有多少個RF鏈接線。經過VIDIOC_ENUMOUTPUT ioctl返回的v4l2_output結構體中type成員表明V4L2_OUTPUT_TYPE_MODULATOR,modulator成員包含調製器的索引。
Radio輸出設備有一個索引號爲0的調製器,沒有視頻輸出。
一個視頻或無線設備不可能同時支持調製器和調諧器。這樣的硬件須要兩個徹底分開的設備節點,一個支持調諧器功能,另外一個支持調製器功能。這樣的緣由是由於經過VIDIOC_S_FREQUENCY ioctl的頻率將沒法判斷是調製器的仍是調諧器的。
應用程序可使用VIDIOC_G_MODULATOR和VIDIOC_S_MODULATOR ioctl來查詢和改變調製器屬性。當有一個以上調製器的時候,VIDIOC_S_MODULATOR並不會進行切換。當前的視頻輸出決定使用哪一個調製器。若設備擁有一個或以上的調製器,則其驅動必須支持這些ioctl,並在v4l2_capability結構體中設置V4L2_CAP_MODULATOR標籤。
應用程序能夠經過VIDIOC_G_FREQUENCY和VIDIOC_S_FREQUENCY ioctl來獲取和設置調諧器或調製器的無線頻率,其參數均爲v4l2_frequency結構體。對TV和Radio設備這些ioctl使用方法同樣。當調製器或調諧器的ioctl被支持,或是當設備是一個radio無線設備的話,驅動必須支持這些ioctl。