Skip to main content

Camsys子系统

系统概述

S100 camsys子系统包含Camera sensor (包括 SerDes)、VIN(包括 MIPI、CIM)、ISP、PYM、GDC、YNR、STITCH模块。

简称全称说明
MIPIMobile Industry Processor Interface移动产业处理器接口,MIPI联盟制定的标准
CSICamera Serial InterfaceCamera串行接口
IPIImage Pixel InterfaceMIPI与CIM之间的图像传输接口
FOVField of View视场角
SERSerializer加串器
SerDesSerializer and Deserializer加串与解串器
DESDeserializer解串器
CIMCamera Interface MangerCamera接入管理模块,支持online或offline工作
VINVideo In(CIM+MIPI+LPWM+VCON)视频输入模块
ISPImage Signal Processor图像信号处理器
PYMPyramid金字塔处理模块: 图像缩小及ROI
GDCGeometric Distortion Correction几何畸变校正模块
VPFVideo Process Framework(VIN+ISP+PYM..)视频处理管理模块
VIOVideo In/Out (VIN+VPM)视频输入/输出模块
STITCHStitch hardware Module图像拼接处理模块
CAMSYSCamera System (Camera+VPF)相机图像系统

camsys硬件框图

子模块

CIM

CIM(Camera Interface Manager)是一种专门用来接收MIPI-RX IPI图像数据的硬件。CIM负责同时接入多路图像数据,并改变MIPI IPI接口的时序以匹配后级硬件或DDR的输入时序要求,将图像通过硬件直连或DDR形式提供给ISP和PYM。

  • S100上共有3个CIM模块,分别为CIM0 CIM1 CIM4;
  • 单个CIM最大支持接入4V * 8M * 30fps,支持接入RAW8、RAW10、RAW12、RAW14、RAW16、RAW20、YUV422-8Bit图像;
  • CIM0 CIM1可以硬件直连otf输出至ISP、PYM,同时支持离线输出至ddr,CIM4只支持离线输出;
  • CIM0的IPI0最大接入宽为5696,CIM0其他的IPI和其他CIM中的IPI最大接入宽为4096;

ISP

ISP (Image Signal Processor)图像信号处理器,是一种专门用于图像信号处理的引擎。 ISP的功能包括对原始图像进行各类算法处理、图像特性统计、色彩空间转换、多路通道分时复用控制等,最终输出更清晰、更准确、高质量的图像。

  • S100上共有2个ISP模块,分别为ISP0 ISP1;
  • 每个ISP硬件模块IP最大支持12路sensor的接入能力;
  • ISP处理最大分辨率为4096 * 2160
  • ISP处理pipeline如下图:
  • MCFE: Multi-Context Front End,用于ISP多路调度控制与buffer管理,one by one进行Multi-camera图像处理。
  • RAW Domain: RAW域图像处理,包含input port (含input crop功能)、channel switch、input formatter、sensor offset linear、digtal gain、gamma FE(即decompander)、gamma_sqrt、raw frontend、static defected、sinter、chromatic aberration、gamma_sq、gamma BE、static white blance、radial shading correction、mesh shading correction、digital gain iridix、iridix、demosaic等。
  • RGB Domain: RGB域图像处理,包含purple fringe correction、color matrix、gamma RGB forward SQ、crop、CNR、gamma RGB reverse SQ、RGB gamma等。
  • Output formatter: CS(color space) coversion,将RGB通道数据转换成YUV 等format,output control 进行输出控制。

YNR

YNR为yuv域的降噪模块Digital Noise Reduction,YNR支持2DNR与3DNR模式

  • S100上共有一个YNR模块,YNR1,只支持ISP1-online-YNR1-online-PYM1场景;
  • 在3DNR模式下,处理的最大宽高为2048x2048,在2DNR模式下支持3840x2160;

PYM

PYM(Pyramid)作为一个硬件加速模块,对输入的图像按照金字塔图层的方式处理,并输出到DDR。

alt text

  • S100上共有3个PYM模块,分别为PYM0 PYM1 PYM4;
  • SRC层:代表源图像层;
  • BL层:代表双线性下采样层,BL Base 0~4依次是源图层的1/2,1/4,1/8,1/16,1/32;
  • DS层:输出层,每层能够任意选择输入图层(SRC或0~4BL),并进行下采样和ROI处理后输出到DDR;
  • 最大输入宽度输入高度均为4096,最小输入宽度及高度为32;
  • 缩小ratio(1/2,1],不支持放大;
  • PYM0/1:4k@120fps,PYM4:4K@90fps,PYM4不支持online输入;

GDC

GDC作为一个硬件模块,可将输入的图像进行视角变换、畸变校正和指定角度(0,90,180,270)旋转。

模式支持的输入图像典型尺寸为3840x2160,2688x1944,1920x1080,1280x720,640x480,480x320。

硬件特性如下:

  • 最大分辨率:3840x2160
  • 最小分辨率:96x96(奇数行或者列不支持)
  • 性能:3840x2160,60fps
  • 工作模式:ddr-gdc-ddr
  • 输入格式:YUV420 semi-planar
  • 输出格式:YUV420 semi-planar
GDCTool简介

GDC Tool是一种可在PC上进行处理效果仿真的工具。用户可准备jpg模式的图像,load 到gdc-tool中进行离线校正,校正完成后可以直接保存config.bin文件用于硬件校正,也可用保存layout.json文件生成config.bin进行硬件校正

GDC Tool 启动
  1. window环境启动

    安装环境:依赖nodejs安装,参考:https://nodejs.cn/download/

    安装执行依赖:在win命令行,进入GDC 发布的工具文件(如gdc-tool-gui-xxxx-windows)目录下,执行npm install express

    启动应用:在win 命令行进入文件目录(如gdc-tool-gui-xxxx-windows),执行node.exe app.js,Chrome浏览器登陆http://localhost:3000/

  2. unix 环境启动

    安装环境:mac: brew install node

    安装执行依赖:文件目录下执行npm install -production

    启动应用:执行node app.js,登陆http://localhost:3000/

GDC Tool 中的变换模式

变换模式有Affine,Equisolid,Equisolid(cylinder),Equidistant, Custom, Keystone+dewarping六种变换供选择,这些模式与软件中的变换模式对应关系见GDC Bin API文档中的 transformation_t 描述,下表是各个变换的用途

变换模式用途
Affine一种线性变换,简单的图像旋转功能,没有畸变校正
Equisolid全景变换,变换网格最大
Equisolid(cylinder)圆柱形变换
Equidistant等距变换,变换后的距离等距。
Custom用户定制变换
Keystone+dewarping相对于Equidistant,dewarp_keystone 多了两个参数trapezoid_left_angle 和 trapezoid_right_angle。默认情况下这两个参数90度,效果和Equidistant一样。

所有转换类型都有以下三个常用参数Pan、Tile、Zoom(举例:等距变换,输入/输出分辨率1280x720): 以下输出图像中的蓝色矩形表示仅将特殊参数设置为该值, 并且一个转换中的其他参数保持默认值。

  • Pan

    水平方向 (-1280, +1280)通过给定的像素数,偏移变换网格。如下所示: alt text

  • Tile

    垂直方向 (-720, +720)通过给定的像素数,偏移变换网格。如下所示: alt text

  • Zoom

    按提供的因子 (0, +∞)缩放变换输出,(0, 1)表示值大于 0 且小于 1。如下所示: alt text

  1. Affine

    • 功能描述

      提供线性的变换

      alt text

    • 成员说明

      成员含义
      int32_t pandefault 0, 不修改
      int32_t tiltdefault 0, 不修改
      zoom按提供的因子缩放转换输出, 当旋转角度为180或270时,该值需>=1.03
      double angle(rotation)图像旋转的角度 0/90/180/270
      注意!

      输入输出尺寸的宽应保持16字节对齐。

      zoom 参数在旋转角度为180或270时,需>=1.03

  2. Equisolid

    • 功能描述

      此转换提供等实体(全景panoramic)校正,并将结果显示为平面上的投影。

      alt text

    • 成员说明

      成员含义
      int32_t pandefault 0, 不修改
      int32_t tiltdefault 0, 不修改
      zoom按提供的因子缩放转换输出
      double strengthX沿X轴的变换强度(非负参数)
      double strengthY沿Y轴的变换强度(非负参数)
      double angle(rotation)图像旋转的角度 0/90/180/270

      strength x调试效果,在X轴的转换强度,取值(0, +∞)。如下所示: alt text

      strength y调试效果,在Y轴的转换强度,取值(0, +∞)。如下所示: alt text

      Rotation调试效果,取值(-180, 180)。如下所示: alt text

      注意!

      输入输出尺寸的宽应保持16字节对齐。

  3. Equisold(cylinder)

    • 功能描述

      此转换提供等实体(全景panoramic)校正,并将结果显示为平面上的投影。

      alt text

    • 成员说明

      成员含义
      int32_t pandefault 0, 不修改
      int32_t tiltdefault 0, 不修改
      zoom按提供的因子缩放转换输出
      strength转换的强度
      double angle(rotation)图像旋转的角度 0/90/180/270

      strength 调试效果,转换的强度(0,+∞)。如下所示:

      alt text

      rotation 调试效果,取值范围(-180,+180)。如下所示

      alt text

      注意!

      输入输出尺寸的宽应保持16字节对齐。

  4. Equidistant

    • 功能描述

      等距变换包含许多参数,这些参数允许它为投影提供一系列不同的目标平面。这使用户可以更自由地选择要变换的鱼眼帧的所需区域。

      alt text

    • 成员说明

      成员含义
      int32_t pandefault 0, 不修改
      int32_t tiltdefault 0, 不修改
      zoom按提供的因子缩放转换输出
      double angle(rotation)图像旋转的角度 0/90/180/270
      double elevation定义了投影轴的仰角,范围0到90
      double azimuth定义了投影轴的方位角度。如果仰角参数elevation为0,则方位角将没有可见效果
      int32_t keep_ratio转当“保持比率”参数打开时,FOV高度参数将被忽略,其值将自动计算,以在水平和垂直方向上保持相同的拉伸强度
      double FOV_h描述水平维度中输出视图字段的大小(以度为单位)。有效值的范围是从0到180
      double FOV_w描述垂直维度中输出视图字段的大小(以度为单位)。有效值的范围是从0到180
      double cylindricity_y描述目标投影沿Y轴的球面度。此值从0到1,其中1是球形的。如果此值设置为1,而“圆柱度X”值设置为0,则投影将沿Y轴形成圆柱体
      double cylindricity_x描述目标投影沿X轴的球面度。此值从0到1,其中1是球形的。如果此值设置为1,并且“圆柱度Y”值设置为0,则投影将沿X轴形成圆柱体

      elevation 调试效果:

      alt text

      azimuth 调试效果:

      alt text

      rotation 调试效果:

      alt text

      cylindricity x调试效果:

      描述目标投影沿X轴的球形程度。该值的范围为0到1,其中1为球形。如果该值设置为1,圆柱度Y值设置为0,则投影将沿X轴形成圆柱。如下所示:

      alt text

      cylindricity y调试效果:

      描述目标投影沿Y轴的球形程度。该值的范围为0到1,其中1为球形。如果该值设置为1,圆柱度X值设置为0,则投影将沿Y轴形成一个圆柱体。如下所示:

      alt text

      注意!

      输入输出尺寸的宽应保持16字节对齐。 正常的视力值大约是90度。对于圆柱度(见下文)等于“0”的变换,视场宽度和高度180的值将导致图像无限拉伸。 如果cylindricity_x和cylindricity_y圆柱度值都设置为1,则投影将是球形的。如果两者都是0,则变换将是矩形的。

  5. Custom

    • 功能描述

      采用custom变换后,输入图像中的每个多边形都会变换为正方形。换句话说,任何形状的任何四个邻近输入点在转换后都是正方形,如下图所示。但是,多边形的形状和位置在变换后会发生变化。

      alt text

      它们用于创建任何提供的转换都无法描述的转换。为了纠正任意失真,必须向GDC工具提供一个特殊的校准文件config0.txt。如下图

      alt text

    • 成员说明

      成员含义
      int32_t pandefault 0, 不修改
      int32_t tiltdefault 0, 不修改
      zoom按提供的因子缩放转换输出
      char custom_file[128]config.txt文件名称
      custom_tranformation_t custom解析的自定义转换结构

      Config file的规则大致需要注意一下几点:

      1. 第一行是在像素计算中使能full tile, 1是enable, 0是disable。

      2. 第二行是如果使能了full file,则要跳过的像素数量;这些值需要大于 0,数字越小,libgdc 的性能越慢(性能越慢是指config.bin的大小更大, libgdc生成config.bin的时间更长)。

      3. 第三行是垂直方向和水平方向标定点的个数, 第一个值Y = 1081指的是垂直方向有1081个标定点,第二个值X = 1921指的水平是方向有1921个标定点。

      4. 第四行是选中区域的中心点,通常是(Y-1)/2、(X-1)/2。

      5. 标定点必须是大于等于0的int或float类型、相邻两行的标定点不能重复。 eg.下图是截取的其中的一部分数据图片,第五行到第九行就是标定点在源图的坐标值,格式是Y: X。以下图为例,一共有1081x1921个标定点。

        alt text

      6. 由于标定点必须是等距离的,这意味着输出图片的分辨率取决于标定点的点数。

        alt text

        eg. 输出图片的Width = 100, Height计算为340,计算过程如下:100/height = (96-1)/(324-1)
        下图是更简单的3x3坐标点转换的示例图

        alt text

  6. Keystone+dewarping

    • 功能描述

      alt text

    • 成员说明

      成员含义
      int32_t pandefault 0, 不修改
      int32_t tiltdefault 0, 不修改
      zoom按提供的因子缩放转换输出
      double angle(rotation)图像旋转的角度 0/90/180/270
      double elevation定义了投影轴的仰角,范围0到90
      double azimuth定义了投影轴的方位角度。如果仰角参数elevation为0,则方位角将没有可见效果
      int32_t keep_ratio当“保持比率”参数打开时,FOV高度参数将被忽略,其值将自动计算,以在水平和垂直方向上保持相同的拉伸强度
      double FOV_h描述水平维度中输出视图字段的大小(以度为单位)。有效值的范围是从0到180
      double FOV_w描述垂直维度中输出视图字段的大小(以度为单位)。有效值的范围是从0到180
      double cylindricity_y描述目标投影沿Y轴的球面度。此值从0到1,其中1是球形的。如果此值设置为1,而“圆柱度X”值设置为0,则投影将沿Y轴形成圆柱体
      double cylindricity_x描述目标投影沿X轴的球面度。此值从0到1,其中1是球形的。如果此值设置为1,并且“圆柱度Y”值设置为0,则投影将沿X轴形成圆柱体
      double trapezoid_left_angle默认90;0.1到90 ;变换网格中,左边边界相对于底边边界的角度,见实际效果
      double trapezoid_right_angle默认90;0.1到90 ;变换网格中,右边边边界相对于底边边界的角度,见实际效果
      注意!

      输入输出尺寸的宽应保持16字节对齐。

GDC Tool变换模式参数说明

