Camera (api1)的打开过程

Camera api1)的打开过程

 

setModuleFromIndex()@CameraActivity.javaà

{       

   mPhotoModule = new PhotoModule();

mPhotoModule.init(this,mCameraPhotoModuleRootView);         

mCurrentModule= mPhotoModule;

}

init ()@PhotoModule.java à

{

         mOpenCameraThread= new OpenCameraThread();

         mOpenCameraThread.start();

}

private class OpenCameraThread extendsThread {

//先打开camera设备,然后启动预览

         openCamera();

startPreview();

}

openCamera()@PhotoModule.javaà

{

//这里的mCameraDevice实际对应了AndroidCameraProxyImpl的实例,而AndroidCameraProxyImpl类中有一个android.hardware.Camera.java对象,这个对象通过jni对应了cameraService.Client这个内部类的实例,根据不同apicameraService.Client又对应了CameraClient或者Camera2Client

         mCameraDevice= CameraUtil.openCamera(

                   mActivity,mCameraId, mHandler,

                   mActivity.getCameraOpenErrorCallback());

}

openCamera()@CameraUtil.javaà

CameraProxy open()@CameraHolder.javaà

{

         CameraProxymCameraDevice;

         mCameraDevice= CameraManagerFactory

                   .getAndroidCameraManager().cameraOpen(handler,cameraId, cb);

}

CameraManager.CameraProxy cameraOpen()@AndroidCameraManagerImpl.javaà

{

// 发出OPEN_CAMERA消息执行打开camera的操作,如果正常打开了camera设备,就返回一个AndroidCameraProxyImpl实例。

         mCameraHandler.obtainMessage(OPEN_CAMERA,cameraId, 0,

                   CameraOpenErrorCallbackForward.getNewInstance(

                   handler,callback)).sendToTarget();

 

         if(mCamera != null)

                   returnnew AndroidCameraProxyImpl();

}

OPEN_CAMERA消息的处理是调用android.hardware.Camera.java中的open方法:

mCamera = android.hardware.Camera.open(msg.arg1)@AndroidCameraManagerImpl.javaà

Camera open(int cameraId) @frameworks/base/core/java/android/hardware/Camera.javaà

Camera(int cameraId) @frameworks/base/core/java/android/hardware/Camera.javaà

cameraInitNormal ()@frameworks/base/core/java/android/hardware/Camera.javaà

cameraInitVersion()@frameworks/base/core/java/android/hardware/Camera.javaà

{

//核心操作,通过jni调用到c++层。

return native_setup(newWeakReference<Camera>(this), cameraId, halVersion, packageName);

}

 

Step1、从app侧调用到framework侧的android.hardware.Camera.java,调用它的open函数,通过JNI调用到本地层,android_hardware_Camera.cpp中的android_hardware_Camera_native_setup(),调用到framework/av侧的Camera.cppconnect,通过它完成camera实例的创建,让clientservice建立联系,

同时创建一个监听类JNICameraContext,监听camera底层回传的数据和消息,notifycallbackdatacallbackdatacallbacktimestamp

 

android_hardware_Camera_native_setup()@frameworks/base/core/jni/android_hardware_Camera.cppà

{

//这里调用到Camera.cpp中,这里主要做了2件事情,一个是通过Camera.cpp间接加载camera设备,一个是创建了JNICameraContext实例,这个实例对象中会保存camera.cpp间接打开的camera设备,所以后面通过context.getCamera()返回的就是Camera.cpp间接打开的设备,同时camera->setListener(context)设置了监听,这样camera设备中的回调就可以通过这个listener传到Framework层,比如下面的dataCallback(),其中的listener就是这个context

         camera= Camera::connect(cameraId, clientName,

                   Camera::USE_CALLING_UID,Camera::USE_CALLING_PID);

         sp<JNICameraContext>context = newJNICameraContext(env, weak_this,clazz, camera);

         camera->setListener(context);

}

 

