概述
google在android5.0(Lollipop)開始對(duì)Camera的架構(gòu)進(jìn)行了調(diào)整,廢棄了Camera API1接口。使用Camera API2把相機(jī)設(shè)備當(dāng)成一個(gè)流水線。每一個(gè)請(qǐng)求都可以從獲取相機(jī)設(shè)備獲取一張的圖像。這種request、response模式其實(shí)就是CS架構(gòu),事實(shí)上底層是實(shí)現(xiàn)了CameraDeviceClient.
CameraManager
操作相機(jī)需要一個(gè)CameraManager實(shí)例,它其實(shí)是一個(gè)系統(tǒng)服務(wù),通過context.getSystemService(Context.CAMERA_SERVICE)可以獲取。其提供一些描述相機(jī)的屬性信息,例如系統(tǒng)支持的相機(jī)個(gè)數(shù)列表getCameraIdList()和單個(gè)相機(jī)特性getCameraCharacteristics(cameraId)。當(dāng)然也可以調(diào)用openCamera(cameraId,stateCallback,handler)打開相機(jī)。
CameraDevice
CameraDevice可以表示一個(gè)打開的相機(jī)設(shè)備, CameraDevice.StateCallback的onOpened回調(diào)返回此實(shí)例對(duì)象。
CreateCaptureSession
想從相機(jī)設(shè)備中獲取Image,應(yīng)用要?jiǎng)?chuàng)建一個(gè)camera capture session 把接收數(shù)據(jù)的載體傳給相機(jī)設(shè)備,目前能接收相機(jī)數(shù)據(jù)的載體是Surface和SurfaceTexture。其中它們的size和format需要和相機(jī)支持的匹配。SurfaceView、TextureView、MediaCodec、MediaRecorder、Allocation、ImageReader都提供接收相機(jī)數(shù)據(jù)的載體。
通過情況下,相機(jī)的預(yù)覽數(shù)據(jù)可以使用SurfaceView和TextureView接收。拍照使用ImageReader、錄視頻使用MediaCodec或MediaRecorder。
CaptureRequest
應(yīng)用需要?jiǎng)?chuàng)建一個(gè)CaptureRequest向相機(jī)申請(qǐng)?jiān)O(shè)置參數(shù)。通過調(diào)用CameraCaptureSession的setRepeatingRequest接口實(shí)現(xiàn)。
Camera API2架構(gòu)圖
由圖可知,Java層要想與C++層的CameraService層進(jìn)行通信,都是通過Java層的IPC Binder進(jìn)制進(jìn)行的,主要包括ICameraService.aidl以及ICameraDeviceUser.aidl兩個(gè)接口來實(shí)現(xiàn),其會(huì)在Java層維護(hù)一個(gè)CameraDeviceImpl即Camera設(shè)備的代理,而CameraService以及CameraDeviceImpl的初始化會(huì)在此文的第二,第三節(jié)進(jìn)行分析。而Java層對(duì)Camera的具體操作的操作流程大致為,Java層通過Device代理發(fā)送一個(gè)CaptureRequest,而C++層進(jìn)行相應(yīng)的處理,再調(diào)用相應(yīng)的回調(diào)來通知Java相應(yīng)的處理結(jié)果,并將相應(yīng)的Capture數(shù)據(jù)保存在Surface Buffer里,這樣Java層在回調(diào)函數(shù)中可以對(duì)數(shù)據(jù)進(jìn)行相應(yīng)的處理。而對(duì)于具體操作流程的分析,請(qǐng)參考文章開始時(shí)的Camera2相關(guān)文章的連接。