android Camera framework层解析

本文详细解析了Android Camera服务框架的各个层次,包括相机服务初始化、连接相机服务的过程,涉及Binder RPC在不同层的交互,以及相机设置和控制、事件处理的实现。通过分析源码,展示了从APP层到本地库的相机服务连接和控制流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

转载请注明出处,谢谢!

相机服务框架类

相机服务是如何运作的呢?若弄清这个问题,必须先了解组成Service Framework的各个类与Bind RPC的连接关系。图-1描述了在不同的三个部分中各个类与Binder RPC的关系。

(a)       Camera 类继承自ICameraClient类,负责在应用程序与相机服务间传递Binder RPC数据。

(b)       CameraService 类继承了ICameraService类,负责应用程序与相机服务间的连接。

(c)       CameraService::Client类继承自ICamera类,负责相机设备的设置,控制及来自相机设备的事件。

各个类与Binder RPC的具体关系:

(1)       android.hardware.Camera 中的本地方法通过JNI调用本地库中Camera的成员函数。

(2)       在应用程序连接相机服务时,Camera 通过BpCameraService(服务代理)BnCamera Service (服务stub)进行Binder RPC操作(经由ICameraService接口执行Binder RPC交互)。

(3)       应用程序中请求相机设备或预览功能时,Camera通过BpCamera(服务代理)bnCamera进行binder RPC操作(经由ICamera接口执行Binder RPC交互)。

(4)       当相机设备发生事件时,CameraService::Client 通过BpCameraClientBnCamera进行Binder RPC操作(经由ICameraClient接口执行Binder RPC).

相机服务初始化

/frameworks/base/media/mediaserver/main_mediaserver.cpp

 

int main(int argc, char** argv)

{

    sp<ProcessState> proc(ProcessState::self());

    sp<IServiceManager> sm = defaultServiceManager();

    LOGI("ServiceManager: %p", sm.get());

 

   //add for coredump .check only in debug mode

    {

        char value[PROPERTY_VALUE_MAX];

        property_get("ro.debuggable", value, "0");

        if(value[0] == '1' )

        {

            struct rlimit rl;

            rl.rlim_cur = -1;

            rl.rlim_max = -1;

            setrlimit(4,&rl);

        }

    }

 

    VolumeManager::instantiate(); // volumemanager have to be started before audioflinger

    AudioFlinger::instantiate();

    MediaPlayerService::instantiate();

    CameraService::instantiate();

    AudioPolicyService::instantiate();

    ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();

}

查看CameraService::instantiate()源码遇到问题,到CameraService.cpp文件里面却找不到instantiate()这个方法,它在哪?

frameworks/base/media/mediaserver/main_mediaserver.cpp文件中发现蛛丝马迹:

#include <grp.h>

#include <binder/IPCThreadState.h>

#include <binder/ProcessState.h>

#include <binder/IServiceManager.h>

#include <utils/Log.h>

 

#include <AudioFlinger.h>

#include <CameraService.h>

#include <MediaPlayerService.h>

#include <AudioPolicyService.h>

#include <private/android_filesystem_config.h>

所以去frameworks/base/services/camera/libcameraservice/CameraService.h一探究竟。

 

class CameraService :

    public BinderService<CameraService>,

    public BnCameraService

{

    class Client;

    friend class BinderService<CameraService>;

public:

    static char const* getServiceName() { return "media.camera"; }

 

                        CameraService();

    virtual             ~CameraService();

 

    virtual int32_t     getNumberOfCameras();

    virtual status_t    getCameraInfo(int cameraId,

...

从以上定义可以看出CameraService继承于BinderService和BnCameraService所以CameraService::instantiate()可能继承父类的方法,到父类BinderService中一看,果不其然,其父类BinderService中有instantiate方法,并且是个静态方法。

 

frameworks/base/include/binder/BinderService.h

 

class BinderService

{

public:

    static status_tpublish() {

        sp<IServiceManager> sm(defaultServiceManager());

        returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE());

    }

 

    static void publishAndJoinThreadPool() {

        sp<ProcessState> proc(ProcessState::self());

        sp<IServiceManager> sm(defaultServiceManager());

        sm->addService(String16(SERVICE::getServiceName()), new SERVICE());

        ProcessState::self()->startThreadPool();

        IPCThreadState::self()->joinThreadPool();

    }

 

    static void instantiate() { publish(); }

 

    static status_t shutdown() {

        return NO_ERROR;

    }

};

 

 

}; // namespace android

可以发现在publish()函数中,CameraService完成服务的注册。这里面有个SERVICE,源码中有说明

template<typename SERVICE>

这表示SERVICE是个模板,这里是注册CameraService,所以可以用CameraService代替SERVICE,这段代码可以替换为:

return sm->addService(String16(CameraService::getServiceName()), new CameraService());

好了这样,Camera就在ServiceManager完成服务注册,提供给client随时使用。

 

main_mediaserver.cpp编译后生成out/target/product/sp8825ea/system/bin/mediaserver ;

Main_MediaServer主函数由init.rc在启动是调用,所以在设备开机的时候Camera就会注册一个服务,用作binder通信。

service media /system/bin/mediaserver

    class main

    user media

    group system audio camera graphics inet net_bt net_bt_admin net_bw_acct drmrpc radio

ioprio rt 4

 

连接相机服务

在使用相机服务之前,应用程序必须先与相机服务连接起来,(在应用程序看来,连接就是调用open函数)。在连接的过程中,ICameraServiceBinder RPC扮演连接桥梁的角色。在完成连接以后,相应的Binder RPC关系就确定了。利用它可以设置相机设备,传递相应命令、接收相应的事件。

连接过程

(1)       应用程序调用android.hardware.Cameraopen()方法;

(2)       Open方法调用native_setup();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值