void Camera::dataCallback(int32_t msgType,const sp<IMemory>& dataPtr,

                          camera_frame_metadata_t*metadata)

{

   sp<CameraListener> listener;

    {

       Mutex::Autolock _l(mLock);

       listener = mListener;

    }

   if (listener != NULL) {

       listener->postData(msgType, dataPtr, metadata);

    }

}

Step2camera.cpp中的connect函数,client会向service发起连接请求,获取cameraservice实例,connect的返回值会关联到client,也就是camera.cpp这个实例,这样客户端服务端就建立了连接,上层对camera功能的调用,通过camera.cpp这个实例,传到cameraserviceclient,实现对hal层的控制。在connect过程中,创建CameraClient时,创建了另一个实例:camerahardwareinterface它负责cameraservicehal层的交互,通过CameraHardwareInterface这个实例,注册了notifycallbackdatacallbackdatacallbacktimestamp这三个回调,这个hardware实例会打开camera驱动,初始化预览窗口,cameraservice在第一次被引用时,会通过hw_get_module加载camerahal模块,这样cameraservice就可以通过这个module对象对camera hal模块的控制。

 

Camera::connect()@Frameworks/av/camera/camera.cppà

CameraBaseT::connect()@Frameworks/av/camera/camera.cppà

typedef CameraBase<TCam>        CameraBaseT@CameraBase.h

sp<TCam> CameraBase<TCam,TCamTraits>::connect()@CameraBase.cppà

{

//这里会先获取cameraService的句柄,然后调用cameraService中的connect方法。我们这里看下c->mCamera这个出参是什么类型?CameraBase是一个模板类,它的connect是一个模板方法,那么对应的TCam实际是Camera.cpp的这个Camera类型,这个可以从:

class Camera :publicCameraBase<Camera>……看出。

所以c->mCameramCamera就是就是CameraBase中成员变量sp<TCamUser>  mCamera;

这个出参在CameraService中被赋值为CameraService.Client

         sp<TCam>c = new TCam(cameraId);

         sp<TCamCallbacks>cl = c;

         constsp<::android::hardware::ICameraService> cs = getCameraService();

         ret= (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,

                   clientPid,/*out*/ &c->mCamera);

        

}

//因为CameraService继承了RefBase,所以被实例化时会执行onFirstRef方法,这个调用是在CameraService启动时执行的。

CameraService::onFirstRef()@frameworks/av/services/camera/libcameraservice/cameraservice.cpp

{

//这里是加载camera模块,打开camera设备,打开的设备句柄handle保存在:

camera_module_t-> hw_module_t-> (void*dso);

然后创建CameraModule实例,后续Cameraservice就可以通过CameraModule实例来访问camera设备,

         camera_module_t*rawModule;

         interr = hw_get_module(CAMERA_HARDWARE_MODULE_ID,

           (const hw_module_t **)&rawModule);

         mModule= new CameraModule(rawModule);

}

//接着看CameraServiceconnect方法。

CameraService::connect()@frameworks/av/services/camera/libcameraservice/cameraservice.cpp

{

//这个client实例赋值给了上面提到的 connect()@CameraBase.cpp中的&c->mCamera

         sp<Client>client = nullptr;

         ret= connectHelper<ICameraClient,Client>(cameraClient, id,

         CAMERA_HAL_API_VERSION_UNSPECIFIED,clientPackageName, clientUid, clientPid, API_1,

         /*legacyMode*/false, /*shimUpdateOnly*/ false, /*out*/client);

         *device= client;

}

//这个函数的主要作用就是调用makeClient生成CameraClient,调用它的初始化方法,同时把这个CameraClient实例赋值给上面的sp<Client> client

CameraService::connectHelper()@CameraService.h{

         ret= makeClient(this, cameraCb, clientPackageName, id, facing, clientPid,

                   clientUid,getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,

                   /*out*/&tmp);        

         err= client->initialize(mModule)

}

