android2.2 — 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的專欄

發佈留言