陳二微
隨著行業(yè)互聯(lián)網(wǎng)的持續(xù)發(fā)展,各行業(yè)對(duì)Camera數(shù)據(jù)的采集、應(yīng)用提出了不同的需求。以Linux操作系統(tǒng)為基礎(chǔ)的V4L2子系統(tǒng)是一種較為通用的驅(qū)動(dòng)架構(gòu)。本文描述基于電子的硬件ISP在V4L2接口下的實(shí)現(xiàn)方法、Camera連接的拓?fù)浣Y(jié)構(gòu)、提出了一種3A獨(dú)立進(jìn)程的圖像調(diào)試方式,及其靈活的、可拓展的應(yīng)用形式。
Linux V412及ISP硬件
Video For Linux 2(V412),是Linux Kernel中專用于處理視頻、圖像的子系統(tǒng)框架,向Linux操作系統(tǒng)應(yīng)用層提供了ISP及Camera硬件的標(biāo)準(zhǔn)接口,被廣泛應(yīng)用于各芯片廠商的設(shè)備驅(qū)動(dòng)。通過對(duì)數(shù)據(jù)流的詳細(xì)定義,使得應(yīng)用程序的開發(fā)有統(tǒng)一的接口,LinuxTV組織即是這個(gè)子系統(tǒng)的維護(hù)者。
ISP在本文中指集成于SoC中的圖像處理核心,它能夠?qū)amera感光元件獲取的Raw Bayer原始數(shù)據(jù)進(jìn)行去馬賽克(Demosaicing)處理,從而轉(zhuǎn)成一張YUV或RGB圖像;同時(shí)對(duì)圖像進(jìn)行3A (Auto Focus,Auto Exposure,Auto White Balance)信息統(tǒng)計(jì)并調(diào)試校正出一張曝光及白平衡準(zhǔn)確的圖像。ISP的硬件接口靈活,能夠接收不同分辨率、不同格式、MIPI或DVP協(xié)議傳輸?shù)脑紙D像數(shù)據(jù),也可接收已經(jīng)調(diào)試好的YUV或RGB圖像輸入;能夠?qū)υ瓐D進(jìn)行裁剪、縮放,并可同時(shí)輸出兩路不同格式(YUV或RGB)、不同大小的圖像。
驅(qū)動(dòng)的實(shí)現(xiàn)方法
一個(gè)完整的ISP傳輸Camera數(shù)據(jù)鏈路如圖1所示,它分為了Camera感光Sensor(可以包含一個(gè)或多個(gè)),MIPI DPHY 數(shù)據(jù)傳輸通路,ISP轉(zhuǎn)發(fā)數(shù)據(jù),統(tǒng)計(jì)圖像信息,調(diào)試參數(shù)配置,雙路圖像輸出6個(gè)大模塊。各個(gè)模塊分別表示為一個(gè)Entity 節(jié)點(diǎn),使用Link將兩個(gè)Entity連接起來,從而形成一條或2條的鏈路。
其中Camera攝像頭Entity可以支持1個(gè)或多個(gè),在建立Link鏈接時(shí),可以指定當(dāng)前有效的攝像頭。2個(gè)的圖像輸出接口從上一級(jí)Entity處得到圖像后,可以分別自由地裁剪、縮放并輸出。3A的調(diào)試過程從統(tǒng)計(jì)輸出數(shù)據(jù)Entity獲取3A信息,調(diào)整后將修改數(shù)據(jù)由調(diào)試參數(shù)Entity傳入,直到統(tǒng)計(jì)值收斂。
各個(gè)Entity需要按功能實(shí)現(xiàn)回調(diào)函數(shù)。如攝像頭、ISP轉(zhuǎn)發(fā)數(shù)據(jù)、圖像輸出接口,都需要實(shí)現(xiàn)set_fmt、get_fmt用于設(shè)置圖像的大小與格式;s_power用于給模塊上下電;s_stream用于使能數(shù)據(jù)流的輸出。圖像輸出接口另外還需要實(shí)現(xiàn)與應(yīng)用層的buffer輪轉(zhuǎn),即QBUF、DQBUF、QBUF...這樣的循環(huán)操作,以及裁剪與縮放接口,即s_selection,g_selection。這里采用v412框架中集成的vb2(video buffer 2)管理buffer,同時(shí)實(shí)現(xiàn)ISP內(nèi)嵌的iommu模塊,將不連續(xù)的物理內(nèi)存映射成ISP可以訪問的虛擬的連接內(nèi)存。
攝像頭模塊并不集成在SoC芯片中,與MIPI DPHY或ISP是物理上獨(dú)立的,驅(qū)動(dòng)上它也是最大限度地獨(dú)立,并且通過異步加載的形式注冊(cè)成為子設(shè)備(Sub-Device)。
應(yīng)用開發(fā)與3A獨(dú)立成一個(gè)進(jìn)程
基于V4L2的驅(qū)動(dòng)接口,應(yīng)用程序開發(fā)獲取圖像幀數(shù)據(jù),主要包括設(shè)置鏈路選擇攝像頭輸入、打開/dev/video設(shè)備、設(shè)置各個(gè)Entity的輸入與輸出大小格式、分配存儲(chǔ)Buffer、通過QBUF將Buffer配置到kernel、使能整個(gè)鏈路、等待一幀數(shù)據(jù)完成并DQBUF到應(yīng)用層、Buffer處理(或顯示或保存等等)完畢后再通過QBUF配置到kernel,并循環(huán)DQBUF與QBUF的操作直到退出。
得益于驅(qū)動(dòng)的標(biāo)準(zhǔn)化,例如v4l-utils、gstreamer、vlc等通用程序能直接獲取數(shù)據(jù)流并顯示出圖像、視頻。然而因公司的策略,3A調(diào)試部分是閉源且不在驅(qū)動(dòng)中實(shí)現(xiàn)。在沒有3A調(diào)試時(shí),應(yīng)用程序獲取的圖像或偏亮或偏暗,或顏色與實(shí)際相差太大。雖然有提供動(dòng)態(tài)鏈接庫供調(diào)用并使能3A,以完成圖像的調(diào)試,但需要修改v4l-utils、gstreamer、vlc等的源代碼,加入3A的初始化、使能與關(guān)閉。
本文提出了將3A與數(shù)據(jù)流分割開,獨(dú)立成一個(gè)進(jìn)程。令3A進(jìn)程通過v4l2-event 監(jiān)聽isp驅(qū)動(dòng)中start_stream與stop_ stream操作,在start_stream時(shí)在用戶空間完成3A的初始化,反之在stop_stream時(shí)關(guān)閉3A的操作。從而使得v4l-utils等工具能夠無縫地直接使用,也簡(jiǎn)化了應(yīng)用程序的開發(fā)。
Camera驅(qū)動(dòng)開發(fā)
除了應(yīng)用的開發(fā),另一個(gè)大塊是Camera(Sensor)攝像頭的驅(qū)動(dòng)如何移植。
基于該ISP的驅(qū)動(dòng)結(jié)構(gòu),Camera作為一個(gè)sub-device,驅(qū)動(dòng)的移植有簡(jiǎn)潔統(tǒng)一的步驟。概括為6個(gè)部分:
照datasheet 編寫上電時(shí)序,主要包括vdd,reset,powerdown,clk等;
配置sensor的寄存器以輸出所需的分辨率、格式;
編寫struct v4l2_subdev_ops所需要的回調(diào)函數(shù),一般包括set_fmt,get_fmt,s_power,s_stream,用于描述Camera所支持的格式與分辨率,上下電及輸出的開關(guān);
增加v412controller用來設(shè)置女口fps,exposure,gain,test pattern,用于調(diào)整幀率,設(shè)置曝光及增益,輸出內(nèi)嵌的測(cè)試圖片編寫.probe()函數(shù),并添加media control 及v4l2sub device 初始化代碼,使得該設(shè)備可以作為一個(gè)sub-device添加到ISP的完整鏈路中;
Dts(Device Tree Source)中通過remote-endpoint建立與ISP的具體鏈接信息。
相對(duì)于舊的驅(qū)動(dòng),新的驅(qū)動(dòng)主要的提升包含6個(gè)內(nèi)容,
①是使接口標(biāo)準(zhǔn)化;
②是使得3A進(jìn)程獨(dú)立運(yùn)行,極簡(jiǎn)了應(yīng)用的開發(fā);
③是雙路的圖像輸出可以同時(shí)獨(dú)立地進(jìn)行;
④是采用了vb2的buffer管理,有效地復(fù)用了代碼;
⑤是使得Camera,MipiDphy,ISP驅(qū)動(dòng)相互獨(dú)立,Camera異步注冊(cè),從而解耦合了整體結(jié)構(gòu);
⑥是能復(fù)用ISP模塊支持多個(gè)Camera接入到同一個(gè)ISP。
該isp驅(qū)動(dòng)已經(jīng)形成了一套完整的Camera驅(qū)動(dòng)、應(yīng)用程序開發(fā)方法,于項(xiàng)目實(shí)踐中應(yīng)用。