国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Android 4.0 Camera架構(gòu)分析之Camera初始化

Android 4.0 Camera架構(gòu)分析之Camera初始化

http://blog.csdn.net/dnfchan/article/details/7594590

Android Camera 采用C/S架構(gòu),client 與server兩個獨立的線程之間使用Binder通信,這里將介紹Camera從設備開機,到進入相機應用是如何完成初始化工作的。

    首先既然Camera是利用binder通信,它肯定要將它的service注冊到ServiceManager里面,以備后續(xù)Client引用,那么這一步是在哪里進行的呢?細心的人會發(fā)現(xiàn),在frameworks\base\media\mediaserver\Main_MediaServer.cpp下有個main函數(shù),可以用來注冊媒體服務。CameraService完成了服務的注冊

 

  1. int main(int argc, char** argv)  
  2. {  
  3.     sp<ProcessState> proc(ProcessState::self());  
  4.     sp<IServiceManager> sm = defaultServiceManager();  
  5.     LOGI("ServiceManager: %p", sm.get());  
  6.     waitBeforeAdding( String16("media.audio_flinger") );  
  7.     AudioFlinger::instantiate();  
  8.     waitBeforeAdding( String16("media.player") );  
  9.     MediaPlayerService::instantiate();  
  10.     waitBeforeAdding( String16("media.camera") );  
  11.     CameraService::instantiate();  
  12.     waitBeforeAdding( String16("media.audio_policy") );  
  13.     AudioPolicyService::instantiate();  
  14.     ProcessState::self()->startThreadPool();  
  15.     IPCThreadState::self()->joinThreadPool();  


 

可是我們到CameraService文件里面卻找不到instantiate()這個函數(shù),它在哪?繼續(xù)追到它的一個父類BinderService
  1. static void instantiate() { publish(); }  

  1. static status_t publish() {  
  2.     sp<IServiceManager> sm(defaultServiceManager());  
  3.     return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());  
  4. }  


可以發(fā)現(xiàn)在publish()函數(shù)中,CameraService完成服務的注冊 。這里面有個SERVICE,源碼中有說明 
  1. template<typename SERVICE>  

這表示SERVICE是個模板,這里是注冊CameraService,所以可以用CameraService代替
  1. return sm->addService(String16(CameraService::getServiceName()), new CameraService());  

好了這樣,Camera就在ServiceManager完成服務注冊,提供給client隨時使用。

Main_MediaServer主函數(shù)由init.rc在啟動是調(diào)用,所以在設備開機的時候Camera就會注冊一個服務,用作binder通信。

  1. service media /system/bin/mediaserver  
  2.     class main  
  3.     user media  
  4.     group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc  
  5.     ioprio rt 4  

Binder服務已注冊,那接下來就看看client如何連上server端,并打開camera模塊。

咱們先從camera app的源碼入手。在onCreate()函數(shù)中專門有一個open Camera的線程

public void onCreate(Bundle icicle) {

......

mCameraOpenThread.start();

}

再看看mCameraOpenThread

Thread mCameraOpenThread = new Thread(new Runnable() {
        public void run() {
            try {
                qcameraUtilProfile("open camera");
                mCameraDevice = Util.openCamera(Camera.this, mCameraId);
                qcameraUtilProfile("camera opended");
            } catch (CameraHardwareException e) {
                mOpenCameraFail = true;
            } catch (CameraDisabledException e) {
                mCameraDisabled = true;
            }
        }
    });

繼續(xù)追Util.openCamera

return CameraHolder.instance().open(cameraId)

又來了個CameraHolder,該類用一個實例openCamera

public synchronized android.hardware.Camera open(int cameraId)
            throws CameraHardwareException {

    mCameraDevice = android.hardware.Camera.open(cameraId);

   return mCameraDevice;

}

在這里就開始進入framework層了,調(diào)用frameworks\base\core\java\android\hardware\Camera.java類的open方法 。

public static Camera open(){

    return new Camera(i);

}

