当前位置:操作系统 > 安卓/Android >>

Andriod4.2 Camera 架构与实现

1.Camera架构包括客户端和服务端,他们之间的通信采用Binder机制实现。
Camera的实现主要包括本地代码和Java代码两个层次:
Camera本地框架:
frameworks/native/include/ui
frameworks/native/libs/ui
frameworks/av/camera/
Camera的本地实现包含在上述目录中,这部分内容被编译生成库libui.so和libcamera_client.so。
Camera服务部分:
frameworks/av/services/camera/libcameraservice
这部分编译生成libcameraservice.so。
Camera HAL:
frameworks/av/camera
frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
CameraHardwareInterface.h是HAL接口的定义,需要各个系统根据自己的情况实现。
2.AndroidCamera采用C/S架构,client与server两个独立的线程之间使用Binder通信。这里将介绍Camera从设备开机,到进入相机应用是如何完成初始化工作的。
首先既然Camera是利用binder通信,它肯定要将它的service注册到ServiceManager里面,以备后续Client引用,那么这一步是在哪里进行的呢?在frameworks/av/media/mediaserver/main_mediaserver.cpp下有个main函数,可以用来注册媒体服务。在这里,CameraService完成了服务的注册。
 
intmain(int argc, char** argv)
 
{
 
sp<ProcessState>proc(ProcessState::self());
 
sp<IServiceManager> sm= defaultServiceManager();
 
ALOGI("ServiceManager:%p", sm.get());
 
AudioFlinger::instantiate();
 
MediaPlayerService::instantiate();
 
CameraService::instantiate();
 
AudioPolicyService::instantiate();
 
ProcessState::self()->startThreadPool();
 
IPCThreadState::self()->joinThreadPool();
 
}
 
可是我们到CameraService文件里面却找不到instantiate()这个函数,它在哪?继续追到它的一个父类BinderService
template<typenameSERVICE>
classBinderService
{
public:
static status_t publish(bool allowIsolated =false) {
sp<IServiceManager>sm(defaultServiceManager());
returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE(),allowIsolated);
}
 
static void publishAndJoinThreadPool(boolallowIsolated = false) {
sp<IServiceManager>sm(defaultServiceManager());
sm->addService(String16(SERVICE::getServiceName()),new SERVICE(), allowIsolated);
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
staticvoid instantiate(){ publish(); }
static status_t shutdown() {
return NO_ERROR;
}
};
 
可以发现在publish()函数中,CameraService完成服务的注册。这里面有个SERVICE,源码中有说明
template<typenameSERVICE>
这表示SERVICE是个模板,这里是注册CameraService,所以可以用CameraService代替
sm->addService(String16(SERVICE::getServiceName()),new SERVICE(), allowIsolated);
这样,Camera就在ServiceManager完成服务注册,提供给client随时使用。
Main_MediaServer主函数由init.rc在启动是调用,所以在设备开机的时候Camera就会注册一个服务,用作binder通信。
 
servicemedia /system/bin/mediaserver
 
class main
 
user media
 
group audio camera inetnet_bt net_bt_admin net_bw_acct drmrpc
 
ioprio rt 4
 
Binder服务已注册,那接下来就看看client如何连上server端,并打开camera模块。
 
咱们先从testingcameraapp的源码入手。在setUpCamera()函数中专门有一个open(mCameraId)函数进入framework层,调用frameworks/base/core/java/android/hardware/Camera.java类的open方法。
 
publicstatic Camera open(int cameraId) {
 
return newCamera(cameraId);
 
}
 
这里调用了Camera的构造函数,在看看构造函数
 
Camera(int cameraId) {
 
mShutterCallback = null;
 
mRawImageCallback = null;
 
mJpegCallback = null;
 
mPreviewCallback = null;
 
mPostviewCallback = null;
 
mZoomListener = null;
 
Looper looper;
 
if ((looper =Looper.myLooper()) != null) {
 
mEventHandler = newEventHandler(this, looper);
 
} else if ((looper =Looper.getMainLooper()) != null) {
 
mEventHandler = newEventHandler(this, looper);
 
} else {
 
mEventHandler = null;
 
}
 
native_setup(newWeakReference<Camera>(this), cameraId);
 
}
 
 
好,终于来到JNI了,继续看camera的JNI文件frameworks/base/core/jni/android_hardware_Camera.cpp
 
// connect to cameraservice
 
static voidandroid_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
 
jobject weak_this,jint cameraId)
 
{
 
sp<Camera>camera = Camera::connect(cameraId);
 
 
 
if (camera == NULL) {
 
jniThrowRuntimeException(env,"Fail to connect to camera service");
 
return;
 
}
 
 
 
// make sure camerahardware is alive
 
if(camera->getStatus() != NO_ERROR) {
 
jniThrowRuntimeException(env,"Camera initialization failed");
 
return;
 
}
 
 
 
jclass clazz =env->GetObjectClass(thiz);
 
if (clazz == NULL) {
 
jniThrowRuntimeException(env,"Can't find android/hardware/Camera");
 
return;
 
}
 
 
 
// We use a weakreference so the Camera object can be garbage collected.
 
// The reference isonly used as a proxy for callbacks.
 
sp<JNICameraContext>context = new JNICameraContext(env, weak_this, clazz, camera);
 
context->incStrong(thiz);
 
camera->setListener(context);
 
 
 
// save context inopaque field
 
env->SetIntField(thiz,fields.context, (int)context.get());
 
}
 
JNI函数里面,我们找到CameraC/S架构的客户端了,它调用connect函数向服务器发送连接请求。JNICameraContext这个类是一个监听类,用于处理底层Camera回调函数传来的数据和消息
 
看看客户端的connect函数有什么
 
===>>>frameworks/av/camera/Camera.cpp
 
sp<Camera>Camera::connect(int cameraId)
 
{
 
ALOGV("connect");
 
sp<Camera> c = new Camera();
 
const sp<ICameraService>& cs =getCameraService();
 
if (cs !=
补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,