Android4.2.2 CameraService服务启动和应用端camera初始化记录
之前的10篇博文主要是记录了Android4.2.2的SurfaceFlinger的相关内容,为何之前会投入那么多的时间,原因就在于之前在看camera的架构时,遇到了本地的ANativeWindow和Surface的内容。而这些是SurfaceFlinger中最常见的应用端的使用品。故而在学习完了SurfaceFlinger之后就来看看Camera的的架构内容。这里先和大家分享android4.2.2的CameraService的启动过程与其的架构。
1.cameraService在何处启动
mediaserver启动了我们cameraservice,即所谓的多媒体相关的服务总管。
int main(int argc, char** argv) { signal(SIGPIPE, SIG_IGN); 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(); }
之前的文章有提到过一般的Service的启动方式,这里是典型的一种BinderService的启动
class BinderService { public: static status_t publish(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); } static void publishAndJoinThreadPool(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); } static void instantiate() { publish(); }//两种初始化binder服务的方式 static status_t shutdown() { return NO_ERROR; } };
CameraService::CameraService() :mSoundRef(0), mModule(0) { ALOGI("CameraService started (pid=%d)", getpid()); gCameraService = this; } void CameraService::onFirstRef()//camerservice生成sp后被调用 { BnCameraService::onFirstRef(); if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&mModule) < 0) {//获取并加载mModule变量,实际的hal层的硬件库camera.fiber.so,加载了模块 ALOGE("Could not load camera HAL module"); mNumberOfCameras = 0; } else { mNumberOfCameras = mModule->get_number_of_cameras();//通过hal获取camera的数目 if (mNumberOfCameras > MAX_CAMERAS) { ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", mNumberOfCameras, MAX_CAMERAS); mNumberOfCameras = MAX_CAMERAS; } for (int i = 0; i < mNumberOfCameras; i++) { setCameraFree(i); } } }
调用CameraService的构造函数后,会自动执行onFirstRef().在该函数内部主要实现了对Camera的Hal层的操作。
通过hw_get_module()获得加载HAL层的模块句柄到mModule成员变量之中,并获得硬件的Camera的个数到mNumberOfCameras之中。可以看到CameraService比起SurfaceFinger这个强大的service来说简单了很多。
step3,camera客户端的建立
通java层的new Camera()来到JNI层,依次经过camera.java再到本地JNI的android_hardware_Camera.cpp。
camera.java中Camera.open()函数的执行
public static Camera open(int cameraId) { return new Camera(cameraId); } /** * Creates a new Camera object to access the first back-facing camera on the * device. If the device does not have a back-facing camera, this returns * null. * @see #open(int) */ public static Camera open() { int numberOfCameras = getNumberOfCameras(); CameraInfo cameraInfo = new CameraInfo(); for (int i = 0; i < numberOfCameras; i++) { getCameraInfo(i, cameraInfo); if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { return new Camera(i); } } return null; }
Camera中的类
Camera(int cameraId) { mShutterCallback = null; mRawImageCallback = null; mJpegCallback = null; mPreviewCallback = null; mPostviewCallback = null; mZoomListener = null; Looper looper; if ((looper = Looper.myLooper()) != null) { ..... native_setup(new WeakReference<Camera>(this), cameraId); }
JNI层的android_hardware_camera.cpp中:
// connect to camera service static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId) { sp<Camera> camera = Camera::connect(cameraId);//调用Camera的connect函数 if (camera == NULL) { jniThrowRuntimeException(env, "Fail to connect to camera service"); return; } // make sure camera hardware 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; } ...... }
来到Camera应用层的类connect函数,目标是请求CameraService新建一个Camera客户端。
step4:camera客户端的connect函数
sp<Camera> Camera::connect(int cameraId) { ALOGV("connect"); sp<Camera> c = new Camera();//BnCameraClient const sp<ICameraService>& cs = getCameraService();//获取一个Bpcamerservice if (cs != 0) { c->mCamera = cs->connect(c, cameraId);//基于binder驱动最终会去调用camerservice侧的connect,mCamera指向一个Bpcamera } if (c->mCamera != 0) { c->mCamera->asBinder()->linkToDeath(c); c->mStatus = NO_ERROR; } else { c.clear(); } return c; }
新建一个应用端的Camera,该类class Camera : public BnCameraClient, public IBinder::DeathRecipient继承关系如下。
cs = getCameraService()通过SM获取CameraService在本地的一个代理。调用connect函数后最终调用CameraService侧的connect()函数。
virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(cameraClient->asBinder()); data.writeInt32(cameraId);//发送到服务端的数据包 remote()->transact(BnCameraService::CONNECT, data, &reply);//实际调用的是Bpbinder的transact return interface_cast<ICamera>(reply.readStrongBinder());//传入Bpbinder的handle数值返回一个new BpCamera,实际是服务端的Bncamera } };
在这里可以看到这边传入一个本地Camera类对象即new Camera(),这个匿名的binder对象将通过Binder驱动传递给CameraService。主要用于后续CameraService的回调给应用层的Camera来处理
step5:CameraSevice端的connect函数
sp<ICamera> CameraService::connect( const sp<ICameraClient>& cameraClient, int cameraId) { int callingPid = getCallingPid(); LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId); if (!mModule) { ALOGE("Camera HAL module not loaded"); return NULL; } sp<Client> client; if (cameraId < 0 || cameraId >= mNumberOfCameras) { ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).", callingPid, cameraId); return NULL; } char value[PROPERTY_VALUE_MAX]; property_get("sys.secpolicy.camera.disabled", value, "0"); if (strcmp(value, "1") == 0) { // Camera is disabled by DevicePolicyManager. ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); return NULL; } Mutex::Autolock lock(mServiceLock); if (mClient[cameraId] != 0) { client = mClient[cameraId].promote(); if (client != 0) { if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { LOG1("CameraService::connect X (pid %d) (the same client)", callingPid); return client; } else { ALOGW("CameraService::connect X (pid %d) rejected (existing client).", callingPid); return NULL; } } mClient[cameraId].clear(); } if (mBusy[cameraId]) { ALOGW("CameraService::connect X (pid %d) rejected" " (camera %d is still busy).", callingPid, cameraId); return NULL; } struct camera_info info; if (mModule->get_camera_info(cameraId, &info) != OK) {//获取camera的相关信息 ALOGE("Invalid camera id %d", cameraId); return NULL; } int deviceVersion; if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) { deviceVersion = info.device_version; } else { deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; } switch(deviceVersion) { case CAMERA_DEVICE_API_VERSION_1_0: client = new CameraClient(this, cameraClient, cameraId, info.facing, callingPid, getpid());//client是CameraClient的基类,新建一个camerservice侧的cameraclient break; case CAMERA_DEVICE_API_VERSION_2_0: client = new Camera2Client(this, cameraClient, cameraId, info.facing, callingPid, getpid()); break; default: ALOGE("Unknown camera device HAL version: %d", deviceVersion); return NULL; } if (client->initialize(mModule) != OK) {//cameraclient init初始化,实际调用的是CameraClient return NULL; } cameraClient->asBinder()->linkToDeath(this); mClient[cameraId] = client;//连接请求后新建立的 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid()); return client;//返回CameraClient }
分以下几个过程来分析这个函数:
a. sp<Client> client;一个CameraService内部的客户端类
先查看当前服务端维护的camera client个数mClient[cameraId] != 0,初次启动是该数为0.
b.获取底层camera模块的信息get_camera_info,查看当前的api版本信息是CAMERA_MODULE_API_VERSION_2_0还是CAMERA_MODULE_API_VERSION_1_0.我的平台是1.0故执行如下:
switch(deviceVersion) { case CAMERA_DEVICE_API_VERSION_1_0: client = new CameraClient(this, cameraClient, cameraId, info.facing, callingPid, getpid());//client是CameraClient的基类,新建一个camerservice侧的cameraclient break;
c.CameraClient的建立,该类继承了public CameraService::Client这个CameraService的内部类,Client继承了BnCamera。
d.client->initialize(mModule)的处理,和硬件相关
status_t CameraClient::initialize(camera_module_t *module) {//一个cameraClient新建一个CameraHardwareInterface硬接口 int callingPid = getCallingPid(); LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId); char camera_device_name[10]; status_t res; snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId); mHardware = new CameraHardwareInterface(camera_device_name);//新建一个camera硬件接口,camera_device_name为设备名 res = mHardware->initialize(&module->common);//直接底层硬件的初始 if (res != OK) { ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); mHardware.clear(); return NO_INIT; } mHardware->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, (void *)mCameraId);//将camerservice处的回调函数注册到HAL处 // Enable zoom, error, focus, and metadata messages by default enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS | CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE | CAMERA_MSG_CONTINUOUSSNAP | CAMERA_MSG_SNAP | CAMERA_MSG_SNAP_THUMB | CAMERA_MSG_SNAP_FD); //enable the continuoussnap and singlesnap message by fuqiang LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId); return OK; }
这里出现了一个封装Camera底层操作的一个硬件接口类CameraHardwareInterface,可以屏蔽不同的平台硬件特性,主要是实现的HAL的相关操作。
step6.CameraHardwareInterface接口类的实现initialize()函数。
status_t initialize(hw_module_t *module) { ALOGI("Opening camera %s", mName.string()); int rc = module->methods->open(module, mName.string(), (hw_device_t **)&mDevice);//这里打开camera硬件设备 if (rc != OK) { ALOGE("Could not open camera %s: %d", mName.string(), rc); return rc; } initHalPreviewWindow();//初始preview的相关流opspreview_stream_ops,初始化hal的预览窗口 return rc; }
这里的module就是底层的camera模块,最终完成open的操作,这里占时不说明HAL的操作,后续会专门分享camera的HAL的实现。
step7:setCallbacks()设置回调函数,即注册回调函数到HAL处
void setCallbacks(notify_callback notify_cb, data_callback data_cb, data_callback_timestamp data_cb_timestamp, void* user) { mNotifyCb = notify_cb; mDataCb = data_cb; mDataCbTimestamp = data_cb_timestamp; mCbUser = user; ALOGV("%s(%s)", __FUNCTION__, mName.string()); if (mDevice->ops->set_callbacks) { mDevice->ops->set_callbacks(mDevice, __notify_cb, __data_cb, __data_cb_timestamp, __get_memory, this);//传入的是__notify_cb函数 }//硬件设备设置回调 }
分别消息回调,数据回调,时间戳回调,以及内存相关操作的回调。
step8:
mClient[cameraId] = client将新建好的cameraclient对象维护到CameraService中并返回退出connect,而最终通过Binder驱动返回到客户端的是CameraClient的代理BpCameraClient,是一个匿名的Binder服务。
c->mCamera = cs->connect(c, cameraId);将这个服务端的cameraclient维护到本地应用端的Camera的mCamera成员中。而后续的Camera的相关操作都通过该mCamera成员和CameraService进行进一步的交互操作。
camera的一个调用架构图:
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。