写过一篇 发表于 2025-3-7 11:59:44

Camera camx hal-架构(一)

二、camx 编译
=====================================================================
camx的核心目录是 vendor/qcom/proprietary/camx/src/目录下面:

total 40

drwxrwxr-x 10 lxl lxl 40964月4 10:52 ./

drwxrwxr-x4 lxl lxl 40964月4 10:52 ../

drwxrwxr-x3 lxl lxl 40964月4 10:52 chiiqutils/

drwxrwxr-x7 lxl lxl 40964月4 10:56 core/

drwxrwxr-x7 lxl lxl 40964月4 10:52 csl/

drwxrwxr-x 14 lxl lxl 40964月4 10:52 hwl/

drwxrwxr-x3 lxl lx 40964月4 10:52 lib/

drwxrwxr-x3 lxl lxl 40964月4 10:52 osutils/

drwxrwxr-x 11 lxl lxl 40964月4 10:52 swl/

drwxrwxr-x3 lxl lxl 40964月4 10:52 utils/



核心的Android.mk在 ./lib/build/android/Android.mk 中。
其中包罗的静态库如下:

# Libraries to link

LOCAL_STATIC_LIBRARIES :=   \

    libcamxcore             \

    libcamxchi            \

    libcamxcsl            \

    libcamxofflinestats   \

    libnc                   \

    libcamxncs            \

    libifestriping          \

    libstriping



LOCAL_WHOLE_STATIC_LIBRARIES := \

    libcamxdspstreamer          \

    libcamxhwlbps               \

    libcamxgenerated            \

    libcamxhal                  \

    libcamxhalutils             \

    libcamxhwlfd                \

    libcamxhwlife               \

    libcamxhwlipe               \

    libcamxhwliqmodule          \

    libcamxswlfdmanager         \

    libcamxswljpeg            \

    libcamxhwljpeg            \

    libcamxhwllrme            \

    libcamxswlransac            \

    libcamxhwltitan17x          \

    libcamxiqsetting            \

    libcamxosutils            \

    libcamxstats                \

    libcamxsensor               \

    libcamxutils





这些静态库都是camx或者其他的目录下编译的,编译工程的时间,我们要先编译这些静态库,然后编译camx的动态库(/vendor/lib/hw/camera.qcom.so)。
#三、camx 代码流程分析
camera.provider中怎样实现到camera hal层的跳跃,camera service调用到camera provider中的接口方法,如今调用到 camera provider中的 hardware/interfaces/camera/device/3.2/default/CameraDeviceSession.cpp中的processCaptureRequest(...)方法,最终会调用到:

 status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);