這里調(diào)用了Camera的構(gòu)造函數(shù),在看看構(gòu)造函數(shù)

Camera(int cameraId){

native_setup(new WeakReference<Camera>(this), cameraId)

}

static JNINativeMethod camMethods[] = {
  { "getNumberOfCameras",
    "()I",
    (void *)android_hardware_Camera_getNumberOfCameras },
  { "getCameraInfo",
    "(ILandroid/hardware/Camera$CameraInfo;)V",
    (void*)android_hardware_Camera_getCameraInfo },
  { "native_setup",
    "(Ljava/lang/Object;I)V",
    (void*)android_hardware_Camera_native_setup },
  { "native_release",
    "()V",
    (void*)android_hardware_Camera_release },
  { "setPreviewDisplay",
    "(Landroid/view/Surface;)V",
    (void *)android_hardware_Camera_setPreviewDisplay },
  { "setPreviewTexture",
    "(Landroid/graphics/SurfaceTexture;)V",
    (void *)android_hardware_Camera_setPreviewTexture },
  { "startPreview",
    "()V",
    (void *)android_hardware_Camera_startPreview },
  { "_stopPreview",
    "()V",
    (void *)android_hardware_Camera_stopPreview },
  { "previewEnabled",
    "()Z",
    (void *)android_hardware_Camera_previewEnabled },
  { "setHasPreviewCallback",
    "(ZZ)V",
    (void *)android_hardware_Camera_setHasPreviewCallback },
  { "_addCallbackBuffer",
    "([BI)V",
    (void *)android_hardware_Camera_addCallbackBuffer },
  { "native_autoFocus",
    "()V",
    (void *)android_hardware_Camera_autoFocus },
  { "native_cancelAutoFocus",
    "()V",
    (void *)android_hardware_Camera_cancelAutoFocus },
  { "native_takePicture",
    "(I)V",
    (void *)android_hardware_Camera_takePicture },
  { "native_setParameters",
    "(Ljava/lang/String;)V",
    (void *)android_hardware_Camera_setParameters },
  { "native_getParameters",
    "()Ljava/lang/String;",
    (void *)android_hardware_Camera_getParameters },
  { "reconnect",
    "()V",
    (void*)android_hardware_Camera_reconnect },
  { "lock",
    "()V",
    (void*)android_hardware_Camera_lock },
  { "unlock",
    "()V",
    (void*)android_hardware_Camera_unlock },
//HTC_START howard 20120904
  { "setPinchZoom",
    "(I)V",
    (void *)android_hardware_Camera_setPinchZoom },
//HTC_END
  { "startSmoothZoom",
    "(I)V",
    (void *)android_hardware_Camera_startSmoothZoom },
  { "stopSmoothZoom",
    "()V",
    (void *)android_hardware_Camera_stopSmoothZoom },
  { "setDisplayOrientation",
    "(I)V",
    (void *)android_hardware_Camera_setDisplayOrientation },
  { "_startFaceDetection",
    "(I)V",
    (void *)android_hardware_Camera_startFaceDetection },
  { "_stopFaceDetection",
    "()V",
    (void *)android_hardware_Camera_stopFaceDetection},
  { "enableFocusMoveCallback",
    "(I)V",
    (void *)android_hardware_Camera_enableFocusMoveCallback},
};

好,終于來到JNI了

繼續(xù)看camera的JNI文件android_hardware_camera.cpp

static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId)
{
    sp<Camera> camera = Camera::connect(cameraId);

    sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
    camera->setListener(context);

}

JNI函數(shù)里面,我們找到Camera C/S架構(gòu)的客戶端了,它調(diào)用connect函數(shù)向服務器發(fā)送連接請求。JNICameraContext這個類是一個監(jiān)聽類,用于處理底層Camera回調(diào)函數(shù)傳來的數(shù)據(jù)和消息

看看客戶端的connect函數(shù)有什么

