Camera-MTK OpenCamera时序以及耗时

OpenCamera时序分析

1.应用层

08:53:56.087 应用层调用openCamera接口

2.CameraService层

08:53:56.099 10ms左右CameraService(进程号:742 线程号:25763)进行相关打印,从应用层到CameraServer之间经过FrameWork层(同一进程)以及ICameraService与CameraService之间的跨进程AIDL通信。此时CameraManagera(进程号:29471 线程号:29508)的相关部分处于阻塞状态,等待CameraService处理完成。

3.CameraProvider(Camera HAL Interface-CameraProviderImpl SP端)

08:53:56.116 17ms左右CameraProvider的device部分进行相关的log打印,从CameraService(CameraProviderManager)到CameraProvider(ICameraProviderImpl)之间有着跨进程的HIDL通信,此时CameraProviderManager(进程号:742 线程号:25763)处于阻塞状态,等待ICameraProviderImpl相关处理完成。

 

4.Camera HAL Interface

08:53:56.151 耗时35ms Camera HAL Interface(很多人把这个层级称为CameraProvider层,可能因为它跟CameraServer是通过ICameraProviderImpl进行交互的)(进程号:773 线程号:5314)完成相关操作,之前被阻塞的CameraServer的CameraProviderManager拿到相应的信息,开始执行,但是此时并没有openCamera,才刚刚powerOn拉高camera。

而且Camera HAL Interface相关的时序以及逻辑是在手机启动之后就已经起来的,与相机有没有打开没有关系,且里面会分成Provider、Commmon、Device、Session等好多模块对相机的open、preview、capture动作进行传递。

5.Camera HAL

08:53:56.151 开始执行Camera HAL层(进程号:773 线程号:29521)相关的时序及逻辑

08:53:56.220 直到应用层/FrameWork层CameraManagera、ICameraService相关的进程结束阻塞,Camera HAL里面还有很多在执行。

 

6.Log时序总结

openCamera是从08:53:56.087-08:53:56.220结束

CameraProviderManager - ICameraProviderImpl HIDL跨进程通信耗时35ms

ICameraService - CameraService AIDL跨进程通信中主要的阻塞、等待或者消费方式以及接口需要更进一步研究与明确耗费时间。

OpenCamera调用接口分析

1.应用层

 

 

 

2.Camera FrameWork

可以在这边打Log,相关进程会hang在这边connectDevice的调用下

3.CameraService 

CameraSevice里面与openCamera相关的重要节点都在connectHelper里面了,比如:

handleEvictionsLocked:这里面会处理所有的camera id冲突场景,且会给不同调用camera id的packages进行打分操作。

 下面的ClientDescriptor相关的还没搞懂。

 

makeClient:Binder的Bn端,会初始化CameraDeviceClient、Camera2ClientBase、CameraDeviceClientBase以及调用其initialize方法。

 

 

 这边InitializeImpl主要最主要的是run了FrameProcess这个线程,这个线程就在后面的过程中用来接收预览帧数据。

 这边关键节点是startCameraOps、然后又调用了CameraDeviceBase的initialize方法

 可以看到这边定义了很多纯虚函数,需要找到其具体的实现接口

相关方法的接口具体实现都在Camera3Device里面

 CameraProviderManager里面的deviceInfo3在刚开机时候CameraServer与CameraProvider之间的交互过程中已经获取了。

 

4.Camera HardWare Interface(CameraProvider)

这边其实和展锐平台相关的HardWare Interface相关节点都是一样的

主要就是几个关键的结构体的传递,建立了Camera HardWare Interface和Camera HAL之间的联系。

1.hw_device_t里面有hw_module_t,可以通过hw_module_t去调用open方法。

2.hw_module_t这边在里面封装了hw_module_methods_t的函数指针,指向了open的实例化函数接口。

3.camera3_device_t在MTK camera HAL架构中貌似没有用到,在展讯的平台架构中使用场景还是挺多的。

 

 4.camera_module_t 这个结构体算是链接Camera HardWare Interface和Camera HAL层最为紧密的纽带了。

 5.Camera HAL

MTK HAL层有三个entry接口,具体咋么实现什么情况对应哪个需要再去研究。

vendor/mediatek/proprietary/hardware/mtkcam3/main/mtkhal/hidl/depend/entry.cpp

可以看到对Camera HardWare Interface里面camera_module_t的所有接口说明都在这边进行了实例化。接下来对一些比较重要的接口进行详细说明和解释

extern "C" NSCam::legacy_dev3::LegacyCameraModule* getLegacyCameraModule() {
  static NSCam::CameraDeviceManagerImpl singleton("legacy");
  static bool init = singleton.initialize();
  if (!init) {
    MY_LOGE("CameraDeviceManagerImpl::initialize fail %p", &singleton);
    return nullptr;
  }
  static NSCam::legacy_dev3::LegacyCameraModule* module =
      createLegacyCameraModule(&singleton);
  if (module == nullptr) {
    MY_LOGE("LegacyCameraModule is null: %p", module);
    return nullptr;
  }
  return module;
}


//  Implementation of hw_module_methods_t

