ubuntu添加自定義vga輸出分辨率

Ubuntu有點折騰人....可是在折騰以後發現它更加方便,並且懂得更多的東西git

最近在調試一個視頻採集芯片的驅動,主要是接收vga輸入和hdmi輸入,在實驗的過程當中遇到了一個惱火的問題,就是同一臺電腦(個人聯想筆記本y400),在win8的vga輸出的1360768分辨率個人採集芯片能識別到,可是ubuntu下,一樣的分辨率卻沒法識別到,採集芯片識別到參數和VESA上的標準彷佛不一致...問題到底出如今哪裏呢?另一個問題,win8的vga輸出多了好幾個分辨率好比說19201080@60...而ubuntu卻沒有,最大隻到1360*768..ubuntu

個人ubuntu的顯卡驅動有安裝啊...難道是英偉達區別對待??我不相信...應用開發商不開發應用這我沒辦法,可是硬件應該是能夠保持功能上的一致。下面就來講我是如何解決這個問題的。bash

必須知道的一些視頻知識

vga視頻信號是模擬信號,一開始它(VGA)表示一個視頻分辨率640*480後面也一般表示爲一個視頻接口(硬件接口,規定引腳功能和電平等),咱們知道顯示分辨率有很是多種,見下圖:服務器

display resolution

即便同一分辨率可是他們的時序不必定同樣的,這個時序規定什麼呢?視頻信號除了有效圖像數據還有消隱區,這個消隱區存在的理由是由於:網絡

行場消隱信號,是針對老式顯像管的成像掃描電路而言的。電子槍所發出的電子束從屏幕的左上角開始向右掃描,一行掃完需將電子束從右邊移回到左邊以便掃描第 二行。在移動期間就必須有一個信號加到電路上,使得電子束不能發出,否則這個回掃線會破壞屏幕圖像。這個阻止回掃線產生的信號就叫做消隱信號,場信號的消隱也是一個道理。ide

除了消隱區以外,還有一個東西是必備的,那就是同步信號。測試

幾乎全部通訊都須要同步信號,無線通訊(3G、4G),TCP/IP通訊等。ui

視頻信號的同步,有能夠分爲外同步和內嵌同步,同步信號又分爲:數據使能信號(DE)、水平同步信號(HS),垂直同步信號(VS)/場同步信號(Filed).net

用下面一幅圖來講明這些同步信號在傳輸視頻中的位置:調試

如上圖所示,上半部分是者視頻一行以內的信號,而下半部分是視頻總體同步信號狀況,data enable就是DE信號它指示了有效數據開始的時候,在視頻處理中,只要知道這個信號咱們就能夠取出有效數據了.

而後是hs信號,它的做用就是上面提到的消隱區問題,它決定了行消隱區插入的時刻,若是是內嵌同步信號的話,也決定了EAV和SAV信號的插入時刻。

VS信號的做用是決定場消隱信號的插入時刻...

不一樣視頻標準一樣分辨率下時序的不一樣就體如今,諸如VS,HS寬度不一樣,HS到有效數據之間長度(顯示後沿:148),HS離上一行結束的長度(顯示前沿:88)

內嵌同步信號出現的緣由是個人猜測是解決並行的干擾,或者少幾條線吧..就是在數據線中傳輸同步信號,而後接受方檢測頭...內嵌同步的狀況是這樣滴:

一行從參考時序EAV(有效視頻結尾)開始,EAV後面就是水消隱白區,水消隱白區的結尾是SAV。有SAV後面緊跟的就是有效視頻區。有效視頻區的樣本就是真正顯示在屏幕上的點,而空白區對應的就是模擬視頻信號中的消隱區效視頻開始)

這就是內嵌同步下一行視頻的狀況...

其中,SAV是有效視頻行的開始標誌,佔4個字,前三個是3FF、000、000第四個字是XYZ,包含主要的時序信息。EAV表示有效視頻行的結束,同SAV格式相同。

其中,F表示該行屬於哪個場,F=0表示場1,F=1表示場2。V表示該行是否爲場消隱區的行,H用於區分EAV和SAV,H=0表示SAV,H=1表示EAV。
P3=V⊕h、P2=F⊕H、P1=F⊕V、P0=F⊕V⊕H
EAV以後的兩個字LN,表示該視頻行在特定的視頻格式中所處的行數,色度和亮度信息中的LN是相同的。
LN後面的兩個字是前一行的循環冗餘碼(CRC)

因爲接收端須要,個人視頻採集芯片配置都是內嵌同步模式..須要根據視頻標準指定上面提到的同步信號的一些信息,好比和說一行之中總共像素,有效像素,一行所用時間,hs和vs的寬度,hs或者vs的顯示前沿和顯示後沿的寬度,這些信號的有效電平是高仍是低等等。

視頻標準

