寫在開頭:本文為學(xué)習(xí) camera2 過程中的知識(shí)點(diǎn)歸納總結(jié)。
1. camera2 相機(jī)體系結(jié)構(gòu)

https://blog.csdn.net/u012596975/article/details/107138177
對(duì)于Camera Api v2的實(shí)現(xiàn),是通過Camera Framework來完成的,而該層也有著一次不小的演變,剛開始Framework層并不是直接通過AIDL接口與Camera Service進(jìn)行通信,而是通過一個(gè)JNI層來完成從Java到Native的轉(zhuǎn)換,而Native部分作為客戶端,保持對(duì)Service的通信。這種設(shè)計(jì),很顯然會(huì)比較臃腫,并且代碼難以維護(hù),所以之后由于AIDL接口的提出,谷歌直接將其加入到相機(jī)框架中,用于保持Framework與Service的通信,進(jìn)而擯棄了JNI層,進(jìn)一步減少了不必要的層級(jí)結(jié)構(gòu),保持了整個(gè)體系簡(jiǎn)潔性。
更多可參考 深入理解Android相機(jī)體系結(jié)構(gòu) 系列。
2. camera1和camera2的使用簡(jiǎn)單對(duì)比
先回顧一下,camera1和camera2的簡(jiǎn)單使用。
這兩篇camera1和camera2的預(yù)覽demo,十分簡(jiǎn)潔,功能單一,可供對(duì)比。
Android Camera1最簡(jiǎn)單的預(yù)覽框顯示
Android Camera2最簡(jiǎn)單的預(yù)覽框顯示
下面這兩張思維導(dǎo)圖,較為詳細(xì)得說明了camera的使用流程和API。這不是本篇的重點(diǎn)。


camera1 的 open 簡(jiǎn)單代碼流程可參考這篇:
Android Camera open 從上到下代碼流程
camera2 的 open 簡(jiǎn)單代碼流程可參考這篇:
Android CameraManager open 從上到下代碼流程
如果需要更詳細(xì)的demo,可參考官方的 demo:cameraview
camera1和camera2 的調(diào)用流程對(duì)比,可參考這張圖??梢钥吹?API V2是沒有通過JNI的api的,這里是直接調(diào)用的service。

谷歌在Andorid 5.0(API Level 21)便重新對(duì)Camera進(jìn)行了設(shè)計(jì),摒棄了Camera Api v1的設(shè)計(jì)邏輯,提出了一個(gè)全新的API – camera2,引入了Session以及Request概念,將控制邏輯統(tǒng)一成一個(gè)視圖,因此在使用上更加復(fù)雜,同時(shí)也支持了更多特性,比如逐幀控制曝光、感光度以及支持Raw格式的輸出等。并且由于對(duì)控制邏輯的高度抽象化,使得該接口具有很高的靈活性,可以通過簡(jiǎn)單的操作實(shí)現(xiàn)30fps的全高清連拍的功能,總得來說,該接口極大地提高了對(duì)于相機(jī)框架的控制能力,同時(shí)也進(jìn)一步大幅度提升了其整體性能。
camera2的應(yīng)用層與framework層之間的流程如下:

簡(jiǎn)單來說就是,引入了Session以及Request,使用更加復(fù)雜,功能多,更加靈活了。
注意,雖然新增了camera2的api,camera1的代碼依然在android源碼中。分析的時(shí)候要注意。
frameworks/base/core/java/android/hardware/camera2/這個(gè)目錄下的是camera2的framework層代碼。
Camera整體架構(gòu)簡(jiǎn)述

忽略掉驅(qū)動(dòng)層,就是這張圖。

了解完Android Camera工作大體流程后,來看看部分細(xì)節(jié)。
2. 源碼簡(jiǎn)單分析
本篇源碼分析,不會(huì)涉及驅(qū)動(dòng)層及以下(最多一點(diǎn)點(diǎn))。另由于MTK和高通camera,還有android原生的,在camera這塊差異很大,流程分析查找資料的時(shí)候要注意下。
Android Camera工作大體流程:

