<3>Android4.2.2 CameraService服务启动和应用端camera初始化记录

转载来自:http://www.android100.org/html/201406/03/16779.html

之前的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 proc(ProcessState::self());
    sp 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 sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
    }

    static void publishAndJoinThreadPool(bool allowIsolated = false) {
        sp 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) 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 

调用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 

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(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::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::connect(int cameraId)
{
    ALOGV("connect");
    sp c = new Camera();//BnCameraClient
    const sp& 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 connect(const sp& 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(reply.readStrongBinder());//传入Bpbinder的handle数值返回一个new BpCamera,实际是服务端的Bncamera
    }
};

在这里可以看到这边传入一个本地Camera类对象即new Camera(),这个匿名的binder对象将通过Binder驱动传递给CameraService。主要用于后续CameraService的回调给应用层的Camera来处理

step5:CameraSevice端的connect函数

sp CameraService::connect(
        const sp& 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;
    if (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;一个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的一个调用架构图:

\

本文基于Android 4.2.2从进程/文件的角度审视Android Camera子系统。

AndroidCamera子系统的整体架构分成客户端(Client)和服务器(Server)两个部分,它们建立在Android的进程间通讯机制Binder的基础之上。

n块ズn块ズn块ズn块ズn块ズhttp://www.android100.org/html/201406/03/16528.html

n块ズ



 在ICameraClient.h和ICameraService.h文件中,ICameraClient和ICameraService都继承自IInterface,也就是Binder通信的基础,此外ICamera.h也继承自IInterface
class ICameraClient:public IInterface
class ICameraService :public IInterface
class ICamera: publicIInterface
然后发现BnCameraClient继承自BnInterface<ICameraClient>,作为ICameraClient的服务器端存在:
class BnCameraClient: publicBnInterface<ICameraClient>
BnCameraService继承自BnInterface<ICameraService>,作为ICameraService的服务器端存在:
class BnCameraService: publicBnInterface<ICameraService>
BnCamera继承自BnInterface<ICamera>,作为ICamera的服务器端存在:
class BnCamera: public BnInterface<ICamera>
对应的上述三个分别存在一个作为Binder客户端的类存在,为Bp***:
class BpCameraClient:public BpInterface<ICameraClient>
class BpCameraService:public BpInterface<ICameraService>
class BpCamera: publicBpInterface<ICamera>
上述三个的实现分别在ICameraClient.cpp、ICameraService.cpp、ICamera.cpp,在这三支文件中分别实现了三组Binder的Server端和Client端,Camera常用的方法都在ICamera中实现。
n块ズ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值