Android Camera HAL3 - 開篇詞

好久沒有寫技術文章了,寫這類東西需要耗費的精力太多,但是最近工作中頻繁會接觸到 Camera 的知識,不總結下看來也是對不起我新買的筆記本,這篇就算是稀裏糊塗的開篇文章吧。技術類的文章產出總歸是要非常慢的,之前寫的 OpenMax 和 V4L2 每一篇都耗費了極長的時間,寫的過程中會很苦惱,怎麼組織自己的語言都感覺沒法很好的表達自己的想法,讓人忍不住時不時想口吐芬芳。

Camera 基礎模塊

Camera 涉及到視頻採集端的一系列模塊,其中 RAW圖像採集、ISP、Scale 模塊是必須要有的,只有它們全部組合起來才能夠完成完整的最基礎的視頻採集工作。在此基礎上會有其它的擴展項:

  • 畸變校正。其實畸變校正現在也算是個必須有的功能了,至少我見到的需要視頻採集的設備基本上都是有畸變校正功能的。
  • 電子防抖。這個我個人覺得相較於畸變校正算是個更高級一點的功能,它的技術難度在開發過程中讓我覺得比畸變校正更高,你可能覺得畸變校正難度更高點,但是我不要你覺得,我要我覺得,都聽我的,一個人說了算。
  • Jpeg 編碼。這個按道理來講很多產品終端都集成在了編解碼模塊中,但是在手機上面,你像驍龍8XX系列它是放在 Camera 這個模組裏面的,因爲現在拍照算是個極其重要且普遍的功能了,乾脆直接出 Jpeg,現在除了 Jpeg 也擴展出其它風格了,像蘋果的 HEIC 格式等。
  • 人臉檢測。人臉檢測在手機上面是一個自帶的相機功能,有的是用第三方的算法庫實現的,有的是有專門的獨立於 Camera 之外硬件模塊實現,有的呢就是直接集成在 Camera 這個大的模塊組裏面了。
  • 圖像視覺。這個目前還比較少見直接集成在 Camera 模塊組裏面,大都是單獨列出來一個硬件模塊或者使用軟件的第三方算法實現。

在手機上面,ISP 的功能也是日益完善且不斷擴展出新的處理模式,比如在降噪、變焦、超分辨率上面也做了很多的探索與擴展,另外單純的 ISP 效果也在不斷的增強,更大的分辨率,更加接近單反的調色等等。

總之在手機領域,Camera 模塊已經不再是以前那個單純的 Camera 了,它已經超越了視頻採集,在妄想一統便攜式單反、望遠鏡、顯微鏡、整容師的路上漸行漸遠了。

非安卓系統的 Camera

之前做的是非安卓系統裏面的視頻採集,除了內核裏面的驅動端框架是基於 V4L2 的之外,用戶空間的全部都是自研的致敬式架構,根據我的觀察,它的結構與安卓 Camera HAL1 的用法還是比較類似的。基本上的結構就是:

  1. 內核
  2. 用戶空間的中間件(類似於安卓 Camera HAL1)
  3. APP,或者中間再加一個業務邏輯框架層

其中我接觸比較多的就是內核以及中間件這部分,內核就不必說了,大量依附於 V4L2 爲基礎進行相關的邏輯構建,涉及的比較多的就是純 V4L2 的概念,畢竟內核已經幫你想好一整套的解決方案了,在大多數時候這些都是可以滿足需求的,只需要按照內核的規定去實現它就好。

用戶空間的中間件實現方式比較自由,因爲不像內核那樣是個非常標準的框架,世界上所有的 Linux 系統都在用。說到這裏,我想起來一個想法,就是內核的 V4L2 框架設計脈絡十分的清晰,看代碼實現也覺得這樣實現出來好像也是不復雜的,並且基於此實現具體的業務邏輯看起來也很簡單,就會有一種錯覺,覺得這個框架讓我自己搞一個看起來也不是不可能啊。後來工作中嘗試設計一個很小的模塊,發現你要把它搞得如此通用,並且讓別人理解起來邏輯又是如此的清晰,從 0 到 1 這個過程是極其困難的,你想象不到的那種困難。

之前接觸的都是基於組件化進行開發的中間件,這個跟 gstreamer 的以 pipeline 爲單位的使用方式是不一樣的,gstreamer 在使用上常常是基於 pipeline 爲單位進行構建數據流邏輯的,而我之前做的是基於一個個組件進行數據流邏輯建立的。其實基於組件在一定程度上來講,它的自由度會更加高,類似沙盒遊戲一般,但是 pipeline 爲單位的會使得上層的集成開發更加簡單高效,並且由於 element 的高度統一化抽象,使得內部的擴展更加容易實現,也就是更容易新增模塊,並且保持代碼的簡潔性,完全基於組件的實現,擴展起來就會比較麻煩,需要從下至上一整套的代碼適配,工作量會比較大,重複代碼也會比較多,但是它設計起來是相對比較簡單的。

非安卓系統的 Camera 從另外一個角度來講,它的業務邏輯也沒有那麼地複雜,因爲用不着安卓系統說明本身這個產品的複雜度與性能不是那麼的高,不像手機一樣,完全就是瑞士軍刀的路子,非安卓系統的通常都是細分領域的產品,功能相對來說比較單一,通常只會關注兩到三個主要功能進行開發研製。手機的主要功能那就多了去了,就算是隻說相機這一個,手機對相機的要求,目前來看也要遠比其它的設備來得複雜。

