2.6camera session創建過程

如第一章所述,得到CameraDevice對象後就可以創建session了,還是以createCaptureSession爲例,這是一個抽象方法,我們已經介紹過,它的實現在CameraDeviceImpl中。

方法首先將傳入的Surface構建OutputConfiguration,OutputConfiguration是輸出的Surface的配置,包含一些基本的配置信息。

隨後調用createCaptureSessionInternal方法,如同Camera open時最終都是調用openCameraDeviceUserAsync方法一樣,create session最終也都是調用這個方法。

首先判斷異常情況,包括相機已經關閉、相機出錯以及high speed限制。判斷session是否爲空,如果不爲空就調用CameraCaptureSessionCore的

replaceSessionClose方法。

CameraCaptureSessionCore是一個接口,它的實現是CameraCaptureSessionImpl。

  1. replaceSessionClose方法調用了 close方法;
  2. 調用CameraDeviceImpl的stopRepeating方法;
  3. 調用ICameraDeviceUser的cancelRequest();
  4. 在Camera open的地方我們已經知道,在AIDL的另一頭的實現是CameraDeviceClient,所以調用它的cancelRequest();
  5. 調用Camera3Device的clearStreamingRequest()方法,最終調用clear方法;clear方法會清空RepeatingRequests list,然後遍歷並清空隊列中的buffer。

完成這些操作,當前正在運行的session就close了。

接下來調用configureStreamsChecked方法,這個方法的作用是create stream。

首先檢查outputConfiguration和inputConfiguration,確保配置正確。

接着檢查Camera的狀態,如果有異常則關閉camera,拋出異常。

 

遍歷outputConfigurations,確定哪些config需要創建steam和需要刪除。

mCallOnBusy內部有一個同步鎖mInterfaceLock,configureStreamsChecked方法也有這個鎖,所以它會等configureStreamsChecked方法執行完才執行run方法。StateCallbackKK是CameraDeviceImpl的一個內部靜態抽象類,包含了session的一些狀態,與CameraCaptureSession.StateCallback是不同的。

接下來調用waitUntilIdle方法,我們可以直接到CameraDeviceClient中找到相應的方法,在經過了多個狀態判斷之後,調用的核心代碼是mDevice的waitUntilDrained方法,我們已經知道mDevice是Camera3Device,直接去查看。跳過中間步驟,最終的核心代碼是一個do…while循環。如果status是active就結束。

 

Create steam

接下來就正式開始創建steam。

由於inputConfiguration通常是null所以直接看createSteam方法。

方法首先進行了大量狀態判斷,

然後遍歷bufferProducers,這部分是android的surface機制相關的內容,我們也暫時不管。

 

接下來這段就是核心方法,調用Camera3Device的createSteam方法。

同樣做了多個判斷。在switch中判斷mStatus的狀態,在初次創建Camera3Device的時候,initialize方法調用initializeCommonLocked方法,調用internalUpdateStatusLocked方法時,mStatus賦值爲STATUS_UNCONFIGURED,

所以在上面的代碼中直接執行了break語句,跳出來switch。

在判斷都沒有異常的情況下,就進入流的創建。根據流的類型不同,調用不同的構造方法。

創建完steam之後,就steam設置id,

Id是在已有的基礎上+1,所以如果有多個流,id就是連續的數字,至此一個steam就創建完成了。回到CameraDeviceImpl中,for循環遍歷outconfig,也就是遍歷surfaces,創建多個steam。

方法的最後調用endConfigure方法,我們依然到CameraDeviceClient中查看endConfigure方法的源碼,可以看到核心的代碼是調用Camera3Device中的configureStreams方法,直接查看源碼。

-> filterParamsAndConfigureLocked方法-> configureStreamsLocked方法

這個方法的主要行爲是給已經創建的steam添加buffersize、執行HAL配置、結束配置。

配置成功就調用outputStream的finishConfiguration方法。這個方法在Camera3Stream中實現,並調用子類Camera3OutputStream的configureQueueLocked的方法。在這個方法裏最重要的是

這句話。

前面提到mConsumer就是surface,執行surface的connect方法。

這裏是我們第二次遇到Surface機制的內容。

當遇到Camera的preview黑屏無法顯示的問題,如果出現了與Surface相關的異常,那麼就是可能是這兩個地方存在問題。一是GraphicBufferProducer構建出現問題,傳入的gbp是null,二是當前surface的GraphicBufferProducer有其他鏈接。

之後就是根據connect返回的狀態進行處理,計算mTotalBufferCount等操作。

至此steam的創建就全部完成了。

Create Session

Steam創建成功只有,就做好了創建session的全部準備工作了。

創建CameraCaptureSessionImpl對象,它是CameraCaptureSession的子類。

這個構造方法裏,除去直接構建的全局變量,主要就是構建StateCallback的createUserStateCallbackProxy方法,方法創建了一個SessionStateCallbackProxy對象,這個類是CameraCaptureSession.StateCallback的子類,並且內部持有一個StateCallback的對象,也就是APP創建並傳下來的callback。

CameraCaptureSessionImpl的構造函數的最後,如果一切配置正常就調用StateCallback的onConfiged方法,APP就會在會調用執行應用定義的行爲,一般就是構建CaptureRequest。

至此Session就全部創建完成了。

總結

通過上面代碼的分析,我們可以看到創建session主要有三個步驟

  1. 創建outputConfiguration;
  2. 創建Steam;
  3. 創建Session,調用Callback;
發佈了87 篇原創文章 · 獲贊 13 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章