static int open_device(hw_module_t const* module,
                       const char* name,
                       hw_device_t** device) {
  // return  getLegacyCameraModule()->open(device, module, name);
#warning "set device_version to 0 to avoid build error"
  // device_version = 0 would query info every time
  return getLegacyCameraModule()->open(device, module, name, 0);
}

static hw_module_methods_t* get_module_methods() {
  static hw_module_methods_t _methods = {.open = open_device};
  return &_methods;
}

vendor/mediatek/proprietary/hardware /mtkcam3/main/mtkhal/devicemgr/depend/CameraDeviceManagerImpl.cpp

class CameraDeviceManagerImpl : public CameraDeviceManagerBase {
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  //  Implementations.
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 public:      Instantiation.
  explicit CameraDeviceManagerImpl(char const* type);
  virtual ~CameraDeviceManagerImpl();

 protected:      Operations.
  virtual auto onEnumerateDevicesLocked() -> ::android::status_t;

  virtual auto onGetMaxNumOfMultiOpenCameras() const -> uint32_t;

  virtual auto onValidateOpenLocked(
      const std::shared_ptr<IVirtualDevice>& pVirtualDevice) const
      -> ::android::status_t;

  virtual auto onAttachOpenDeviceLocked(
      const std::shared_ptr<IVirtualDevice>& pVirtualDevice) -> void;

  virtual auto onDetachOpenDeviceLocked(
      const std::shared_ptr<IVirtualDevice>& pVirtualDevice) -> void;

  virtual auto onEnableTorchLocked(const std::string& deviceName, bool enable)
      -> ::android::status_t;
};

vendor/mediatek/proprietary/hardware/mtkcam3/main/mtkhal/devicemgr/base/CameraDeviceManagerBase.cpp

vendor/mediatek/proprietary/hardware/mtkcam3/include/mtkcam3/main/mtkhal/devicemgr/ICameraDeviceManager.h

class ICameraDeviceManager {
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  //  Definitions.
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 public:  
  class IVirtualDevice : virtual public ::android::RefBase {
   public:
    /**
     * The device instance names must be of the form
     *      "device@<major>.<minor>/<type>/<id>" where
     * <major>/<minor> is the HIDL version of the interface.
     * <id> is a small incrementing integer for "internal" device types,
     * with 0 being the main back-facing camera and 1 being the main
     * front-facing camera, if they exist.
     */

    struct Info {
      std::string mInstanceName;   //  instance device:
                                   //  "device@<major>.<minor>/<type>/<id>"
      int32_t mInstanceId;         //  instance id
      int32_t mVirtualInstanceId;  //  virtual instance id
      uint32_t mMajorVersion;      //  major version
      uint32_t mMinorVersion;      //  minor version
      bool mHasFlashUnit;          //  has flash unit
      bool mIsHidden;              //  Is camera hidden
      int32_t mFacing;             //  facing
//      mcam::DeviceType mType;    //  NormalDevice/PostProcDevice/...
    };

   public:
    virtual auto getDeviceInterface(std::shared_ptr<IVirtualDevice>& rpDevice)
        const -> ::android::status_t = 0;
    virtual auto getDeviceInfo() const -> Info const& = 0;
    virtual auto getInstanceName() const -> char const* {
      return getDeviceInfo().mInstanceName.c_str();
    }

    ...

}

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3Impl.h