配置文件可由GDC tool 生成,以layout.json存在。不同的变换模式有不同的参数,以custom模式和keystone+dewarping模式为例,说明配置参数。

  1. keystone+dewarping模式

    {
    "inputRes": [
    1920, // 输入图像尺寸的宽
    1080 // 输入图像尺寸的高
    ],
    "param": {
    "fov": 180, // 输入图像的视场角
    "diameter": 1080, // 输入图像的直径,可控制变换网格的整体大小
    "offsetX": 0, // 变换网格在水平方向的偏移
    "offsetY": 0 // 变换网格在垂直方向的偏移
    },
    "outputRes": [
    1920, // 输出图像尺寸的宽
    1080 // 输出图像尺寸的高
    ],
    "transformations": [
    {
    "transformation": "Dewarp_keystone", // 变换模式
    "position": [ // 输出图像的ROI区域设定
    0, // 输出图像的ROI水平方向的偏移
    0, // 输出图像的ROI垂直方向的偏移
    1920, // 输出图像的ROI的宽
    1080 // 输出图像的ROI的高
    ],
    "param": {
    "left_base_angle": 90, // 默认90;0.1到90;变换网格中,左边边界相对于底边边界的角度
    "right_base_angle": 90, // 默认90;0.1到90;变换网格中,右边边界相对于底边边界的角度
    "azimuth": 90, // 定义了投影轴的方位角度。如果仰角参数elevation为0,则方位角将没有可见效果
    "elevation": 0, // 定义了投影轴的仰角,范围0到90
    "rotation": 0, // 输出图像要旋转的角度
    "fovWidth": 90, // 描述水平维度中输出视图字段的大小(以度为单位)。 数值越大,变换网格水平方向越宽,有效值的范围是从0到180
    "fovHeight": 90, // 描述垂直维度中输出视图字段的大小(以度为单位)。数值越大,变换网格垂直方向越宽,有效值的范围是从0到180
    "keepRatio": 0, // 当“保持比率”参数为1时候,fovHeight参数将被忽略,其值将自动计算,以在水平和垂直方向上保持相同的拉伸强度
    "cylindricityX": 1, // 描述目标投影沿X轴的球面度。此值从0到1,其中1是球形的。如果此值设置为1,并且“圆柱度Y”值设置为0,则投影将沿X轴形成圆柱体。
    "cylindricityY": 1 // 描述目标投影沿X轴的球面度。此值从0到1,其中1是球形的。如果此值设置为1,并且“圆柱度Y”值设置为0,则投影将沿X轴形成圆柱体。
    },
    "ptz": [
    0, // pan参数
    0, // tile参数
    1 // zoom参数
    ],
    "roi": { // 输入图像ROI区域设定
    "x": 0, // 输入图像ROI区域的水平方向偏移
    "y": 0, // 输入图像ROI区域的垂直方向偏移
    "w": 1920, // 输入图像ROI区域的宽
    "h": 1080 // 输入图像ROI区域的高
    }
    }
    ],
    "mode": "planar420", // 处理的格式设定
    "eccMode": "eccDisabled", // 处理的ecc模式
    "colourspace": "yuv" // 处理的数据格式
    }
  2. custom模式

    {
    "inputRes": [
    1280, // 输入图像尺寸的宽
    720 // 输入图像尺寸的高
    ],
    "param": {
    "fov": 192, // 输入图像的视场角
    "diameter": 720, // 输入图像的直径,可控制变换网格的整体大小
    "offsetX": 0, // 变换网格在水平方向的偏移
    "offsetY": 0 // 变换网格在垂直方向的偏移
    },
    "outputRes": [
    560, // 输出图像尺寸的宽
    258 // 输出图像尺寸的高
    ],
    "transformations": [
    {
    "transformation": "Custom", // 变换模式
    "position": [ // 输出图像的ROI区域设定
    0, // 输出图像的ROI水平方向的偏移
    0, // 输出图像的ROI垂直方向的偏移
    560, // 输出图像的ROI的宽,小于等于outputRes的宽
    258 // 输出图像的ROI的高,小于等于outputRes的高
    ],
    "ptz": [
    0, // pan参数
    0, // tile参数
    1 // zoom参数
    ],
    "roi": { // custom模式下无效
    "x": 0, // custom模式下无效
    "y": 0, // custom模式下无效
    "w": 0, // custom模式下无效
    "h": 0 // custom模式下无效
    },

    "param": {
    "customTransformation": "/path_to/camera_0_gdc.txt" // 坐标点文件的在板子中的路径
    }
    }
    ],
    "mode": "planar420", // 处理的格式设定
    "eccMode": "eccDisabled", // 处理的ecc模式
    "colourspace": "yuv" // 处理的数据格式
    }
    注意!
    1. ecc mode统一填写ecc is disable。可选ecc mode使能,但没有实际效果。
    2. 当参数为小数时,保证精度为浮点运算以后8位小数及以上,否则可能生成的bin不一致。
    3. 用户填充数据结构或者json时填充的信息应该包含各种模式示例所有项。
    4. 非custom模式,配置文件中的roi参数代表输入图片的roi。
    5. 配置文件中的position参数代表输出图片的roi。
  3. Affine 配置文件内容如下:

    {
    "inputRes": [
    1920,
    1080
    ],
    "param": {
    "fov": 160,
    "diameter": 1080,
    "offsetX": 0,
    "offsetY": 0
    },
    "outputRes": [
    1920,
    1080
    ],
    "transformations": [
    {
    "transformation": "Affine",
    "position": [
    0,
    0,
    1920,
    1080
    ],
    "param": {
    "rotation": 0
    },
    "ptz": [
    0,
    0,
    1
    ],
    "roi": {
    "x": 0,
    "y": 0,
    "w": 1920,
    "h": 1080
    }
    }
    ],
    "mode": "planar420",
    "eccMode": "eccDisabled",
    "colourspace": "yuv"
    }

    输入图片加变换网格如下

    alt text

    输出图片如下

    alt text

  4. Equisolid 配置文件内容如下:

    {
    "inputRes": [
    1920,
    1080
    ],
    "param": {
    "fov": 160,
    "diameter": 1080,
    "offsetX": 0,
    "offsetY": 0
    },
    "outputRes": [
    1920,
    1080
    ],
    "transformations": [
    {
    "transformation": "Panoramic",
    "position": [
    0,
    0,
    1920,
    1080
    ],
    "param": {
    "strength": 1,
    "strengthY": 1,
    "rotation": 0
    },
    "ptz": [
    0,
    0,
    1
    ],
    "roi": {
    "x": 0,
    "y": 0,
    "w": 1920,
    "h": 1080
    }
    }
    ],
    "mode": "planar420",
    "eccMode": "eccDisabled",
    "colourspace": "yuv"
    }

    输入图片加变换网格如下

    alt text

    输出图片如下

    alt text

  5. Equisolid(cylinder) 配置文件内容如下:

    {
    "inputRes": [
    1920,
    1080
    ],
    "param": {
    "fov": 160,
    "diameter": 1080,
    "offsetX": 0,
    "offsetY": 0
    },
    "outputRes": [
    1920,
    1080
    ],
    "transformations": [
    {
    "transformation": "Stereographic",
    "position": [
    0,
    0,
    1920,
    1080
    ],
    "param": {
    "strength": 1,
    "rotation": 0
    },
    "ptz": [
    0,
    0,
    1
    ],
    "roi": {
    "x": 0,
    "y": 0,
    "w": 1920,
    "h": 1080
    }
    }
    ],
    "mode": "planar420",
    "eccMode": "eccDisabled",
    "colourspace": "yuv"
    }

    输入图片加变换网格如下

    alt text

    输出图片如下

    alt text

  6. Equidistant 配置文件内容如下:

    {
    "inputRes": [
    1920,
    1080
    ],
    "param": {
    "fov": 160,
    "diameter": 1080,
    "offsetX": 0,
    "offsetY": 0
    },
    "outputRes": [
    1920,
    1080
    ],
    "transformations": [
    {
    "transformation": "Universal",
    "position": [
    0,
    0,
    1920,
    1080
    ],
    "param": {
    "azimuth": 0,
    "elevation": 0,
    "rotation": 0,
    "fovWidth": 90,
    "fovHeight": 90,
    "keepRatio": 0,
    "cylindricityX": 1,
    "cylindricityY": 1
    },
    "ptz": [
    0,
    0,
    1
    ],
    "roi": {
    "x": 0,
    "y": 0,
    "w": 1920,
    "h": 1080
    }
    }
    ],
    "mode": "planar420",
    "eccMode": "eccDisabled",
    "colourspace": "yuv"
    }

    输入图片加变换网格如下

    alt text

    输出图片如下

    alt text

  7. Custom 输入1280x720,输出560x258。配置文件内容如下:

    {
    "inputRes": [
    1280,
    720
    ],
    "param": {
    "fov": 192,
    "diameter": 720,
    "offsetX": 0,
    "offsetY": 0
    },
    "outputRes": [
    560,
    258
    ],
    "transformations": [
    {
    "transformation": "Custom",
    "position": [
    0,
    0,
    560,
    258
    ],
    "ptz": [
    0,
    0,
    1
    ],
    "roi": {
    "x": 0,
    "y": 0,
    "w": 0,
    "h": 0
    },
    "param": {
    "customTransformation": "/path_to/camera_0_gdc_config_3.1.txt"
    }
    }
    ],
    "mode": "semiplanar420",
    "eccMode": "eccDisabled",
    "colourspace": "yuv"
    }

    输入图片加变换网格如下

    alt text

    输出图片如下

    alt text

  8. Keystone+dewarping 配置文件内容如下:

    {
    "inputRes": [
    1920,
    1080
    ],
    "param": {
    "fov": 180,
    "diameter": 1080,
    "offsetX": 0,
    "offsetY": 0
    },
    "outputRes": [
    1920,
    1080
    ],
    "transformations": [
    {
    "transformation": "Dewarp_keystone",
    "position": [
    0,
    0,
    1920,
    1080
    ],
    "param": {
    "left_base_angle": 90,
    "right_base_angle": 90,
    "azimuth": 0,
    "elevation": 0,
    "rotation": 0,
    "fovWidth": 90,
    "fovHeight": 90,
    "keepRatio": 0,
    "cylindricityX": 1,
    "cylindricityY": 1
    },
    "ptz": [
    0,
    0,
    1
    ],
    "roi": {
    "x": 0,
    "y": 0,
    "w": 1920,
    "h": 1080
    }
    }
    ],
    "mode": "planar420",
    "eccMode": "eccDisabled",
    "colourspace": "yuv"
    }

    输入图片加变换网格如下

    alt text

    输出图片如下

    alt text

GDC bin 相关API参考

以下API用于GDC BIN生成,GDC模块控制API见HBN API。

  1. hb_vio_gen_gdc_cfg

    【函数声明】

    int32_t hb_vio_gen_gdc_cfg(param_t *gdc_parm, window_t *wnds, uint32_t wnd_num, void **cfg_buf, uint64_t *cfg_size)

    【参数描述】

    • [IN] param_t *gdc_parm:gdc对应参数,包括分辨率,格式等。
    • [IN] window_t *wnds:gdc内部区域参数。
    • [IN] uint32_t wnd_num: window 数目。
    • [OUT] uint32_t **cfg_buf:生成的gdc cfg bin,内部分配。
    • [OUT] uint64_t *cfg_size:gdc cfg bin文件的大小。

    【返回值】

    • 成功:E_OK: Success
    • 失败:E_NOT_OK: Fail,return error code;失败,返回错误码;range:[-10000,-1]

    【功能描述】

    生成gdc模块工作所需的bin文件。

  2. hb_vio_set_gdc_cfg

    【函数声明】

    int32_t hb_vio_set_gdc_cfg(uint32_t pipeline_id, uint32_t *cfg_buf, uint64_t cfg_size)

    【参数描述】

    • [IN] uint32_t pipeline_id:pipeline id ; 软件通道id;range:[0, 23],default:0;
    • [IN] cfg_buf:config buffer of gdc cfg bin; gdc cfg bin 的buffer
    • [IN] cfg_size:size of gdc cfg bin ; gdc cfg bin文件的大小

    【返回值】

    • 成功:E_OK: Success;成功
    • 失败:E_NOT_OK: Fail,return error code;失败,返回错误码;range:[-10000,-1]

    【功能描述】

    设置gdc模块的cfg bin。

  3. hbn_free_gdc_bin

    【函数声明】

    void hb_vio_free_gdc_cfg(uint32_t *cfg_buf)

    【参数描述】

    • [IN] uint32_t* cfg_buf:Buffer of gdc cfg bin; gdc cfg bin的buffer.

    【返回值】

    • NONE

    【功能描述】

    释放生产gdc模块cfg bin的buffer

GDC bin 相关参数说明
  1. typedef struct param_t

    名称类型最小值最大值默认值含义必选
    formatframe_format_t处理图像格式
    inreso lution_t实际输入图像尺寸
    outreso lution_t实际输出图像尺寸
    x_offsetint32_t00输入区域沿 x轴的偏移像素数
    y_offsetint32_t00输入区域沿 y轴的偏移像素数
    diameterint32_t定义矩形输入图 像上包含实际鱼眼 照片的输入圆形区 域的像素直径。对 于某些相机,此圆 形图像区域的直径 可以大于或小于矩 形画布的尺寸(有 时可能会被裁剪)一般情况下 diameter 应保持与 input.height 一致。
    fovdouble0视场定 义输入图像的可视 角度,影响源网格 的曲率。视场越大 ,透视变形越大。
  2. typedef enum frame_format frame_format_t

    名称类型最小值最大值默认值含义必选
    FM T_UNKNOWNenum未知格式
    FMT_LUMINANCEenum暂不支持
    FMT_P LANAR_444enum暂不支持
    FMT_P LANAR_420enum暂不支持
    FMT_SEMIP LANAR_420enumNV12
    FM T_GDC_MAXenum
  3. typedef struct resolution_s resolution_t

    名称类型最小值最大值默认值含义必选
    wuint32_t宽度(像素)
    huint32_t高度(像素)
  4. typedef struct window_t

    名称类型最小值最大值默认值含义必选
    out_rrect_t输出数据大小信息
    transformtransformation_t060使用的转换模式
    input_roi_rrect_troi区域
    panint32_t以输出图像为中心的水平方向目标位移(像素单位)
    tiltint32_t以输出图像为中心的垂直方向目标位移(像素单位)
    zoomdouble目标缩放系数
    strengthXdoublex方向变换的非负变换强度参数
    strengthYdoubley方向变换的非负变换强度参数
    angledouble主投影轴绕自身旋转的角度
    elevationdouble指定主投影轴的角度
    azimuthdouble指定主投影轴的角度,从北方向顺时针计数
    keep_ratioint32_t在水平方向和垂直方向保持相同的拉伸强度
    FOV_hdouble输出视场的垂直尺寸以度数表示
    FOV_wdouble输出视场的水平尺寸以度数表示
    cylindricity_ydouble目标在垂直方向上的投影形状的圆柱度水平
    cylindricity_xdouble目标在水平方向上的投影形状的圆柱度水平
    custom_file[128]charcustom模式下的自定义转换描述文件
    customcustom_tranformation_t自定义模式下的转换信息
    trapezoid_left_angledouble梯形底与斜边之间的左锐角
    trapezoid_right_angledouble梯形底与斜边之间的右锐角
    check_computeuint8_t暂时无用
  5. typedef struct rect_s rect_t

    名称类型最小值最大值默认值含义必选
    xint32_t起始点x坐标
    yint32_t起始点y坐标
    wint32_t宽度
    hint32_t高度
  6. typedef enum gdc_transformation transformation_t

    名称类型最小值最大值默认值含 义必选
    PANORAMICenum全景变 换
    CYLINDRICALenumNA
    STEREOGRAPHICenum畸变校正与全景变换相同,但输出图像是圆柱全景图,而不是平 面图
    UNIVERSALenumEquidistant 等距变 换
    CUSTOMenum用户定制的变换,可定制用于变换的网 格
    AFFINEenum线性变 换
    DEWARP_KEYSTONEenum相对于等距变换,可选择非等距。等距变换 Equidistant 是其 一种特殊情况
  7. typedef struct point_s point_t

    名称类型最小值最大值默认值含义必选
    xdoublex 坐标
    ydoubley 坐标
  8. typedef struct custom_tranformation_s custom_tranformation_t

    名称类型最小值最大值默认值含义必选
    full_tile_calcuint8_t是否开启分块计算;如果使能 fulltile,libgdcbin 会额外分块做 min/max 计算,tile 越多,精度越高,效果越好,但生成 bin 的时间也越长
    tile_incr_xuint16_ttile increase in x
    tile_incr_yuint16_ttile increase in y
    wint32_t自定义转换网格中水平方向上的数字或点
    hint32_t自定义转换网格中垂直方向上的数字或点
    centerxdouble沿 x 轴的中心,通常是水平方向坐标点数的一半
    centerydouble沿 y 轴的中心,通常是垂直方向坐标点数的一半
    *pointspoint_tconfig.txt 中定义的转换点序列,数量 = w * h