这个mDevice->ops 就是 hardware/libhardware/include/hardware/camera3.h中的 camera3_device_ops 布局体: (参考:https://www.jianshu.com/p/099cc3b0ab25)

typedef struct camera3_device_ops {

    int (*initialize)(const struct camera3_device *,

            const camera3_callback_ops_t *callback_ops);

    int (*configure_streams)(const struct camera3_device *,

            camera3_stream_configuration_t *stream_list);

    int (*register_stream_buffers)(const struct camera3_device *,

            const camera3_stream_buffer_set_t *buffer_set);

    const camera_metadata_t* (*construct_default_request_settings)(

            const struct camera3_device *,

            int type);

    int (*process_capture_request)(const struct camera3_device *,

            camera3_capture_request_t *request);

    void (*get_metadata_vendor_tag_ops)(const struct camera3_device*,

            vendor_tag_query_ops_t* ops);

    void (*dump)(const struct camera3_device *, int fd);

    int (*flush)(const struct camera3_device *);



    /* reserved for future use */

    void *reserved;

} camera3_device_ops_t;



camera3_device_ops_t 映射函数指针操作: hardware/libhardware/modules/camera/3_0/Camera.cpp

const camera3_device_ops_t Camera::sOps = {

    .initialize = default_camera_hal::initialize,

    .configure_streams = default_camera_hal::configure_streams,

    .register_stream_buffers = default_camera_hal::register_stream_buffers,

    .construct_default_request_settings

      = default_camera_hal::construct_default_request_settings,

    .process_capture_request = default_camera_hal::process_capture_request,

    .get_metadata_vendor_tag_ops = NULL,

    .dump = default_camera_hal::dump,

    .flush = default_camera_hal::flush,

    .reserved = {0},

};



这样找到在camera hal层的函数指针的映射关系。
映射到:vendor/qcom/proprietary/camx/src/core/hal/camxhal3entry.cpp中的static Dispatch g_dispatchHAL3(&g_jumpTableHAL3);:

/// Array containing camera3_device_ops_t methods

static camera3_device_ops_t g_camera3DeviceOps =

{

    CamX::initialize,

    CamX::configure_streams,

    NULL,

    CamX::construct_default_request_settings,

    CamX::process_capture_request,

    NULL,

    CamX::dump,

    CamX::flush,

    {0},

};



定义了g_camera3DeviceOps变量:

/// Array containing camera3_device_ops_t methods

static camera3_device_ops_t g_camera3DeviceOps =

{

    CamX::initialize,

    CamX::configure_streams,

    NULL,

    CamX::construct_default_request_settings,

    CamX::process_capture_request,

    NULL,

    CamX::dump,

    CamX::flush,

    {0},

};



并在\vendor\qcom\proprietary\camx\src\core\hal\camxhaldevice.cpp的Initialize方法中通过GetCamera3DeviceOps获取,创建联系:

CamxResult HALDevice::Initialize(

    const HwModule* pHwModule,

    UINT32          cameraId)

{

    CamxResult result = CamxResultSuccess;



    m_cameraId = cameraId;



    if (CamxResultSuccess == result)

    {

      m_camera3Device.hwDevice.tag   = HARDWARE_DEVICE_TAG; /// @todo (CAMX-351) Get from local macro

      m_camera3Device.hwDevice.version = CAMERA_DEVICE_API_VERSION_3_3;

      m_camera3Device.hwDevice.close   = reinterpret_cast<CloseFunc>(GetHwDeviceCloseFunc());

      m_camera3Device.pDeviceOps       = reinterpret_cast<Camera3DeviceOps*>(GetCamera3DeviceOps());

      m_camera3Device.pPrivateData   = this;

      // NOWHINE CP036a: Need exception here

      m_camera3Device.hwDevice.pModule = const_cast<HwModule*>(pHwModule);



      m_HALCallbacks.ProcessCaptureResult = ProcessCaptureResult;

      m_HALCallbacks.NotifyResult         = Notify;

      CamX::ChiOverrideBypass(&m_HALCallbacks);

    }



    m_pHALSession = NULL;

    Utils::Memset(m_flushRequest, 0, sizeof(m_flushRequest));



    return result;

}



看一下g_jumpTableHAL3 变量:在 vendor/qcom/proprietary/camx/src/core/hal/camxhal3.cpp 中定义的:



// Jump table for HAL3



JumpTableHAL3 g_jumpTableHAL3 =

{

    open,

    get_number_of_cameras,

    get_camera_info,

    set_callbacks,

    get_vendor_tag_ops,

    open_legacy,

    set_torch_mode,

    init,

    parallelQuery,

    setCallBack,

    get_tag_count,

    get_all_tags,

    get_section_name,

    get_tag_name,

    get_tag_type,

    close,

    initialize,

    configure_streams,

    construct_default_request_settings,

    process_capture_request,

    dump,

    flush,

    camera_device_status_change,

    torch_mode_status_change,

    process_capture_result,

    notify

};



这儿直接构成了指针函数的映射关系(对应camxhaldevice.cpp中的函数)。vendor/qcom/proprietary/camx/src/core/chi/camxchitypes.h中定义了CHIAppCallbacks布局体,如下:

struct CHIAppCallbacks

{

    /// @brief Called by the driver to get number of cameras

    INT(*CHIGetNumCameras)(

      UINT32* pNumFwCameras,

      UINT32* pNumLogicalCameras);



    /// @brief Called by the driver to get the camera info for the camera id

    CamxResult (*CHIGetCameraInfo)(

      UINT32      cameraId,

      CameraInfo* pCameraInfo);



    /// @brief Defines the prototype for the device status change callback method from to the framework. Please refer to

    ///      the camera_device_status_change documentation in hardware/camera_common.h.

    VOID (*CHIInitializeOverrideSession)(

      UINT32               cameraId,

      const Camera3Device* pCamera3Device,

      const HALCallbacks*pHALCallbacks,

      Camera3StreamConfig* pStreamConfig,

      BOOL*                isOverrideEnabled,

      VOID**               ppPrivate);



    /// @brief Defines the prototype for the torch mode status change callback method from to the framework. Please refer to

    ///      the torch_mode_status_change documentation in hardware/camera_common.h.

    VOID (*CHIFinalizeOverrideSession)(

      const Camera3Device* pCamera3Device,

      UINT64*            pSession,

      VOID**               ppPrivate);



    /// @brief Called by the driver to inform about session closing

    VOID (*CHITeardownOverrideSession)(

      const Camera3Device* pCamera3Device,

      UINT64*            pSession,

      VOID*                pPrivate);



    /// @brief Called by the driver to pass on capture request call to CHI

    INT (*CHIOverrideProcessRequest)(

      const Camera3Device*    pCamera3Device,

      Camera3CaptureRequest*pCaptureRequest,

      VOID*                   pPrivate);



    /// @brief Called by the driver to allow for additional override processing during open()

    INT(*CHIExtendOpen)(

      UINT32cameraId,

      VOID*   pPrivateData);



    /// @brief Called by the driver to allow for additional override processing during close()

    INT(*CHIExtendClose)(

      UINT32cameraId,

      VOID*   pPrivateData);



    /// @brief Called by the driver to allow override to remap special camera IDs into logical camera IDs

    UINT32(*CHIRemapCameraId)(

      UINT32            frameworkCameraId,

      CameraIdRemapMode   mode);



    /// @brief Interface to allow various override-specific settings to be toggled.

    UINT32(*CHIModifySettings)(

      VOID*   pPrivateData);



    /// @brief Get any vendor tag specific request settings the override wants to get added to the default settings

    VOID (*CHIGetDefaultRequestSettings)(

      UINT32         frameworkCameraId,

      INT            requestTemplate,

      const Metadata** pAdditionalMetadata);



    /// @brief Called by the driver to allow for flush()

    INT(*CHIOverrideFlush)(

      const Camera3Device*    pCamera3Device);

    INT(*CHIParallelQuery) (INT num, char* list[]);

    INT(*CHISetCallback) (void*);



};



typedef VOID(*CHIHALOverrideEntry)(CHIAppCallbacks* pCHIAppCallbacks);



这个布局体是函数指针,映射关系:vendor/qcom/proprietary/camx/src/core/hal/camxhal3module.h中定义了 CHIAppCallbacks m_ChiAppCallbacks;

   CHIAppCallbacks       m_ChiAppCallbacks;                  ///< CHI HAL override entry



vendor/qcom/proprietary/camx/src/core/hal/camxhal3module.cpp中的 HAL3Module构造函数中,存在下面的执行语句:

CHIHALOverrideEntry funcCHIHALOverrideEntry =

    reinterpret_cast<CHIHALOverrideEntry>(

      CamX::OsUtils::LibGetAddr(m_hChiOverrideModuleHandle, "chi_hal_override_entry"));



if (NULL != funcCHIHALOverrideEntry)

{

    funcCHIHALOverrideEntry(&m_ChiAppCallbacks); //对应到 chxextensioninterface.cpp 中的chi_hal_override_entry函数



    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIGetNumCameras);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIGetCameraInfo);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIFinalizeOverrideSession);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIInitializeOverrideSession);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIOverrideProcessRequest);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIOverrideFlush);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHITeardownOverrideSession);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIExtendOpen);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIExtendClose);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIRemapCameraId);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIModifySettings);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIParallelQuery);

    CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHISetCallback);



    if ((NULL != m_ChiAppCallbacks.CHIGetNumCameras)             &&

      (NULL != m_ChiAppCallbacks.CHIGetCameraInfo)             &&

      (NULL != m_ChiAppCallbacks.CHIFinalizeOverrideSession)   &&

      (NULL != m_ChiAppCallbacks.CHIInitializeOverrideSession) &&

      (NULL != m_ChiAppCallbacks.CHIOverrideProcessRequest)    &&

      (NULL != m_ChiAppCallbacks.CHIOverrideFlush)             &&

      (NULL != m_ChiAppCallbacks.CHITeardownOverrideSession)   &&

      (NULL != m_ChiAppCallbacks.CHIExtendOpen)                &&

      (NULL != m_ChiAppCallbacks.CHIExtendClose)               &&

      (NULL != m_ChiAppCallbacks.CHIRemapCameraId)             &&

      (NULL != m_ChiAppCallbacks.CHIModifySettings)            &&

      (NULL != m_ChiAppCallbacks.CHIParallelQuery)             &&

      (NULL != m_ChiAppCallbacks.CHISetCallback))

    {

      CAMX_LOG_WARN(CamxLogGroupHAL, "CHI Module library function pointers exchanged");

    }

}