關於視頻標準,真是五代十國般混亂,所謂視頻標準就是規定上面說的這些時序..咱們知道視頻信號有模擬的,數字的,高清的,非高清的,還有各類各樣的視頻接口:hdmi、vga、S-vdieo、DVI、DP等,串行的並行的...不管它們怎麼傳,它們傳的視頻信號都是按照上面說的形式來組織的。

首先是VESA:

視頻電子標準協會(Video Electronics Standards Association, VESA)是由表明來自世界各地的、享有投票權利的140多家成員公司的董事會領導的非盈利國際組織,總部設立於加利福尼亞州的Milpitas,自1989年創立以來,一直致力於制訂並推廣顯示相關標準

VESA這個組織總共弄了三個標準:GTF、DMT和CVT。

gtf和cvt準確的說都是一套公式用於計算視頻時序..你只要給出視頻長寬和幀率就能按照其公式算出相關時序。

Generalized Timing Formula (GTF) is a method of generating industry standard timings used by a wide variety of display products

而cvt是:

Coordinated Video Timings (CVT) were released on March 2003 as the newest VESA standard for generating display timings

cvt是gtf的代替者。

dmt是啥?咱們知道網絡通訊的OSI分爲七層,這是專家們制定的標準,可是最後採用的倒是TCP/IP的4層結構...緣由就是市場每每是是否採用某個標準的決定性緣由.

dmt就是這樣的一個視頻時序集,它是在市面上早已採用的視頻標準集,這些視頻格式大部分不兼容cvt和gtf公式,可是它卻被市場所採納。

Display Monitor Timings (DMT) are a list of VESA standard pre-defined timings which are commonly used within the Computer industry

這兩年高清視頻很火,但是高清視頻的標準是另一個制定的(==!),可是後來VESA的dmt也收集部分高清視頻格式並標明是取至哪一個標準.

好比說:CEA/EIA

Electronic Industries Alliance (EIA-861B) refers to a CEA/EIA standard which consists of display timing and formats supported by Digital Television

這貨是專門制定數字視頻標準的,難道模擬信號的vga就不能輸出1080p@60的視頻嗎,咱們的電腦最後處理和顯示都是數字信號,模擬信號都須要通過ADC轉換的,因此答案是:能夠。

好比在VESA DMT 12p3標準中:對1080p@60視頻格式有這樣註明:

關於內嵌同步的標準有bt.656和bt.1120這樣的標準,關於輸入顏色空間有bt.601和bt.709這樣的標準,關於視頻接口好比說hdmi或者sdi又有各自的標準,咱們作信號採集和處理的(用fpga、dsp或者專用芯片)必須仔細查看這些標準才能準確解出視頻信號而後才能處理..

ubuntu的vga輸出分辨率問題

有了上面的知識,如今知道爲啥一樣分辨率一樣的幀率,一樣的硬件,爲何在win8能夠檢測到,而在ubuntu檢測不到的答案嗎?梳理了一遍知識,發現很大多是採用的標準不一樣致使的!!

ubuntu自帶了兩個命令:cvtgtf

這兩個命令根據輸入的分辨率和幀率獲得相應的時序...

好比說

cvt 1366 768 60
# 1360x768 59.80 Hz (CVT) hsync: 47.72 kHz; pclk: 84.75 MHz
Modeline "1360x768_60.00"   84.75  1360 1432 1568 1776  768 771 781 798 -hsync +vsync
gtf  1360 768 60
# 1360x768 @ 60.00 Hz (GTF) hsync: 47.70 kHz; pclk: 84.72 MHz
  Modeline "1360x768_60.00"  84.72  1360 1424 1568 1776  768 769 772 795  -HSync +Vsync

值得注意,在VESA制定視頻標準中,一樣視頻分辨率和會分爲normal blanking和reduced blanking這兩種類型的視頻格式,這是因爲當今時代的顯示器再也不須要像之前那樣用電子槍掃了...因此場消隱,行消隱其實沒啥意義並且浪費帶寬..因此催生了一種reduced blanking的視頻格式,意在減小視頻信號在帶寬的佔用...

cvt 1360 768 60 -r
# 1360x768 59.96 Hz (CVT) hsync: 47.37 kHz; pclk: 72.00 MHz
Modeline "1360x768R"   72.00  1360 1408 1440 1520  768 771 781 790 +hsync -vsync

以上,ubuntu可能使用cvt的1360768@60或者gtf的1360768@60或者使用rb(reduced blanking)的1360*768@60。

而在win8上的1360*768@60則是按照dmt來輸出的,由於我是按照dmt中的參數來設置視頻採集芯片的。

因此在不改變視頻採集芯片的前提下,是想辦法讓ubuntu能夠輸出dmt中指定的視頻信號。

