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

Android : Camera之CHI API

来自:

https://www.cnblogs.com/szsky/articles/10861918.html

一、CAM CHI API功能介绍:

  CHI API建立在Google HAL3的灵活性基础之上,目的是将Camera2/HAL3接口分离出来用于使用相机功能,它是一个灵活的图像处理驱动程序(摄像头硬件接口)。HAL3是根据摄像机pipeline request控制而设计,以提供完整的功能处理用户的控制请求。CHI旨在提供更细粒度的控制,以及访问ISP内的处理引擎,使得OEM和最终用户可以利用CHI API在相机驱动程序中实现自定义图像处理功能。如:通过高通的ISP、®Adreno™GPU 和 ®Hexagon™DSP等实现相应的Use Cases。

  但OEM并不能以此作为通用接口实现方式,Camera2/HAL3接口有如下几个限制:

  • 没有接口可以单独访问ISP内部固定引擎
  • 没有接口可以显示的对一个use case申请一个处理流程
  • use case可以宽泛的定义,具体的处理流程可以实现的不一样
  • framework之前的请求必须全部有返回结果
  • Pipeline深度基于use cases调整,实现太复杂的pipeline对于大部分HAL3 相机驱动来说请求太多
  • 对于应用程序来说没有"fast path"来简化处理流程和降低延迟

  

 1.Qualcomm Spectra 2xx相机驱动程序有五个关键的可定制组件,使OEM能够充分利用CHI进行相机应用开发:

  • CHI Override 模块补充了Google HAL3接口,允许符合HAL3标准的相机应用程序直接控制图像处理流水线的生成、引擎选择和多帧控制等。
  • CHI pipeline  旨在将任意的计算管道构造用于图像处理,管道可以由QTI或扩展节点提供的ISP(FF-ISP)固定功能模块组成,由摄像机驱动程序堆栈外部控制。对于Camera2/HAL3实现,可以利用XML文件指定与现有Camera2/HAL3 use case 的拓扑图,然后通过程序直接调用CHI来实现pipeline。
  • CHI节点扩展是CHI的进一步扩展,提供了方便的hooks方法来简化CPU,GPU(通过OpenCL,OpenGL ES或Vulkan),或 DSP(通过OpenDSP,FastCV™软件开发套件或自定义编程)上的额外处理。 自定义节点可以指定私有供应商标记,用于被应用使用以及 与CHI FF-ISP节点或其他扩展节点交互。
  • CHI统计信息覆盖(包括3A)机制允许覆盖任何QTI的默认值统计算法,且无需改驱动程序。外部统计算法可以存储私有数据,也可以由自定义节点访问。
  • CHI传感器XML允许设备制造商为其特定硬件配置参数,包括相机模块,图像传感器, 执行器,电子可擦除可编程只读存储器(EEPROM)和 闪存组件。

 2.关键术语:

  Use case:相机管道的特定配置,实现了良好的定义的功能,例如,带有ZSL的20 MP快照和2k上的预览显示是就是一个用例。 CHI API允许开发者在底层硬件的限制范围内自行配置use case,并且不需要修改驱动。
  Session:相机管道被创建开始处理图像到被销毁的过程,称之为会话,同时可以存在多个会话。  
  
Request :请求处理从图像传感器中提取的数据帧,或从内存中提取的数据帧,驱动处理结果必须返回到相机应用程序。
  Sub-request :将单个HAL3请求分解为多个CHI子请求操作,子请求的结果不会从驱动程序中返回出去,而是合并为单个结果给原始请求。子请求一般用于启用Camera2的某些功能,例如HDR、多帧后处理等。
  Stream:具有相同大小和格式的缓冲区序列,用于处理图像数据。可以将不同类型的多个stream指定为输入和输出到camera pipeline。stream是定义Camera2 / HAL3 use case的关键组成部分。
  Per-session settings:影响相机管道处理的设置, 会话开始后就无法被更改。例如, 允许图像稳定处理。
  Per-request settings:影响各个请求的设置。例如,设置手动曝光值。
  Topology:有向无环图(DAG)由一系列处理节点和一组链接组成,它描述了那些正在被节点处理的缓冲区。拓扑通过XML文件指定。
  Engine:用于处理数据的硬件。 如Spectra ISP,Snapdragon CPU, Adreno和DSP 是CHI API可用的引擎示例。
  Node:像机管道中的逻辑功能块(节点),节点链接在一起形成拓扑。在初始版本中 CHI API,ISP外部的所有节点都通过CPU代码通过本地API(OpenCL和FastCV之类的引擎)调用,Chi API可以在将来扩展到允许在不重用本地api的情况下缓存和重用硬件命令。
  Pipeline:启用数据操作的唯一上下文。每个管道都可以维护自己的状态跨多个请求,而不受其他管道的影响。管道利拓扑结构定义Engine使用和数据处理流程。
  Statistics:包括3A算法,用于自动控制图像传感器和相机ISP实现更好的图像质量。这些特定领域的算法被处理成为CHI API的专用部分。
  Live stream:从图像传感器接收数据的处理进程,不能修改之前请求的任何数据。如果处理速率和传感器数据传输不匹配则会移至Offline stream。
  Offline stream:不从图像传感器直接获取数据处理的进程,在Chi API中,Offline stream可以与Live stream成对存在而不造成额外的延迟,处理结果可以返回到相机。

二、CHI 体系结构模式

 1.基本拓扑关系图

  

 2.Chi 硬件接口
  谷歌HAL3的扩展接口,允许通过请求调整拓扑结构和低延迟控制,一些使用特性如下:

  • 自定义ZSL
  • 多帧请求生成 和 处理
  • 图像稳定
  • 低延迟后处理

 3.Chi 节点接口

  CHI驱动程序提供默认节点来启用相机use cases。oem厂商可以在现有的CHI驱动上添加功能,以获得独特的相机体验。这是一个简单而强大的接口,可以在相机pipeline中无缝添加图像处理功能。

 4.拓扑图形

  CHI拓扑XML是相机use cases的拓扑框架描述(DAG:有向无环图),它在HAL进程初始化时被加载。它本质上是一个键值+数据的存储结构,其中的键值主要用于从可用集中选择特定数据,键值代表每个会话设置+集合的流。高通为常见use cases提供了默认拓扑XML(titan17x_usecases.xml)。oem厂商可以编辑默认XML和创建自定义拓扑XML,CHI API也提供了一个接口来显式地选择自定义拓扑。
 

 5.use case示例

  下面的时序图大致描述了一个CHI的use case创建流程:

   

  其中CameraType定义如下:

  

  • Nodes:每个请求都会访问所有节点,也可以忽略某些请求不需要的节点。
  • Links: 链接指定了所有使用到的缓冲区格式和大小(无论作为源还是接收器)。节点之间的链接可以根据父节点上输出端口的最小数量指定尽可能多的格式,以及在子节点上的接收端口的数量。
  • Buffers: Topology 控制给定类型的缓冲区数量,应用程序可以根据需要多少缓冲区微调内存使用情况以减少处理延迟。