m_ChiAppCallbacks 通过 funcCHIHALOverrideEntry 映射到 chi_hal_override_entry这个 chi_hal_override_entry 就是指vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensioninterface.cpp中的 chi_hal_override_entry 函数,如下:

void chi_hal_override_entry(

    chi_hal_callback_ops_t* callbacks)

{

    ExtensionModule* pExtensionModule = ExtensionModule::GetInstance();



    CHX_ASSERT(NULL != callbacks);



    if (NULL != pExtensionModule)

    {

      callbacks->chi_get_num_cameras            = chi_get_num_cameras;

      callbacks->chi_get_camera_info            = chi_get_camera_info;

      callbacks->chi_initialize_override_session= chi_initialize_override_session;

      callbacks->chi_finalize_override_session    = chi_finalize_override_session;

      callbacks->chi_override_process_request   = chi_override_process_request;

      callbacks->chi_teardown_override_session    = chi_teardown_override_session;

      callbacks->chi_extend_open                  = chi_extend_open;

      callbacks->chi_extend_close               = chi_extend_close;

      callbacks->chi_remap_camera_id            = chi_remap_camera_id;

      callbacks->chi_modify_settings            = chi_modify_settings;

      callbacks->chi_get_default_request_settings = chi_get_default_request_settings;

      callbacks->chi_override_flush               = chi_override_flush;

      callbacks->chi_parallelquery                = chi_parallelquery;

      callbacks->chi_setcallback                  = chi_setcallback;

    }

}