CameraService::makeClient( )@cameraservice.cpp

{

//根据不同的api生成不同的实例。

         caseCAMERA_DEVICE_API_VERSION_1_0:

         *client= new CameraClient(cameraService, tmp, packageName, cameraId, facing,

                   clientPid,clientUid, getpid(), legacyMode);

         caseCAMERA_DEVICE_API_VERSION_3_0:

         *client= new Camera2Client(cameraService, tmp, packageName, cameraId, facing,

                   clientPid,clientUid, servicePid, legacyMode);

         *client= new CameraDeviceClient(cameraService, tmp, packageName, cameraId,

                   facing,clientPid, clientUid, servicePid);

}

//CameraClient为例,

CameraClient::initialize()@CameraClient.cpp

{

//创建一个CameraHardwareInterface,其中initialize的参数module就是CameraService中创建的CameraModule实例,CameraClient可以通过mHardware对象跟camera设备通信。

         mHardware= new CameraHardwareInterface(camera_device_name);

//这里打开camera设备,初始化Hal层的预览窗口

         res= mHardware->initialize(module);

//设置回调函数。

         mHardware->setCallbacks(notifyCallback,

                   dataCallback,dataCallbackTimestamp,

                   (void*)(uintptr_t)mCameraId);

}

Step3camera hal层的实现

Hal层的创建过程中,会生成一个camerahardwarecomip实例,会创建三个比较重要的线程,previewThreadcapturethreadautofocusthreadhal层处理完数据会有回调,有三种,notifycallbackdatacallbackdatacallbacktimestamp,这些回调会报给jni层的JNIcameracontext

底层cameahardwarecomip这个实例创建后,做很多的初始化,如isp数据加载,底层支持的照片大小,对焦模式,感光度,把底层的图片格式设置为jpeg,这些camera底层参数的默认设置,然后等待上层的回调。

 

 

Step4、预览功能

Hal层的预览是又previewthread线程实现的,在打开camera驱动,创建cameahardwarecomip实例时,同时创建了previewthreadfocusethreadcapturethreadhardware创建以后,previewthread就启动了,但是因为预览窗口没有设置,app层也没法预览命令,实际这个线程时处于阻塞状态的。

接下来,appstartpreview命令,当前是拍照模式,就是photomodule发起这个命令,cameraservice处理这个请求,并传入到hal层,调用hardwaresetpreviewwindowstartpreview设置预览窗口,开启预览,会根据用户的设置重新设置camera底层的参数,激活前面堵塞的previewthread,完成预览功能的开启。

Step5、拍照功能

App层发送拍照命令,就是shutterbutton的触发,调用onshutterbuttonfocus,onshutterbuttonclick,进行存储空间的检查,底层进行拍照,触发capturethread线程的运行,申请snapshot需要的buffer,从预览获取图片帧进行编码,在对图形数据编码前,对图片做缩放,生成thumbnail,设置图片的exif信息,编码生成图片文件,上层shutterbutton抬起,底层的数据处理还在进行,底层编码图片结束,会有jpegcallbackcamerastorage开始进行图片存储,开始写exif信息,写文件流,写图片结束后,把数据记录插入数据库

大致关系:

一,Camera.cpp 实现了ICameraClient的回调接口如:notifyCallbackdataCallback等,

BpCameraClient通过ipc调用这些callbackBnCameraClient,然后BnCameraClient把请求转到Camera.cpp,从Camera.cpp继承了BnCameraClient可以得出这个结论,

class Camera : public::android::hardware::BnCameraClient

二,Camera.cpp对应了CameraClient,在api2中实际是CameraDeviceClient,这个CameraDeviceClient对应了CameraService中的client,即CameraService::Client,在connectHelper中生成一个client后即makeClient后,会调用finishConnectLocked把这个client保存到mActiveClientManager中,这里保存了当前活动的应用层的client,以便cameraservice可以跟这些client通信。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值