三、Metadata

  CHI中的沟通渠道可以分为以下几类:

(1)Data 传递给应用程序
(2)Data 传递到加工管道
(3)Inter-node 沟通使用发布和订阅机制ChiNode1 ↔ ChiNode2 使用 Android tags/ChiVendorTagsChiNode1 ↔ ExtNode1 使用 Android tags/ChiVendorTags / ExtCompVendorTagsExtNode1 ↔ ExtNode2 使用 Android tags/ChiVendorTags/ExtCompVendorTags

  元数据标签可以是预定义的Android tags,也可以是定制的vendor tags。元数据标签使CHI内外的组件能够与每个组件通信另外还有面向应用程序的摄像头API。在CHI中,Androidtags通过不可变值来预定义,而vendor tags不能是固定绝对值,要取决于目标扩展组件的数量和类型。CHI使用动态索引(base +偏移量)来使供应vendor tags组件能够彼此通信。
  元数据标记ID是一个32位的值,它被限制在特定的部分中。每一个section以0x1_0000偏移量开始。标记空间的范围从0x0000_0000到0x8000_0000保留给Android tags,供应商部分是预定在0x8000_0000之后开始。在初始化期间,当CHI扫描目标中的可用组件时,它为发布自定义组件的每个组件分配一个vendor tags,组件通过Base + Offset枚举, 基地址由CHI分配。

  metadata空间示例,包括ChiVendorTags和两个ExtCompVendorTags(EXT_COMP_1和EXT_COMP_2),如下图所示:

  

四、加载外部二进制文件

  在camera服务启动时会加载初始化自定义的处理模块,包括那些由QTI的模块。

 1.外部模块命名要求

  每个节点必须由单独的.so实现,其命名结构如下:

  com.<vendor>.<category>.<algorithm>.so 

<vendor> —— 对应厂商定义的节点模块。例如,节点由QTI提供,则命名为< QTI >。
<category> —— 模块类型,有效值为 <node> 和 <stats>。
<algorithm> - so对应的独有算法名。示例:QTI提供的3A算法命名为:com.qti.3a.aec.so QTI提供的高通®Clear Sight™相机功能后处理节点命名为:com.qti.node.clearsight.so
 

  对于nodes,名称必须和拓扑XML中指定的名称对应。
  对于stats,有效值只有 <af>、<aec>、<awb>、<asd>和<afd>。
  所有.so文件必须位于/sys/data/camx/components/中。

 2.初始化流程

  设备开机过程中会初始化相机服务,加载CHI HAL3模块。在初始化CHI HAL3模块期间,驱动程序会查询并加载/sys/data/camx/components/下面正确命名的.so文件。

 (1)导出入口函数:ChiNodeEntry()

    根据.so文件的名称,CHI将导出.so对应的ChiNodeEntry()函数,驱动程序是阻塞调用entry函数,直到其处理完成。entry函数主要工作是初始化接口函数指针,另外不作任何进一步处理。此期间初始化的接口函数指针是用于相机会话对外部组件以及CHI驱动程序的调用。

 (2)组件初始化函数

    每个组件都有一个名为ChiSetupComponent的函数作为其接口的一部分,CHI驱动会创建一个单独的线程来调用ChiSetupComponent函数,以便并行初始化其他组件。每个组件的ChiSetupComponent函数都接受一个SectionIdentifier,即用于填充CHI驱动程序和谷歌相机框架,包括该组件所需的自定义vendor tags。

    (此处应有流程时序图。。。待画)

五、拓扑图XML解析

  相机子系统中每个节点是一个功能逻辑块,实现一个use case需要多个node相互配合,用来描述节点之间联系及数据流通的结构称为拓扑。use case由一组要被处理的目标和每个会话如何处理数据的设置构成,每个use case可以由拓扑结构表示,定义了HAL3 API 之间如何进行信息传递和数据处理。在configure_streams期间会根据XML中的<Targets>和< SystemwideSettings >两个部分来选择一个用例:

  • XSD模式定义了XML结构。
  • 工具用于将XML文件打包为二进制文件,供CHI驱动程序使用。

 1.Node, port, link 
  
节点代表拓扑结构中的硬件或软件处理组件,包括QTI提供的默认节点,以及为使用CHI驱动自定义的节点。节点有一组输入端口和一组输出端口,输出数据到HAL3图像缓冲区的输出端口称为SinkBuffer,也有一些输出端口不输出到任何图像数据,仅用于发出该节点正在被使用的信号。拓扑中的DAG(有向无环图)是通过将节点的输入端口连接到前一个节点的输出端口形成,或者在需获取反馈结果的情况下,节点的输出端口也可以连接到自己的输入端口。各个节点之间的链接还包含有使用到的缓冲区的必要信息。

  图解:

   

 2.配置项解析

复制代码

复制代码

<UsecaseDef> :根标记,属性必须定义。如: <UsecaseDef xmlns:xsi=http://www.w3.org/2001/XMLSchema-instancexsi:noNamespaceSchemaLocation="topology.xsd"> <Usecase> :用例,代表一种功能特性(如:ZSL),tags存在于<Usecase> </Usecase>之间如下: <UsecaseName> - Value field. Exactly 1 tag is required. <Targets> - Exactly 1 is required. <StreamConfigMode> - Value field. Exactly 1 is required. <SystemwideSetting> - Exactly 1 is required. <Topology> - At least 1 is required. <Targets> :流的列表,包括用例执行的格式和大小范围。这里列出的流对应于传入HAL3的configure_streams () API,通过tag值找到匹配的<Usecase>。<Target> and <SystemwideSettings> 用于从XML中选择一个<Usecase>。Valid tag: <TargetName> - Value field. Exactly 1 is required. <TargetDirection> - Value field. Exactly 1 is required. <TargetFormat> - Value field. At least 1 is required. <Range> - Exactly 1 is required. <Range> : 缓冲区的分辨率范围。Valid tag: <MinW> - Value field. Exactly 1 required. <MinH> - Value Field. Exactly 1 required. <MaxW> - Value Field. Exactly 1 required.  <MaxH> - Value Field. Exactly 1 required. 一个Target示例:(当驱动程序处理configure_streams()时,如果有一个输出流的缓冲区格式是YUV420NV12且分辨率小于等于1080p时,就会匹配到如下Target。)

复制代码

复制代码

<Targets><Target><TargetName>TARGET_BUFFER_PREVIEW</TargetName><TargetDirection>TargetOutput</TargetDirection><Formats>YUV420NV12</Formats><Range><MinW>0</MinW><MinH>0</MinH><MaxW>1920</MaxW><MaxH>1080</MaxH></Range></Target>
</Targets>        