这样就创建了 CHIAppCallbacks 中函数指针的逐一映射关系。
https://img-blog.csdnimg.cn/img_convert/f2d3fe4ad0c2363b5b31e3723b356f2f.png
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp 中的 ExtensionModule::OverrideProcessRequest 函数中执行了 m_pUsecaseFactory->CreateUsecaseObject,如下:

m_pSelectedUsecase =

            m_pUsecaseFactory->CreateUsecaseObject(&m_logicalCameraInfo,

                static_cast<UsecaseId>(m_SelectedUsecaseId),

                m_pStreamConfig);



直接调用到:vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecaseutils.cpp中的 UsecaseFactory::CreateUsecaseObject 函数:

Usecase* UsecaseFactory::CreateUsecaseObject(

    LogicalCameraInfo*            pLogicalCameraInfo,   ///< camera info

    UsecaseId                     usecaseId,            ///< Usecase Id

    camera3_stream_configuration_t* pStreamConfig)          ///< Stream config

{

    Usecase* pUsecase= NULL;

    UINT   camera0Id = pLogicalCameraInfo->ppDeviceInfo->cameraId;

    CHX_LOG_ERROR("UsecaseFactory::CreateUsecaseObject id = %d", usecaseId);

    switch (usecaseId)

    {

      case UsecaseId::PreviewZSL:

            pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);

            break;

      case UsecaseId::MultiCamera:

            pUsecase = UsecaseMultiCamera::Create(pLogicalCameraInfo, pStreamConfig);

            break;

      case UsecaseId::MultiCameraVR:

            pUsecase = UsecaseMultiVRCamera::Create(pLogicalCameraInfo, pStreamConfig);

            break;

      case UsecaseId::MFNR:

            pUsecase = UsecaseMFNR::Create(camera0Id, pStreamConfig);

            break;

      case UsecaseId::QuadCFA:

            pUsecase = UsecaseQuadCFA::Create(pLogicalCameraInfo, pStreamConfig);

            break;

      case UsecaseId::Torch:

            pUsecase = UsecaseTorch::Create(camera0Id, pStreamConfig);

            break;

      default:

            pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);

            break;

    }



    return pUsecase;

}