出處: https://blog.csdn.net/TaylorPotter/article/details/105387109
綠色框中是應(yīng)用開發(fā)者需要做的操作,藍(lán)色為AOSP提供的API,黃色為Native Framework Service,紫色為HAL層Service.
描述一下步驟:
- 1.App一般在MainActivity中使用SurfaceView或者SurfaceTexture + TextureView或者GLSurfaceView等控件作為顯示預(yù)覽界面的控件,共同點(diǎn)都是包含了一個(gè)單獨(dú)的Surface作為取相機(jī)數(shù)據(jù)的容器.
- 2.在MainActivity onCreate的時(shí)候調(diào)用API 去通知Framework Native Service CameraServer去connect HAL繼而打開Camera硬件sensor.
- 3.openCamera成功會(huì)有回調(diào)從CameraServer通知到App,在onOpenedCamera或類似回調(diào)中去調(diào)用類似startPreview的操作.此時(shí)會(huì)創(chuàng)建CameraCaptureSession,創(chuàng)建過程中會(huì)向CameraServer調(diào)用ConfigureStream的操作,ConfigureStream的參數(shù)中包含了第一步中空間中的Surface的引用,相當(dāng)于App將Surface容器給到了CameraServer,CameraServer包裝了下該Surface容器為stream,通過HIDL傳遞給HAL,繼而HAL也做configureStream操作
- 4.ConfigureStream成功后CameraServer會(huì)給App回調(diào)通知ConfigStream成功,接下來App便會(huì)調(diào)用AOSP setRepeatingRequest接口給到CameraServer,CameraServer初始化時(shí)便起來了一個(gè)死循環(huán)線程等待來接收Request.
- 5.CameraServer將request交到Hal層去處理,得到HAL處理結(jié)果后取出該Request的處理Result中的Buffer填到App給到的容器中,
SetRepeatingRequest 為了預(yù)覽,則交給Preview的Surface容器,如果是Capture Request則將收到的Buffer交給ImageReader的Surface容器. - 6.Surface本質(zhì)上是BufferQueue的使用者和封裝者,當(dāng)CameraServer中App設(shè)置來的Surface容器被填滿了BufferQueue機(jī)制將會(huì)通知到應(yīng)用,此時(shí)App中控件取出各自容器中的內(nèi)容消費(fèi)掉,Preview控件中的Surface中的內(nèi)容將通過View提供到SurfaceFlinger中進(jìn)行合成最終顯示出來,即預(yù)覽;而ImageReader中的Surface被填了,則App將會(huì)取出保存成圖片文件消費(fèi)掉.
簡(jiǎn)單圖如下:

https://blog.csdn.net/TaylorPotter/article/details/105387109
通過AIDL binder調(diào)用向Framework層的CameraServer進(jìn)程下指令,從CameraServer進(jìn)程中取的數(shù)據(jù).
基本過程都如下:
- 1.openCamera:Sensor上電
- 2.configureStream: 該步就是將控件如GLSurfaceView,ImageReader等中的Surface容器給到CameraServer.
- 3.request: 預(yù)覽使用SetRepeatingRequest,拍一張可以使用Capture,本質(zhì)都是setRequest給到CameraServer
- 4.CameraServer將Request的處理結(jié)果Buffer數(shù)據(jù)填到對(duì)應(yīng)的Surface容器中,填完后由BufferQueue機(jī)制回調(diào)到引用層對(duì)應(yīng)的Surface控件的CallBack處理函數(shù),接下來要顯示預(yù)覽或保圖片App中對(duì)應(yīng)的Surface中都有數(shù)據(jù)了
著重看看以下幾點(diǎn)
- CameraService和CameraProvider服務(wù)啟動(dòng)
- open
- configure
- request
2.1 CameraService和CameraProvider服務(wù)啟動(dòng)
層級(jí)架構(gòu)概覽

總體邏輯順序計(jì)
(1) CameraProvider進(jìn)程啟動(dòng)、注冊(cè)
(2) CameraServer進(jìn)程啟動(dòng)、注冊(cè)、初始化
(3) CameraServer初始化過程中通過HIDL通信獲取CameraProvider,并對(duì) CameraProvider進(jìn)行初始化
CameraService和CameraProvider初始化

CameraServer初始化

具體代碼流程可參考:
Android 8.1 Camera2架構(gòu)解析(1) CameraService和CameraProvider服務(wù)啟動(dòng)流程
[Android O] Camera 服務(wù)啟動(dòng)流程簡(jiǎn)析
2.2 open
可直接參考這篇:
camera framework open流程
有道筆記上排版更好。
camera2 open流程
最后來張時(shí)序圖加深下印象。

2.3 configure
以下代碼出自這篇Android Camera2最簡(jiǎn)單的預(yù)覽框顯示。
/**
* 打開相機(jī),預(yù)覽是在回調(diào)里面執(zhí)行的。
*/
private void openCamera() {
try {
// 4.權(quán)限檢查
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
return;
}
// 5.真正打開相機(jī)
Log.i(TAG, "openCamera");
mCameraManager.openCamera(mCameraId, mStateCallback, null);
} catch (CameraAccessException e) {
Log.e(TAG, "openCamera error = " + e.getMessage());
}
/**
* 相機(jī)狀態(tài)監(jiān)聽對(duì)象
*/
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
Log.i(TAG, "StateCallback! onOpened");
mCameraDevice = camera; // 打開成功,保存代表相機(jī)的CameraDevice實(shí)例
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mTextureView.getWidth(), mTextureView.getHeight());
Surface surface = new Surface(surfaceTexture);
ArrayList<Surface> previewList = new ArrayList<>();
previewList.add(surface);
try {
// 6.將TextureView的surface傳遞給CameraDevice
mCameraDevice.createCaptureSession(previewList, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(surface); // 必須設(shè)置才能正常預(yù)覽
CaptureRequest captureRequest = builder.build();
// 7.CameraCaptureSession與CaptureRequest綁定(這是最后一步,已可顯示相機(jī)預(yù)覽)
session.setRepeatingRequest(captureRequest, mSessionCaptureCallback, null);
} catch (CameraAccessException e) {
Log.e(TAG, "createCaptureRequest error = " + e.getMessage());
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Log.e(TAG, "onConfigureFailed");
}
}, null);
} catch (CameraAccessException e) {
Log.e(TAG, "createCaptureSession error = " + e.getMessage());
}
}
應(yīng)用層在openCamera之后,會(huì)調(diào)用createCaptureSession。

