[Android]Camera2——(1) camera模块初始化

本文深入剖析了Android Camera2框架在framework层的初始化过程,包括CameraService的注册、CameraProviderManager的使用,以及如何通过HAL层获取摄像头设备信息。通过源码分析,展示了CameraService如何启动、CameraProviderManager如何管理camera provider,以及如何通过provider获取摄像头设备列表。文章详细介绍了从CameraService到CameraDevice的层层交互,为理解Android相机系统提供了清晰的路径。

前言

本系列文章旨在分析android应用打开摄像头并显示预览的流程。
文章将通过源码分析,总结和时序图的方式,帮助理解Camera2框架。
本篇文章将分析framework层camera相关模块的初始化,为后续分析打下基础。

1 相关源码分析

frameworks\av\camera\cameraserver\main_cameraserver.cpp

int main(int argc __unused, char** argv __unused)
{
    hardware::configureRpcThreadpool(3, /*willjoin*/ false);
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    // 通过service manager注册CameraService
    CameraService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
} 

调用了CameraService::instantiate(), 其最终调用service maneger的addService;

1.1 CameraService初始化

frameworks/av/services/camera/libcameraservice/CameraService.cpp
当CameraService派生自RefBase,当其第一次被引用时,有如下的调用:

void CameraService::onFirstRef() {
    ALOGI("CameraService process starting");
    BnCameraService::onFirstRef();
    ................
    // 从hal层的CameraProvider/ExternalCameraProvider获得摄像头设备
    res = enumerateProviders();
    ................
} 

enumerateProviders将通过hal服务CameraProvider/ExternalCameraProvider获取摄像头设备信息;

status_t CameraService::enumerateProviders() {
    status_t res;
    std::vector<std::string> deviceIds;
    {
        Mutex::Autolock l(mServiceLock);
        if (nullptr == mCameraProviderManager.get()) {
            // 初始化CameraProviderManager
            mCameraProviderManager = new CameraProviderManager();
            res = mCameraProviderManager->initialize(this);
        }
        ................
        ................
        deviceIds = mCameraProviderManager->getCameraDeviceIds();
    }
    
    for (auto& cameraId : deviceIds) {
        String8 id8 = String8(cameraId.c_str());
        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
    }
    return OK;
} 

enumerateProvider将初始化CameraProviderManager,CameraProviderManager将通过hal服务来获取摄像头的信息。

1.2 CameraProviderManager

1.2.1 类结构

frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h
CameraProviderManager用于管理android设备上的camera provider,它会枚举出camera provider以及这些provider提供的摄像头设备,并提供方法去访问它们。

class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification {
public:
    ................
    ................
    struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
        virtual bool registerForNotifications(const std::string &serviceName, const sp<hidl::manager::V1_0::IServiceNotification> &notification) override {
            return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(serviceName, notification);
        }
        virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(const std::string &serviceName) override {
            return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
        }
    };
    ................
    status_t initialize(wp<StatusListener> listener, 
            ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);
    ................
private:
    ................
    static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
    ................
} 

initialize方法的第二个参数是一个默认值,它是内部的静态对象,它能从获取对应的hal层服务。

1.2.2 CameraProviderManager::initialize

/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp)
在cpp中,定义了如下两个静态变量:

namespace {
// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the service manager
const std::string kLegacyProviderName("legacy/0");
const std::string kExternalProviderName("external/0");
} 

上述定义了传统camera provider和外部camera provider的服务名;

status_t CameraProviderManager::initialize( wp<CameraProviderManager::StatusListener> listener,
        ServiceInteractionProxy* proxy) 
{
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    mListener = listener;
    // 传入的是默认值
    mServiceProxy = proxy;
    // Registering will trigger notifications for all already-known providers
    bool success = mServiceProxy->registerForNotifications(
                   /* instance name, empty means no filter */ "",
                   this);
    .................
    // 获取不同的camera provider:legacy和external
    addProviderLocked(kLegacyProviderName, /*expected*/ false);
    addProviderLocked(kExternalProviderName, /*expected*/ false);
    return OK;
} 

initialize中主要通过两个addProviderLocked方法,获得CameraProvider和ExternalCameraProvider服务的代理,封装为ProviderInfo,初始化ProviderInfo,最后将ProviderInfo添加到链表中管理。