enum class UsecaseId

{

    NoMatch         = 0,

    Default         = 1,

    Preview         = 2,

    PreviewZSL      = 3,

    MFNR            = 4,

    MFSR            = 5,

    MultiCamera   = 6,

    QuadCFA         = 7,

    RawJPEG         = 8,

    MultiCameraVR   = 9,

    Torch         = 10,

    YUVInBlobOut    = 11,

    MaxUsecases   = 12,

};



前置摄像头的UsecaseId是 PreviewZSL,是单摄,后置摄像头的UsecaseId是 MultiCamera,是多摄。
https://img-blog.csdnimg.cn/img_convert/c5effdebcfa503967719b5de36cc93df.png
camx-usecase
https://img-blog.csdnimg.cn/img_convert/e72d97d17c0a7b73bc88002741910ae7.png
vendor/qcom/proprietary/camx/src/core/chi/camxchi.cpp中的 ChiEntry函数如下:



/// ChiEntry



CAMX_VISIBILITY_PUBLIC VOID ChiEntry(

    ChiContextOps* pChiContextOps)

{

    if (NULL != pChiContextOps)

    {

      pChiContextOps->size                     = sizeof(ChiContextOps);



      pChiContextOps->majorVersion               = CHI_API_MAJOR_VERSION;

      pChiContextOps->minorVersion               = CHI_API_MINOR_VERSION;

      pChiContextOps->pOpenContext               = CamX::ChiOpenContext;

      pChiContextOps->pCloseContext            = CamX::ChiCloseContext;

      pChiContextOps->pGetNumCameras             = CamX::ChiGetNumCameras;

      pChiContextOps->pGetCameraInfo             = CamX::ChiGetCameraInfo;

      pChiContextOps->pEnumerateSensorModes      = CamX::ChiEnumerateSensorModes;

      pChiContextOps->pCreatePipelineDescriptor= CamX::ChiCreatePipelineDescriptor;

      pChiContextOps->pDestroyPipelineDescriptor = CamX::ChiDestroyPipelineDescriptor;

      pChiContextOps->pCreateSession             = CamX::ChiCreateSession;

      pChiContextOps->pDestroySession            = CamX::ChiDestroySession;

      pChiContextOps->pFlushSession            = CamX::ChiFlushSession;

      pChiContextOps->pActivatePipeline          = CamX::ChiActivatePipeline;

      pChiContextOps->pDeactivatePipeline      = CamX::ChiDeactivatePipeline;

      pChiContextOps->pSubmitPipelineRequest   = CamX::ChiSubmitPipelineRequest;

      pChiContextOps->pTagOps                  = CamX::ChiGetTagOps;

    }



    // This is the workaround for presil HAL3test on Windows

    // On Device, set_camera_metadata_vendor_ops will be call the set the

    // static vendor tag operation in camera_metadata.c

    //

    // On Windows side, theoretically hal3test should mimic what Android framework

    // does and call the set_camera_metadata_vendor_ops function in libcamxext library

    // However, in Windows, if both hal3test.exe and hal.dll link to libcamxext library,

    // there are two different instance of static varibles sit in different memory location.

    // Even if set_camera_metadata_vendor_ops is called in hal3test, when hal try to

    // access to vendor tag ops, it is still not set.

    //

    // This is also a workaround to call vendor tag ops in Chi at GetNumCameras which happens to get called before

    // GetVendorTagOps

    CamX::g_vendorTagOps.get_all_tags   = CamX::ChiGetAllTags;

    CamX::g_vendorTagOps.get_section_name = CamX::ChiGetSectionName;

    CamX::g_vendorTagOps.get_tag_count    = CamX::ChiGetTagCount;

    CamX::g_vendorTagOps.get_tag_name   = CamX::ChiGetTagName;

    CamX::g_vendorTagOps.get_tag_type   = CamX::ChiGetTagType;



    set_camera_metadata_vendor_ops(&(CamX::g_vendorTagOps));

}



