『壹』 android 開發,使用ndk調用v4l2來讀取Android攝像頭的數據靠譜嗎
一、用NDK進行C代碼的調取(已熟悉此調取技術)
二、攝像頭的獲取,這個不能用SDK來調,因為用SDK來調頭部跟蹤程序很難獲得我們的
數據,也不大能考慮AIDL跨進程通信的方案,因為這樣數據交互可能太慢。
問題:
頭部跟蹤移植到Android系統中,跟蹤程序需通過核心程序(C實現)調取Camera而不是通過Android SDK進行調取Camera。
前提:
Android的四個層次如下,
一個完成的Android應用,一般都是有java框架的,雖然NDK(Native Development Kit,一系列工具的集合)提供了一系列的工具,幫助開發者快速開發 C (或 C++ )的動態庫,並能自動將 so 和 java 應用一起打包成 apk 。但是NDK 並沒有提供各種系統事件處理支持,也沒有提供應用程序生命周期維護。此外,在本次發布的 NDK 中,應用程序 UI 方面的 API 也沒有提供。至少目前來說,使用純 C 、 C++ 開發一個完整應用的條件還不完備。所以,就目前來說,必須依賴上層Java框架的支持。
解決方案:
初步考慮有三種方式可以實現:
一、由於Android是運行在linux上的,所以可以考慮讓C程序調V4L2
介面來獲取攝像頭數據。Video4linux2(簡稱V4L2),是linux中關於視頻設備的內核驅動。在Linux中,視頻設備是設備文件,可以像訪問普通文件一樣對其進行讀寫,攝像頭在/dev/video0下。,不過可移植性差,因為不同廠家的設備驅動介面可能不完全一樣,另外也要求開發者熟悉Linux內核編譯。
二、SDK獲取攝像頭數據,再用JNI調C來處理圖像,也就是使用JNI來調取跟蹤程序並進行數據交互。
三、通過查看Android系統的底層代碼,發現Android系統調攝像頭也是通過JNI編程來實現的,所以考慮到是否能在JNI調用的Android底層Camera的底層流程中增加一步添加自己的業務邏輯。具體表現在調取Camera之前先啟動頭像識別程序,讓頭像識別程序去調Camera設備並獲得進行數據交互,比如可以考慮在人像識別中調取android_hardware_Camera.cpp。Camera進程機制如下圖:
在Android中,Camera的代碼主要在以下的目錄中:
Camera的JAVA程序的路徑:packages/apps/Camera/src/com/android/camera/
在其中Camera.java是主要實現的文件
Camera的JAVA本地調用部分(JNI):
frameworks/base/core/jni/android_hardware_Camera.cpp
這部分內容編譯成為目標是libandroid_runtime.so
。
Camera底層庫在以下的目錄中:
frameworks/base/libs/ui/
這部分的內容被編譯成庫libui.so。
Camera服務部分:
frameworks/base/camera/libcameraservice/
這部分內容被編譯成庫libcameraservice.so。
為了實現一個具體功能的Camera,在最底層還需要一個硬體相關的Camer庫(例如通過調用video for linux驅動程序和Jpeg編碼程序實現)。這個庫將被Camera的服務庫libcameraservice.so調用。
在 Camera系統的各個庫中,libui.so位於核心的位置,它對上層的提供的介面主要是Camera類,類 libandroid_runtime.so通過調用Camera類提供對JAVA的介面,並且實現了android.hardware.camera 類。 libcameraservice.so是Camera的伺服器程序,它通過繼承libui.so的類實現伺服器的功能,並且與libui.so中的另外一部分內容則通過進程間通訊(即Binder機制)的方式進行通訊。
libandroid_runtime.so和libui.so兩個庫是公用的,其中除了Camera還有其他方面的功能。
特別說明:Camera在模擬器上無法運行,以上所述方案暫時不能做測試,而且底層調取Camera屬於系統開發和嵌入開發的范疇,需要的知識面比較廣,我也只是在初步研究中,以上所述,如有錯誤,還請批評指正及包涵。