android Camera 架構簡介

目前需要做一個語音通話及視頻聊天功能開發,主要分為音頻及視頻兩個部分,必然會涉及到Camera及AudioFlinger部分,對於顯示部分又會涉及到SurfaceFlinger部分,因此需要一步步的進行學習並確認設計是否合理.

這篇文章主要針對Camera作個簡要的介紹,瞭解需要開發的各個環節。

 

攝像頭系統提供的功能如下幾個方面:

a、預覽功能preview

b、視頻兒取功能 recording

c、拍照功能 takePicture

d、參數設置

 

1、android中基本的架構都是C/S層架構,客戶端提供調用接口,實現工作由服務端完成,那麼Camera也同樣

   滿足此條件:Client進程雖然不曾擁有任何實質的Camera數據,但是service端為它提供瞭豐富的接口,

   它可以輕松的獲得Camera數據的地址,然後處理這些數據。兩者通過Binder進行通訊。

  

首先我們來理清其工作流程,如此才能夠知道到底是個啥回事:

 

 按照上圖的流程,一路下來都是客戶端調用與實現,而這些接口的真正實現卻在服務端:

 

通過閱讀其interface函數知道,ICamera中提供的都是控制類接口,而ICameraClient定義的都是回調函數

 接口,即真正的數據流傳輸都是通過回調函數實現的。

 ok,通過以上應該知道瞭基本的攝像頭基本層次結構

        

2、重點介紹一下CamerService , 這是一個承上啟下的服務進程

   代碼路徑: frameworks\base\camera\libcameraservice 

   這部分內容編譯生成libcameraservice庫,這裡有個fake的攝像頭代碼,由USE_CAMERA_STUB宏進行設定。

 

class CameraService : public BnCameraService

{

// ICameraService interface

virtual sp<ICamera>     connect(const sp<ICameraClient>& cameraClient);
 

void            removeClient(const sp<ICameraClient>& cameraClient);
 

//… 省略部分內容

 

class Client : public BnCamera

{

//… 省略部分內容 

} }

 

運行過程中,利用CameraService::connect得於一個CameraService::Client 代碼如下所示:

sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) 

{

// create a new Client object

 client = new Client(this, cameraClient, callingPid);

mClient = client;

return client;

}

 

使用過程中,主要通過mClient這個類的接口來實現完成Camera 的功能

具體看下實現層代碼:

拍照功能:

//* take a picture – image is returned in callback */

status_t CameraService::Client::takePicture()

{

    LOGV("takePicture (pid %d)", getCallingPid());

    Mutex::Autolock lock(mLock);
    status_t result = checkPid();
    if (result != NO_ERROR) return result;

    if (mHardware == 0) {
        LOGE("mHardware is NULL, returning.");
        return INVALID_OPERATION;
    }

    mHardware->enableMsgType(CAMERA_MSG_SHUTTER |
                             CAMERA_MSG_POSTVIEW_FRAME |
                             CAMERA_MSG_RAW_IMAGE |
                             CAMERA_MSG_COMPRESSED_IMAGE);

    return mHardware->takePicture();

}

 

這裡用到瞭mHardware對象,調用所有的HAL層接口都是通過這個對象進行操作的,而這是如何生成的呢?

  mHardware = openCameraHardware();

   註意這個函數 openCameraHardware() , 這個函數位於硬件抽象層libcamera.so庫中,函數定義如下:

  /* factory function to instantiate a camera hardware object */
extern "C" sp<CameraHardwareInterface> openCameraHardware();

       
    3、攝像頭過程中會產生大量的數據流,這部分又是如何進行操作的呢?

未完,下一篇文章繼續解讀

 

摘自 andyhuabing的專欄

發佈留言