这个函数映射关系很紧张,也在camx chi中比较常见,直接映射在此文件的CamxChi类中。都是从 vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp中调用过来的。
下面是预览时capture request 处理流程图:
https://img-blog.csdnimg.cn/img_convert/cbb518890f8c0b8d9119d0986368c962.png
check这段流程的时间我们最关注应该是5个紧张的处理类型:


[*] 1.UseCase
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecase.h上面有介绍类图。UseCase在camx中很有很多衍生类,这是camx针对差别的stream来创建差别的usecase对象,用来管理选择feature,而且创建 pipeline以及session。
[*] 2.ChiFeature
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxfeature.h, usecase选择相应的feature,关联一组pipeline,收到request哀求,根据request选择对应的feature。
[*] 3.Node
vendro/qcom/propriatary/camx/src/core/camxnode.h,下面有类图。Node是camx中非常紧张的一个父类,是camx中处理camera 哀求的一个中间节点,用于处理pipeline下发的哀求,下面有类图介绍,比较紧张**的Node子类已经标出来了。
[*] 4.pipeline
一连串node的集合,通过pipeline下发给各个node处理。
[*] 5.session
若干个有关联的pipeline的集合,用来管理pipeline,利用pipeline处理哀求。
注: Node 节点在camx chi架构中至关紧张,数据的处理都是通过封装好的Node节点来举行的。
https://img-blog.csdnimg.cn/img_convert/ec9e19e9d0a5aef6b0881b6dbb19989c.png
camxnode布局图:
https://img-blog.csdnimg.cn/img_convert/b745eacd0404d01631376ffb30b189e7.png
node节点的创建地方在vendor/qcom/proprietary/camx/src/hwl/titian17x/camxtitian17xfactory.cpp

Node* Titan17xFactory::HwCreateNode(

    const NodeCreateInputData* pCreateInputData,

    NodeCreateOutputData*      pCreateOutputData

    ) const

{

    Node* pNode = NULL;



    switch (pCreateInputData->pNodeInfo->nodeId)

    {

      case AutoFocus:

            pNode = AutoFocusNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case BPS:

            pNode = BPSNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case IFE:

            pNode = IFENode::Create(pCreateInputData, pCreateOutputData);

            break;

      case IPE:

            pNode = IPENode::Create(pCreateInputData, pCreateOutputData);

            break;

      case Sensor:

            pNode = SensorNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case StatsProcessing:

            pNode = StatsProcessingNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case JPEG:

            pNode = JPEGEncNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case JPEGAggregator:

            pNode = JPEGAggrNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case StatsParse:

            pNode = StatsParseNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case ChiExternalNode:

            pNode = ChiNodeWrapper::Create(pCreateInputData, pCreateOutputData);

            break;

      case FDHw:

            pNode = FDHwNode::Create(pCreateInputData, pCreateOutputData);

            break;

      case FDManager:

            pNode = FDManagerNode::Create(pCreateInputData, pCreateOutputData);


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Camera camx hal-架构(一)