1.2.3 CameraProviderManager::addProviderLocked

根据服务名称获取provider,并初始化

status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
    ................
    sp<provider::V2_4::ICameraProvider> interface;
    // mServiceProxy即initalize()传入的第二个默认参数
    // 若是legacy,hal层服务实现为CameraProvider
    // 若是external,hal层服务实现为ExternalCameraProvider
    interface = mServiceProxy->getService(newProvider);
    ................
    sp<ProviderInfo> providerInfo =
            new ProviderInfo(newProvider, interface, this);
            
    // ProviderInfo初始化
    status_t res = providerInfo->initialize();
    
    // 将其添加到链表中
    mProviders.push_back(providerInfo);
    return OK;
} 

若传入的是“legacy/0”,则获取hal层的CameraProvider;
若传入的是"external/0",则获取hal层的ExternalCameraProvider。
并将它们的代理封装为ProviderInfo,再初始化。

1.3 CameraProviderManager::ProviderInfo

1.3.1 ProviderInfo::initialize

ProviderInfo定义在CameraProviderManager.h中,它的初始化如下:

status_t CameraProviderManager::ProviderInfo::initialize() {
    ................
    std::vector<std::string> devices;
    // 通过CameraProvider获取摄像头设备信息
    hardware::Return<void> ret = mInterface->getCameraIdList(
        [&status, &devices]
        (Status idStatus,const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) 
        {
            status = idStatus;
            if (status == Status::OK) {
                for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
                    devices.push_back(cameraDeviceNames[i]);
                }
            } 
        });
     ................
     sp<StatusListener> listener = mManager->getStatusListener();
     // 根据获取到的摄像头设备信息,调用addDevice
     for (auto& device : devices) {
         std::string id;
         status_t res = addDevice(device,hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
         ................
     }
     mInitialized = true;
     return OK;
} 

ProviderInfo的initialize主要是从hal获取摄像头设备的信息;
然后调用addDevice;

1.3.2 ProviderInfo::addDevice

status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name, CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
    uint16_t major, minor;
    std::string type, id;
    status_t res = parseDeviceName(name, &major, &minor, &type, &id);
    ................
    std::unique_ptr<DeviceInfo> deviceInfo;
    switch (major) {
        ................
        case 3:
            deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid, id, minor);
            break;
        default:
            return BAD_VALUE;
    }
    ................
    deviceInfo->mStatus = initialStatus;
    ................
    // 缓存DeviceInfo对象
    mDevices.push_back(std::move(deviceInfo));
    ................
    return OK;
} 

addDevice主要是根据传入的name来解析device的信息;
调用initalizeDeviceInfo创建DeviceInfo对象;
最后将DeviceInfo缓存;

1.3.3 ProviderInfo::initializeDeviceInfo

template<class DeviceInfoT>
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
CameraProviderManager::ProviderInfo::initializeDeviceInfo(
        const std::string &name, const metadata_vendor_id_t tagId,
        const std::string &id, uint16_t minorVersion) const {
    Status status;
    // 传入的模板类是DeviceInfo3
    // 获取到hal层CameraDevice的接口
    auto cameraInterface = getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
    ................
    CameraResourceCost resourceCost;
    // 获取camera冲突/负载相关信息
    cameraInterface->getResourceCost([&status, &resourceCost]
            (Status s, CameraResourceCost cost) 
            {
                status = s;
                resourceCost = cost;
            });
    ................
    return std::unique_ptr<DeviceInfo>
           (new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,cameraInterface));
} 

其中getDeviceInterface如下:

template<>
sp<device::V3_2::ICameraDevice>
CameraProviderManager::ProviderInfo::getDeviceInterface
        <device::V3_2::ICameraDevice>(const std::string &name) const 
{
    Status status;
    sp<device::V3_2::ICameraDevice> cameraInterface;
    hardware::Return<void> ret;
    // mInterface是CameraProvider/ExternalCameraProvider
    ret = mInterface->getCameraDeviceInterface_V3_x
              (name, [&status, &cameraInterface]
                    (Status s, sp<device::V3_2::ICameraDevice> interface)
                    {
                        status = s;
                        cameraInterface = interface;
                    }
              );
    // 若是legacy,实现是CameraDevice
    // 若是external,实现是ExternalCameraDevice
    return cameraInterface;
} 

