Android Camera2+HAL3架構

整體架構概述

Android Camera整體框架主要包括三個進程:app進程、camera server進程、hal進程。進程之間的通信都是通過binder實現,其中app和camera server通信使用aidl,camera server和hal通信使用hidl。Android Camera2整體架構如下圖:

Camera architecture
大致分爲這幾個部分:

  1. Application framework
    這一層是用於給APP提供訪問hardware的Camera API2,通過binder來訪問camera service。有兩個主要的類:
  • CameraManager,CameraManager是一個獨一無二地用於檢測、連接和描述相機設備的系統服務,負責管理所有的CameraDevice相機設備。通過ICameraService調用到CameraService。
// CameraManager.java
private void connectCameraServiceLocked() {  // CameraManager是一個系統服務,應該是開機就會被創建起來
	IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
	ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);  // 返回Stub.Proxy對象,也就是ICameraServiceProxy
	CameraStatus[] cameraStatuses = cameraService.addListener(this);                      // 註冊 ICameraServiceListener                
	mCameraService = cameraService;
}
  • CameraDevice:CameraDevice是連接在安卓設備上的單個相機的抽象表示。通過ICameraDeviceUser調用到CameraDeviceClient。
private CameraDevice openCameraDeviceUserAsync() {
	CameraDevice device = null;
	ICameraDeviceUser cameraUser = null;

	android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =      // CameraDeviceImp繼承自CameraDevice
		new android.hardware.camera2.impl.CameraDeviceImpl(cameraId, ...);
	ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();    // 獲取CameraDevice的回調函數
	ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
	cameraUser = cameraService.connectDevice(callbacks, cameraId, ...);  // connect到camera service,並將camera device callback註冊進去
    // 返回的ICameraDeviceUser就是CameraDeviceClient的本地接口
	deviceImpl.setRemoteDevice(cameraUser);
	device = deviceImpl;

	return device;
}
  1. AIDL
    基於Binder實現的一個用於讓App fw代碼訪問natice fw代碼的接口。其實現存在於下述路徑:frameworks/av/camera/aidl/android/hardware。其中:
    (1) ICameraService 是相機服務的接口。用於請求連接、添加監聽等。
    (2) ICameraDeviceUser 是已打開的特定相機設備的接口。應用框架可通過它訪問具體設備。
    (3) ICameraServiceListener 和 ICameraDeviceCallbacks 分別是從 CameraService 和 CameraDevice 到應用框架的回調。
  2. Natice framework
    代碼路徑位於:frameworks/av/。提供了ICameraService、ICameraDeviceUser、ICameraDeviceCallbacks、ICameraServiceListener等aidl接口的實現。以及camera server的main函數。
  3. Binder IPC interface
    提供進程間通信的接口,APP和CameraService的通信、CameraService和HAL的通信。其中,AIDL、HIDL都是基於Binder實現的。
  4. Camera Service
    代碼路徑:frameworks/av/services/camera/。同APP、HAL交互的服務,起到了承上啓下的作用。
  5. HAL
    Google的HAL定義了可以讓Camera Service訪問的標準接口。對於供應商而言,必須要實現這些接口。

核心概念:Request

request是貫穿camera2數據處理流程最爲重要的概念,應用框架是通過向camera子系統發送request來獲取其想要的result。request有下述幾個重要特徵:

  1. 一個request可以對應一系列的result。
  2. request應當包含所有必要的配置信息,存放於metadata中。如:分辨率和像素格式;sensor、鏡頭、閃光等的控制信息;3A 操作模式;RAW 到 YUV 處理控件;以及統計信息的生成等。
  3. request需要攜帶對應的surface(也就是框架裏面的stream),用於接收返回的圖像。
  4. 多個request可以同時處於in-flight狀態,並且submit request是non-blocking方式的。也就是說,上一個request沒有處理完,也可以submit新的request。
  5. 隊列中request的處理總是按照FIFO的形式。
  6. snapshot的request的preview的request擁有更高的優先級。

request的整體處理流程如下圖:
request processing

  • open 流程(黑色箭頭線條)
    • CameraManager註冊AvailabilityCallback回調,用於接收相機設備的可用性狀態變更的通知。
    • CameraManager通過調用getCameraIdList()獲取到當前可用的camera id,通過getCameraCharacteristcs()函數獲取到指定相機設備的特性。
    • CameraManager調用openCamera()打開指定相機設備,並返回一個CameraDevice對象,後續通過該CameraDevice對象操控具體的相機設備。
    • 使用CameraDevice對象的createCaptureSession()創建一個session,數據請求(預覽、拍照等)都是通過session進行。在創建session時,需要提供Surface作爲參數,用於接收返回的圖像。
  • configure stream流程(藍色箭頭線條)
    • 申請Surface,如上圖的OUTPUT STREAMS DESTINATIONS框,用於在創建session時作爲參數,接收session返回的圖像。
    • 創建session後,surface會被配置成框架的stream。在框架中,stream定義了圖像的size及format。
    • 每個request都需要攜帶target surface用於指定返回的圖像是歸屬到哪個被configure的stream的。
  • request處理流程(橙色箭頭線條)
    • CameraDevice對象通過createCaptureRequest()來創建request,每個reqeust都需要有surface和settings(settings就是metadata,request包含的所有配置信息都是放在metadata中的)。
    • 使用session的capture()、captureBurst()、setStreamingRequest()、setStreamingBurst()等api可以將request發送到框架。
    • 預覽的request,通過setStreamingRequest()、setStreamingBurst()發送,僅調用一次。將request set到repeating request list裏面。只要pending request queue裏面沒有request,就將repeating list裏面的request copy到pending queue裏面。
    • 拍照的request,通過capture()、captureBurst()發送,每次需要拍照都會調用。每次觸發,都會直接將request入到pending request queue裏面,所以拍照的request比預覽的request的優先級更高。
    • in-progress queue代表當前正在處理的request的queue,每處理完一個,都會從pending queue裏面拿出來一個新的request放到這裏。
  • 數據返回流程(紫色箭頭線條)
    • 硬件層面返回的數據會放到result裏面返回,會通過session的capture callback回調響應。

request在HAL的處理方式

  1. framework發送異步的request到hal。
  2. hal必須順序處理request,對於每一個request都要返回timestamp(shutter,也就是幀的生成時間)、metadata、image buffers。
  3. 對於request引用的每一類steam,必須按FIFO的方式返回result。比如:對於預覽的stream,result id 9必須要先於result id 10返回。但是拍照的stream,當前可以只返回到result id 7,因爲拍照和預覽用的stream不一樣。
  4. hal需要的信息都通過request攜帶的metadata接收,hal需要返回的信息都通過result攜帶的metadata返回。

HAL處理request的整體流程如下圖。
Camera HAL Process Request

  • request處理流程(黑色箭頭線條)
    • framework異步地submit request到hal,hal依次處理,並返回result。
    • 每個被submit到hal的request都必須攜帶stream。stream分爲input stream和output stream:input stream對應的buffer是已有圖像數據的buffer,hal對這些buffer進行reprocess;output stream對應的buffer是empty buffer,hal將生成的圖像數據填充的這些buffer裏面。
  • input stream處理流程(圖像的INPUT STREAM 1)
    • request攜帶input stream及input buffer到hal。
    • hal進行reprocess,然後新的圖像數據重新填充到buffer裏面,返回到framework。
  • output stream處理流程(圖像的OUTPUT STREAM 1…N)
    • request攜帶output stream及output buffer到hal。
    • hal經過一系列模塊的的處理,將圖像數據寫到buffer中,返回到frameowork。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章