STITCH

简介

stitch是一个可配置的图像拼接计算单元,可以完成多幅图像之间的融合拼接,主要应用于自动泊车场景下的360度环视图像拼接。stitch基于ROI进行计算,每个ROI可以完成两幅源图像的alpha-beta blending融合, 并将其写入目标图像指定的ROI中,这种融合拼接方式可以使得拼接过渡更加自然,同时stitch还支持Y、U、V各通道的增益调节,可以实现源图像间的亮度、色度均衡,进一步提升拼接效果。此外stitch支持用户输入自定义像素级alpha-beta权重值,基此可实现多种融合效果,如背景虚化、图像水印等。

硬件工作模式

  • Online blnding: 无需输入LUT表,硬件自动进行融合拼接,要求ROI w=h;该模式下硬件依据配置参数中的过渡带宽度、方向等,自动计算出每个像素点的alpha、beta权重值。
  • Alpha blending: 需要输入alpha LUT表,硬件读取DDR中的alpha权重值进行加权融合; 其中alpha LUT表中存储着该ROI中每个像素点的alpha权重值。对于每个像素点硬件会分别读取y、uv、alpha的值进行加权融合。
  • Alpha-beta blending: 需要输入alpha、beta LUT表,硬件读取DDR中的alpha、beta权重值进行加权融合。
  • Src copy: 不需要输入LUT表,硬件直接拷贝src0。
  • Src alpha copy: 需要alpha LUT表,硬件读取DDR中的alpha权重值并进行融合src0。 其中,LUT表指的是融合拼接权重参数buf

硬件拼接示意图

通过使用图片上的两个源ROI进行不同blend mode的拼接,最终输出对应的ROI结果

拼接方案介绍

硬件拼接功能可以完成将多张图片拼接融合生成一张图片。硬件上设计灵活,以ROI为基本处理单位,基于alpha blend算法,使用不同的配置字参数划分出不同的ROI划分区域灵活的配置生成多种不同的拼接方案,并且运用LUT表处理拼接的过渡区域优化效果,在自动驾驶以及ADAS的APA场景下,可以将四路摄像头已经被畸变矫正过后的IPM图像数据拼接成一路360环视图,用于停车位的检测,方便用户查看车位线周边情况进行停车。

典型场景 在APA场景,四路环视泊车,GDC从DDR中获取4张回灌图片和参考点(CFG BIN)通过畸变矫正输出4张IPM图,然后通过STITCH硬件拼接模块使用预先定义好的配置字拼接方案参数(CPG PARAM)进行硬件拼接输出鸟瞰图。

摆放位置

  1. 四张IPM图通过copy模式放到指定输出地址的指定位置
  2. 没有重合的区域可以使用直接拷贝模式
  3. ROI重合区域使用Alpha Blend模式进行融合拼接

LUT表

LUT表存放的是alpha/beta融合参数系数,类似权重值,每个ROI都要生成对应像素点的融合参数系数,范围0-255,依次存放进LUT表的内存中, 当ROI的拼接模式使用alpha和beta融合时候,会使用该参数进行融合。

比如 坐标点参数举例章节中的LUT生成: ROI-0/1: 256512 ROI-2/3: 560256 ROI-4/5:256218 ROI-6/7:256186 LUT:ROI-0 + ROI-1 + ROI-2 + ROI-3 + ROI-4 + ROI-5 + ROI-6 + ROI-7 目前LUT表可以通过convert_tool工具生成。

坐标点参数举例

硬件拼接的ROI的划分与相机的安装位置有直接关系,目前可以通过convert-tool工具生成,下图为各ROI划分区域坐标点显示示例。

ROI范围SRC0起点大小SRC1起点大小目标起点模式
0左视全图左视(frame0)(0,0)-256,512///(0,40)直接拷贝
1右视全图右视(frame2)(0,0)-256,512///(304,40)直接拷贝
2后视全图后视(frame3)(0,0)-560,256///(0,366)直接拷贝
3前视全图前视(frame1)(0,0)-560,256///(0,0)直接拷贝
4左视与前视重合左视(frame0)(0,0)-256,218前视(frame1)(0,40)-256,218(0,40)AlphaBlend
5右视与前视重合右视(frame2)(0,0)-256,218前视(frame1)(304,40)-256,218(304,40)AlphaBlend
6左视与后视重合左视(frame0)(0,366)-256,186后视(frame3)(0,0)-256,186(0,366)AlphaBlend
7右视与后视重合右视(frame2)(0,366)-256,186后视(frame3)(304,0)-256,218-304,366AlphaBlend

数据流和性能指标

RDK-S100 接入camera 后,进入后级模块处理,其数据流通路如下图所示:

  • MIPI RX: 3路 CDPHY,每路为 DPHY 最大 4.5Gbps/lane x 4lane 或 CPHY 最大 3.5Gbps/trio x 3trio,每路支持4VC,理论最多支持 12 路接入 。
RDK-S100 软件预计最大支持 6路 camera,RX4 通过 serdes 最多可接入 4 路 camera,RX0 和 RX1 各接入 1路 camera,如果不是这种常规接法,请联系 FAE 进行确认。
  • CIM: RX 接入,可 online 输出到 ISP0/ISP1(RAW) 与 PYM0/PYM1(YUV),也可 offline 下 DDR,之后各模块通过 DDR 读取使用数据流。

  • ISP: 2 个 ISP 设备,各支持 4 路 online + 8 路 offline 输入,每个 ISP 最大支持 2x4K@60fps 处理。

  • PYM: 3 个 PYM 设备,其中 PYM0/PYM1 为全功能模块支持 online/offline,PYM4 只支持 offline,4K@60fps处理。

  • GDC: 1 个 GDC 设备,只支持 offline 方式,4K@60fps 处理。

CIMISP0 / ISP1PYM0 / PYM1PYM4GDCYNRSTITCH
1080P处理每帧耗时3.7151 ms1.8616 ms2.2373 ms2.7616 ms3.7447 ms1.7774 ms1.5739 ms
4k处理每帧耗时14.8606 ms7.4467 ms7.1356 ms10.7018 ms15.0624 ms7.1096 ms5.7349 ms

已点亮sensor

类型sensor name备注
MIPI sensorIMX219raw10 1080p
GMSL sensor0820cyuv 4k & 1080p
OVX3Craw12 1280P
OVX8Braw12 4K

Camera API

注意,本章节是基于 HBN 架构进行描述和列举内容,非 V4L2 架构。

模块描述

RDK-S100 HBN Camera 包含三个组件:Camera sensor、解串器(Deserial)、串行器(Serializer)。串行器是对 mipi tx 的封装。 每个组件都有 attach、detach 接口和 vin 绑定或解绑。如 camera 和 vin 绑定,就是确定 camera 使用 SoC 上的哪个 mipi rx、i2c controller 然后初始化 sensor 的过程。

API参考

  1. hbn_camera_create

【函数声明】

int32_t hbn_camera_create(camera_config_t *cam_config, camera_handle_t *cam_fd)

【参数描述】

[IN] camera_config_t *cam_config:要配置的camera对应的参数结构体指针;

[OUT] camera_handle_t *cam_fd:根据配置参数返回的fd,作为camera的操作handle;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

根据camera_config_t传入的配置创建camera handle。

【注意事项】

API里面会对sensor lib 进行检查,如果sensor 驱动代码不符合 HBN 框架规范,则会检查报错。

API里面会对cam_config 进行检查,如果配置不符合IP 硬件能力,则会检查报错。

  1. hbn_camera_destroy

【函数声明】

int32_t hbn_camera_destroy(camera_handle_t cam_fd)

【参数描述】

[IN] camera_handle_t cam_fd:camera的操作handle,由hbn_camera_create所创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

根据camera handle销毁对应的软件资源。

【注意事项】

hbn_camera_destroy 需要和hbn_camera_create 成对使用。

hbn_camera_destroy 会释放sensor lib, 执行完成后,sensor 将无法正常访问。

hbn_camera_destroy 内部会调用hbn_camera_detach_from_vin,会触发sensor停流操作,所以hbn_camera_destroy需要在hbn_vflow_destroy之前调用。

  1. hbn_camera_attach_to_vin

【函数声明】

int32_t hbn_camera_attach_to_vin(camera_handle_t cam_fd, vpf_handle_t vin_fd)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

[IN] vpf_handle_t vin_fd:由hbn_vnode_open接口创建的vin node handle。

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

通过camera和vin node的handle,将两者在vpf框架中绑定,并对camera的硬件初始化。

【注意事项】

同一个camera,不能重复执行hbn_camera_attach_to_vin,否则会报attach error错误。

  1. hbn_camera_detach_from_vin

【函数声明】

int32_t hbn_camera_detach_from_vin(camera_handle_t cam_fd)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

将camera与vin node解绑,并做去初始化操作。

【注意事项】

hbn_camera_detach_from_vin需要和hbn_camera_attach_to_vin成对使用。

hbn_camera_destroy内部调用了hbn_camera_detach_from_vin,所以调用了hbn_camera_destroy接口,hbn_camera_detach_from_vin可以不再调用。

  1. hbn_camera_attach_to_deserial

【函数声明】

int32_t hbn_camera_attach_to_deserial(camera_handle_t cam_fd, deserial_handle_t des_fd, camera_des_link_t link)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

[IN] deserial_handle_t des_fd:deserial handle,由hbn_deserial_create创建;

[IN] camera_des_link_t link:camera与deserial的link方式,根据camera接到哪个link决定。

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

通过camera和deserial的handle,将两者绑定,并对deserial和camera硬件初始化。

【注意事项】

硬件上有解串器时才需要调用该接口。

执行hbn_camera_attach_to_deserial后,就不需要再执行hbn_camera_attach_to_vin,而是由deserial绑定到vin node。

  1. hbn_camera_detach_from_deserial

【函数声明】

int32_t hbn_camera_detach_from_deserial(camera_handle_t cam_fd)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

将camera与deserial解绑,并做去初始化操作。

【注意事项】

hbn_camera_detach_from_deserial需要和hbn_camera_attach_to_deserial成对使用。

调用该api前需要先调用 hbn_deserial_detach_from_vin

  1. hbn_camera_start

【函数声明】

int32_t hbn_camera_start(camera_handle_t cam_fd)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

配置camera寄存器,开始出流。

【注意事项】

camera handle attach 到 vflow 后,该接口可以不调用。如果要调用必须先调用hbn_vflow_start,再调用hbn_camera_start。

  1. hbn_camera_stop

【函数声明】

int32_t hbn_camera_stop(camera_handle_t cam_fd)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

camera关流。

【注意事项】

需要和hbn_camera_start成对使用。

  1. hbn_camera_reset

【函数声明】

int32_t hbn_camera_reset(camera_handle_t cam_fd)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

通过重新初始化sensor来做reset。

【注意事项】

如果在camera attach vin之前调用该接口,则会通过camera_attach_to_vin接口来给sensor初始化,达到reset效果。如果是在camera attach vin之后调用该接口,则会调用sensor stop,sensor deinit,然后初始化再重新init sensor,start sensor。

  1. hbn_camera_change_fps

【函数声明】

int32_t hbn_camera_change_fps(camera_handle_t cam_fd, int32_t fps)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

[IN] int32_t fps:sensor出图帧率;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

动态切换sensor帧率。

【注意事项】

该功能需要在sensor lib库中实现相应的回调函数 dynamic_switch_fps。

  1. hbn_camera_read_register

【函数声明】

int32_t hbn_camera_read_register(camera_handle_t cam_fd, camera_reg_type_t type, uint32_t reg_addr)

【参数描述】

[IN] camera_handle_t cam_fd:camera handle,由hbn_camera_create创建;

[IN] camera_reg_type_t type:读取sensor寄存器的类型;

[IN] uint32_t reg_addr:寄存器地址;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

读取camera寄存器的值。

【注意事项】

  1. hbn_camera_get_handle

【函数声明】

camera_handle_t hbn_camera_get_handle(vpf_handle_t vin_fd, int32_t camera_index)

【参数描述】

[IN] vpf_handle_t vin_fd:vin node的fd;

[IN] int32_t camera_index:camera的port index;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

通过vin node handle或者camera port index,获取对应的camera handle。

【注意事项】

  1. hbn_camera_init_cfg

【函数声明】

int32_t hbn_camera_init_cfg(const char *cfg_file)

【参数描述】

[IN] const char *cfg_file:camera配置文件路径(json);

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

通过传入的配置,创建camera handle和deserial handle并绑定。

【注意事项】

该API是通过解析json方式来创建camera,与sample中非json方式接口不同,详情请咨询FAE。

  1. hbn_deserial_create

【函数声明】

int32_t hbn_deserial_create(deserial_config_t *des_config, deserial_handle_t *des_fd)

【参数描述】

[IN] deserial_config_t *des_config:deserial配置参数结构体指针;

[OUT] deserial_handle_t *des_fd:根据配置创建的deserial handle;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

根据传入的配置,创建deserial handle。

【注意事项】

硬件上有解串器时才需要调用该接口。

该接口会对deserial的配置进行检查,如果配置超出一定范围,则会报错。

该接口会对deserial lib进行检查,如果不符合HBN架构规范,则会报错。

  1. hbn_deserial_destroy

【函数声明】

int32_t hbn_deserial_destroy(deserial_handle_t des_fd)

【参数描述】

[IN] deserial_handle_t des_fd:deserial handle,由hbn_deserial_create创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

根据deserial handle销毁对应的软件资源。

【注意事项】

hbn_deserial_destroy需要和hbn_deserial_create成对使用。

  1. hbn_deserial_attach_to_vin

【函数声明】

int32_t hbn_deserial_attach_to_vin(deserial_handle_t des_fd, camera_des_link_t link, vpf_handle_t vin_fd)

【参数描述】

[IN] deserial_handle_t des_fd:deserial handle,由hbn_deserial_create创建;

[IN] camera_des_link_t link:deserial的link编号;

[IN] vpf_handle_t vin_fd:要绑定到的vin node handle;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

将deserial与vin node绑定。

【注意事项】

硬件上带有解串器,则 camera与deserial进行绑定,deserial与vin node 绑定。

  1. hbn_deserial_detach_from_vin

【函数声明】

int32_t hbn_deserial_detach_from_vin(deserial_handle_t des_fd, camera_des_link_t link)

【参数描述】

[IN] deserial_handle_t des_fd:deserial handle,由hbn_deserial_create创建;

[IN] camera_des_link_t link:deserial的link编号;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

将deserial与vin node解绑。

【注意事项】

hbn_deserial_detach_from_vin与hbn_deserial_attach_to_vin需要成对使用。

  1. hbn_txser_create

【函数声明】

int32_t hbn_txser_create(txser_config_t *txs_config, txser_handle_t *txs_fd)

【参数描述】

[IN] txser_config_t *txs_config:tx serial配置参数结构体指针;

[OUT] txser_handle_t *txs_fd:根据配置创建的tx serial handle;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

根据传入的配置,创建串行器句柄 tx serial handle。

【注意事项】

硬件上有串行器时才需要调用该接口。

该接口会对txser的配置进行检查,如果配置超出一定范围,则会报错。

该接口会对txser lib进行检查,如果不符合HBN架构规范,则会报错。

  1. hbn_txser_destroy

【函数声明】

int32_t hbn_txser_destroy(txser_handle_t txs_fd)