综上initializeDeviceInfo的实际为:通过name解析device相关信息;
获得hal层CameraDevice/ExternalCameraDevice的代理;
封装DeviceInfo对象。

1.4 hal相关方法

1.4.1 CameraProvider获取device

/hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp)
在1.3.3中,远程接口调用了方法getCameraDeviceInterface_V3_x,其在CameraProvider中的实现为:

Return<void> CameraProvider::getCameraDeviceInterface_V3_x( const hidl_string& cameraDeviceName,
        getCameraDeviceInterface_V3_x_cb _hidl_cb)  
{
    std::string cameraId, deviceVersion;
    ................
    std::string deviceName(cameraDeviceName.c_str());
    ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
    ................
    sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
    ................
    switch (mPreferredHal3MinorVersion) {
        case 2: {
            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl = 
                    new android::hardware::camera::device::V3_2::implementation::CameraDevice(mModule, cameraId, mCameraDeviceNames);
            ................
            device = deviceImpl;
            break;
        }
        case 3: {
            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
                    new android::hardware::camera::device::V3_3::implementation::CameraDevice(mModule, cameraId, mCameraDeviceNames);
            ................
            device = deviceImpl;
            break;
        }
        default:
            device = nullptr;
            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
            return Void();
    }
    _hidl_cb (Status::OK, device);
    return Void();
} 

可以看到,构造了CameraDevice对象,并将其通过hidl的回调反馈给framework。
ExternalCameraProvider构造ExternalCameraDevice流程与上述相似,就不再阐述。
上述代码中,用于构造CameraDevice的mModule又是什么?

1.4.2 CameraProvider初始化

/hardware/interfaces/camera/provider/2.4/default/CameraProvider.h
先看下CameraProvider的声明,其内部包含一个mModule对象:

struct CameraProvider : public ICameraProvider, public camera_module_callbacks_t {
    CameraProvider();
    ~CameraProvider();
    ................
private:
    Mutex mCbLock;
    sp<ICameraProviderCallback> mCallbacks = nullptr;
    
    sp<CameraModule> mModule;
    ................
} 

在其initialize方法调用时,通过hw_get_module获取了camera_module_t,从而完成了一系列初始化;
hw_get_module通过id找到硬件模块的动态链接库地址,然后通过load打开动态链接库,并获得硬件模块结构体的地址,最终通过它与硬件模块交互;

bool CameraProvider::initialize() {
    camera_module_t *rawModule;
    int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&rawModule);
    
    mModule = new CameraModule(rawModule);
    err = mModule->init();
    ................
    err = mModule->setCallbacks(this);
    ................
    mPreferredHal3MinorVersion =
            property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
    switch(mPreferredHal3MinorVersion) {
        case 2:
        case 3:
            // OK
            break;
        default:
            mPreferredHal3MinorVersion = 3;
    }
    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    for (int i = 0; i < mNumberOfLegacyCameras; i++) {
        struct camera_info info;
        auto rc = mModule->getCameraInfo(i, &info);
        ................
        char cameraId[kMaxCameraIdLen];
        snprintf(cameraId, sizeof(cameraId), "%d", i);
        std::string cameraIdStr(cameraId);
        mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
        addDeviceNames(i);
    }
    return false; // mInitFailed
} 

1.5 小结

① CameraService被添加到Service Manager中;
② CameraManagerProvider被构造,并初始化;
③ CameraManagerProvider初始化时获得hal层CameraProvider或ExternalCameraProvider服务代理,并将其封装为ProviderInfo;
④ ProviderInfo初始化;
⑤ ProviderInfo初始化时,通过CameraProvider或ExternalCameraProvider获取摄像头名称信息,解析名称,并由名称通过CameraProvider/ExternalCameraProvider获得对应的CameraDevice/ExteralCameraDevice;最终封装为DeviceInfo,并由ProviderInfo管理。

上述模块依赖关系如下所示:

2 启动时序图


最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。

小编在这里祝小伙伴们在未来的日子里都可以 升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰!!

不论遇到什么困难,都不应该成为我们放弃的理由!

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,需要一份小编整理出来的学习资料的关注我主页或者点击扫描下方二维码免费领取~

这里是关于我自己的Android 学习,面试文档,视频收集大整理,有兴趣的伙伴们可以看看~

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值