当前位置: 首页 > web >正文

高通camx Node相关

一、node的存放位置

        node在camx和chi中均会存在,但存在的位置不一样。

        Camx中主要位于:android/vendor/qcom/proprietary/camx/src/(hwl/swl),例如:IFE,IPE,BPS,Sensor等。

        Chi中主要位于:android/vendor/qcom/proprietary/chi-cdk/oem/qcom/node/,例如:三方EIS,memcpy等。

二、两种node的差异

        Camx node是平台已经封装好的节点,一般不需要改动;而Chi node则是提供给vendor自定义实现的节点,用于自定义算法处理。

三、node是如何启用的

        一个node会被编译成一个.so文件。在开机过程中系统会加载很多东西,比如各种应用程序、so文件等等,在加载HAL进程时,会一起加载node。

具体实现如下: 

 probechicomponents代码如下:

CamxResult ProbeChiComponents(ExternalComponentInfo* pExternalComponentInfo,
UINT*                  pNumExternalComponent)
//返回so的文件数量fileCountTypeNode  = OsUtils::GetFilesFromPath(ExtCompPath,FILENAME_MAX,&soFilesName[0][0],"*",      //VendorName"node",  //CategoryName
,例如com.qti.node.memcpy.so,  com.wt.node.sat.so"*","*",&SharedLibraryExtension[0]);
//循环加载Node节点while (index < fileCountTypeNode + fileCountTypeStats + fileCountTypeHvx){CamX::OSLIBRARYHANDLE handle = CamX::OsUtils::LibMap(&soFilesName[index][0]);// 1.dlopen的封装方法if (index < fileCountTypeNode){pNodeEntry = reinterpret_cast<PFCHINODEENTRY>(CamX::OsUtils::LibGetAddr(handle, "ChiNodeEntry"));  // 2.dlsys的封装方法CAMX_ASSERT(NULL != pNodeEntry);pExternalComponentInfo[index].nodeCallbacks.size = sizeof(ChiNodeCallbacks);if (NULL != pNodeEntry){pNodeEntry(&pExternalComponentInfo[index].nodeCallbacks);// 3.Node API’s Callbacks}if (NULL != pExternalComponentInfo[index].nodeCallbacks.pQueryVendorTag){GetComponentTag(pExternalComponentInfo[index].nodeCallbacks.pQueryVendorTag);}pExternalComponentInfo[index].nodeAlgoType = ExternalComponentNodeAlgo::COMPONENTNODE;}

代码中的核心方法:

1、dlopen 

OSLIBRARYHANDLE ChxUtils::LibMap(const CHAR* pLibraryName)
{
    OSLIBRARYHANDLE hLibrary  = NULL;
    const UINT bindFlags = RTLD_NOW | RTLD_LOCAL;
    hLibrary = dlopen(pLibraryName, bindFlags);
    if (NULL == hLibrary)
    {
        CHX_LOG_ERROR("Failed to load library %s error %s", pLibraryName, dlerror());
        CHX_ASSERT(0 == dlerror());
    }
    return hLibrary;
}

2、dlsym

VOID* ChxUtils::LibGetAddr(OSLIBRARYHANDLE hLibrary,
                           const CHAR*     pProcName)
{
    VOID* pProcAddr = NULL;
    if (hLibrary != NULL)
    {
        pProcAddr = dlsym(hLibrary, pProcName);
    }
    return pProcAddr;
}


首先要知道.so 库文件是一个 ELF 文件,可以通过 readelf -s 命令查看对应的.so文件描述,如下图可以看到其中有一个 Name 属性为 ChiNodeEntry。 

获取node方法总体解释: 也就是:CamX通过GetFilesFromPath遍历camera/components目录下的所有so,调用dlopen()来打开目标库获取handle(定位库文件的地址),然后使用dlsym()来得到符号名字为"ChiNodeEntry"的地址,因为所有Node都有一个入口方法ChiNodeEntry,这样便可以加载所有的Node。

CDK_VISIBILITY_PUBLIC VOID ChiNodeEntry(CHINODECALLBACKS* pNodeCallbacks)
{if (NULL != pNodeCallbacks){if (pNodeCallbacks->majorVersion == ChiNodeMajorVersion &&pNodeCallbacks->size >= sizeof(CHINODECALLBACKS)){pNodeCallbacks->majorVersion             = ChiNodeMajorVersion;pNodeCallbacks->minorVersion             = ChiNodeMinorVersion;pNodeCallbacks->pGetCapabilities          = MemCpyNodeGetCaps;pNodeCallbacks->pQueryVendorTag          = MemCpyNodeQueryVendorTag;pNodeCallbacks->pCreate                  = MemCpyNodeCreate;pNodeCallbacks->pDestroy                 = MemCpyNodeDestroy;pNodeCallbacks->pQueryBufferInfo         = MemCpyNodeQueryBufferInfo;pNodeCallbacks->pSetBufferInfo           = MemCpyNodeSetBufferInfo;pNodeCallbacks->pProcessRequest          = MemCpyNodeProcRequest;pNodeCallbacks->pChiNodeSetNodeInterface = MemCpyNodeSetNodeInterface;}
}

加载node之后,如何使用node中的方法呢? 

        通过调用pNodeEntry对pExternalComponentInfo[index].nodeCallbacks参数进行取地址赋值,这样就可以使用Node中的方法,其他的节点类似就好。

 

 

       总结:node 的加载是通过编译成.so文件使用,当程序起来的时候,就可以使用.so文件,加载node节点,通过ChiNodeEntry,就可以加载node里面的方法。

 

http://www.xdnf.cn/news/12139.html

相关文章:

  • UI学习—cell的复用和自定义cell
  • 验证电机理论与性能:电机试验平板提升测试效率
  • 【Redis】笔记|第10节|京东HotKey实现多级缓存架构
  • Flask+LayUI开发手记(八):通用封面缩略图上传实现
  • 适用于vue3的移动端Vant4组件库
  • Java-39 深入浅出 Spring - AOP切面增强 核心概念 通知类型 XML+注解方式 附代码
  • 华为云Flexus+DeepSeek征文 | 基于DeepSeek-V3构建企业知识库问答机器人实战
  • Linux主要目录
  • 自定义事件wpf
  • Zookeeper 和 Kafka 版本与 JDK 要求
  • Nginx部署vue项目, 无法直接访问其他路径的解决方案
  • JVM垃圾回收器-ZGC
  • nano编辑器的详细使用教程
  • 中达瑞和SHIS高光谱相机在黑色水彩笔墨迹鉴定中的应用
  • xmind转换为markdown
  • Numpy入门4——结构化数组和Numpy文件
  • C++多态与继承实战解析
  • 如何判断是 CPU 密集还是 IO 密集型任务?
  • C++语法系列之IO流
  • JAVA 集合进阶 01 - 05 双列集合
  • FEMFAT许可分析中的关键指标
  • Java直接内存(directMemory)分配与查看
  • DNS解析深入探讨
  • linux扫描所有私有网段shell脚本
  • 2.MySQL基础:SQL语句
  • 【Python实战】零基础实战教程(三) 变量与数据类型
  • 【Python指南】离线安装顽固复杂的第三方库指南
  • Transformers生成文本:max_new_tokens揭秘
  • 第二十三章 Shell的基础语法
  • haribote原型系统改进方向