【参数描述】

[IN] txser_handle_t txs_fd:tx serial handle,由hbn_txser_create创建;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

根据tx serial handle销毁对应的软件资源。

【注意事项】

硬件上有串行器时才需要调用该接口。

hbn_txser_destroy与hbn_txser_create需要成对使用。

  1. hbn_txser_attach_to_vin

【函数声明】

int32_t hbn_txser_attach_to_vin(txser_handle_t txs_fd, camera_txs_csi_t csi, vpf_handle_t vin_fd)

【参数描述】

[IN] txser_handle_t txs_fd:tx serialhandle,由hbn_txser_create创建;

[IN] camera_txs_csi_t csi:tx csi index;

[IN] vpf_handle_t vin_fd:要绑定到的vin node handle;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

将tx serial与vin node绑定。

【注意事项】

硬件上有串行器时才需要调用该接口。

该接口会对txser硬件进行初始化。

硬件上带有串行器,则camera与txser进行绑定,txser与vin node 绑定。

  1. hbn_txser_detach_from_vin

【函数声明】

int32_t hbn_txser_detach_from_vin(txser_handle_t txs_fd, camera_txs_csi_t csi)

【参数描述】

[IN] txser_handle_t txs_fd:tx serial handle,由hbn_txser_create创建;

[IN] camera_txs_csi_t csi:tx csi index;

【返回值】

成功:RET_OK 0

失败:异常为负值错误码

【功能描述】

将tx serial与vin node解绑。

【注意事项】

hbn_txser_detach_from_vin需要与hbn_txser_attach_to_vin成对使用。

参数说明

typedef struct camera_config_s

名称类型最小值最大值默认值含义必选
name[CAMERA_MODULE_NAME_LEN]char-CAMERA_MODULE_NAME_LEN(108)-camera 模组名称,需要和 sensor lib 名称对应,如:sensor 驱动名称为:libimx219.so,那么 name 为 imx219
addruint32_t0x000x7f0x00sensor 设备地址,一般是 i2c 7位地址
isp_addruint32_t0x000x7f0x00isp 设备地址(如有),默认无
eeprom_addruint32_t0x000x7f0x00eeprom 设备地址(如有),默认无
serial_addruint32_t0x000x7f0x00serdes 设备地址(如有),默认无
sensor_modeuint32_t151sensor 工作模式,可以使用 enum sensor_mode_e 枚举,定义如下:
1:NORMAL_M,linear 模式;
2:DOL2_M,hdr2帧合成1帧;
3:DOL3_M,hdr3帧合成1帧;
4:DOL4_M,hdr4帧合成1帧;
5:PWL_M,hdr 模式 sensor 内部合成
sensor_clkuint32_t--0x00sensor 一些 clk 时钟配置,目前未生效,备用
gpio_enableuint32_t00xFFFFFFFF0是否使用 X5 gpio 控制 camera sensor 的引脚,以满足 sensor 上下电的时序要求。
如:使用 gpio 来控制 sensor XSHUTDN 引脚。
注意:需要在 dts 中配置对应的 gpio number。
0:不使用 gpio 来控制;
非0:使用 gpio 来控制 sensor,按照 bit 来使能 gpio。比如: 0x07 则代表使能 [gpio_a, gpio_b, gpio_c] 3 个 gpio。
gpio_leveluint32_t010如果选择 gpio_enablet,则可以配置 gpio_level bit 来控制 sensor 引脚高低电平。某个 gpio bit 与 sensor 管脚高低电平关系如下:
0: 先输出低电平, sleep 1s,再输出高电平;
1: 先输出高电平,sleep 1s,再输出低电平。
比如:0x05 = 101,从 bit0 到 bit2 分别代表 gpio_a 先输出高电平,再输出低电平,gpio_b 先输出低电平,再输出高电平,gpio_c 先输出高电平,再输出低电平。
需要根据 sensor spec 上电时序来自定义。
bus_selectuint32_t060sensor i2c number 选择,一般硬件固定后,对应的 i2c 也是固定的,所以建议在 dts 中配置,这里可以省去。
dts 中绑定 sensor i2c,详情见:camera 点亮说明文档。
bus_timeoutuint32_t0-0I2C 的 timeout 时间配置。配置了 bus_select,才需要配置。
fpsuint32_t01200sensor 帧率配置。
widthuint32_t081920sensor 出图宽度(pixel)
heightuint32_t040960sensor 出图高度(pixel)
formatuint32_t---sensor 数据类型,常见的如下:
RAW8: 0x2A;
RAW10: 0x2B;
RAW12: 0x2C;
YUV422 8-bit: 0x1E
flagsuint32_t0-0可选功能:诊断,恢复,debug 等
extra_modeuint32_t0-0各 sensor 库内部定制配置: 多用于区分模组与功能开关
config_indexuint32_t0-0各 sensor 库内部定制配置: 多用于区分模组与功能开关
ts_compensateuint32_t0-0预留参数,备用
mipi_cfgmipi_config_t---MIPI 配置, 置为 NULL 自动从 sensor 驱动中获取配置(get_csi_attr)。
calib_lnamechar---sensor 效果库路径,默认路径为 /usr/hobot/lib/sensor
sensor_paramchar---sensor 自定义数据
iparam_modeuint32_t---预留参数,备用
end_flaguint32_t---结构体配置的结束标志,默认为 CAMERA_CONFIG_END_FLAG

typedef struct deserial_config_s

名称类型最小值最大值默认值含义必选
namechar[CAMERA_MODULE_NAME_LEN]---Deserial 的名称,例如 max9296。
addruint32_t0--Deserial 设备的地址。
gpio_enableuint32_t0--GPIO 操作使能位,索引自 VCON。
gpio_leveluint32_t0--GPIO 工作状态位,表示当前 GPIO 状态。
gpio_mfpuint8_t[CAMERA_DES_GPIO_MAX]0CAMERA_DES_GPIO_MAX0x0MFP 的 GPIO 功能选择,用于指定 GPIO 的多功能配置。
bus_selectuint32_t0--I2C 总线选择,索引自 VCON。
bus_timeoutuint32_t0--I2C 超时时间设置,单位为毫秒。
lane_modeuint32_t0--PHY 配置的 lane 模式选择。
lane_speeduint32_t0--PHY 配置的 lane 速率。
link_mapuint32_t0--Link 和 CSI/VC 的映射关系配置。
link_despchar[CAMERA_DES_LINKMAX][CAMERA_DES_PORTDESP_LEN]---各 Link 连接模组的配置描述,用于多进程使用。
reset_delayuint32_t0--Reset 操作的延迟时间,单位为毫秒。
flagsuint32_t0--可选功能标志,例如诊断、调试等。
poc_cfgpoc_config_t*--NULLPOC 配置指针,若为 NULL 则无 POC 功能。
mipi_cfgmipi_config_t*--NULLMIPI 配置指针,若为 NULL 则自动获取配置。
deserial_paramchar*--NULLDeserial 自定义数据指针。
end_flaguint32_t00xFFFFFFFF-结构体配置的结束标志,默认为 DESERIAL_CONFIG_END_FLAG

typedef struct poc_config_s

名称类型最小值最大值默认值含义必选
namechar[CAMERA_MODULE_NAME_LEN]---POC 的名称,例如 max20087。
addruint32_t0--POC 设备的地址。
gpio_enableuint32_t0--GPIO 操作使能位,索引自 VCON。
gpio_leveluint32_t0--GPIO 工作状态位,表示当前 GPIO 状态。
poc_mapuint32_t0--POC 与 Link 的映射关系。
power_delayuint32_t0--POC 开关操作的延迟时间,单位为毫秒。
end_flaguint32_t00xFFFFFFFF-结构体配置的结束标志,用于校验完整性,默认为 POC_CONFIG_END_FLAG

返回值说明

错误码宏定义描述常见原因及解决方法
0HBN_STATUS_SUCESS成功
1HBN_STATUS_INVALID_NODEvnode 无效,找不到对应的 vnode
2HBN_STATUS_INVALID_NODETYPEvnode 类型无效,找不到对应的 vnode对于 VIN,vnode 类型为 HB_VIN
3HBN_STATUS_INVALID_HWID无效的硬件模块 id对于 VIN,hw_id 取值为 0
4HBN_STATUS_INVALID_CTXID无效的 context id可设置为 AUTO_ALLOC_ID,由 HBN 框架自动分配
8HBN_STATUS_INVALID_NULL_PTR空指针
9HBN_STATUS_INVALID_PARAMETER无效的参数,版本检查失败
10HBN_STATUS_ILLEGAL_ATTR无效的参数
11HBN_STATUS_INVALID_FLOW无效的 flow,找不到对应的 flow
12HBN_STATUS_FLOW_EXISTflow 已经存在
13HBN_STATUS_FLOW_UNEXISTflow 不存在
14HBN_STATUS_NODE_EXISTnode 已经存在
15HBN_STATUS_NODE_UNEXISTnode 不存在
16HBN_STATUS_NOT_CONFIG预留
19HBN_STATUS_ALREADY_BINDEDnode 已经绑定
20HBN_STATUS_NOT_BINDEDnode 未绑定
21HBN_STATUS_TIMEOUT超时
22HBN_STATUS_NOT_INITIALIZED未初始化
23HBN_STATUS_NOT_SUPPORT通道不支持或未激活
24HBN_STATUS_NOT_PERM操作不允许
25HBN_STATUS_NOMEM内存不足
31HBN_STATUS_JSON_PARSE_FAILjson 解析失败
34HBN_STATUS_SET_CONTROL_FAIL模块控制、调节参数(如 ISP 效果参数)设置失败
35HBN_STATUS_GET_CONTROL_FAIL模块控制、调节参数(如 ISP 效果参数)获取失败
36HBN_STATUS_NODE_START_FAILnode 开启失败
37HBN_STATUS_NODE_STOP_FAILnode 停止失败
42HBN_STATUS_NODE_ILLEGAL_EVENTnode 通道 poll 时事件非法
43HBN_STATUS_NODE_DEQUE_ERRORnode 通道 dequeue buffer 错误
51HBN_STATUS_INVALID_VERSION底层驱动模块和上层库版本号不匹配错误
52HBN_STATUS_GET_VERSION_ERROR获取底层驱动模块版本号错误
128HBN_STATUS_ERR_UNKNOW未知错误

Camera 点亮

HBN API

描述

在软件上,Camera是单独一套API,Camera之后的模块用vnode来抽象,vnode抽象的模块包括VIN、ISP、PYM、GDC。 多个vnode组成一条vflow(类似于一条pipeline)。Camera和VIN通过attach接口绑定起来。 用户只需要调用HBN接口完成模块的初始化和绑定,vflow建立并启动后,用户无须关心数据帧的传递,SDK内部会将数据帧由上游传递到下游。

一个vflow由一个或多个vnode组成,一个vnode有一个输入通道,一个或多个输出通道。

接口调用示例:

API参考

  1. hbn_vnode_open

【函数声明】

hobot_status hbn_vnode_open(hb_vnode_type vnode_type, uint32_t hw_id, int32_t ctx_id, hbn_vnode_handle_t *vnode_fd)

【参数描述】

[IN] hb_vnode_type vnode_type:vnode类型,每个硬件模块对应一个vnode类型。取值为HB_VIN、HB_ISP、HB_PYM等;

[IN] uint32_t hw_id:模块的硬件id。

[IN] uint32_t ctx_id:模块的context id,软件上的概念,可指定context id值,也可设置为AUTO_ALLOC_ID,由SDK自动分配context id;

[OUT] hbn_vnode_handle_t *vnode_fd:返回模块的vnode handle;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明。

【功能描述】

初始化某个模块,打开该模块设备节点,返回该模块的vnode handle。

【注意事项】

  1. hbn_vnode_close

【函数声明】

void hbn_vnode_close(hbn_vnode_handle_t vnode_fd)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

【返回值】

【功能描述】

关闭模块的设备节点。

【注意事项】

调用了hbn_vflow_destroy就无须再调用hbn_vnode_close。

模块单独使用时(例如只是GDC回灌)可调用hbn_vnode_close,模块串在vflow中,调用hbn_vflow_destroy即可,无须调用hbn_vnode_close。

  1. hbn_vnode_set_attr

【函数声明】

hobot_status hbn_vnode_set_attr(hbn_vnode_handle_t vnode_fd, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] void *attr:模块的基本属性结构体指针。基本属性结构体可以是vin_attr_t、isp_attr_t、pym_attr_t等,以模块名+_attr_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

设置模块的基本属性。

【注意事项】

  1. hbn_vnode_get_attr

【函数声明】