复制代码

复制代码

<SystemwideSettings> : 会话组的设定,与<targets>结合使用定义了use case的键值,这些设置对应于Android属性。Valid tag: <Setting> - At least 1 is required. <Setting> : 设置说明,用于选择对应的use case。Valid tag: <SettingName> - Value field. Exactly 1 is required. <SettingDataType> - Value field. Exactly 1 is required <SettingMatch> - Value field. Exactly 1 is required 示例:
          <SystemwideSettings><SettingName>EIS</SettingName><SettingDataType>BOOL</SettingDataType><SettingMatch>FALSE</SettingMatch></SystemwideSettings>
<Topology> :描述了驱动对每个节点的顺序和依赖关系的解析,以处理上层请求。

           Valid tag:

             <TopologyName> - Value field. Exactly 1 is required.
             <TopologyNodesList> - Exactly 1 is required.
             <PortLinkage> - At least 1 is required. 

 <TopologyNodesList> :包含在Topology中的Node列表,形成处理框架。

           Valid tag:
             <Node> - At least 1 is required. 

<Node> : 单个处理逻辑块,用于告诉驱动如何来处理一个请求。Valid tags: <NodeProperty> - Optional. Several properties allowed. <NodeName> - Value field. Exactly 1 is required. <NodeId> - Value field. Exactly 1 is required. <NodeInstance> - Value field. Exactly 1 is required. <NodeInstanceId> - Value field. Exactly 1 is required. 例子:     

复制代码

复制代码

<Node><NodeProperty><PropertyName>PropXYZ</PropertyName><PropertyDataType>UINT</PropertyDataType><PropertyValue>6</PropertyValue></NodeProperty><NodeName>NodeXYZ</NodeName><NodeId>1</NodeId><NodeInstance>NodeXYZInstanceName0</NodeInstance><NodeInstanceId>0</NodeInstanceId>
</Node> 

复制代码

复制代码

  驱动程序根据nodeId解析节点类型,对于所有自定义节点该字段的值为255,并带有一个NodeProperty来告知驱动程序切确的自定义节点类型。如下:

复制代码

复制代码

<Node><NodeProperty><PropertyName>CustomNodeLibrary</PropertyName><PropertyDataType>STRING</PropertyDataType><PropertyValue>customnodelib.so</PropertyValue></NodeProperty><NodeName>CustomNode</NodeName><NodeId>255</NodeId><NodeInstance>CustomNodeInstanceName0</NodeInstance><NodeInstanceId>0</NodeInstanceId>
</Node>   

复制代码

复制代码

<NodePortLinkage> : 描述节点列表以及它们如何相互连接。Valid tags: <SourceNode> - Value field. Exactly 1 is required. <SourceNodeInstance> - Value field. Exactly 1 is required. <Link> - At least 1 is required. <Link> :单个node之间的连接。Valid tags: <SrcPort> - Exactly 1 is required. <DstPort> - At least 1 is required. <BufferProperties> - Optional. <SrcPort> :一个节点的输出端口,该节点输出的图像数据到<DstPort>被使用修改,从<SrcPort>到<DstPort>可以有一对多的关系。Valid tags: <PortName> - Value field. Exactly 1 is required. <PortId> - Value field. Exactly 1 is required. <NodeName> - Value field. Exactly 1 is required. <NodeId> - Value field. Exactly 1 is required. <NodeInstance> - Value field. Exactly 1 is required. <NodeInstanceId> - Value field. Exactly 1 is required. 

<DstPort> :接收从<SrcPort>节点的输出数据。Valid tags <PortName> - Value field. Exactly 1 is required. <PortId> - Value field. Exactly 1 is required. <NodeName> - Value field. Exactly 1 is required. <NodeId> - Value field. Exactly 1 is required. <NodeInstance> - Value field. Exactly 1 is required. <NodeInstanceId> - Value field. Exactly 1 is required. <BufferProperties> :输入/输出缓冲区的属性。Valid tags: <BatchMode> - Value field. Exactly 1 is required. <BufferFormat> - Value field. Exactly 1 is required. <BufferQueueDepth> - Value field. Exactly 1 is required. <BufferHeap> - Value field. Exactly 1 is required. <BufferFlags> - Value field. Exactly 1 is required <UsecaseName>:任何字符串可以定义一个用例名称;例如,指定此流输出缓冲区由名为“NodeXYZ”的节点生成,则在<Link>标签内相应配置:

复制代码

复制代码

<Link><SrcPort><PortName>IFEOutputPortFull</PortName><PortId>0</PortId><NodeName>IFE</NodeName><NodeId>65536</NodeId><NodeInstance>IFEInstanceName0</NodeInstance><NodeInstanceId>0</NodeInstanceId></SrcPort><DstPort><PortName>IPEInputPortFull</PortName><PortId>0</PortId><NodeName>IPE</NodeName><NodeId>65538</NodeId><NodeInstance>IPEInstanceName0</NodeInstance><NodeInstanceId>0</NodeInstanceId></DstPort><BufferProperties><BatchMode>false</BatchMode><BufferFormat>YUV420NV12</BufferFormat><BufferQueueDepth>8</BufferQueueDepth><BufferHeap>Ion</BufferHeap><BufferFlags>MemFlagHw</BufferFlags></BufferProperties>
</Link>

复制代码

复制代码

<TargetName>:用于指定输出端口对应的缓冲区。

》》》以下标签指定了封装标签要用的值,不能在其中嵌入额外的标签:

<UsecaseName> :用于标识 Use case 的字符串。

      Valid value:
         Any string that is a valid C variable 
      例子:<UsecaseName>UsecasePreview</UsecaseName>

<TargetName> : 该字串用于映射流的输出缓冲区到拓扑中节点的输出端口,其中<TargetName>包含的字符串用于关联节点的输出端口与此流的输出缓冲区。

       Valid value:
         Any string that is a valid C variable, however, there must be a matching string name in the <PortName> of any <DstPort> which is a sink port.

       例子:<TargetName>TARGET_BUFFER_PREVIEW</TargetName>

  <TargetDirection>:此标签用于指定流的方向(或流类型),即它是否是输入流、输出流或双向流。

      Valid values: TargetOutput TargetInput TargetBidirectional 例子:<TargetDirection>TargetOutput</TargetDirection>