上面命令Modeline一行能夠用於xorg的配置,至於xorg的配置文件做用和語法請看這個連接: Linux系統中xorg.conf文件簡介,這裏猜測這個東西能夠用於規定分辨率相關東東,在Ubuntu14.04中已經沒有xorg.conf這個文件,而是分爲多個文件了,放在/usr/share/X11/xorg.conf.d中。

首先搞清楚上面的命令輸出的意思:我對照dmt彷佛不能找到啥規律:

而後後來我找到一個計算cvt的程序,源文件連接以下:cvt.c

下載後執行gcc cvt.c -O2 -o cvt -lm -Wall就好了

這個cvt命令能輸出更多的信息..借鑑這些信息以後我就知道Modeline那一行的意義了:

./cvt 1360 768 60  -v

1: [V FIELD RATE RQD]         :       60.000000
 2: [H PIXELS RND]             :     1360.000000
 2.5: [ASPECT_RATIO]           :       16:9
 2.5: [V SYNC]                 :        5.000000
 3: [LEFT MARGIN (PIXELS)]     :        0.000000
 3: [RIGHT MARGIN (PIXELS)]    :        0.000000
 4: [TOTAL ACTIVE PIXELS]      :     1360.000000
 5: [V LINES RND]              :      768.000000
 6: [TOP MARGIN (LINES)]       :        0.000000
 6: [BOT MARGIN (LINES)]       :        0.000000
 7: [INTERLACE]                :        0.000000
 8: [H PERIOD EST]             :       20.903589
 9: [Actual V_SYNC_BP]         :       26.311272
 9: [Estimated V_SYNC_BP]      :       27.000000
 9: [V_SYNC_BP]                :       27.000000
10: [Back porch]               :       22.000000
11: [TOTAL V LINES]            :      798.000000
12: [IDEAL DUTY CYCLE]         :       23.728924
13: [H BLANK]                  :      416.000000
14: [TOTAL PIXELS]             :     1776.000000
15: [Non-rounded PIXEL FREQ]   :       84.961487
15: [ACT PIXEL FREQ]           :       84.750000
16: [ACT H FREQ]               :       47.719593
17: [ACT FIELD RATE]           :       59.798988
18: [ACT FRAME RATE]           :       59.798988
20: [H BACK PORCH]             :      208.000000
21: [H SYNC RND]               :      136.000000
22: [H FRONT PORCH]            :       72.000000
23: [V FRONT PORCH]            :        3.000000

  # 1360x768 @ 60.00 Hz (CVT)
  #   field rate 59.80 Hz; hsync: 47.72 kHz; pclk: 84.75 MHz
  Modeline "1360x768_60.00"  84.75  1360 1432 1568 1776  768 771 776 798  -HSync +Vsync

通過對照dmt中的參數,Modeline那一行中,84.75是像素始終對應dmt中的Pixel Clock,1360對應Hor Pixels,1432對應Hor Pixels+H Front Porch(像素),1568對應Hor Pixels+H Back Porch(像素),1766對應Hor Total Time中對應的象素,768對應Ver Pixels,771對應Ver Pixels+V Front Porch(行數)
776對應Ver Pixels+V Front Porch(行數)+Ver Sync Time(行數),798對應Ver Total Time(行數),-HSync指的是hs信號爲負,+表示爲正,對應dmt中的Hor Sync PolarityVer Sync Polarity

有了這些理解,咱們就能夠創造出本身的Modeline了.根據dmt中的1360*768@60 normal blanking描述:獲得這樣Modeline:

Modeline "1360x768_60.00"  85.50 1360 1424 1616 1792 768 771 777 795 +hsync +vsync

看吧和cvt計算出來的差異仍是有滴,hs極性都不一樣...

怎麼將這個分辨率添加到vga輸出呢,有一種臨時的方法(註銷後失效),還有一種永久性的方法(就是xorg配置文件)。

先介紹臨時方法,主要命令是xrandr命令,

xrandr - primitive command line interface to RandR extension

其中RandR是:

RandR is a communications protocol written as an extension to the X11[2] and Wayland[3] protocols for display servers. Both, XRandR and WRandR facilitate the ability to resize, rotate and reflect the root window of a screen.

反正就是控制display server的命令就對啦...它能控制屏幕分辨率,旋轉大小等...固然顯示服務器的下面必須有顯卡驅動,顯卡驅動下面必須有顯卡這個硬件,顯示服務器上面必須有顯示器或者其它視頻接收設備,否則這個命令不會起做用。

執行xrandr輸出相關硬件信息:

xrandr
Screen 0: minimum 8 x 8, current 1366 x 768, maximum 16384 x 16384
VGA-0 disconnected (normal left inverted right x axis y axis)
LVDS-0 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 310mm x 174mm
   1366x768       60.0*+
   1024x768       60.0  
   960x540        60.0  
   840x525        59.9  
   800x600        60.3  
   800x512        60.2  
   720x450        59.9  
   700x525        60.0  
   680x384        60.0     59.8  
   640x512        60.0  
   640x480        59.9     60.0  
   576x432        60.1  
   512x384        60.0  
   400x300        60.3  
   320x240        60.1  