hobot_status hbn_vnode_get_attr(hbn_vnode_handle_t vnode_fd, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[OUT] void *attr:模块的基本属性结构体指针。基本属性结构体可以是vin_attr_t、isp_attr_t、pym_attr_t等,以模块名+_attr_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

获取模块的基本属性。

【注意事项】

  1. hbn_vnode_set_attr_ex

【函数声明】

hobot_status hbn_vnode_set_attr_ex(hbn_vnode_handle_t vnode_fd, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] void *attr:模块的扩展属性结构体指针。扩展属性结构体可以是vin_attr_ex_t等,以模块名+_attr_ex_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

设置模块的扩展属性,可在应用运行中动态设置。

【注意事项】

  1. hbn_vnode_get_attr_ex

【函数声明】

hobot_status hbn_vnode_get_attr_ex(hbn_vnode_handle_t vnode_fd, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[OUT] void *attr:模块的扩展属性结构体指针。扩展属性结构体可以是vin_attr_ex_t等,以模块名+_attr_ex_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

获取模块的扩展属性。

【注意事项】

  1. hbn_vnode_set_ochn_attr

【函数声明】

hobot_status hbn_vnode_set_ochn_attr(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;;

[IN] void *attr:模块的输出通道属性结构体指针。输出通道属性可以是vin_ochn_attr_t、isp_ochn_attr_t等,以模块名+_ochn_attr_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

设置模块的输出通道属性。

【注意事项】

  1. hbn_vnode_get_ochn_attr

【函数声明】

hobot_status hbn_vnode_get_ochn_attr(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;

[OUT] void *attr:模块输出通道属性结构体指针。输出通道属性可以是vin_ochn_attr_t、isp_ochn_attr_t等,以模块名+_ochn_attr_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

获取模块的输出通道属性。

【注意事项】

  1. hbn_vnode_set_ochn_attr_ex

【函数声明】

hobot_status hbn_vnode_set_ochn_attr_ex(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;

[IN] void *attr:模块的输出通道扩展属性结构体指针。输出通道扩展属性可以是pym_ochn_attr_ex_t等,以模块名+_ochn_attr_ex_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

设置模块的输出通道扩展属性,可在应用运行中动态设置。

【注意事项】

  1. hbn_vnode_set_ichn_attr

【函数声明】

hobot_status hbn_vnode_set_ichn_attr(hbn_vnode_handle_t vnode_fd, uint32_t ichn_id, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ichn_id:模块的输入通道id,通道id见模块通道说明;

[IN] void *attr:模块的输入通道属性结构体指针。输入通道属性可以是vin_ichn_attr_t、isp_ichn_attr_t等,以模块名+_ichn_attr_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

设置模块的输入通道属性。

【注意事项】

  1. hbn_vnode_get_ichn_attr

【函数声明】

hobot_status hbn_vnode_get_ichn_attr(hbn_vnode_handle_t vnode_fd, uint32_t ichn_id, void *attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ichn_id:模块的输入通道id,通道id见模块通道说明;

[OUT] void *attr:模块的输入通道属性结构体指针。输入通道属性可以是vin_ichn_attr_t、isp_ichn_attr_t等,以模块名+_ichn_attr_t结尾的属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

获取模块的输入通道属性。

【注意事项】

  1. hbn_vnode_set_ochn_buf_attr

【函数声明】

hobot_status hbn_vnode_set_ochn_buf_attr(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, hbn_buf_alloc_attr_t *alloc_attr)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;

[IN] hbn_buf_alloc_attr_t *alloc_attr:buffer分配属性;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

设置输出通道buffer属性。

【注意事项】

  1. hbn_vnode_start

【函数声明】

hobot_status hbn_vnode_start(hbn_vnode_handle_t vnode_fd)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

模块启动。

【注意事项】

启动前需要先打开模块。

  1. hbn_vnode_stop

【函数声明】

hobot_status hbn_vnode_stop(hbn_vnode_handle_t vnode_fd)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

模块停止。

【注意事项】

  1. hbn_vnode_getframe

【函数声明】

hobot_status hbn_vnode_getframe(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, uint32_t millisecondTimeout, hbn_vnode_image_t *out_img)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;

[IN] uint32_t millisecondTimeout:超时等待时间;

[OUT] hbn_vnode_image_t *out_img:输出图像buffer结构体地址;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

获取模块输出通道的图像,阻塞型接口。

【注意事项】

  1. hbn_vnode_releaseframe

【函数声明】

hobot_status hbn_vnode_releaseframe(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, hbn_vnode_image_t *img)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;

[IN] hbn_vnode_image_t *img:图像buffer结构体地址;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

释放图像buffer,buffer会归还到指定的输出通道。

【注意事项】

  1. hbn_vnode_getframe_group

【函数声明】

hobot_status hbn_vnode_getframe_group(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, uint32_t millisecondTimeout,hbn_vnode_image_group_t *out_img);

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;

[IN] uint32_t millisecondTimeout:超时等待时间;

[OUT] hbn_vnode_image_group_t *out_img:输出图像buffer结构体地址;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

获取模块输出通道的多层聚合图像,阻塞型接口。

【注意事项】

ISP和PYM输出图像需要调用该接口获取

  1. hbn_vnode_releaseframe_group

【函数声明】

hobot_status hbn_vnode_releaseframe_group(hbn_vnode_handle_t vnode_fd, uint32_t ochn_id, hbn_vnode_image_group_t*img)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ochn_id:模块的输出通道id,通道id见模块通道说明;

[IN] hbn_vnode_image_t *img:图像buffer结构体地址;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

释放多层聚合图像buffer,buffer会归还到指定的输出通道。

【注意事项】

  1. hbn_vnode_sendframe

【函数声明】

hobot_status hbn_vnode_sendframe(hbn_vnode_handle_t vnode_fd, uint32_t ichn_id, hbn_vnode_image_t *img)

【参数描述】

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

[IN] uint32_t ichn_id:模块的输入通道id,通道id见模块通道说明;

[IN] hbn_vnode_image_t *img:输入图像buffer地址;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

发送图像到模块的输入通道,会触发模块进行处理。阻塞型接口,等待硬件处理完再返回,默认超时时间为1秒。

【注意事项】

  1. hbn_vflow_create

【函数声明】

hobot_status hbn_vflow_create(hbn_vflow_handle_t *vflow_fd)

【参数描述】

[OUT] hbn_vflow_handle_t *vflow_fd:vflow handle;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

创建一个vflow,返回vflow handle。

【注意事项】

  1. hbn_vflow_destroy

【函数声明】

void hbn_vflow_destroy(hbn_vflow_handle_t vflow_fd)

【参数描述】

[IN] hbn_vflow_handle_t *vflow_fd:vflow handle;

【返回值】

【功能描述】

根据vflow handle,销毁一个vflow。

【注意事项】

  1. hbn_vflow_add_vnode

【函数声明】

hobot_status hbn_vflow_add_vnode(hbn_vflow_handle_t vflow_fd, hbn_vnode_handle_t vnode_fd)

【参数描述】

[IN] hbn_vflow_handle_t *vflow_fd:vflow handle;

[IN] hbn_vnode_handle_t vnode_fd:模块的vnode handle;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

把模块添加到vflow里面,用vflow管理起来。

【注意事项】

  1. hbn_vflow_bind_vnode

【函数声明】

hobot_status hbn_vflow_bind_vnode(hbn_vflow_handle_t vflow_fd, hbn_vnode_handle_t src_vnode_fd, uint32_t out_chn, hbn_vnode_handle_t dst_vnode_fd, uint32_t in_chn)

【参数描述】

[IN] hbn_vflow_handle_t *vflow_fd:vflow handle;

[IN] hbn_vnode_handle_t src_vnode_fd:源模块的vnode handle;

[IN] uint32_t out_chn:源模块的输出通道id,通道id见模块通道说明;

[IN] hbn_vnode_handle_t dst_vnode_fd:目的模块的vnode handle;

[IN] uint32_t in_chn:目的模块的输入通道id,通道id见模块通道说明;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

把两个模块绑定到一起。绑定后src_vnode_fd模块的数据帧会自动流向dst_vnode_fd模块。

【注意事项】

flow需要创建,模块需要open。

  1. hbn_vflow_unbind_vnode

【函数声明】

hobot_status hbn_vflow_unbind_vnode(hbn_vflow_handle_t vflow_fd, hbn_vnode_handle_t src_vnode_fd, uint32_t out_chn, hbn_vnode_handle_t dst_vnode_fd, uint32_t in_chn)

【参数描述】

[IN] hbn_vflow_handle_t *vflow_fd:vflow handle;

[IN] hbn_vnode_handle_t src_vnode_fd:源模块的vnode handle;

[IN] uint32_t out_chn:源模块的输出通道id,通道id见模块通道说明;

[IN] hbn_vnode_handle_t dst_vnode_fd:目的模块的vnode handle;

[IN] uint32_t in_chn:目的模块的输入通道id,通道id见模块通道说明;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

解绑src_vnode_fd和dst_vnode_fd模块。

【注意事项】

暂不支持。

  1. hbn_vflow_start

【函数声明】

hobot_status hbn_vflow_start(hbn_vflow_handle_t vflow_fd)

【参数描述】

[IN] hbn_vflow_handle_t vflow_fd:vflow handle;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

启动一条vflow。vflow里包含的vnode都会启动。

【注意事项】

模块vnode需要事先添加到vflow中。

  1. hbn_vflow_stop

【函数声明】

hobot_status hbn_vflow_stop(hbn_vflow_handle_t vflow_fd)

【参数描述】

[IN] hbn_vflow_handle_t vflow_fd:vflow handle;

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

停止一条vflow。vflow里包含的vnode都会停止。

【注意事项】

和hbn_vflow_start成对使用。

  1. hbn_vflow_get_vnode_handle

【函数声明】

hbn_vnode_handle_t hbn_vflow_get_vnode_handle(hbn_vflow_handle_t vflow_fd, hb_vnode_type vnode_type, uint32_t index)

【参数描述】

[IN] hbn_vflow_handle_t vflow_fd:vflow handle;

[IN] hb_vnode_type vnode_type:模块id;

[IN] uint32_t index:context id,范围为[0, 7]

【返回值】

成功:HBN_STATUS_SUCESS 0

失败:异常为负值错误码,参考返回值说明

【功能描述】

通过模块id和context id获取vnode handle。

【注意事项】

模块需要事先open。

参数说明

公共

hbn_vnode_image_t

名称类型含义最大值最小值默认值是否必选
infohbn_frame_info_t图像信息结构----
bufferhb_mem_graphic_buf_t图像内存信息----
metadatavoid *meta数据----

hbn_frame_info_t

名称类型含义最大值最小值默认值是否必选
frame_iduint32_t帧号----
timestampsuint64_t系统时间----
tvstruct timeval硬件时间戳----
trig_tvstruct timeval外部触发的硬件时间戳----
bufferindexint32_tbuffer索引----

hb_mem_graphic_buf_t

名称类型含义最大值最小值默认值是否必选
fd[MAX_GRAPHIC_BUF_COMP]int32_t文件描述符----
plane_cntint32_tplane个数----
formatint32_t图像格式----
widthint32_t宽度----
heightint32_t高度----
strideint32_t宽度stride----
vstrideint32_t高度stride----
is_contigint32_tbuffer物理地址是否连续----
share_id[MAX_GRAPHIC_BUF_COMP]int32_t共享id----
flagsint64_t标识----
size[MAX_GRAPHIC_BUF_COMP]uint64_tbuffer size----
virt_addr[MAX_GRAPHIC_BUF_COMP]uint8_t *虚拟地址----
phys_addr[MAX_GRAPHIC_BUF_COMP]uint64_t物理地址----
offset[MAX_GRAPHIC_BUF_COMP]uint64_t内存偏移----

hbn_vnode_image_group_t

名称类型含义最大值最小值默认值是否必选
infohbn_frame_info_t图像信息结构----
buf_grouphb_mem_graphic_buf_group_tgroup图像内存信息----
metadatavoid *meta数据----

hb_mem_graphic_buf_group_t

名称类型含义最大值最小值默认值是否必选
graph_group[HB_MEM_MAXIMUM_GRAPH_BUF];hb_mem_graphic_buf_t图像内存信息----
group_idint32_tgroup id号----
bit_mapuint32_t用bit标识graph_group中可用的层----

VIN

vin_attr_t

名称类型含义最大值最小值默认值是否必选
vin_node_attrvin_node_attr_tvin node节点属性结构---
magicNumberuint32_t属性结构体校验值,需要填写为MAGIC_NUM---

vin_node_attr_t

名称类型含义最大值最小值默认值是否必选
cim_attrcim_attr_tcim参数---
lpwm_attrlpwm_attr_tlpwm参数---
vcon_attrvcon_attr_tvcon参数---
magicNumberuint32_t属性结构体校验值,需要填写为MAGIC_NUM---

cim_attr_t

名称类型含义最大值最小值默认值是否必选
mipi_enuint32_t是否使能mipi输入10-
mipi_rxuint32_tmipi rx索引,可选值为0,1,440-
vc_indexuint32_tcim ipi索引30-
cim_pym_flybyuint32_t是否使能cim pym硬件直连10-
cim_isp_flybyuint32_t是否使能cim isp硬件直连10-

vin_ichn_attr_t

名称类型含义最大值最小值默认值是否必选
formatuint32_tmipi输入图像格式,例raw12对应0x2c0x270x1E-
widthuint32_tmipi输入图像宽409632-
heightuint32_tmipi输入图像高216032-

vin_ochn_attr_t

名称类型含义最大值最小值默认值是否必选
ddr_enuint32_t是否使能cim ddr输出10-
roi_enuint32_t是否使能cim roi通道输出10-
emb_enuint32_t是否使能cim emb通道输出10-
rawds_enuint32_t是否使能raw scaler10-
pingpong_ringuint32_t是否使能乒乓buffer10-
ochn_attr_typevin_ochn_attr_type_e输出通道类型: VIN_MAIN_FRAME 主数据通路 VIN_ONLINE online输出通路 VIN_EMB embeded数据通路 VIN_ROI roi数据通路---
vin_basic_attrvin_basic_attr_tvin基础属性---
rawds_attrvin_rawds_attr_tvin raw scaler属性---
roi_attrstruct vin_roi_attr_svin roi 属性---
emb_attrvin_emb_attr_tvin embeded属性---
magicNumberuint32_t属性结构体校验值,需要填写为固定值MAGIC_NUM---

vin_basic_attr_t

名称类型含义最大值最小值默认值是否必选
pack_modeuint32_tpack使能,不配置默认pack101
wstrideuint32_t输出宽stride,置0内部自动计算101
vstrideuint32_t输出高stride,置0内部自动计算101
formatuint32_t输出图像格式,例raw12对应0x2c0x270x1E-

ISP

isp_attr_t

名称类型含义最大值最小值默认值是否必选
channelisp_channel_tisp通道属性---
sched_modesched_mode_eisp调度模式 1 SCHED_MODE_MANUAL manual模式 2 SCHED_MODE_PASS_THRU 全online模式21-
work_modeisp_work_mode_eisp工作模式 0 ISP_WORK_MODE_NOMAL 普通模式 1 ISP_WORK_MODE_TPG isp输出testpattern模式 2 ISP_WORK_MODE_CIM_TPG cim输出testpattern模式20-
hdr_modehdr_mode_eisp hdr模式使能10-
sizeimage_size_tisp处理尺寸---
frame_rateuint32_tisp帧率1201-
isp_combineisp_combine_tisp主从模式---
algo_stateuint32_t2A算法使能10-

isp_channel_t

名称类型含义最大值最小值默认值是否必选
hw_iduint32_tisp硬件id10-
slot_iduint32_tisp内部硬件通道 online输入时配置0~3,offline输入时配置4~111100

image_size_t

名称类型含义最大值最小值默认值是否必选
widthuint32_tisp处理宽度409632-
heightuint32_tisp处理高度216032-

isp_ichn_attr_t

名称类型含义最大值最小值默认值是否必选
input_crop_cfgcrop_cfg_t输入裁剪配置---
in_buf_nocleanuint32_t输入buffer是否做cache clean10-
in_buf_noncacheduint32_t输入buffer是否分配为non cache内存10-

crop_cfg_t

名称类型含义最大值最小值默认值是否必选
rectimage_rect_t输入裁剪尺寸---
enableHB_BOOL是否是能crop10-

image_rect_t

名称类型含义最大值最小值默认值是否必选
xuint32_tx坐标---
yuint32_ty坐标---
widthuint32_trect宽度---
heightuint32_trect高度---

isp_ochn_attr_t

名称类型含义最大值最小值默认值是否必选
stream_output_modeisp_stream_output_mode_e是否otf输出:1-enable0-disable100
axi_output_modeisp_axi_output_mode_eddr输出类型:AXI_OUTPUT_MODE_DISABLE = 0,1400
AXI_OUTPUT_MODE_RGB888 = 1,
AXI_OUTPUT_MODE_RAW8 = 2,
AXI_OUTPUT_MODE_RAW10 = 3,
AXI_OUTPUT_MODE_RAW12 = 4,
AXI_OUTPUT_MODE_RAW16 = 5,
AXI_OUTPUT_MODE_RAW24 = 6,
AXI_OUTPUT_MODE_YUV444 = 7,
AXI_OUTPUT_MODE_YUV422 = 8, /* yuv422 */
AXI_OUTPUT_MODE_YUV420 = 9, /* yuv420 */
AXI_OUTPUT_MODE_IR8 = 10,
AXI_OUTPUT_MODE_YUV420_RAW12 = 11,/* yuv420 & raw12*/
AXI_OUTPUT_MODE_YUV422_RAW12 = 12,/* yuv422 & raw12 */
AXI_OUTPUT_MODE_YUV420_RAW16 = 13, /* yuv420 & raw16 */
AXI_OUTPUT_MODE_YUV422_RAW16 = 14, /* yuv422 & raw16 */
output_crop_cfgcrop_cfg_t输出裁剪配置---
out_buf_noinvaliduint32_t输出buffer是否做cacha invalid100
out_buf_noncacheduint32_t输出buffer是否分配为non cached100
buf_numuint32_t分配输出buffer的个数1630

YNR

ynr_init_attr

名称类型含义最大值最小值默认值是否必选
work_modeuint32_tynr工作模式21-
1:Manual模式
,online链接,
前级模块是sw
trigger;
2:单路Online
(前级PYM硬件
直连)模式;
slot_iduint32_tynr硬件通道id70-
widthuint32_tynr处理宽度204832
heightuint32_tynr处理高度204832
nr_static_switchuint32_tnr3den<<1|nr2d_en
in_strideuint32_ty stride和uv stride
nr2d_enuint32_t2dnr使能10
nr3d_enuint32_t3dnr使能10
dma_output_enuint32_tdma输出使能10
如果使能3dnr,需
要使能dma输出
debug_enuint32_t是否打开debug调试10

hobot_ynr_channel_input_config

名称类型含义最大值最小值默认值是否必选
ch_img_widthuint32_tynr输入宽度409632-
ch_img_heightuint32_tynr输入高度216032-

hobot_ynr_channel_output_config

名称类型含义最大值最小值默认值是否必选
ch_nr3d_pix_out_dma_bypsuint32_tdma输出数,建议配置为0409632-
ch_nr3d_debug_enuint32_tdebug开关,建议配置为010-

PYM

roi_box_t

名称类型含义最大值最小值默认值是否必选
start_topuint32_t从原始图像中截取图像的Y轴位置ds 层:<= region_height bl 层:<= bl_base_height bl_base_height = region_width >> (ds_roi_layer + 1)ds层:>= region_height - out_height bl层:>= bl_base_height - out_height-
start_leftuint32_t从原始图像中截取图像的X轴位置ds层:<= region_width bl层:<= bl_base_width bl_base_width = region_width >> (ds_roi_layer + 1)ds层:>= region_width - out_width bl层:>= bl_base_width - out_width-
region_widthuint32_t截取图像的宽度---
region_heightuint32_t截取图像的高度---
wstride_uvuint32_t输出的uv层stride-
wstride_yuint32_t输出的y层stride---
vstrideuint32_ty层高度stried--out_height
step_vuint32_t--(1 << 16) * (out_height - region_height) / out_height
step_huint32_t--(1 << 16) * (out_width - region_width) / out_width否·
out_widthuint32_t输出图像的宽度---
out_heightuint32_t输出图像的高度---
phase_y_vuint32_t0
phase_y_huint32_t0

chn_ctrl_t

名称类型含义最大值最小值默认值是否必选
pixel_num_before_soluint32_t--2
invalid_head_linesuint32_t---
src_in_widthuint32_t输入宽度,且2对齐< 4096> 32-
src_in_heightuint32_t输入高度,且2对齐< 4096> 32-
src_in_stride_yuint32_t输入y plane stride, 且16对齐< 4096> src_in_width-
src_in_stride_uvuint32_t输入uv stride,且16对齐< 4096> src_in_width-
suffix_hb_valuint32_t<= 152>= 16100
prefix_hb_valuint32_t<= 2>= 02
suffix_vb_valuint32_t<= 20>= 010
prefix_vb_valuint32_t<= 2>= 00
bl_max_layer_enuint8_t选择bl层时,使能bl层数> ds_roi_layer[chn]5
ds_roi_enuint8_tds层输出使能,总共6层,按bit位使能< (1 << 6)--
ds_roi_uv_bypassuint8_tds层uv plane输出bypass使能,按bit位使能< (1 << 6)--
ds_roi_sel[MAX_DS_NUM]uint8_t图层选择,0 src层;1 bl层< 3--
ds_roi_layer[MAX_DS_NUM]uint8_tds_roi_sel = 0时, 只能为0--
ds_roi_info[MAX_DS_NUM]roi_box_tds层配置---

pym_cfg_t

名称类型含义最大值最小值默认值是否必选
hw_iduint8_tpym 硬件模块id (0, 1 , 4)---
pym_modeuint8_tpym 工作模式 1:Manual模式,online链接,前级模块是sw trigger; 2:单路Online(前级-PYM硬件直连)模式; 3:离线模式(输入:YUV420SP,输出:YUV420SP<= 3>= 1-
slot_iduint8_tpym 硬件通道id70-
out_buf_noinvaliduint8_t模块输出buf内部是否会执行invaild cache操作101
out_buf_noncacheduint8_t模块输出buf是否使能non-cache内存分配10-
in_buf_nocleanuint8_t输入buf是否做cache clean101
in_buf_noncacheduint8_t模块输入buf(一般回灌buf)是否使能non-cache内存分配10-
buf_consecutiveuint8_t内存是否连续10-
pingpong_ringuint8_t是否开启乒乓buffer-
output_buf_numuint32_t输出buf数目,当PYM离线模式时,回灌buf数目按照该数目默认分配<= 640-
timeoutuint32_t超时时间<= 10000-
threshold_timeuint32_t-
layer_num_trans_nextint32_t传输到后级模块的层数< 6--1
layer_num_share_prevint32_t< 6--1
chn_ctrlchn_ctrl_t设置输入输出格式大小
fb_buf_numuint32_t回灌buffer个数<= 16-2
reserved[6]uint32_t保留位置---
magicNumberuint32_t属性结构体校验值,需要填写为固定值MAGIC_NUM---

GDC

gdc_cfg_t

名称类型含义最大值最小值默认值是否必选
input_widthuint32_t输入图像宽度, 且2对齐<= 3840>= 96-
input_heightuint32_t输入图像高度,且2对齐<= 2160>= 96-
output_widthuint32_t输出图像宽度<= 3840>= 96-
output_heightuint32_t输出图像高度<= 2160>= 96-
buf_numuint32_t正常输入buf数量<= 3206
fb_buf_numuint32_t回灌buf数量<= 3202
in_buf_nocleanuint32_t输入buf是否做cache clean101
in_buf_noncacheduint32_t模块输入buf(一般回灌buf)是否使能non-cache内存分配---
out_buf_noinvaliduint32_t模块输出buf内部是否会执行invaild cache操作--1
out_buf_noncacheduint32_t模块输出buf是否使能non-cache内存分配---
gdc_pipelineuint32_t---

STITCH

stitch_base_attr

名称类型含义最大值最小值默认值是否必选
modeuint32_t工作模式
0-外部buffer回灌模式
1-内部buffer回灌模式
2-flow绑定模式
roi_numsuint32_troi区域个数121
img_numsuint32_t输入图像的数量-1
alpha_lutstructalpha lookup table
lut_attr
beta_lutstructbeta lookup table
lut_attr
blendingstruct融合属性
blending_attr

lut_attr

名称类型含义最大值最小值默认值是否必选
share_idint32_thbmem buffer的shareid
存放lut buffer需要
通过hbmem申请
vaddruint64_tlut虚拟地址
offsetuint64_t偏移
sizeuint64_t大小

blending_attr

名称类型含义最大值最小值默认值是否必选
roi_indexuint32_troi索引
blending_modeuint32_t融合模式:
BLENDING_MODE_ONLINE = 0, //online mode
BLENDING_MODE_ALPHA = 1, //alpha mode
BLENDING_MODE_ALPH = 2, //alpha beda mode
BLENDING_MODE_SRC = 3, //src copy mode
BLENDING_MODE_ALPHA_SRC = 5 //arpha src0 mode
directuint32_t融合方向:
BLENDING_DIRECT_LT = 0, //left and top direct
BLENDING_DIRECT_RB = 1, //right and bottom direct
BLENDING_DIRECT_LB = 2, //left and bottom direct
BLENDING_DIRECT_RT = 3, //right and top direct
uv_enuint32_t输入图像是否包含uv
src0_indexuint32_tsrc0对应输源
src1_indexuint32_tsrc1对应输源
marginuint32_t可选参数,可不配置
margin_invuint32_t可选参数,可不配置
gain_src0_yuvuint32_t固定256 //0:y 1:u 2:v
gain_src1_yuvuint32_t固定256 //0:y 1:u 2:v

roi_info

名称类型含义最大值最小值默认值是否必选
roi_indexuint32_troi索引
roi_xuint32_t坐标起始x
roi_yuint32_t坐标起始y
roi_wuint32_t宽度
roi_huint32_t高度

stitch_ch_attr

名称类型含义最大值最小值默认值是否必选
widthuint32_t输入或输出宽
heightuint32_t输入或输出高
strid[MAX_STH_FRAME_PLAN]uint32_tstride
rois[MAX_STH_ROI_NUMS]struct roi_inforoi区域描述

通道绑定说明

模块输出通道编号通道功能
VIN0offline通道,输出camera帧到ddr
1online通道,连接到isp或pym
ISP0offline通道,输出isp处理后的帧到ddr
1online通道,连接到pym
PYM0offline通道,输出pym图像至ddr
GDC0offline通道,输出gdc处理后的帧到ddr

online表示硬件直连,offline表示输出至ddr缓存

返回值说明

错误码宏定义描述
0HBN_STATUS_SUCESS成功
1HBN_STATUS_INVALID_NODEvnode无效,找不到对应的vnode
2HBN_STATUS_INVALID_NODETYPEvnode类型无效,找不到对应的vnode
3HBN_STATUS_INVALID_HWID无效的硬件模块id
4HBN_STATUS_INVALID_CTXID无效的context id
5HBN_STATUS_INVALID_OCHNID无效的输出通道id
6HBN_STATUS_INVALID_ICHNID无效的输入通道id
7HBN_STATUS_INVALID_FORMAT无效的格式
8HBN_STATUS_INVALID_NULL_PTR空指针
9HBN_STATUS_INVALID_PARAMETER无效的参数,版本检查失败
10HBN_STATUS_ILLEGAL_ATTR无效的参数
11HBN_STATUS_INVALID_FLOW无效的flow,找不到对应的flow
12HBN_STATUS_FLOW_EXISTflow已经存在
13HBN_STATUS_FLOW_UNEXISTflow不存在
14HBN_STATUS_NODE_EXISTnode已经存在
15HBN_STATUS_NODE_UNEXISTnode不存在
16HBN_STATUS_NOT_CONFIG预留
17HBN_STATUS_CHN_NOT_ENABLED通道未使能
18HBN_STATUS_CHN_ALREADY_ENABLED通道已使能
19HBN_STATUS_ALREADY_BINDEDnode已经绑定
20HBN_STATUS_NOT_BINDEDnode未绑定
21HBN_STATUS_TIMEOUT超时
22HBN_STATUS_NOT_INITIALIZED未初始化
23HBN_STATUS_NOT_SUPPORT通道不支持或未激活
24HBN_STATUS_NOT_PERM操作不允许
25HBN_STATUS_NOMEM内存不足
26HBN_STATUS_INVALID_VNODE_FD无效的node文件描述符
27HBN_STATUS_INVALID_ICHNID_FD无效的输入通道文件描述符
28HBN_STATUS_INVALID_OCHNID_FD无效的输出通道文件描述符
29HBN_STATUS_OPEN_OCHN_FAIL打开输出通道失败
30HBN_STATUS_OPEN_ICHN_FAIL打开输入通道失败
31HBN_STATUS_JSON_PARSE_FAILjson解析失败
32HBN_STATUS_REQ_BUF_FAIL请求buffer失败
33HBN_STATUS_QUERY_BUF_FAIL查询buffer信息失败
34HBN_STATUS_SET_CONTROL_FAIL模块控制、调节 参数(如ISP效果参数)设置失败
35HBN_STATUS_GET_CONTROL_FAIL模块控制、调节 参数(如ISP效果参数)获取失败
36HBN_STATUS_NODE_START_FAILnode开启失败
37HBN_STATUS_NODE_STOP_FAILnode停止失败
38HBN_STATUS_NODE_POLL_ERRORnode通道poll错误
39HBN_STATUS_NODE_POLL_TIMEOUTnode通道poll超时
40HBN_STATUS_NODE_POLL_FRAME_DROPnode通道poll时发生丢帧
41HBN_STATUS_NODE_POLL_HUPnode通道poll时描述符挂起
42HBN_STATUS_NODE_ILLEGAL_EVENTnode通道poll时事件非法
43HBN_STATUS_NODE_DEQUE_ERRORnode通道dequeue buffer错误
44HBN_STATUS_ILLEGAL_BUF_INDEX无效的buffer索引
45HBN_STATUS_NODE_QUE_ERRORnode通道queue buffer错误
46HBN_STATUS_FLUSH_FRAME_ERRORnode通道帧flush错误
47HBN_STATUS_INIT_BIND_ERROR用json解析并绑定时发生错误
48HBN_STATUS_ADD_NODE_FAIL向flow中添加node失败
49HBN_STATUS_WRONG_CONFIG_ID系统不支持的node id
50HBN_STATUS_BIND_NODE_FAILflow绑定node时发生错误
51HBN_STATUS_INVALID_VERSION底层驱动模块和上层 库版本号不匹配错误
52HBN_STATUS_GET_VERSION_ERROR获取底层驱动模块版本号错误
53HBN_STATUS_MEM_INIT_FAILhbmem内存初始化失败
54HBN_STATUS_MEM_IMPORT_FAILhbmem内存引入失败
55HBN_STATUS_MEM_FREE_FAILhbmem内存释放失败
56HBN_STATUS_SYSFS_OPEN_FAIL系统文件打开失败
57HBN_STATUS_STRUCT_SIZE_NOT_MATCHhal层结构体大小与kernel层不匹配
58HBN_STATUS_RGN_UNEXIST获取不到对应的rgn数据
59HBN_STATUS_RGN_INVALID_OPERATIONrgn操作无效
60HBN_STATUS_RGN_OPEN_FILE_FAILrgn模块打开文件失败
128HBN_STATUS_ERR_UNKNOW未知错误

V4L2

S100 Camsys 部分模块已经接入V4L2,可以通过标准V4L2编程及开源工具获取camsys数据流

使用方式

开机启动后camsys默认运行在hbn模式,可以通过加载camsys V4L2 ko,切换到V4L2模式

切换v4l2方式:

  #卸载hbn驱动
rmmod hobot_isp
rmmod hobot_cim
rmmod hobot_mipidbg
rmmod hobot_mipicsi
rmmod hobot_pym_jplus
rmmod hobot_gdc
rmmod hobot_ynr

#加载v4l2驱动
modprobe videobuf2-common
modprobe videobuf2-v4l2
modprobe videobuf2-memops
modprobe videobuf2-common
modprobe videobuf2-dma-contig
modprobe videobuf2-v4l2
modprobe v4l2-mem2mem
modprobe imx219
modprobe v4l_mipicsi
modprobe v4l2_cim
modprobe hobot_isp_v4l2
modprobe pym_v4l_drv
modprobe gdc_v4l_drv
modprobe hobot_ynr_v4l2
modprobe vid_v4l2 scene=[scene num] #scene num见下表
nohup isp_service &

场景切换方式:


rmmod vid_v4l2
modprobe vid_v4l2 scene=[scene num]

场景说明

scene num场景简述场景描述对应video节点(相对)
0CIM-DDR输出CIM0 输出1路至DDR (对应video0)video0
CIM1 输出1路至DDRvideo1
CIM4 输出4路至DDR(serdes场景)video2~5
1CIM-OTF-ISP-DDRCIM0-OTF-ISP0-DDRvideo0
CIM1-OTF-ISP1-DDRvideo1
2CIM-OTF-ISP-OTF-PYM-DDR 2路CIM0-OTF-ISP0-OTF-PYM0,video0对应第一路pym ds0
PYM输出一个通道
CIM1-OTF-ISP1-OTF-PYM1,video1对应第二路pym ds0
PYM输出一个通道
3CIM-OTF-ISP-OTF-PYM-DDRCIM0-OTF-ISP0-OTF-PYM0,video0video5对应ds05
2路输出6通道PYM输出6个通道
CIM1-OTF-ISP1-OTF-PYM1,video6video11对应ds0ds5
PYM输出6个通道
4CIM-DDR-ISP-DDRCIM0-DDR-ISP0-DDRvideo0
CIM1-DDR-ISP1-DDRvideo1
5CIM-DDR-ISP-OTF-PYMCIM0-DDR-ISP0-OTF-PYM0video0
输出一个通道
6CIM-OTF-ISP-DDR-GDCCIM0-OTF-ISP-DDR-GDCvideo0
输出一个通道
7DDR-PYM-DDR回灌输出回灌PYM输出6路至DDRvideo0 ~ 5
回灌PYM输出6路至DDRvideo6 ~ 11
DDR-GDC-DDR回灌输出回灌GDC输出至DDRvideo12
回灌GDC输出至DDRvideo13
9CIM-DDR-ISP-OTF-YNR-PYMCIM0-DDR-ISP1-OTF-YNR1-OTF-PYM1video0
CIM1-DDR-ISP1-OTF-YNR1-OTF-PYM1video1

(其他link场景暂不支持,持续更新中)

camsys sample

imx219 + MIPI + CIM + ISP + PYM:

         // imx219 的sample配置
static mipi_config_t imx219_mipi_config = {
.rx_enable = 1,
.rx_attr = {
.phy = 0,
.lane = 2,
.datatype = 0x12b,
.fps = 30,
.mclk = 24,
.mipiclk = 1728,
.width = 0,
.height = 0,
.linelenth = 0,
.framelenth = 0,
.settle = 0,
.channel_num = 0,
.channel_sel = {0},
},

.rx_ex_mask = 0x40,
.rx_attr_ex = {
.stop_check_instart = 1,
},

.end_flag = MIPI_CONFIG_END_FLAG,
};

static camera_config_t imx219_camera_config = {
/* 0 */
.name = "imx219",
.addr = 0x10,
.eeprom_addr = 0x51,
.serial_addr = 0x40,
.sensor_mode = 1,
.fps = 30,
.width = 1920,
.height = 1080,
.extra_mode = 0,
.config_index = 0,
.mipi_cfg = &imx219_mipi_config, // MIPI配置,NULL自动获取
.end_flag = CAMERA_CONFIG_END_FLAG,
.calib_lname = "disable",
};

static isp_cfg_t imx219_isp_config = {
.isp_attr = {
.channel = {
.hw_id = 0,
.slot_id = 4,
.ctx_id = -1, //#define AUTO_ALLOC_ID -1
},
.work_mode = 0,
.hdr_mode = 1,
.size = {
.width = 1920,
.height = 1080,
},
.frame_rate = 30,
.sched_mode = 1,
.algo_state = 1,
.isp_combine = {
.isp_channel_mode = 0, //ISP_CHANNEL_MODE_NORMAL
.bind_channel = {
.bind_hw_id = 0,
.bind_slot_id = 0,
},
},
.clear_record = 0, //json和代码中未拿到,设置为0
.isp_sw_ctrl = {
.ae_stat_buf_en = 1,
.awb_stat_buf_en = 1,
.ae5bin_stat_buf_en = 1,
.ctx_buf_en = 0,
.pixel_consistency_en = 0,
},
},
.ichn_attr = {
.input_crop_cfg = {
.enable = 0,
.rect = {
.x = 0,
.y = 0,
.width = 0,
.height = 0,
},
},
.in_buf_noclean = 1,
.in_buf_noncached = 0,
},
.ochn_attr = {
.output_crop_cfg = {
.enable = 0,
.rect = {
.x = 0,
.y = 0,
.width = 0,
.height = 0,
},
},
.out_buf_noinvalid = 1,
.out_buf_noncached = 0,
.output_raw_level = 0, //ISP_OUTPUT_RAW_LEVEL_SENSOR_DATA
.stream_output_mode = 0, //convert_isp_stream_output(1),
.axi_output_mode = 9, //convert_isp_axi_output(0),
.buf_num = 3,
}
};

static vin_attr_t imx219_vin_attr = {
.vin_node_attr = {
.vcon_attr = {
.bus_main = 2,
.bus_second = 2,
},

.cim_attr = {
.mipi_en = 1,
.cim_isp_flyby = 0,
.cim_pym_flyby = 0,
.mipi_rx = 0,
.vc_index = 0,
.ipi_channels = 1,
.y_uv_swap = 0, //(uint32_t)vpf_get_json_value(p_node_mipi, "y_uv_swap");
.func = {
.enable_frame_id = 1,
.set_init_frame_id = 1,
.enable_pattern = 0,
},
.rdma_input = {
.rdma_en = 0,
.stride = 0,
.pack_mode = 1,
.buff_num = 6,
},
},
},

.vin_ichn_attr = {
.width = 1920,
.height = 1080,
.format = 43,
},

.vin_attr_ex = {
.cim_static_attr = {
.water_level_mark = 0,
},
},

.vin_ochn_attr = {
[VIN_MAIN_FRAME] = { //vin_ochn0_attr
.ddr_en = 1,
.vin_basic_attr = {
.format = 43,
.wstride = 0,
.pack_mode = 1,
},
.pingpong_ring = 1,
.roi_en = 0,
.roi_attr = {
.roi_x = 1280,
.roi_y = 720,
.roi_width = 64,
.roi_height = 64,
},
.rawds_en = 0,
.rawds_attr = {
.rawds_mode = 0,
},
},
},
.vin_ochn_buff_attr = {
[VIN_MAIN_FRAME] = { //vin_ochn0_buff_attr
.buffers_num = 6,
},
[VIN_EMB] = { //vin_ochn3_buff_attr
.buffers_num = 6,
},
[VIN_ROI] = { //vin_ochn4_buff_attr
.buffers_num = 6,
},
},
.magicNumber = MAGIC_NUMBER,
};

pym_cfg_t pym_common_config = {
.hw_id = 1,
.pym_mode = 3,
.slot_id = 0,
.pingpong_ring = 0,
.output_buf_num = 6,
.fb_buf_num = 2,
.timeout = 0,
.threshold_time = 0,
.layer_num_trans_next = 0,
.layer_num_share_prev = -1,
.out_buf_noinvalid = 1,
.out_buf_noncached = 0,
.in_buf_noclean = 1,
.in_buf_noncached = 0,
.chn_ctrl = {
.pixel_num_before_sol = DEF_PIX_NUM_BF_SOL,
.invalid_head_lines = 0,
.src_in_width = 1920,
.src_in_height = 1080,
.src_in_stride_y = 1920,
.src_in_stride_uv = 1920,
.suffix_hb_val = DEF_SUFFIX_HB,
.prefix_hb_val = DEF_PREFIX_HB,
.suffix_vb_val = DEF_SUFFIX_VB,
.prefix_vb_val = DEF_PREFIX_VB,
.ds_roi_en = 1,
.bl_max_layer_en = DEF_BL_MAX_EN,
.ds_roi_uv_bypass = 0,
.ds_roi_sel = {
[0] = 0,
},
.ds_roi_layer = {
[0] = 0,
},
.ds_roi_info = {
[0] = {
.start_left = 0,
.start_top = 0,
.region_width = 1920,
.region_height = 1080,
.wstride_uv = 1920,
.wstride_y = 1920,
.out_width = 1920,
.out_height = 1080,
.vstride = 1080, //.out_height,
},
},
},
.magicNumber = MAGIC_NUMBER,
};

// imx219初始化
hbn_camera_create(camera_config, &cam_fd);

// cim 初始化
hbn_vnode_open(HB_VIN, hw_id, AUTO_ALLOC_ID, &vin_node_handle);
hbn_vnode_set_attr(vin_node_handle, vin_attr);
hbn_vnode_set_ichn_attr(vin_node_handle, 0, vin_ichn_attr);
hbn_vnode_set_ochn_attr(vin_node_handle, (uint32_t)VIN_MAIN_FRAME, vin_ochn_attr);
if (vin_ochn_attr->ddr_en) {
memset(&alloc_attr, 0, sizeof(hbn_buf_alloc_attr_t));
alloc_attr.buffers_num = vin_attr->vin_ochn_buff_attr[VIN_MAIN_FRAME].buffers_num;
alloc_attr.is_contig = 1;
alloc_attr.flags = (int64_t)((uint64_t)HB_MEM_USAGE_CPU_READ_OFTEN | (uint64_t)HB_MEM_USAGE_CPU_WRITE_OFTEN | (uint64_t)HB_MEM_USAGE_CACHED);
hbn_vnode_set_ochn_buf_attr(vin_node_handle, (uint32_t)VIN_MAIN_FRAME, &alloc_attr);
}

// isp 初始化
hbn_vnode_open(HB_ISP, hw_id, ctx_id, &isp_node_handle);
hbn_vnode_set_attr(isp_node_handle, &isp_config->isp_attr);
hbn_vnode_set_ichn_attr(isp_node_handle, 0, &isp_config->ichn_attr);
hbn_vnode_set_ochn_attr(isp_node_handled, 0, &isp_config->ochn_attr);

// pym 初始化
hbn_vnode_open(HB_PYM, pym_cfg->hw_id, AUTO_ALLOC_ID, &pym_node_handle);
hbn_vnode_set_attr(pym_node_handle, pym_cfg);
hbn_vnode_set_ichn_attr(pym_node_handle, 0, pym_cfg);
hbn_vnode_set_ochn_attr(pym_node_handle, 0, pym_cfg);
if (pym_cfg->output_buf_num > 0u) {
memset(&alloc_attr, 0, sizeof(hbn_buf_alloc_attr_t));
alloc_attr.buffers_num = pym_cfg->output_buf_num;
alloc_attr.is_contig = 1;
alloc_attr.flags = (int64_t)((uint64_t)HB_MEM_USAGE_CPU_READ_OFTEN | (uint64_t)HB_MEM_USAGE_CPU_WRITE_OFTEN);
if (pym_cfg->out_buf_noncached == 0u) {
alloc_attr.flags |= (uint64_t)HB_MEM_USAGE_CACHED;
}
ret = hbn_vnode_set_ochn_buf_attr(pym_node_handle, 0, &alloc_attr);
}

// vflow 初始化
hbn_vflow_create(&vflow_fd);
hbn_vflow_add_vnode(vflow_fd, vin_node_handle);
hbn_vflow_add_vnode(vflow_fd, isp_node_handle);
hbn_vflow_add_vnode(vflow_fd, pym_node_handle);
hbn_camera_attach_to_vin(cam_fd, vin_node_handle);
hbn_vflow_bind_vnode(vflow_fd, vin_node_handle, 0, isp_node_handle, 0);
hbn_vflow_bind_vnode(vflow_fd, isp_node_handle, 0, pym_node_handle, 0);
hbn_vflow_start(vflow_fd);

// 从pym获取图像并返还buffer
hbn_vnode_getframe_group(pym_node_handle, 0, VP_GET_FRAME_TIMEOUT, out_image_group);
fill_image_frame_from_vnode_image_group(frame, ochn_id);
memcpy(frame_buffer, frame.data[0], frame.data_size[0]); //frame_buffer 即为获取到的完成图像
if (frame.plane_count > 1)
memcpy(frame_buffer + frame.data_size[0], frame.data[1], frame.data_size[1]);
hbn_vnode_releaseframe_group(pym_node_handle, 0, out_image_group); |

0820c + 96712解串 + MIPI + CIM + PYM:

// 0820c 的sample 配置
static mipi_config_t ar0820std_mipi_config = {
.rx_enable = 1,
.rx_attr = {
.phy = 0,
.lane = 1,
.datatype = 30,
.fps = 30,
.mclk = 24,
.mipiclk = 810,
.width = 3840,
.height = 2160,
.linelenth = 2149,
.framelenth = 1125 * 2,
.settle = 22,
.channel_num = 1,
.channel_sel = {0},
},
};

static camera_config_t ar0820std_camera_config = {
/* 0 */
.name = "ar0820std",
.addr = 0x10,
.eeprom_addr = 0x51,
.serial_addr = 0x40,
.sensor_mode = 0x5,
.fps = 30,
.width = 3840,
.height = 2160,
.extra_mode = 5,
.config_index = 512,
.end_flag = CAMERA_CONFIG_END_FLAG,
.calib_lname = "disable",
};

static poc_config_t g_poc_cfg[] = {
{
.addr = 0x28,
.poc_map = 0x2013,
.end_flag = POC_CONFIG_END_FLAG,
},
};

static deserial_config_t ar0820std_deserial_config = {
.name = "max96712",
.addr = 0x29,
.poc_cfg = &g_poc_cfg[0],
.end_flag = DESERIAL_CONFIG_END_FLAG,
};

static vin_attr_t ar0820std_vin_attr = {
.vin_node_attr = {
.cim_attr = {
.cim_isp_flyby = 0,
.cim_pym_flyby = 0,
.mipi_en = 1,
.mipi_rx = 4,
.vc_index = 0,
.ipi_channels = 1,
.y_uv_swap = 0, //(uint32_t)vpf_get_json_value(p_node_mipi, "y_uv_swap");
.func = {
.enable_frame_id = 1,
.set_init_frame_id = 1,
.enable_pattern = 0,
.skip_frame = 0,
.input_fps = 0,
.output_fps = 0,
.skip_nums = 0,
.hw_extract_m = 0,
.hw_extract_n = 0,
.lpwm_trig_sel = (int32_t)LPWM_CHN_INVALID,
},
.rdma_input = {
.rdma_en = 0,
.stride = 0,
.pack_mode = 1,
.buff_num = 6,
},
},
},

.vin_ichn_attr = {
.width = 3840,
.height = 2160,
.format = 30,
},

.vin_attr_ex = {
.cim_static_attr = {
.water_level_mark = 0,
},
},

.vin_ochn_attr = {
[VIN_MAIN_FRAME] = { //vin_ochn0_attr
.ddr_en = 1,
.vin_basic_attr = {
.format = 30,
.wstride = 0,
.vstride = 0,
.pack_mode = 1,
},
.pingpong_ring = 1,
.roi_en = 0,
.roi_attr = {
.roi_x = 1280,
.roi_y = 720,
.roi_width = 64,
.roi_height = 64,
},
.rawds_en = 0,
.rawds_attr = {
.rawds_mode = 0,
},
},
},

.vin_ochn_buff_attr = {
[VIN_MAIN_FRAME] = { //vin_ochn0_buff_attr
.buffers_num = 6,
},
[VIN_EMB] = { //vin_ochn3_buff_attr
.buffers_num = 6,
},
[VIN_ROI] = { //vin_ochn4_buff_attr
.buffers_num = 6,
},
},
.magicNumber = MAGIC_NUMBER,
};

pym_cfg_t pym_common_config = {
.hw_id = 1,
.pym_mode = 3,
.slot_id = 0,
.pingpong_ring = 0,
.output_buf_num = 6,
.fb_buf_num = 2,
.timeout = 0,
.threshold_time = 0,
.layer_num_trans_next = 0,
.layer_num_share_prev = -1,
.out_buf_noinvalid = 1,
.out_buf_noncached = 0,
.in_buf_noclean = 1,
.in_buf_noncached = 0,
.chn_ctrl = {
.pixel_num_before_sol = DEF_PIX_NUM_BF_SOL,
.invalid_head_lines = 0,
.src_in_width = 1920,
.src_in_height = 1080,
.src_in_stride_y = 1920,
.src_in_stride_uv = 1920,
.suffix_hb_val = DEF_SUFFIX_HB,
.prefix_hb_val = DEF_PREFIX_HB,
.suffix_vb_val = DEF_SUFFIX_VB,
.prefix_vb_val = DEF_PREFIX_VB,
.ds_roi_en = 1,
.bl_max_layer_en = DEF_BL_MAX_EN,
.ds_roi_uv_bypass = 0,
.ds_roi_sel = {
[0] = 0,
},
.ds_roi_layer = {
[0] = 0,
},
.ds_roi_info = {
[0] = {
.start_left = 0,
.start_top = 0,
.region_width = 1920,
.region_height = 1080,
.wstride_uv = 1920,
.wstride_y = 1920,
.out_width = 1920,
.out_height = 1080,
.vstride = 1080, //.out_height,
},
},
},
.magicNumber = MAGIC_NUMBER,
};

// 0820c初始化
hbn_camera_create(camera_config, &cam_fd);

// 96712 解串初始化
hbn_deserial_create(deserial_config, &des_fd);

// cim 初始化
hbn_vnode_open(HB_VIN, hw_id, AUTO_ALLOC_ID, &vin_node_handle);
hbn_vnode_set_attr(vin_node_handle, vin_attr);
hbn_vnode_set_ichn_attr(vin_node_handle, 0, vin_ichn_attr);
hbn_vnode_set_ochn_attr(vin_node_handle, (uint32_t)VIN_MAIN_FRAME, vin_ochn_attr);
if (vin_ochn_attr->ddr_en) {
memset(&alloc_attr, 0, sizeof(hbn_buf_alloc_attr_t));
alloc_attr.buffers_num = vin_attr->vin_ochn_buff_attr[VIN_MAIN_FRAME].buffers_num;
alloc_attr.is_contig = 1;
alloc_attr.flags = (int64_t)((uint64_t)HB_MEM_USAGE_CPU_READ_OFTEN | (uint64_t)HB_MEM_USAGE_CPU_WRITE_OFTEN | (uint64_t)HB_MEM_USAGE_CACHED);
hbn_vnode_set_ochn_buf_attr(vin_node_handle, (uint32_t)VIN_MAIN_FRAME, &alloc_attr);
}

// pym 初始化
hbn_vnode_open(HB_PYM, pym_cfg->hw_id, AUTO_ALLOC_ID, &pym_node_handle);
hbn_vnode_set_attr(pym_node_handle, pym_cfg);
hbn_vnode_set_ichn_attr(pym_node_handle, 0, pym_cfg);
hbn_vnode_set_ochn_attr(pym_node_handle, 0, pym_cfg);
if (pym_cfg->output_buf_num > 0u) {
memset(&alloc_attr, 0, sizeof(hbn_buf_alloc_attr_t));
alloc_attr.buffers_num = pym_cfg->output_buf_num;
alloc_attr.is_contig = 1;
alloc_attr.flags = (int64_t)((uint64_t)HB_MEM_USAGE_CPU_READ_OFTEN | (uint64_t)HB_MEM_USAGE_CPU_WRITE_OFTEN);
if (pym_cfg->out_buf_noncached == 0u) {
alloc_attr.flags |= (uint64_t)HB_MEM_USAGE_CACHED;
}
ret = hbn_vnode_set_ochn_buf_attr(pym_node_handle, 0, &alloc_attr);
}

// vflow 初始化
hbn_vflow_create(&vflow_fd);
hbn_vflow_add_vnode(vflow_fd, vin_node_handle);
hbn_vflow_add_vnode(vflow_fd, pym_node_handle);
hbn_camera_attach_to_deserial(cam_fd, des_fd, 0);
hbn_deserial_attach_to_vin(des_fd, 0, vin_node_handle);
hbn_vflow_bind_vnode(vflow_fd, vin_node_handle, 0, pym_node_handle, 0);
hbn_vflow_start(vp_vflow_contex->vflow_fd);

// 从pym获取图像并返还buffer
hbn_vnode_getframe_group(pym_node_handle, 0, VP_GET_FRAME_TIMEOUT, out_image_group);
fill_image_frame_from_vnode_image_group(frame, ochn_id);
memcpy(frame_buffer, frame.data[0], frame.data_size[0]); //frame_buffer 即为获取到的完成图像
if (frame.plane_count > 1)
memcpy(frame_buffer + frame.data_size[0], frame.data[1], frame.data_size[1]);
hbn_vnode_releaseframe_group(pym_node_handle, 0, out_image_group);

GDC STITCH 拼接sample

当前sample采用回灌流程,即从系统存储中读取文件作为GDC的输入图像,调用hbn API,基于GDC配置bin文件完成GDC处理,再通过stitch API和对应的拼接LUT表文件实现对GDC输出图像的拼接,得到鸟瞰图。

后视图原图及经过gdc处理后的输出:

前视图原图及经过gdc处理后的输出

左视图原图及经过gdc处理后的输出

右视图原图及经过gdc处理后的输出

最终stitch拼接输出图像:

对应stitch的ROI区域划分:

ROI范围SRC0起点大小SRC1起点大小目标起点模式方向
0左视图 frame2frame 2(10, 0)(390, 778)(0, 16)3 直接拷贝
1右视图 frame3frame 3(10, 0)(390, 780)(506, 14)3 直接拷贝
2后视图 frame0frame 0(0, 0)(896, 298)(0, 598)3 直接拷贝
3前视图 frame1frame 1(4, 0)(892, 298)(0, 0)3 直接拷贝
4左视图和前视图重合部分frame 2(10, 0)(390, 282)frame 1(2, 16)(390, 282)(0, 16)1 alpha blend0 左上
5右视图和前视图重合部分frame 3(10, 0)(388, 284)frame 1(508, 14)(388, 284)(506, 14)1 alpha blend3 右上
6左视图和后视图重合部分frame 2(10, 582)(390, 196)frame 0(0, 0)(390, 196)(0, 598)1 alpha blend2 左下
7右视图和右视图重合部分frame 3(10, 584)(390, 196)frame 0(506, 0)(390, 196)(506, 598)1 alpha blend1 右下

STITCH配置参数:

struct stitch_ch_attr inch_attr[4] = {
{
.width = 896,
.height = 298,
.strid = {896, 896},
.rois = {
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 2, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 6, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 7, .roi_x = 506, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },

}
},
{
.width = 896,
.height = 298,
.strid = {896, 896},
.rois = {
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 3, .roi_x = 4, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 4, .roi_x = 2, .roi_y = 16, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 5, .roi_x = 508, .roi_y = 14, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },

}
},
{
.width = 400,
.height = 778,
.strid = {400, 400},
.rois = {
{ .roi_index = 0, .roi_x = 10, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 4, .roi_x = 10, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 6, .roi_x = 10, .roi_y = 582, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },

}

},
{
.width = 400,
.height = 780,
.strid = {400, 400},
.rois = {
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 1, .roi_x = 10, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 5, .roi_x = 10, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 7, .roi_x = 10, .roi_y = 584, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },

}
}
};

struct stitch_ch_attr och_attr = {
.width = 896,
.height = 896,
.strid = {896, 896},
.rois = {
{ .roi_index = 0, .roi_x = 0, .roi_y = 16, .roi_w = 390, .roi_h = 778 },
{ .roi_index = 1, .roi_x = 506, .roi_y = 14, .roi_w = 390, .roi_h = 780 },
{ .roi_index = 2, .roi_x = 0, .roi_y = 598, .roi_w = 896, .roi_h = 298 },
{ .roi_index = 3, .roi_x = 0, .roi_y = 0, .roi_w = 892, .roi_h = 298 },
{ .roi_index = 4, .roi_x = 0, .roi_y = 16, .roi_w = 390, .roi_h = 282 },
{ .roi_index = 5, .roi_x = 506, .roi_y = 14, .roi_w = 388, .roi_h = 284 },
{ .roi_index = 6, .roi_x = 0, .roi_y = 598, .roi_w = 390, .roi_h = 196 },
{ .roi_index = 7, .roi_x = 506, .roi_y = 598, .roi_w = 390, .roi_h = 196 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },
{ .roi_index = 0, .roi_x = 0, .roi_y = 0, .roi_w = 0, .roi_h = 0 },

}

STITCH初始化

int32_t init_stitch(test_ctx_t *test_ctx)
{
int32_t ret = 0, i;
hbn_buf_alloc_attr_t alloc_attr = {0};
char res_file_name[128] = {0};
struct stat fileStat;

ret = hbn_vnode_open(HB_STITCH, 0, -1, &test_ctx->sth_handle);
if (ret < 0) {
printf("STH vnode open fail\n");
return -1;
}

memset(res_file_name, 0, sizeof(res_file_name));
sprintf(res_file_name, "%s/%s", g_res_path, "alpha_lut_apa.bin");
if(stat(res_file_name, &fileStat) != 0) {
printf("Failed to get file stats. cfg file = %s\n", res_file_name);
return -1;
}

ret = hb_mem_alloc_com_buf(fileStat.st_size, HB_MEM_USAGE_MAP_INITIALIZED |
HB_MEM_USAGE_PRIV_HEAP_2_RESERVERD | HB_MEM_USAGE_CPU_READ_OFTEN |
HB_MEM_USAGE_CPU_WRITE_OFTEN | HB_MEM_USAGE_CACHED, &alpha_buffer);
if (ret < 0) {
printf("hb_mem_alloc_com_buf alpha_lut faild, ret = %d\n", ret);
return -1;
}

load_file_2_buff(res_file_name, (char *)alpha_buffer.virt_addr, fileStat.st_size);
hb_mem_flush_buf_with_vaddr((uint64_t)alpha_buffer.virt_addr, fileStat.st_size);

base_attr.alpha_lut.share_id = alpha_buffer.share_id;
base_attr.alpha_lut.vaddr = (uint64_t)alpha_buffer.virt_addr;
base_attr.alpha_lut.size = fileStat.st_size;

ret = hbn_vnode_set_attr(test_ctx->sth_handle, &base_attr);
if (ret < 0) {
printf("STH vnode set attr fail\n");
return -1;
}

for (i = 0; i < SENSOR_NUMS; i++) {
ret = hbn_vnode_set_ichn_attr(test_ctx->sth_handle, i, &inch_attr[i]);
if (ret < 0) {
printf("STH vnode set ichn attr fail\n");
return -1;
}
}

ret = hbn_vnode_set_ochn_attr(test_ctx->sth_handle, 0, &och_attr);
if (ret < 0) {
printf("STH vnode set ochn attr fail\n");
return -1;
}

memset(&alloc_attr, 0, sizeof(hbn_buf_alloc_attr_t));
alloc_attr.buffers_num = 3;
alloc_attr.is_contig = 1;
alloc_attr.flags = (int64_t)((uint64_t)HB_MEM_USAGE_CPU_READ_OFTEN |
(uint64_t)HB_MEM_USAGE_CPU_WRITE_OFTEN | (uint64_t)HB_MEM_USAGE_MAP_INITIALIZED);
alloc_attr.flags |= (uint64_t)HB_MEM_USAGE_CACHED;

ret = hbn_vnode_set_ochn_buf_attr(test_ctx->sth_handle, 0, &alloc_attr);
if (ret < 0) {
printf("STH vnode set ochn buf attr fail\n");
return -1;
}

ret = hbn_vnode_start(test_ctx->sth_handle);
if (ret < 0) {
printf("STH vnode start fail\n");
return -1;
}

return 0;
}

V4L2 Sample

imx219 + MIPI + CIM + ISP + PYM:

v4l2-ctl -d 0 --set-fmt-video=width=1920,height=1080,pixelformat=NV12 --stream-mmap --stream-count=120 --stream-to=/userdata/test.yuv

imx219 + MIPI + CIM + ISP + GDC:

v4l2 gdc 应用目前无法使用json文件生成config bin文件,所以目前v4l2 gdc 测试只用已生成好的config bin来进行测试
与原v4l2 取流代码相比,v4l2 gdc 取流代码需增加以下配置

#需增加gdc 输入图像宽高的参数配置
if (TestContext[i].gdc_cfg) {
TestContext[i].pic_width = 1920;
TestContext[i].pic_height = 1080;
TestContext[i].in_pic_width = 1920; //新增的输入图像宽度
TestContext[i].in_pic_height = 1080; //新增的输入图像高度
}

#需增加gdc config的配置
// 为gdc config bin申请内存
int map_gdc_config_buffer(hb_mem_common_buf_t *hb_common_buf, uint32_t size)
{
int64_t alloc_flags = 0;
int ret;

alloc_flags = HB_MEM_USAGE_PRIV_HEAP_2_RESERVED | HB_MEM_USAGE_CPU_READ_OFTEN | HB_MEM_USAGE_CPU_WRITE_OFTEN | HB_MEM_USAGE_CACHED;
memset(hb_common_buf, 0, sizeof(hb_mem_common_buf_t));
ret = hb_mem_alloc_com_buf(size, alloc_flags, hb_common_buf);
if (ret < 0) {
vio_gtest_err("hb_mem_alloc_com_buf size %u failed \n", size);
return ret;
}

return 0;
}

// 向gdc v4l2 驱动下发配置的ioctl接口
int v4l2_set_ext_ctrl(int fd, uint32_t cmd, void *arg)
{
int rc;
struct v4l2_ext_controls ext_ctrl = {0};
struct v4l2_ext_control ctrl = {0};

ext_ctrl.controls = &ctrl;
ext_ctrl.controls->id = cmd;
ext_ctrl.controls->ptr = arg;
ext_ctrl.count = 1;

rc = ioctl(fd, VIDIOC_S_EXT_CTRLS, &ext_ctrl);
if (rc < 0)
vio_gtest_err("%s, cmd=%d, rc=%d\n", strerror(errno), cmd, rc);
return rc;
}

int v4l2_gdc_init(vpm_test_context *ptc)
{
int fd, ret;
FILE *file = NULL;
struct stat fileStat;
hb_mem_common_buf_t hb_common_buf;
gdc_config_t gdc_user_cfg;
work_info_t *winfo = &ptc->work_info;

if (!ptc->gdc_cfg || !winfo->priv_fd)
return -1;

file = fopen(ptc->gdc_cfg, "r");
if (file == NULL) {
perror("Error opening file\n");
return -1;
}
//获取gdc config bin 大小
ret = fstat(fileno(file), &fileStat);
if (ret) {
perror("Error getting file status");
goto err;
}

vio_gtest_info("File size: %ld bytes\n", fileStat.st_size);
// 申请存放gdc config bin的内存
ret = map_gdc_config_buffer(&hb_common_buf, fileStat.st_size);
if (ret)
goto err;
//将gdc config bin内容复制到刚刚申请的内存中
if (fread(hb_common_buf.virt_addr, 1, fileStat.st_size, file) != fileStat.st_size) {
vio_gtest_err("failed to read gdc config file!\n");
ret = -1;
goto err;
}
vio_gtest_info("gdc config bin buffer phy_addr:%p virt_addr:%p size:%d\n",
hb_common_buf.phys_addr, hb_common_buf.virt_addr, hb_common_buf.size);

ret = hb_mem_flush_buf_with_vaddr((uint64_t)hb_common_buf.virt_addr, fileStat.st_size);
if (ret) {
vio_gtest_err("failed to hb_mem_flush_buf_with_vaddr!\n");
goto err;
}

gpm[winfo->pipe_id].gdc_config.config_addr = (uint64_t)hb_common_buf.virt_addr;
gpm[winfo->pipe_id].gdc_config.config_size = hb_common_buf.size;
//gdc 输入图像宽高
gpm[winfo->pipe_id].gdc_config.output_width = ptc->pic_width;
gpm[winfo->pipe_id].gdc_config.output_height = ptc->pic_height;
gpm[winfo->pipe_id].gdc_config.output_stride = ALIGN_UP(ptc->pic_width, STRIDE_ALIGN);
//gdc 输出图像宽高
gpm[winfo->pipe_id].gdc_config.input_width = ptc->in_pic_width;
gpm[winfo->pipe_id].gdc_config.input_height = ptc->in_pic_height;
gpm[winfo->pipe_id].gdc_config.input_stride = ALIGN_UP(ptc->in_pic_width, STRIDE_ALIGN);

gpm[winfo->pipe_id].gdc_config.div_width = 0;
gpm[winfo->pipe_id].gdc_config.div_height = 0;
gpm[winfo->pipe_id].gdc_config.sequential_mode = 0;
gpm[winfo->pipe_id].gdc_config.total_planes = 2;

gpm[winfo->pipe_id].binary_ion_id = hb_common_buf.share_id;
gpm[winfo->pipe_id].binary_offset = hb_common_buf.offset;

gpm[winfo->pipe_id].magicNumber = 0x12345678;

// 将配置下发到gdc v4l2 驱动中
ret = v4l2_set_ext_ctrl(winfo->priv_fd, V4L2_CID_DR_GDC_ATTR, &gpm[winfo->pipe_id]);
if (ret) {
vio_gtest_err("v4l2_set_ext_ctrl error!!!\n");
goto err;
}

err:
fclose(file);
return ret;

}

#释放gdc config bin
void v4l2_gdc_deinit (vpm_test_context *ptc)
{
work_info_t *winfo = &ptc->work_info;
hb_mem_free_buf_with_vaddr((uint64_t)gpm[winfo->pipe_id].gdc_config.config_addr);
}