<TargetFormat>:此标签指定与流关联的缓冲区的格式。允许指定多个标签指定,如果其中一种格式与configure_streams()中给出的配置匹配,就认为与对应的use case相匹配。Valid values: Jpeg Y8 Y16 YUV420NV12 YUV420NV21 YUV422NV16 Blob RawYUV8BIT RawQCOM RawMIPI RawPlain16 RawMeta8BIT UBWCTP10 UBWCNV12 UBWCNV124R例子:<TargetFormat>YUV420NV12</TargetFormat> <MinW> :缓冲区的最小宽度。由<Range>标记使用。Valid value: Unsigned 32-bit integer, which must be less than <MaxW>. 
<MinH> :缓冲区的最小高度。由<Range>标记使用。Valid value: Unsigned 32-bit integer, which must be less than <MaxH>. 
<MaxW> :缓冲区的最大宽度。由<Range>标记使用。Valid value: Unsigned 32-bit integer, which must be greater than <MinW>. 
<MaxH> :缓冲区的最大高度。由<Range>标记使用。Valid value: Unsigned 32-bit integer, which must be greater than <MinH>. <TopologyName> :拓扑的名称。Valid value: Any string <NodeName>:字符串描述的节点名称。Valid value: Any string that is a valid C variable. <NodeId>:标识节点的ID,用于将节点的端口彼此链接。<NodeInstance>:字符串以描述节点实例的名称。Valid value: Any string that is a valid C variable. <NodeInstanceId>:标识节点唯一实例的ID,用于节点之间的端口连接。Valid value: Unsigned 32-bit integer, which must correspond to a unique instantiation of a node of the same engine type. <SettingName>:描述设置名称的字符串。<SettingDataType>:描述变量类型的字符串。Valid values: INT UINT FLOAT BOOL STRING <SettingMatch>:描述配置变量类型的字符串。Valid value: Any valid string, which is a valid constant for the <SettingMatch> tag. <SourceNode>:用于标识节点资源的ID,用于将节点的端口彼此链接。<SourceNodeInstance>:用于标识节点的唯一实例的ID,用于将节点的端口链接到彼此。Valid value: Unsigned 32-bit integer, which must correspond to a unique instantiation of a node of the same engine type. 
<PortName> :描述端口名称的字符串。Valid value: Any string that is a valid C variable. <PortId> :端口的ID,用于各端口之间的连接。
<BatchMode>:确定是否需要批处理。一般来说,只有在HFR中才需要该模式,使ISP在单个硬件提交中处理多帧,一般适用于无法离线操作的链接。Valid value: 0 to disable batch mode, 1 to enable it. <BufferFormat>:缓冲区类型。Valid values: Jpeg Y8 Y16 YUV420NV12 YUV420NV21 YUV422NV16 Blob RawYUV8BIT RawQCOM RawMIPI RawPlain16 RawMeta8BIT UBWCTP10 UBWCNV12 UBWCNV124R示例:<BufferFormat>YUV420NV12</BufferFormat>> <BufferQueueDepth> 一个链接允许创建的最大缓冲区数量。Valid values: 32 bit-unsigned integer. <BufferHeap>:允许在camera ISP之外分配缓存的堆。Valid values: System Ion DSP EGL <BufferFlags>:描述缓冲区的信息,例如设置MemFlagWriteAccess表示节点可写入。Valid values: MemFlagHw MemFlagProtected MemFlagCmdBuffer MemFlagUMDAccess MemFlagCache MemFlagPacketBuffer MemFlagKMDAccess <NodePropertyValue>:节点属性值,包含对应要加载的so模块,如:com.company.node.hdvideo

复制代码

复制代码

六、自定义Use case示例

  CHI override模块为实现HAL-ZSL接口以支持ZSL快照扩展了HAL3功能。此外,CHI override也提供了诸多的API,以实现像MFNR(多帧降噪)这样的多帧处理功能。 

   例如:override模块实现ZSL MFNR快照use case时有如下功能需求:

 能够创建 和 管理 多个 会话 和 相关 的 管道 ZSL 快照需要一 个实时的RAW pipelien和一个离线会话。 MFNR 需要额外的离线会话用于预过滤、混合、再过滤阶段。 能够控制整个会话的各请求和结果传输。 能够在应答framework请求的响应内部生成请求。 能够记录所有内部结果并生成最终的framework应答。 能够管理ZSL队列缓冲区 (图像和元数据)。 能够控制 inter-session buffer, fence, 和 metadata 联系。 能够支持锚帧选择逻辑。

   多帧降噪涉及到相机硬件对帧处理的复杂排序。有不同的处理阶段,即mfnn - prefilter,MFNR-Blend和MFNR-Postfilter,它们调用不同的pipeline,其中Node会在处理阶段被实例化具有不同的功能。例如,基于IPE硬件的预过滤阶段与混合阶段不同,override module实例化不同的实时和离线pipeline来实现MFNR ZSL快照。

  1初始化

   override module在摄像机服务器进程启动期间初始化,此时会加载com.qti.chi.override.so,该库提供了由QTI实现的CHI override接口,所需的函数指针由CHI override module加载,同时会遍历该平台上支持的以及包括自定义nodes的vendor tags。 

   入口函数的伪代码:

void chi_hal_override_entry (const chi_hal_ops_t *ops, ///< [in]chi_hal_callback_ops_t *callbacks) ///< [in | out]
{...// Store the hal opsQtiChiOverride::m_chiOps = *ops;...// Export the callback function pointerscallbacks->chi_initialize_override_session = QtiChiOverride::InitializeOverrideSession;callbacks->chi_finalize_override_session = QtiChiOverride::QtiChiExtFinalizeOverrideSession;...// Optional callback function pointers can be NULL
}

  2创建会话

   驱动程序中的HAL3模块将chi_initialize_override_session传递到CHIoverride module,以便override module用于检查流的配置,以及决定是否重写或忽略use case。override module通过stream的格式、类型和使用标准等配置表明是否需要HAL-ZSL,如果满足ZSL use case的条件,它就将创建realtime和offline pipeline,具体会根据拓扑中对real-time pipeline的描述调用chi_create_pipeline来创建。real-time pipeline除了PREVIEW_TARGET外,还有一个RAW_TARGET来接收原始ZSL buffer的数据。override module会将新创建的real-time pipeline句柄返回给驱动程序。

   Google Framework -> HAL3 -> CHI -> QTI CHI Extension
 

  3 ZSL 预览

   驱动程序将framework层发出的每个请求通过chi_override_process_request接口传递给override module。如果应用程序只需要预览,则只发出请求、申请缓冲区和设置对应preview stream即可。override module从framework获取请求后并为raw target添加额外的请求,override module为raw target分配内部缓冲区并进行管理。修改后的请求调用chi_submit_pipeline_request利用real-time session句柄传递给驱动程序。 
   在目标缓冲区fences都被标记后才会收到驱动返回的结果,驱动程序调用chi_override_result_notify接口来唤醒override module获取结果。override module提取raw target buffer元数据并推入ZSL队列。framework每次发出的预览请求都会重复这个过程。

  (后面时序图画一下。。。。。)

  4 ZSL 拍照(常规请求和结果)

    用户通过应用程序发送拍照请求,override module通过chi_override_process_request接口获取request来解析对ZSL帧的需要。MFNR缺失vendor tags则会使override module做一个常规的ZSL快照,以及在real-time session中的raw target添加内部请求。除此之外,它还标记了两个内部请求,一个使用offline session_1对原始Bayer数据转换成yuv,一个使用offline session_2用于yuv到jpeg的转换,这样标记有助于在之后生成内部请求到pipeline。override module可以在不同的会话中配置访问缓冲区和相关的栅栏,它将会话间缓冲区和栅栏联系起来,以实现无缝控制。

    对于常规的ZSL快照,在它提交完实时请求之后,override module就从ZSL队列及其元数据获取最新的帧,并将其提交到offline session_1。 real-time session返回结果的流程和操作ZSL预览类似当override module接收到offline session_1的结果时,它将根据之前为offline session_2所做的标记生成一个内部请求,此请求将从offline session_1获取YUV输出,以生成一个JPEG编码照片,override module配置offline session_2来使用framework提供的拍照目标缓冲区。

 

  (后面画下时序图。。。)

  5 ZSL 拍照 (MFNR请求) 

    应用程序使用特殊的vendor tags请求ZSL MFNR拍照。当带有vendor tags的请求被override module获取时,它首先扫描可用的ZSL队列,以寻找合适的锚帧,以为raw target创建新的内部请求。

    假设ZSL深度为4,MFNR深度为8,则实时请求的数量是:

      情形1:对于ZSL队列的顶部帧,则MFNR_DEPTH (8) - (ZSL_DEPTH (4)) - AnchorIndex(0) = 4。

      情形2:对于ZSL队列中的最后一帧,然后是MFNR_DEPTH (8) - (ZSL_DEPTH) (4) - 锚定指数(3)= 7。

      情形3:对于ZSL队列中没有帧,则MFNR_DEPTH(8)。

    除了实时请求外,还为不同的对象生成多个offline pipeline对应MFNR处理的不同阶段:MFNR预滤器 = 1; MFNR共混物= N-2 = (8) -2 = 6;MFNR后置滤波器= 1。

    每一个请求都是交错的,并提交给相应的pipeline,这些请求在real-time 和 offline sessions之间ID相同。

  以上大致介绍了 CHI API 框架和一些关键术语的理解,后面可以根据文档各API的说明结合代码进行流程分析。

六、CHI interface

  CHI向谷歌HAL3接口添加了几个关键元素,以支持更细粒度的控制。下面的函数用于访问CHI驱动程序,它们对Camera2/HAL3没有任何依赖。

1.VOLD ChiEntry( CHICONTEXTOPS* pContextOps);  CHI驱动程序的入口点,该函数用指向CHI函数的指针填充pContextOps,在使用CHI的每个进程中,必须至少调用该函数一次。

2.CHIHANDLE (*PFNCHIOPENCONTEXT)(); 此函数用于创建ChiContext的唯一实例。ChiContext是state在ChiSessions中传输的上下文。每个进程至少有1个ChiContext。chicontext之间没有通信信息的机制,ChiSessions和ChiPipelines只能在创造它们的ChiContex中t所使用。返回值:新创建的 ChiContext handle 或 NULL。

3.VOID (*PFNCHICLOSECONTEXT)(CHIHANDLE hChiContext);  此函数用于关闭ChiContext,将终止任何未完成的请求,并释放此上下文声明的所有资源。用户应该在调用PFNCHICLOSECONTEXT之前销毁所有未完成的ChiSessions 和 ChiPipeline,否则可能导致资源泄漏。

4.UINT (*PFNCHIGETNUMCAMERAS)( CHIHANDLE hChiContext); 此函数用于确定平台上可用的相机传感器的数量,可以在创建ChiContext之前调用。如果一个平台有多个相机组合成一个物理通道(例如,在桥接芯片后面),这些相机被认为是一个物理传感器。如果ChiContext句柄无效,则此函数返回-1。

5.CDKResult (*PFNCHIGETCAMERAINFO)( CHIHANDLE hChiContext, UINT32 cameraId, CHICAMERAINFO* pCameraInfo); 该函数用于获取特定camera的详细信息,可以在创建ChiContext之前调用。如果将传感器信息写入pCameraInfo,则返回一个错误代码。

6.CDKResult (*PFNCHIENUMERATESENSORMODES)( CHIHANDLE hChiContext, UINT32 cameraId, UINT32 numSensorModes, CHISENSORMODEINFO* pSensorModeInfo); 该函数用于获取特定sensor模组的详细信息

7.CHIPIPELINEDESCRIPTOR (*PFNCHICREATEPIPELINEDESCRIPTOR)( CHIHANDLE hChiContext, const CHIPIPELINECREATEDESCRIPTOR* pDescriptor, UINT32 numOutputs,CHIPORTBUFFERDESCRIPTOR* pOutputBufferDescriptors, UINT32 numInputs, CHIPIPELINEINPUTOPTIONS* pInputBufferOptions); 该函数用于读取pipeline描述符,确认描述符中包含的拓扑,然后返回pipeline内部驱动程序表示的句柄。在代码的时间敏感部分不应调用此函数。这个函数可以在HAL设备创建之后的任何时候调用。调用者负责使用后销毁pipeline。pipeline可以在会话之间共享,不包含对缓冲区格式或大小的任何绑定。PFNCHICREATEPIPELINEDESCRIPTOR申请输出缓冲区,并确定拓扑中每个节点的入口的大小要求。返回的默认配置保证对给定的输出缓冲区集有效。对于使用传感器作为输入的管道,将返回有效的传感器模式列表,以便用户进行微调。对于使用内存作为输入的管道,将返回大小需求列表。

8.VOID (*PFNCHIDESTROYPIPELINEDESCRIPTOR)( CHIHANDLE hChiContext, CHIPIPELINEDESCRIPTOR hPipelineDescriptor); 销毁一个pipeline描述符,pipeline不维护任何状态(这是session的职责),因此可以在任何时候销毁它们。

9.CHIHANDLE (*PFNCHICREATESESSION)( CHIHANDLE hChiContext, UINT numPipelines, CHIPIPELINEINFO* pPipelineInfo, CHICALLBACKS* pCallbacks, VOID* pPrivateCallbackData, CHISESSIONFLAGS flags); 此函数创建包含一个或多个pipeline的独立处理单元会话。会话是在“停用”状态下创建的,只有在试图激活会话时才会获得资源。会话是不可变的,并且拥有pipeline的所有资源。互斥会话在pipeline之间共享资源。非互斥会话为所有pipeline保留了足够的资源,pipeline可以从内存(offline)或通过流(realtime)获取输入数据。

10.VOID (*PFNCHIDESTROYSESSION )( CHIHANDLE hChiContext, CHIHANDLE hSession BOOL isForced); 销毁一个camera session。

11.CDKResult (*PFNCHIACTIVATEPIPELINE)( CHIHANDLE hChiContext, CHIHANDLE hSession, CHIHANDLE pipeline, CHISENSORMODEINFO* pSensorModeInfo); 此函数激活会话中的pipeline,然后可以开始向pipeline提交请求。

12.CDKResult (*PFNCHIDEACTIVATEPIPELINE)( CHIHANDLE hChiContext, CHIHANDLE hSession, CHIHANDLE pipeline, CHIDEACTIVATEPIPELINEMODE mode); 禁用pipeline,释放会话的资源。驱动程序会试图保留尽可能多的资源,以实现快速地重新激活会话。

13.CDKResult (*PFNCHISUBMITPIPELINEREQUEST)( CHIHANDLE hChiContext, CHIPIPELINEREQUEST* pRequest); 在会话中向特定pipeline提交请求。

14.

15.

16.

17.

18.

19.

20.

相关文章:

Android : Camera之CHI API

来自&#xff1a; https://www.cnblogs.com/szsky/articles/10861918.html 一、CAM CHI API功能介绍&#xff1a; CHI API建立在Google HAL3的灵活性基础之上&#xff0c;目的是将Camera2/HAL3接口分离出来用于使用相机功能&#xff0c;它是一个灵活的图像处理驱动程序&#…...

【动手实验】TCP 连接的建立与关闭抓包分析

本文是基于知识星球程序员踩坑案例分享中的作业进行的复现和总结&#xff0c;借此加深对 TCP 协议的理解&#xff0c; 原文参见TCP 连接的建立和关闭 —— 强烈建议新手看看。 实验环境 这里使用两台位于同一子网的腾讯云服务器&#xff0c;IP 分别是 node2&#xff08;172.1…...

语音识别踩坑记录

本来想在原来的语音识别的基础上增加本地扩展本地词典&#xff0c; 采用的语音识别是Vosk识别器&#xff0c;模型是 vosk-model-small-cn-0.22 // 初始化Vosk识别器 if (recognizer null) {using (Model model new Model(modelPath)){string grammar "{""…...

Conda常用命令汇总

Conda 是一个流行的包管理器和环境管理工具&#xff0c;广泛应用于数据科学、机器学习等领域。它可以帮助我们管理 Python 包以及不同版本的环境&#xff0c;避免包冲突&#xff0c;提升项目的可复现性。以下是一些常用的 Conda 命令&#xff0c;涵盖环境创建、管理、包安装等常…...

消息队列MQ使用场景有哪些?

MQ 在实际项目中的应用场景主要围绕异步处理、系统解耦、流量控制三大核心能力展开&#xff0c;结合具体业务需求可细分为以下场景&#xff1a; 1. 异步处理 典型场景&#xff1a;用户注册成功后发送短信/邮件、支付成功后通知物流系统发货、商品上架后同步至搜索引擎。优势&…...

5. 前后端实现文件上传与解析

1. 说明 在实际开发中&#xff0c;比较常见的一个功能是需要在前端页面中选择系统中的某个文件上传到服务器中进行解析&#xff0c;解析后的文件内容可以用来在服务器中当作参数&#xff0c;或者传递给其它组件使用&#xff0c;或者需要存储到数据库中。所以本文就提供一种方式…...

基于腾讯云高性能HAI-CPU的跨境电商客服助手全链路解析

跨境电商的背景以及痛点 根据Statista数据&#xff0c;2025年全球跨境电商市场规模预计达6.57万亿美元&#xff0c;年增长率保持在12.5% 。随着平台规则趋严&#xff08;如亚马逊封店潮&#xff09;&#xff0c;更多卖家选择自建独立站&#xff0c;2024年独立站占比已达35%。A…...

python中time模块的常用方法及应用

Python 的 time 模块是自带的标准模块&#xff0c;不需要额外安装&#xff0c;可以直接通过import time的方式导入并使用其中的函数和类。该模块提供了与时间相关的各种功能&#xff0c;以下是一些常用方法及其应用场景和示例&#xff1a; ### 1. time.time() - **功能**&…...

JavaScript性能优化

JavaScript性能优化指南 一&#xff1a;性能分析与指标确立 使用性能分析工具 • 使用Lighthouse、Chrome DevTools的Performance面板和WebPageTest进行基准测试&#xff0c;识别加载时间、脚本执行时长等瓶颈。 • 关注核心Web指标&#xff1a;LCP&#xff08;最大内容绘制&a…...

《React 属性与状态江湖:从验证到表单受控的实战探险》

属性初识 属性能解决两个大问题&#xff1a;通信和复用 props.js: import React, { Component } from react import Navbar from ./Navbarexport default class App extends Component {state {a:100}render() {return (<div><div><h2>首页</h2>&l…...

Android Retrofit 框架注解定义与解析模块深度剖析(一)

一、引言 在现代 Android 和 Java 开发中&#xff0c;网络请求是不可或缺的一部分。Retrofit 作为 Square 公司开源的一款强大的类型安全的 HTTP 客户端&#xff0c;凭借其简洁易用的 API 和高效的性能&#xff0c;在开发者社区中广受欢迎。Retrofit 的核心特性之一便是通过注…...

嵌入式学习L6网络编程D3TCP

TCP编程 写代码 第一步socket 绑定 先填充 点分十进制转换成32位整数 client 然后就连接成功了就可以读写数据了 client #include "net.h"int main (void) {int fd -1;struct sockaddr_in sin;/* 1. 创建socket fd */if ((fd socket (AF_INET, SOCK_S…...

【玩转23种Java设计模式】结构型模式篇:享元模式

软件设计模式&#xff08;Design pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...

超分之DeSRA

Desra: detect and delete the artifacts of gan-based real-world super-resolution models.DeSRA&#xff1a;检测并消除基于GAN的真实世界超分辨率模型中的伪影Xie L, Wang X, Chen X, et al.arXiv preprint arXiv:2307.02457, 2023. 摘要 背景&#xff1a; GAN-SR模型虽然…...

产城融合典范:树莓科技如何助力宜宾数字经济腾飞​

宜宾在推动数字经济发展的征程中&#xff0c;树莓科技扮演着至关重要的角色&#xff0c;堪称产城融合的典范。 树莓科技入驻宜宾后&#xff0c;积极与当地政府合作&#xff0c;以产业发展带动城市建设&#xff0c;以城市功能完善促进产业升级。在产业布局上&#xff0c;树莓科…...

Java数据结构第二十二期:Map与Set的高效应用之道(一)

专栏&#xff1a;Java数据结构秘籍 个人主页&#xff1a;手握风云 目录 一、Map和Set 1.1. 概念 二、搜索树 2.1. 概念 2.2. 查找操作 2.2. 插入操作 2.3. 删除操作 2.4. 性能分析 三、搜索 3.1. 概念及场景 3.2. 模型 四、Map 4.1. Map的说明 3.2. Map的使用 五…...

焊接安全的新纪元:智能监管系统的力量

在现代制造业中&#xff0c;焊接作为一项关键工艺&#xff0c;其安全性直接关系到生产质量和人员安全。为了应对这一挑战&#xff0c;一款创新的焊接联网智能化监管系统应运而生&#xff0c;为焊接行业带来了新的安全保障。 智能监管&#xff0c;安全升级 这款系统通过“一机…...

OpenGL中绘制图形元素的实现(使用visual studio(C++)绘制一个矩形)

目标&#xff1a;使用OpenGL提供的函数绘制矩形、线段、三角形等基本图形元素 所需效果 实验步骤 1、配置OpenGL&#xff08;详情参见OpenGL的配置&#xff09; 2、头文件引入 #include <gl/glut.h> 3、编写方法体 1>矩形实现 //绘制矩形 void DisplayRectangl…...

政安晨【零基础玩转各类开源AI项目】Wan 2.1 本地部署,基于ComfyUI运行,最强文生视频 图生视频,一键生成高质量影片

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 目录 下载项目 创建虚拟环境 安装项目依赖 尝试运行 依次下载模型 完成 我们今天要使…...

DeepLabv3+改进8:在主干网络中添加SIM注意力机制|助力涨点

🔥【DeepLabv3+改进专栏!探索语义分割新高度】 🌟 你是否在为图像分割的精度与效率发愁? 📢 本专栏重磅推出: ✅ 独家改进策略:融合注意力机制、轻量化设计与多尺度优化 ✅ 即插即用模块:ASPP+升级、解码器 PS:订阅专栏提供完整代码 论文简介 在本文中,我们提出了…...

卷积神经网络(笔记01)

视觉处理三大任务&#xff1a;分类、目标检测、图像分割 CNN网络主要有三部分构成&#xff1a;卷积层&#xff08;Convolutional Layer&#xff09;、池化层&#xff08;Pooling Layer&#xff09;和激活函数 一、解释卷积层中的偏置项是什么&#xff0c;并讨论在神经网络中引…...

从自己电脑的浏览器访问阿里云主机中运行的LLaMA-Factory webui

阿里云主机上LLaMA-Factory的webui在0.0.0.0:7860侦听&#xff0c;无法直接打开&#xff0c;需要通过代理的方法访问。 在LLaMA-Factory目录下创建一个脚本文件run.sh&#xff0c;并加上执行权限&#xff0c;内容如下&#xff1a; #!/bin/shexport GRADIO_SERVER_PORT7860 ex…...

大数据面试之路 (一) 数据倾斜

记录大数据面试历程 数据倾斜 大数据岗位 &#xff0c;数据倾斜面试必问的一个问题。 一、数据倾斜的表现与原因 表现 某个或某几个Task执行时间过长&#xff0c;其他Task快速完成。 Spark/MapReduce作业卡在某个阶段&#xff08;如reduce阶段&#xff09;&#xff0c;日志显…...

文件上传漏洞 upload-labs靶场

&#xff08;这个没删就是还没做完 ; ω ; &#xff09; 目录 Pass-01 前端绕过 关卡分析 绕过&#xff1a;Burpsuite抓包修改或页面禁用js Pass-02 服务器端检测–IMME类型 关卡分析 Content-type 绕过&#xff1a;抓包修改文件的content-type Pass-03 黑名单绕过 关…...

「 DelegateUI 」Ant-d 风格的 Qt Qml UI 套件

写在前面&#xff1a;关于为什么要写一套新的UI框架 一方面&#xff0c;Qt Qml 生态中缺乏一套既遵循现代设计规范(自带的功能少且丑,懂得都懂)&#xff0c;又能深度整合 Qt 生态的开源组件库。 另一方面&#xff0c;Qt Qml 中也有一些其他方案&#xff0c;例如 FluentUI Qml…...

数字人分身开发指南:从概念到实战

一、什么是数字人分身&#xff1f; 想象一下&#xff0c;在电脑或手机屏幕里&#xff0c;一个能跟你聊天、回答问题&#xff0c;甚至还能做表情的虚拟角色。这就是数字人分身&#xff0c;它用上了人工智能技术&#xff0c;让机器也能像人一样交流。无论是在线客服、网络主播还…...

Java小白-管理项目工具Maven(2)初识Maven

一、Maven安装 ①安装jdk1.8或以上版本 ②下载Maven&#xff08;此为3.6.0&#xff09;&#xff1a;地址&#xff1a;Download Apache Maven – Maven 下载地址&#xff1a;Index of /dist/maven/maven-3/3.6.0/binaries ③安装Maven到无中文路径即可 bin&#xff1a;含…...

【附JS、Python、C++题解】Leetcode 面试150题(8)

一、题目 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。你不能倾斜…...

什么是向量数据库向量搜索?

向量数据库 专为高效存储与检索高维向量设计&#xff0c;支持语义搜索、推荐系统等AI场景&#xff0c;如文本/图像嵌入的相似性匹配。 ChromaDB 轻量级开源向量数据库&#xff0c;优势在于易用性&#xff08;快速部署、简洁API&#xff09;和小规模场景&#xff08;本地开发、…...

【WRF-Urban】使用 LCZ 替换 WRF 运行中的 LUCC 数据

使用 LCZ 替换 WRF 运行中的 LUCC 数据 WRF-UCM中的城市类型LCZ的背景介绍完整步骤总结1. 获取 LCZ 数据2. 获取 WRF 运行所需的 LUCC 数据3. 使用 w2w 替换 WRF 的 LUCC 数据4. 运行 WRF 预处理(WPS & REAL)5. 运行 WRF 并优化城市参数化Q1:使用 LCZ 替换 WRF 运行中的…...

centos 7 安装apache服务

四步骤 解包 使用tar -zxvf 对.tar.gz 进行解压 使用tar -jxvf 对.tar.bz2 进行解压 rpm命令使用集合 rpm -qa 查询系统已安装的软件包 rpm -ql查看指定软件包存放的位置 rpm -qi查看指定软件包的属性 rpm -qf查看指定文件或目录是由哪个软件包所安装的 rpm -qpi查看指…...

2025各省市建筑产业和工程建设计划安排

1. 前言 十四届全国人大三次会议3月5日上午9时在人民大会堂开幕&#xff0c;国务院总理李强作政府工作报告。 《2025年政府工作报告》&#xff08;以下简称 “报告”&#xff09;作为统筹国家经济、战略布局与社会发展的蓝图&#xff0c;与建筑业息息相关&#xff0c;为今后的…...

广告营销,会被AI重构吗?

DeepSeek设计&#xff0c;即梦AI绘图&#xff0c;剪映成片。 DeepSeek的热度还在高开疯走。 用户对于各个场景下DS应用的探索也还在持续&#xff0c;各种DS的模式被挖掘出来&#xff0c;超级个体们开始给手下的大模型团队进行分工&#xff0c;实践出各种场景下最佳的排列组合方…...

01 音视频知识学习(视频)

图像基础概念 ◼像素&#xff1a;像素是一个图片的基本单位&#xff0c;pix是英语单词picture的简写&#xff0c;加上英 语单词“元素element”&#xff0c;就得到了“pixel”&#xff0c;简称px&#xff0c;所以“像素”有“图像元素” 之意。 ◼ 分辨率&#xff1a;是指图像…...

深入探究 Ryu REST API

Ryu 4.34 REST API 详细接口说明与示例 Ryu 4.34 的 REST API 提供了对 SDN 网络的核心管理功能&#xff0c;涵盖交换机、流表、端口、拓扑和 QoS 等操作。以下是详细的接口分类、功能说明及 Python 示例代码。 1. 交换机管理 1.1 获取所有交换机 DPID 端点: GET /stats/swi…...

不同AI生成的PHP版雪花算法

OpenAI <?php /*** Snowflake 雪花算法生成器* 生成的 64 位 ID 结构&#xff1a;* 1 位 保留位&#xff08;始终为0&#xff0c;防止负数&#xff09;* 41 位 时间戳&#xff08;毫秒级&#xff0c;当前时间减去自定义纪元&#xff09;* 5 位 数据中心ID* 5 …...

texstudio: 编辑器显示行号+给PDF增加行号

texstudio在编辑器部分增加行号&#xff1a; texstudio默认在编辑器部分不显示行号&#xff0c;如下图&#xff1a; 要实现以下的在编辑部分增加行号&#xff1a; 执行如下操作&#xff1a; 选项-->设置TexStudio-->编辑器-->显示行号-->所有行号选择好后&…...

强化学习基础-马尔可夫决策过程与贝尔曼方程

马尔可夫决策过程 在老虎机问题中&#xff0c;无论智能代理采取什么行动&#xff0c;之后要解决的问题都是一样的。也就是寻找最好的老虎机。但现实生活中的问题是不同的。例如&#xff0c;在围棋游戏中&#xff0c;智能代理落子后&#xff0c;棋盘上的棋子排列会发生变化&…...

爬虫的精准识别:基于 User-Agent 的正则实现

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

Scala的初步使用

目录 1. Scala简介2. Scala编写的Hello World2.1 pom.xml中依赖和插件的配置2.2 安装Scala2.12.172.3 安装code-server插件2.4 helloworld.scala2.5 helloworld2.scala2.6 java调用scala object 3. Scala调用Java3.1 例子13.2 例子2 参考 1. Scala简介 Scala是一门多范式的编程…...

【Json RPC框架】框架介绍与环境搭建(Ubuntu 22.04)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Json RPC框架 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ JSon RPC框架系列文章Json RPC框架_我们的五年的博…...

python读取word文档 | AI应用开发

python读取word文档 | AI应用开发 RAG中python读取word文档 RAG系统中构建知识库流程中重要的一个步骤是读取外挂的知识文档&#xff0c;为word是其中比较常见的文件。 另一个值得注意的是&#xff0c;RAG在读取文档后需要对文档进行分割&#xff0c;而良好的分割需要有一定结…...

20、组件懒加载

组件懒加载&#xff0c;也被称为异步组件加载&#xff0c;是一种在 Vue 项目中提升性能的重要技术手段。下面从概念、实现原理、使用场景、实现方式几个方面详细介绍&#xff1a; 概念 在传统的 Vue 项目里&#xff0c;当应用启动时&#xff0c;所有的组件代码都会被一次性加…...

打造智能钉钉机器人:借助智谱GLM-4-Flash实现高效智能回复(文末附源码)

文章目录 前言一、准备工作&#xff08;一&#xff09;钉钉机器人&#xff08;二&#xff09;智谱 GLM-4-Flash&#xff08;三&#xff09;内网穿透工具 cpolar&#xff08;四&#xff09;需要准备的工具和环境 二、钉钉机器人的创建与配置步骤1&#xff1a;创建钉钉机器人步骤…...

【故障处理系列--docker卷的挂载】

一位伙伴需求是把容器的目录映射到宿主机且容器目录的内容不被宿主机的空白目录覆盖。我的第一反应是-v 卷的映射&#xff0c;参数是对的&#xff0c;但是用法是错的 1、容器卷的挂载方式 容器把目录映射到宿主机创建volume卷&#xff0c;然后把容器的目录和volume卷绑定 区别…...

兴达易控modbusTCP转profinet接防撞雷达测试

modbusTCP转profinet接防撞雷达测试 随着工业自动化程度的不断提高&#xff0c;现场设备之间的通信需求日益增长。ModbusTCP作为一种广泛应用的工业通信协议&#xff0c;因其简单、可靠的特点&#xff0c;被广泛应用于各种自动化设备中。而Profinet作为工业以太网的一种&#…...

Acknowledgment.nack方法重试消费kafka消息异常

文章目录 问题示例异常 原因nack方法Acknowledgment接口实现类&#xff1a;ConsumerAcknowledgment实现类&#xff1a;ConsumerBatchAcknowledgment 解决方案1 批量消费指定index示例 2 单条消费示例 问题 使用BatchAcknowledgingMessageListener 批量消费Kafka消息&#xff0…...

通过动态获取后端数据判断输入的值打小

eval() 函数在 JavaScript 中是一个非常强大的函数 【1】计算简单公式 很多时候如果需要动态的提供计算的公式&#xff0c;需要写一大段的公式计算逻辑去兼容&#xff0c;可能耗费大量的开发成本。为了快速了解 eval 的用法&#xff0c;直接 ① 打开浏览器&#xff1b;② F1…...

乐维网管平台核心功能解析(一)——告警关联知识

在数字化转型浪潮中&#xff0c;企业IT系统规模呈指数级增长&#xff0c;传统的"人工经验"运维模式已难以应对海量告警处理需求。某银行数据中心曾统计&#xff0c;其日均告警量突破10万条&#xff0c;关键故障的平均定位时间长达3.5小时&#xff0c;直接导致年损失超…...

数据结构_单链表

今天我们要开启链表的学习 &#x1f58b;️&#x1f58b;️&#x1f58b;️ 学了顺序表我们可以知道&#xff1a; &#x1f388;链表其实就是争对顺序表的缺点来设计的&#xff0c;补足的就是顺序表的缺点 &#x1f388;链表在物理上是上一个节点存放的下一个节点的地址 链表 …...