基于V4L2的視頻驅(qū)動(dòng)開發(fā)(1)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
作者:劉洪濤,華清遠(yuǎn)見嵌入式學(xué)院講師。
編寫基于V4L2視頻驅(qū)動(dòng)主要涉及到以下幾個(gè)知識(shí)點(diǎn):
●????攝像頭方面的知識(shí)
????????????????要了解選用的攝像頭的特性,包括訪問控制方法、各種參數(shù)的配置方法、信號(hào)輸出類型等。
●????Camera解碼器、控制器
????????????????如果攝像頭是模擬量輸出的,要熟悉解碼器的配置。最后數(shù)字視頻信號(hào)進(jìn)入camera控制器后,還要熟悉camera控制器的操作。
●????V4L2的API和數(shù)據(jù)結(jié)構(gòu)
????????????????編寫驅(qū)動(dòng)前要熟悉應(yīng)用程序訪問V4L2的方法及設(shè)計(jì)到的數(shù)據(jù)結(jié)構(gòu)。
●????V4L2的驅(qū)動(dòng)架構(gòu)
????????????????最后編寫出符合V4L2規(guī)范的視頻驅(qū)動(dòng)。
本文介紹基于S3C2440硬件平臺(tái)的V4L2視頻驅(qū)動(dòng)開發(fā)。攝像頭采用OmniVision公司的OV9650和OV9655。主要包含以下幾個(gè)方面的內(nèi)容:
視頻驅(qū)動(dòng)的整體驅(qū)動(dòng)框架
●????3C2440 camera控制器+ov9650(ov9655)
????????●????V4L2API及數(shù)據(jù)結(jié)構(gòu)
????????●????V4L2驅(qū)動(dòng)框架
????????●????ov9650(ov9655)+s3c2440+V4L2實(shí)例
一、 視頻驅(qū)動(dòng)的整體框架
視頻驅(qū)動(dòng)的整體框架見下圖:
二、S3C2440 camera控制器+ov9650(ov9655)
(1)S3C2440 camera控制器介紹
S3C2440支持ITU-RBT601/656格式的數(shù)字圖像輸入,支持的2個(gè)通道的DMA,Preview通道和Codec通道,參見下圖。
Preview通道可以將YCbCr4:2:2格式的圖像轉(zhuǎn)換為RGB(16bit或24bit)格式的數(shù)據(jù),并存放于為PreviewDMA分配的內(nèi)存中,最大分辨率為640*480。主要用于本地液晶屏顯示。如果將PreviewDMA的內(nèi)存和Framebuffer內(nèi)存重疊的話,就可以實(shí)現(xiàn)采集直接輸出到液晶屏上了。
Codec通道可以輸出YCbCr4:2:0或YCbCr4:2:2格式到為CodecDMA分配的內(nèi)存中。最大分辨率為4096*4096。主要用于圖像的編解碼處理。
上圖中的windowcut功能是指在圖像可以先做一個(gè)裁剪。通過設(shè)置CIWDOFST完成此功能,見下圖。圖像進(jìn)入P、C通道后,各自的scaler單元還可以對(duì)其進(jìn)行縮放、旋轉(zhuǎn)等處理。
S3C2440camera控制器支持乒乓存儲(chǔ)。為了防止采集和輸出之間的沖突,采用了乒乓存儲(chǔ)方式。每次采集一幀后,自動(dòng)轉(zhuǎn)到下一個(gè)存儲(chǔ)區(qū)。如果你因?yàn)閮?nèi)存空間不足,不想使用此功能的話,可以將四個(gè)區(qū)域設(shè)置到同一塊空間。
在做圖像處理時(shí),需要關(guān)注到最后存儲(chǔ)區(qū)中的圖像格式,如codec通道硬件自動(dòng)把Y、Cb、Cr分離存儲(chǔ)。
S3C2440 camera 控制器Last IRQ功能的使用,也是需要掌握的。如果處理不好,輸出的圖像效果會(huì)受影響。
控制器會(huì)在每個(gè)VSYNC下降沿判斷ImgCptEn信號(hào)等命令。如果在下降沿發(fā)現(xiàn)ImgCptEn信號(hào)有效,則產(chǎn)生IRQ中斷。然后才開始一幀圖像的真正采集。而如果在VSYNC下降沿判斷到ImgCptEn為低電平且之前LastIRQEn沒有使能,則不會(huì)產(chǎn)生任何中斷,且不會(huì)再進(jìn)行下一幀的采集。如果你想在ImgCptEn關(guān)閉后,一幀采集完后產(chǎn)生一個(gè)中斷通知你,那么就需要在最后一次中斷產(chǎn)生前(stopcapturing后的vysnc下將沿)使能lastirq就可以了。
我在移植linux驅(qū)動(dòng)時(shí)就遇到了一個(gè)LastIRQ的問題?,F(xiàn)象是輸出圖像上面總是有一條比其它部分反應(yīng)慢。采集運(yùn)動(dòng)圖像,就能看出現(xiàn)象。查看代碼是因?yàn)闆]有設(shè)立lastirq,因?yàn)槊看稳绻辉趌astirq產(chǎn)生的情況下讀取,圖像緩沖中的數(shù)據(jù)是不穩(wěn)定的,可能照成圖像不完整。修改代碼支持lastirq后,問題解決。
Camera控制器時(shí)鐘設(shè)置也是需要注意的,ov9650需要Camera控制器為其提供時(shí)鐘。
提供給外部攝像頭的時(shí)鐘是由UPLL輸出時(shí)鐘分頻得到的。而CAMIF的時(shí)鐘是由HCLK提供的。本例中,提供給ov9650的時(shí)鐘為24M。
(2)ov9650(ov9655)設(shè)置方法
OV9650是OmniVision公司的COMS攝像頭,130萬像素,支持SXVGA、VGA、QVGA、CIF等圖像輸出格式。最大速率在SXVGA時(shí)為15fps,在VGA時(shí)為30fps。
OV9650攝像頭時(shí)序如下圖:
上圖中D[9:2]用于8-bitYUV或者RGB565/RGB555(D[9]MSB、D[2]LSB)。D[9:0]用于10-bitRGB。本例中使用8-bit YUV模式。
我手邊開發(fā)板的Camera和S3C2440的接線原理圖如下(對(duì)應(yīng)camera中具體的信號(hào)名稱參見前文的驅(qū)動(dòng)整體架構(gòu)圖)。
注:GPG12用于PWEN信號(hào)
OV9650攝像頭設(shè)置方法是通過SCCB總線設(shè)置
SCCB可以看作是一種簡化的I2C總線,可以使用IO模擬SCCB時(shí)序。
(3)編寫ARM測(cè)試代碼測(cè)試camera功能
在Keil環(huán)境下編寫一個(gè)測(cè)試代碼完成從攝像頭采集圖像輸出到液晶屏。下面列出程序的流程。
(4)編寫測(cè)試代碼過程中常見的問題
●????攝像頭寄存器的配置
因?yàn)閿z像頭有很多寄存器,可能一下無法理解里面所有的配置含義,所以開始時(shí)希望得到一份可用的配置。但往往從別人的測(cè)試代碼中拿到配置后,仍然無法使用。我這里列出幾個(gè)可能的原因:(1)攝像頭中的圖像輸出格式和你在camera控制器中設(shè)置的不一致,同一個(gè)攝像頭可以設(shè)置多種輸入格式,如:YCbYCr或CbYCrY。(2)圖像輸出的一些時(shí)序和你的camera控制器設(shè)置不一致,攝像頭可以設(shè)置一些時(shí)序,如:圖像數(shù)據(jù)在CAMPCLK的上升沿有效還是下降沿有效。(3)注意輸出圖像的格式和Framebuffer控制器的匹配,如字節(jié)順序等問題。
●????Ov9650和ov9655的使用區(qū)別
這里主要列出兩者之間在復(fù)位信號(hào)上有差別,ov9650是高電平復(fù)位,而ov9655是低電平復(fù)位。