sp<Camera> Camera::connect(int cameraId)
{
    LOGV("connect");
    sp<Camera> c = new Camera();
    const sp<ICameraService>& cs = getCameraService();
    if (cs != 0) {
        c->mCamera = cs->connect(c, cameraId);
    }
    if (c->mCamera != 0) {
        c->mCamera->asBinder()->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        c.clear();
    }
    return c;
}

先看標紅的第一句,通過getCameraService()函數(shù)獲取一個Camera服務實例。

const sp<ICameraService>& Camera::getCameraService()
{
    if (mCameraService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16("media.camera"));
            if (binder != 0)
                break;
            LOGW("CameraService not published, waiting...");
            usleep(500000); // 0.5 s
        } while(true);
 

        mCameraService = interface_cast<ICameraService>(binder);
    }
    LOGE_IF(mCameraService==0, "no CameraService!?");
    return mCameraService;
}


可以看出,該CameraService實例是通過binder獲取的,由binder機制可以知道,該服務就是CameraService一個實例。

c->mCamera = cs->connect(c, cameraId);

然后執(zhí)行服務端的connect()函數(shù),并返回一個ICamera對象賦值給Camera 的mCamera, 服務端connect()返回的其實是它內(nèi)部類client的一個實例。

sp<ICamera> CameraService::connect(){

    hardware = new CameraHardwareInterface(camera_device_name);
    if (hardware->initialize(&mModule->common) != OK) {
        hardware.clear();
        return NULL;
    }

    client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);
    mClient[cameraId] = client;
    LOG1("CameraService::connect X");
    return client;

}

先實例化Camera Hal接口 hardware,hardware調(diào)用initialize()進入HAL層打開Camear驅(qū)動

status_t initialize(hw_module_t *module)
    {
        LOGI("Opening camera %s", mName.string());
        int rc = module->methods->open(module, mName.string(),
                                       (hw_device_t **)&mDevice);

        if (rc != OK) {
            LOGE("Could not open camera %s: %d", mName.string(), rc);
            return rc;
        }
        initHalPreviewWindow();
        return rc;
    }


module->methods->open(module, mName.string(),
                                       (hw_device_t **)&mDevice)
這一句作用就是打開Camera底層驅(qū)動


hardware->initialize(&mModule->common)中mModule模塊是一個結(jié)構(gòu)體camera_module_t,他是怎么初始化的呢?我們發(fā)現(xiàn)CameraService里面有個函數(shù)

void CameraService::onFirstRef()
{
    BnCameraService::onFirstRef();

    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
                (const hw_module_t **)&mModule) < 0
) {
        LOGE("Could not load camera HAL module");
        mNumberOfCameras = 0;
    }
 
}

了解HAL層的都知道hw_get_module函數(shù)就是用來獲取模塊的Hal stub,這里是通過CAMERA_HARDWARE_MODULE_ID 獲取Camera Hal層的代理stub,并賦值給mModule,后面就可通過操作mModule完成對Camera模塊的控制。那么onFirstRef()函數(shù)又是何時調(diào)用的?

onFirstRef()屬于其父類RefBase,該函數(shù)在強引用sp新增引用計數(shù)時調(diào)用,什么意思?就是當 有sp包裝的類初始化的時候調(diào)用,那么camera是何時調(diào)用的呢?可以發(fā)現(xiàn)在

客戶端發(fā)起連接時候

sp<Camera> Camera::connect(int cameraId)
{
    LOGV("connect");
    sp<Camera> c = new Camera();
    const sp<ICameraService>& cs = getCameraService();

}

    這個時候初始化了一個CameraService實例,且用Sp包裝,這個時候sp將新增計數(shù),相應的CameraService實例里面onFirstRef()函數(shù)完成調(diào)用。
CameraService::connect()返回client的時候,就表明客戶端和服務端連接建立。Camera完成初始化,可以進行拍照和preview等動作。一個看似簡單Camera初始化的過程,研究起來卻也讓人費勁啊。。。

下面是整個過程的時序圖


 


本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android
Android 5
Android的Camera架構(gòu)介紹
高通camera架構(gòu) (二)
Android Camera分析
Camera顯示之Framework層設置顯示窗口
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服