天天看點

camera編解碼介紹1 概述 2  CameraSource.read過程涉及的類圖結構 3 CameraSource.read的調用流程 4 總結

1 概述

camera 的錄像分為三個過程:

  1. camera子產品将從hal層的預覽線程中,擷取原始的未壓縮的yvu視屏幀,通過回調函數傳遞到CameraSource子產品
  2. OMXCodec子產品将從CameraSource子產品的read接口擷取yuv視訊幀拷貝到編碼子產品提供的輸入端口的buffer清單中,編碼子產品從輸入端口的buffer清單讀取包含yuv的buffer、編碼、然後送回到輸出端口的buffer清單,供OMXCodec子產品取回
  3. 從OMXCodec子產品的read接口讀取壓縮編碼後的h264幀,通過TS容器寫到輸出檔案句柄上,得到TS流的檔案

在這篇文章中,我們将集中讨論第一種情況,即CameraSource.read()接口的調用過程

2  CameraSource.read過程涉及的類圖結構

camera預覽線程CameraHardware::inPreviewThread在擷取到yuv視訊幀後,通過調用CameraHardware::frameCallbackNotifier函數,即最終調用到 CameraClient::dataCallbackTimestamp函數,将視訊幀buffer通過ICameraClient binder發送給Camera::dataCallbackTimestamp函數,該函數又通過 ICameraRecordingProxyListener binder将視訊幀對應的Imemory句柄轉發到CameraSource::dataCallbackTimestamp函數。 而在CameraSource::read函數中,會将剛才收到的IMemory句柄對應的記憶體如下的處理: *buffer = new MediaBuffer(frame->pointer(), frame->size()); 以上語句中的pointer()函數會将IMemory句柄對應的記憶體映射到CameraSource所在的程序C位址空間,進而使CameraSource和CameraClient共享同一個yuv視訊記憶體塊。

camera編解碼介紹1 概述 2  CameraSource.read過程涉及的類圖結構 3 CameraSource.read的調用流程 4 總結

需要注意的是:yuv視訊幀,是在CameraClient所在的程序配置設定的,而CameraClient和camera HAL是屬于同一個程序的。

3 CameraSource.read的調用流程

camera編解碼介紹1 概述 2  CameraSource.read過程涉及的類圖結構 3 CameraSource.read的調用流程 4 總結

以上Camerasource.read過程,涉及到2次binder調用,在資料傳遞的過程中,隻是傳遞的共享記憶體對應的句柄(Imemory),而不是傳輸實際的yuv記憶體資料,是以效率比較高。在Camerasource.read函數中,通過調用的Imemory的pointer函數,來講預覽用的記憶體映射到Camerasource.read所在程序,進而可以直接通路該塊記憶體。

另外錄像和預覽是同一個CameraHardware::inPreviewThread線程,這樣就可以在錄像、預覽、停止錄像等之間無縫的快速切換。

4 總結

camera錄像過程,涉及到子產品比較多,有camera子產品,編碼子產品,omx子產品,容器子產品,并且涉及大塊資料在各程序之間的共享操作。是以會比較複雜,中間會頻繁使用binder來進行程序的通訊。一個秘訣就是:循着binder的機制來檢視程式的資料流,而binder機制中的Bpxxx(用戶端),Bnxxx(伺服器端),Ixxx(接口),則是跟蹤程式流程的重要線索。

另外binder服務又分為知名服務,和匿名服務,像camera子產品,就有個media.camera的知名服務,而meidaRecorder子產品則屬于meida.player的知名服務,而更多的則是匿名服務,匿名服務可以通過知名服務或是其他已知的匿名服務來傳遞。

詳細的binder傳遞過程,可以參考binder的驅動相關的文章。

繼續閱讀