createCaptureSession之后的流程可參考這篇:
camera framework configure流程分析
出處:https://blog.csdn.net/haodada1226/article/details/121719939
總結(jié)一下:
① configure為app傳入的surface配置相應(yīng)的stream,然后將gbp、streamid、surfaceid進(jìn)行綁定,以便于發(fā)送request請(qǐng)求的時(shí)候去獲取;
② 告訴hal層,需要從camera中獲取什么樣格式的buffer
簡(jiǎn)單版時(shí)序圖

復(fù)雜版時(shí)序圖

2.4 request
在 Android Camera2最簡(jiǎn)單的預(yù)覽框顯示 這篇文的代碼中可以看到,
調(diào)用createCaptureRequest之后通過build創(chuàng)建CaptureRequest,然后session.setRepeatingRequest,然后就可以預(yù)覽了。

然后接下來的流程可直接參考這篇:
camera framework request流程
出處: https://blog.csdn.net/haodada1226/article/details/121848769
這里總結(jié)一下:
configure的時(shí)候?yàn)槊總€(gè)surface創(chuàng)建相應(yīng)的Camera3OutputStream,然后將相應(yīng)的信息保存起來(注意CameraDeviceClient中的mStreamMap、mConfiguredOutputs以及Camera3Device中的mOutputStreams等),然后告訴hal層需要配置什么格式、分辨率等的流。request中會(huì)將上述的surfaces和outputStreams填充進(jìn)request請(qǐng)求中,然后在Camera3Device中起一個(gè)thread,一直向hal層發(fā)送request請(qǐng)求。
最后來張時(shí)序圖

3.camera中的BufferQueue
http://m.itdecent.cn/p/05a8d6f5b4df
BufferQueue可以理解為一個(gè)生產(chǎn)者-消費(fèi)者”模型,對(duì)GraphicBuffer管理的一種機(jī)制。
需注意的是,可以將BufferQueue當(dāng)作是一個(gè)算法結(jié)構(gòu),并不是只有Surfaceflinger會(huì)使用到,其他進(jìn)程只要有GraphicBuffer的消費(fèi)地方都會(huì)使用到。
BufferQueue結(jié)構(gòu)


http://m.itdecent.cn/p/05a8d6f5b4df
圖形生產(chǎn)者(如相機(jī),View繪制等)先向BufferQueue申請(qǐng)GraphicBuffer,填充完GraphicBuffer后,將GraphicBuffer移交給BufferQueue,BufferQueue會(huì)通知圖形消費(fèi)者(如Surfaceflinger,ImageReader,GLConsumer等)
相機(jī)中preview使用到的TextureView中的成員SurfaceTexture就是個(gè)自帶BufferQueue的組件。
http://m.itdecent.cn/p/05a8d6f5b4df
框架流程匯總

參考鏈接:
深入理解Android相機(jī)體系結(jié)構(gòu)之二
深入理解Android相機(jī)體系結(jié)構(gòu)之三
深入理解Android相機(jī)體系結(jié)構(gòu)之十
Android Camera簡(jiǎn)單整理(一)-Camera Android架構(gòu)(基于Q)
Android Camera簡(jiǎn)單整理(三)-Mtk Camera MtkCam3架構(gòu)學(xué)習(xí)
[Android O] Camera 服務(wù)啟動(dòng)流程簡(jiǎn)析
CameraService啟動(dòng)流程
Android 8.1 Camera2架構(gòu)解析(1) CameraService和CameraProvider服務(wù)啟動(dòng)流程
Camera service服務(wù)啟動(dòng)流程
BufferQueue詳解 原理
Android-Fk:BufferQueue學(xué)習(xí)整理
Android Camera2 Framwork+Hal+Surface整體數(shù)據(jù)流程
Android Camera 打開預(yù)覽流程分析(三)-- Camera 連接到CameraService 過程分析
camera framework configure流程分析
Camera2 API -- OutputConfiguration
camera framework configure流程分析