安卓系統的 Camera

安卓系統的 Camera 從兩個角度說下,主要是以手機爲例,就不說平板什麼的,因爲平板體積的限制,Camera 的發展遠遠抵不上手機,因爲不太會有人拿着一個平板到處拍照。

  1. 硬件複雜度更高。因爲手機的 Camera 要做到超高分辨率,疊加各種 ISP 效果,要有超廣角畸變校正,要有以假亂真的光學變焦(空間連續變換),要有人像模式,要有人臉識別,要有高幀率高分辨率的防抖(或光學或電子),要有各種濾鏡效果,要有物體追蹤(現在感覺不常見,但是之後會是基礎功能,安卓早就已經內置標準命令了)。。。總之,複雜的一批。
  2. 軟件設計自由度更高。硬件的複雜帶來一個副作用,不可避免的,軟件設計也會複雜很多,但是由於處理器的性能足夠,軟件代碼框架的設計上會更加自由,不必像中低端芯片那樣要在軟件設計上一再讓步。這也給了架構師與底層小蝦米更多的實現自由,不必太過於考慮性能問題而無法實現一些高擴展性、功能更加強大的架構。

安卓系統的 framework 以及 APP 端已經有人幫你制定好一整套的開發實現方案了,包括命令怎麼去發送,怎麼使用,數據流應該怎麼獲取,怎麼保存文件等等,都已經有相關的指導文檔,並且十分詳細,爲了保持兼容性你也不太可能說有太大的自由發揮空間,但是 HAL 層的話就針對於 HAL3 來講,還是有比較大的設計自由的。

因爲 HAL3 採用了一種類似於總線式的設計結構,從上層下發下來的命令參數以及 Buffer 等全部都被放置在同一個結構體裏面了,其中最重要的就是 Metadata 與 Buffer、Stream。這樣一個總線式的結構,我覺得給了 HAL 內部的軟件架構更加自由的實現機會。

HAL3 的主要改變

HAL1 其實我沒有太關注過,但是大概有了解過它是怎麼去使用的。HAL1 的話是分散型的控制,參數都有專門的函數調用去完成傳遞,比如像設置 ISP 的某一個參數,比如想拍照、錄像,都是有專門的函數調用來實現,它們是分開來的。而 HAL3 則是把那些控制全部都給放到同一個函數調用流程裏面完成了。

第二個主要的區別的就是 HAL1 從 framework 到 HAL 是直通式調用的,而 HAL3 的 framework 代碼和 HAL 之間是通過 AIDL 接口實現 Binder 遠程調用的。完成該方式轉換的項目叫做 Treble 項目,該項目旨在完成 framework 到 HAL 之間的解耦,以便儘量產生固定化的 framework 代碼,對於需要經常更新的 HAL 層代碼可以實現動態的更新而不需要動 framework 的代碼(無需改動也無需重新編譯),一個是方便代碼級別的更新,另一個就是方便在線升級,可以只更新 vendor 的東西而不用動到其它地方。

HAL3 的主要流程被拆分爲:

  1. 獲取現在設備上面可用的相機設備,包括相機每一個相機的屬性功能,get_number_of_camera。
  2. 獲取想要打開的相機的 information,在調用中被定爲 get_camera_info 函數。
  3. 打開一個設備,保存打開設備時獲取的 camera_module_t 結構體,該結構體就是一個抽象的 camera module 的連接通道。
  4. 通過新建一個 camera device,來獲取一個 camera3_device_t,結構體,該結構體主要用於獲取 notify 和 torch 的狀態。然後新建一個 session,session 就是後續需要與內部的 camera 硬件設備進行控制交互的抽象媒介。
  5. 通過 session 來配置一個 stream,configure_streams 函數可以完成此項工作。
  6. 向 HAL 內部發送控制命令,可以理解爲融合了 HAL1 的各種控制參數,把它們作爲一個總線形式的命令分發下去。相關的函數調用就是 process_capture_request。
  7. 內部 HAL 處理完畢之後會返回 notify 事件,一般就是幀的時間戳。並且通過 process_capture_result 來返回給 framework 相關的結果數據,包括控制參數的內容返回,包括 buffer 的返回等。
  8. 重複 6-7,直到用戶想退出,此時就調用 flush 來進行整個工作隊列的清洗操作。
  9. 關閉整個的 camera 設備,相關函數是 close。

可以看到,HAL3 其實更像是類似 V4L2 的總線式命令設計了,並且整個的過程也和 V4L2 的 ioctl 流程比較相似,就我個人的理解來看,它們的設計有點屬於同一宗派,同門師兄弟的感覺。HAL3 主要是給予了 framework 對於 camera 硬件更加強悍和細節的控制權,簡直可以達到那樣的微操境界,使得更加多樣化的 camera 應用變得可能。

End

這個算是開篇詞了,但是總歸技術類的文章寫出來的速度是比較慢的,我也是爲了工作才切到這上面,用作定時回顧之用,更新速度估計就沒有那麼的快,應該中間會穿插些雜七雜八的 C++ 學習文章,慢慢來吧。小歡喜這部劇還是挺推薦看看的,雖說它裏面的家庭相對中國這千千萬萬的家庭來說,還真就不是普通家庭了,但是裏面還是有不少可以值得學習的地方的,尤其是溝通和對孩子的教育上面,咱也是孩子來的,有些地方還是蠻有感觸的。


想做的事情就去做吧
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章