HDMI-0 disconnected (normal left inverted right x axis y axis)

上面說明了,個人筆記本有一個顯示器處於鏈接狀態(廢話==!),還有一個VGA口和hdmi口處於未鏈接狀態,這和個人硬件是相符合的,在輸出信息中歐你那個須要記住:Screen 0,VGA-0和LVDS-0這樣的名字。

加新分辨率的通常過程以下:

# 獲得某一分辨率的modeline
cvt 1680 1050 60
# 1680x1050 59.95 Hz (CVT 1.76MA) hsync: 65.29 kHz; pclk: 146.25 MHz
Modeline "1680x1050_60.00"  146.25  1680 1784 1960 2240  1050 1053 1059 1089 -hsync +vsync
# 增長一個模式
sudo xrandr --newmode "1680x1050_60.00"  146.25  1680 1784 1960 2240  1050 1053 1059 1089 -hsync +vsync
# 將這個模式添加到硬件上,注意VGA-0可根據須要改爲LCDS-0或者HDMI-0等
sudo xrandr --addmode VGA-0 "1680x1050_60.00"
#在指定硬件輸出指定模式
xrandr --output VGA --mode 1680x1050_60.00

關於1360*768,上面命令中只須要改變modeline參數和模式名字,就好了,實踐結果是吻合上面猜測的.

接下來讓它用久生效:

/usr/share/X11/xorg.conf.d新建一個文件:10-monitor.conf而後輸入如下內容,保存而後註銷,而後測試:

#Modeline 像素時鐘 HP  HP+HFP HP+HBP HTP VP VP+VFP VP+VFP+VSW VTL HS有效電平 VS信號的有效電平
Section "Monitor"
  Identifier "Monitor0"
  HorizSync       30.0 - 83.0
  VertRefresh     56.0 - 75.0
  Option         "DPMS"
  Option "VendorName" "Nvidia Proprietary Driver"
  Modeline "1366x768_60.00"  85.50 1366 1436 1579 1792 768 771 774 798 +hsync +vsync
  Modeline "1360x768_60.00"  85.50 1360 1424 1616 1792 768 771 777 795 +hsync +vsync
  Modeline "1920x1080_60.00"  148.50 1920 2008 2068 2200 1080 1084 1089 1125 +hsync +vsync
  Modeline "1440x900_60.00"  106.50  1440 1528 1672 1904  900 903 909 934 -hsync +vsync
  Modeline "1600x1200_60.00"  162.00 1600 1664 1904 2160 1200 1201 1204 1250 +hsync +vsync
  Modeline "1280x720_60.00"  74.25 1280 1390 1500 1650 720 725 730 750  +hsync +vsync
  Modeline "1600x900_60R"  108.00 1600 1624 1696 1800 900 901 904 1000  +hsync +vsync
EndSection

Section "Screen"
  Identifier "Screen0"
  Device "VGA-0"
  Monitor "Monitor0"
  Option "ModeValidation" "AllowNonEdidModes, NoVirtualSizeCheck, NoMaxPClkCheck, NoWidthAlignmentCheck, NoExtendedGpuCapabilitiesCheck"
  DefaultDepth 24
  SubSection "Display"
    Depth 24
    Modes "1366x768_60.00" "1360x768_60.00" "1920x1080_60.00" "1440x900_60.00" "1600x1200_60.00" "1280x720_60.00" "1600x900_60R"
  EndSubSection
EndSection

Section "Screen"
  Identifier "Screen0"
  Device "LVDS-0"
  Monitor "Monitor0"
  Option "ModeValidation" "AllowNonEdidModes, NoVirtualSizeCheck, NoMaxPClkCheck, NoWidthAlignmentCheck, NoExtendedGpuCapabilitiesCheck"
  DefaultDepth 24
  SubSection "Display"
    Depth 24
    Modes "1366x768_60.00"
  EndSubSection
EndSection

註銷後會發現VGA輸出了多了好多分辨率,並且我指定的分辨率都是我想要的時序,也就是你能隨意的創造出本身的想要的視頻信號時序,這就是ubuntu的魅力!!!

嘿嘿,最後仍是要潑下冷水,英偉達的確區別對待了Linux和windwos...在ubuntu中的nvidia的控制面板上找不到任何關於添加自定義分辨率的選項,而在win8上卻找到了,並且是傻瓜式,也就是說上面說的,win8也能夠作到嘿嘿.:

可是,起碼證實了一點ubuntu也能夠作到..並且在折騰過程當中學到更多...

一些截圖:

相關文章
相關標籤/搜索