        ICameraDeviceManager.h里面并没有相关接口的实例化,真正的接口实例化是在CameraDevice3Impl.cpp里面实现的。

class CameraDevice3Impl
    : public ICameraDeviceManager::IVirtualDevice
{
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//  Definitions.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// public:     

//     struct  MyDebuggee : public IDebuggee
//     {
//         static const std::string        mName;
//         std::shared_ptr<IDebuggeeCookie>mCookie = nullptr;
//         android::wp<CameraDevice3Impl>  mContext = nullptr;

//                         MyDebuggee(CameraDevice3Impl* p) : mContext(p) {}
//         virtual auto    debuggeeName() const -> std::string { return mName; }
//         virtual auto    debug(
//                             android::Printer& printer,
//                             const std::vector<std::string>& options
//                         ) -> void;
//     };

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//  Data Members.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
protected:  

    //  setup during constructor
    int32_t                                 mLogLevel = 0;                  //  log level.
    ICameraDeviceManager*                   mDeviceManager = nullptr;       //  device manager.
    std::shared_ptr<Info>                   mStaticDeviceInfo = nullptr;    //  device info
    // std::shared_ptr<MyDebuggee>             mDebuggee = nullptr;
    ::android::sp<IMetadataProvider>        mMetadataProvider = nullptr;
    ::android::sp<IMetadataConverter>       mMetadataConverter = nullptr;
    ::android::sp<ICameraDevice3Session>    mSession = nullptr;
    std::map<uint32_t, ::android::sp<IMetadataProvider>> mPhysicalMetadataProviders;
    mutable ::android::Mutex                mGetResourceLock;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//  Operations.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public:         Instantiation.
    virtual         ~CameraDevice3Impl();
                    CameraDevice3Impl(
                        ICameraDeviceManager* deviceManager,
                        IMetadataProvider* metadataProvider,
                        std::map<uint32_t, ::android::sp<IMetadataProvider>>const& physicalMetadataProviders,
                        char const* deviceType,
                        int32_t instanceId,
                        int32_t virtualInstanceId);

    virtual auto    initialize(
                        ICameraDevice3Session* session
                        ) -> bool;

public:         Operations.
    auto            getLogLevel() const             { return mLogLevel; }
    auto const&     getStaticDeviceInfo() const     { return mStaticDeviceInfo; }
    auto const&     getMetadataConverter() const    { return mMetadataConverter; }

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//  Interfaces.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public:         ICameraDeviceManager::IVirtualDevice Interfaces.

    virtual auto    getDeviceInterface(
                        ::android::sp<CameraDevice3Impl>& rpDevice
                        ) const -> ::android::status_t override;

    virtual auto    getDeviceInfo() const -> Info const& override;

public:         ICameraDevice Interfaces implement.

    virtual auto    getResourceCost(v3::CameraResourceCost& mtkCost) -> int;

    virtual auto    setTorchMode(v3::TorchMode mode) -> ::android::status_t;

    virtual auto    open() -> ::android::sp<ICameraDevice3Session>;

    virtual auto    dumpState(android::Printer& printer, const std::vector<std::string>& options) -> void;

    virtual auto    getCameraCharacteristics() -> const camera_metadata_t*;

    virtual auto    getPhysicalCameraCharacteristics(
                        int physicalId,
                        camera_metadata* physicalMetadata) -> int;

    virtual auto    isStreamCombinationSupported(
                        const v3::StreamConfiguration& streams,
                        bool& isSupported) -> int;

public:         Operations

    virtual auto    getDeviceSession() -> const ::android::sp<ICameraDevice3Session>;

};

到这边HAL openCamera相关的动作只算走了一半,仅仅是entry.cpp里面实例化CameraDeviceManagerImpl实例化的过程。

这边已经开始对sensor进行了相关的init操作

真正的camera device open操作会在LegacyCameraModule里面,上面的CameraDevice3Impl也有相关的open操作,主要是CameraDeviceSession的调用。

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/entry/legacy/device/LegacyCameraDevice3.cpp

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3Impl.cpp

相关的mSession的实例化的操作在initialize这边,调用的是CameraDevice3Session的open操作

 接下来要追踪的便是CameraDeviceImpl.initial里面的session是谁传过来的,是哪边创建的、创建的什么tag。

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3Factory.cpp

extern "C"
NSCam::ICameraDeviceManager::IVirtualDevice*
createVirtualCameraDevice(CreateVirtualCameraDeviceParams* params)
{
    MY_LOGD("[hidldc] new createVirtualCameraDevice");
    if ( ! params || ! params->pDeviceManager || ! params->pMetadataProvider ) {
        MY_LOGE("Bad params");
        return nullptr;
    }

    auto pDevice = new CameraDevice3Impl(
        params->pDeviceManager,
        params->pMetadataProvider,
        params->physicalMetadataProviders,
        params->deviceType,
        params->instanceId,
        params->virtualInstanceId
    );

    if ( ! pDevice ) {
        MY_LOGE("Fail to new CameraDevice3Impl");
        return nullptr;
    }

    NSCam::ICameraDevice3Session::CreationInfo const info = {
        .mDeviceManager     = params->pDeviceManager,
        .mStaticDeviceInfo  = pDevice->getStaticDeviceInfo(),
        .mMetadataProvider  = params->pMetadataProvider,
        .mMetadataConverter = pDevice->getMetadataConverter(),
        .mPhysicalMetadataProviders = params->physicalMetadataProviders
    };

    bool bInitSuccess = pDevice->initialize(createCameraDevice3Session(info));
    if ( ! bInitSuccess ) {
        delete pDevice;
        pDevice = nullptr;
    }

    return pDevice;
}

createCameraDevice3Session的接口的实现是在CameraDevice3SessionFactory.cpp里面实现的

extern "C"
NSCam::ICameraDevice3Session*
createCameraDevice3Session(
    NSCam::ICameraDevice3Session::CreationInfo const& info
)
{
    //  Based on the information of instanceId + pMetadataProvider,
    //  decide which device session to create.
    return new NSCam::v3::CameraDevice3SessionImpl(info);
}

然后的主要实现就在CameraDevice3SessionImpl

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3SessionImpl.cpp

         这边不在做仔细的剖析了,里面涉及很多接口的调用,直接贴上最关键的节点PipelineMode->open,这样就与MTK 的pipeline mode进行了对接。

        其实在实际解决问题时候,很多人不会去check Camera HAL的前期框架,关注点更会放在MTK Pipeline的框架上,整个流程及框架肯定是越通透对以后的性能、时序分析更加有帮助,能多研究点就多看点呗。

总结

        MTK Camera HAL性能到这边远没有结束,总的MTK Camera HAL层openCamera架构可以简单的以线程号分成三个大的部分,现在仅仅是对PipelineMode之前的部分进行了流程调用分析,其中的耗时以及等待机制还需要打更多的log去追,以后的优化更不是简简单单能搞定的。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值