征程 6E/M 快速上手实战 Sample-Camera

news/2024/9/27 20:45:27

01 Camera 模块简述

本文档简单介绍 Camera 子系统软件架构、列出已支持的 Camera 模组,并提供相应的配置说明,同时引用 Sensor 点亮调试方法介绍一颗新模组接入的步骤,再按根据重要功能按专题介绍接入方案限制、EMB 接收等,并最终汇总平台已有单板的 Camera 接入使用说明,用于指导 征程6 在 Camera 接入上的量产调试。

1.1 硬件特性

征程6 上 Camera 接入后,进入后级模块处理,其数据流通路主要相关模块有如下:

  • MIPI RX: 3 路 CDPHY,每路为 DPHY 最大 4.5Gbps/lane x 4lane 或 CPHY 最大 3.5Gbps/trio x 3trio,每路支持 4VC,最多支持 12 路接入。

  • MIPI TX: 2 路 DPHY,每路为 2.5Gbps/lane x 4lane,支持 RX bypass 与 IDU 输出方式。

  • 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 处理。

此处默认示例使用的模组及连接关系为:

RX 口 LINK 端子模组描述备注 RX0ALCE-OVX8B Fov1203840x2160 RAW12CLCE-OVX8B Fov303840x2160 RAW12DLCE-OVX3C Fov601920x1280 RAW12RX1A-DLCE-OVX3C Fov1001920x1280 RAW12RX4A-DSENSING-ISX031 Fov1901920x1536 YUV422

本 sample 基于 Matrix 6E/M 硬件使用,其硬件连接及数据流通路如下:

image

1.2 软件功能

征程6 的 Sensor 接入属于图像处理子系统中的 Camera 部分,各模块间有结构如下:

image

其中 Camera 部分主要包括:Sensor,Deserial,Poc,Txser 设备驱动及 MIPI 配置操作,系统结构有如下:

image

本 sample 基于 VIO API 实现,调用 libvio 提供的 API,同时通过配置文件的方式,实现单路或多路 Camera 接入验证,并支持将接收的数据图像 dump 到文件系统中,用于图像数据验证,同时还支持可选的 hbplayer 显示功能,用于查看 Camera 输入图像。

image

02 Camera-Sample 使用

本文的 demo sample 实现单路、多路 Camera 接入与处理。

2.1 调用流程

采用 MediaCodec 的 poll 模式来解耦输入和输出,可使编码帧率性能达到最优。在主线程中灌 YUV 数据:取出一个空的 input buffer,配置 YUV 数据的地址信息(如 phys addr),再 queue input buffer 并通知编码器处理该帧数据;另一个线程取输出码流:通过 select 接收硬件编码完成通知,取出一个硬件填满输出码流的 output buffer,将编码结果写到文件中后归还 output buffer。

image

此处的 hb_cam_start/hb_cam_stop 为可选调用,目前在 sample 中未直接使用,若有兼容原 VIO API 流程需要,仍支持继续调用。

int32_t hb_vio_init( const char *cfg_file):初始化 VIO 模块,包括 cim& isp & pym & gdc & ynr,初始化配置文件配置的所有 pipeline,多路场景时配置文件对应包含多路配置,vio init 必须最先调用,再调用 hb_cam_init。

int32_t hb_vio_deinit(void):释放 init 中用到的各种资源,内存等。

int32_t hb_cam_init(uint32_t cfg_index,const char *cfg_file):初始化 cam 模块中的 sensor & mipi rx(mipi tx)。

int32_t hb_cam_deinit(uint32_t cfg_index):释放 camera 模块资源,和 hb_cam_init 对应。

int32_t hb_vio_start_pipeline(uint32_t pipeline_id):启动 vio pipe 通路工作,对应初始化中的数据通路。

int32_t hb_cam_start(uint32_t port):启动 sensor 数据流,mipi 检查是否有 hs 信号,使能对应 cim/cimdma。

int32_t hb_vio_get_data(uint32_t pipeline_id, VIO_DATA_TYPE_E info_type,void* data):指定 pipeline_id,通过 type 类型,执行不同的实际操作,得到对应 type 类型的数据结构,获取到的 yuv 图像地址默认是连续的。

int32_t hb_cam_stop(uint32_t port):关闭 sensor 数据流,执行 mipi stop,关闭对应 cim/cimdma。

int32_t hb_vio_stop_pipeline(uint32_t pipeline_id):关闭 vio 对应 pipe id 通路工作,对应初始化中的数据通路,如果数据通路包含 hb_vio_start_pipeline 所打开的,退出时需要先关闭 camera 数据。

2.2 源码主干

#Sample源码路径
/test/samples/platform_samples/source/S83_Sample/S83E04_Module/camera_sample

Encoder:

static void *vflow_frame_thread(void *arg)
{int32_t ret;float fps;struct timeval last, now;vflow_work_t *vfw = (vflow_work_t *)arg;char tname[32];if ((vfw == NULL) || ((uint32_t)vfw->flow_id >= HB_VIO_PIPELINE_MAX)) {return NULL;}snprintf(tname, sizeof(tname), "cam%d:%s", vfw->flow_id, vio_types[vfw->flow_type]);prctl(PR_SET_NAME, tname);pr_info("thread %s work\n", tname);gettimeofday(&last, NULL);while (check_end() && (vfw->th_create <= 1)) {ret = vflow_frame_do(vfw);if (ret < 0) {usleep(1*1000);continue;}/* fps cal and show */gettimeofday(&now, NULL);if (time_cost_ms(&last, &now) >= (FPS_TIMER_MS - 1)) {memcpy(&last, &now, sizeof(struct timeval));fps = vfw->frame_cntfps / (FPS_TIMER_MS / 1000.0);vfw->frame_cntfps = 0;if (vfw->flow_log & (0x1 << VFLOW_LOG_FPS))pr_info("camera flow%d:t%d-%s frame %d: fps %.2f\n",vfw->flow_id, vfw->flow_type, vio_types[vfw->flow_type],vfw->frame_cntall, fps);}}vfw->th_create = 0;pr_info("thread %s exit\n", tname);return NULL;
}
static int32_t vflow_frame_do(vflow_work_t *vfw)
{int32_t ret, dump = 0;vflow_img_t img = { 0 };int32_t flow_id = vfw->flow_id;uint32_t type = (uint32_t)vfw->flow_type;char dump_name[128];int32_t tsdiff = 0;uint32_t id = 0u, w = 0u, h = 0u;uint64_t tslast = 0ul, ts = 0ul;/* get */ret = vflow_img_get(vfw, &img);if (ret < 0) {vfw->frame_err++;return ret;}/* base info */vflow_img_baseinfo(vfw, &img, &id, &ts, &w, &h);vfw->frame_cntall++;vfw->frame_cntfps++;tslast = (vfw->ts_last) ? vfw->ts_last : ts;vfw->ts_last = ts;/* get show */if (vfw->flow_log & (0x1 << VFLOW_LOG_GET)) {tsdiff = ts_diff(tslast, ts);pr_info("camera flow%d:t%d-%s get: ts %lu.%06lu (+%d %.3fms) id %d\n",flow_id, type, vio_types[type], ts2s(ts), ts2us(ts),tsdiff, (ts2us(tsdiff) / 1000.0), id);}/* info show */if (vfw->flow_log & (0x1 << VFLOW_LOG_INFO)) {vflow_img_info(vfw, &img);}/* detail show */if (vfw->flow_log & (0x1 << VFLOW_LOG_DETAIL)) {vflow_img_detail(vfw, &img);}/* dump */if (vfw->flow_dump) {if ((vfw->flow_dadd) && ((vfw->frame_cntall % vfw->flow_dadd) == 0)) {dump = 1;}if ((vfw->flow_dmax) && (vfw->frame_dump < vfw->flow_dmax)) {dump = 1;}if (dump) {snprintf(dump_name, sizeof(dump_name), "p%d_cam_%s_%dx%d_d%d_f%u_t%lu.%lu.%s",vfw->flow_id, vio_types[type], w, h,vfw->frame_dump, id, ts2s(ts), ts2us(ts), vio_filetypes[type]);vflow_img_dump(dump_name, &img);vfw->frame_dump++;}}/* show */if (vfw->flow_show) {if ((vfw->frame_cntall % vfw->flow_show) == 0)vflow_show_img(vfw, &img);}/* free */vflow_img_free(vfw, &img);return ret;
}

2.3 编译&运行

获取 AppSDK 包后,进入 appuser 执行:

*其中 hbrootfs-sdk_0.0.1.XXX_all.deb 是地平线自己的库和头文件,rootfs-sdk-focal_0.0.1.XXX_all.deb 是系统库,aarch64-linux-hb-gcc_12.2.0_amd64.deb 是 gcc 12.2.0 工具链,目前在 ubuntu22.04 非 docker 环境下运行正常。其它环境不能保证。

dpkg-deb -x rootfs-sdk*.deb ./sdk
dpkg-deb -x hbrootfs-sdk*.deb ./sdk
##移动sdk库路径,本文档放入/usr/lib中
sudo mv sdk/ /usr/lib

进入 toolchain 执行:

dpkg -x aarch64-linux-hb-gcc_12.2.0_amd64.deb ./arm-gnu-toolchain
##移动toolchain库路径,本文档放入/usr/lib中
sudo mv arm-gnu-toolchain/ /usr/lib
nano ~/.bashrc
##添加系统路径
export PATH="/usr/lib/arm-gnu-toolchain/bin:$PATH"
export LD_LIBRARY_PATH="/usr/lib/arm-gnu-toolchain/lib:$LD_LIBRARY_PATH"
##
source ~/.bashrc

Sample 代码路径:

#Sample源码路径
/test/samples/platform_samples/source/S83_Sample/S83E04_Module/camera_sample

运行参数说明:

参数名说明是否必须备注-c 指定 Camera 配置文件,默认为。/hb_j6dev.json 否若非当前目录,需指定-v 指定 VIO 配置文件,默认为。/vpm_config.json 否若非当前目录,需指定-p 指定运行 camera 通道的数量,默认为自动获取否若非全运行,需指定-M 指定运行 camera 通路的掩码,默认为自动获取否若非全运行,可指定-t 指定要获取的数据类型,按 bit 掩码,默认为 CIM_RAW 支持 b#的方式进行配置,如:CIM_RAW:b24,CIM_YUV:b25 否若为 YUV 数据,需指定-d 使能 dump 功能,将数据 dump 到当前运行目录下支持 dump 数量设置,如:-d 10 为前 10 帧否若要 dump 数据,需使能-s 使能 hbplayer 显示功能否若要显示查看,需使能-S 配置 hbplayer 显示用端口,默认 0 使用默认端口否-l 指定 log 打印信息,通过 bit 掩码配置,默认为 1,只打印 fps 统计信息:b0-fps 统计信息,b1-取帧时信息,b2-帧基础信息,b3-帧详细信息,b4-显示发送信息;否-r 指定运行时间,默认为 0,只验证配置后立即退出是若要长时运行,需指定-V 获取 sample 版本信息否-h 查看帮助信息否

复制/src 源码到新建文件夹 codec 并构建新 Makefile:

camera
├── cfg
│   └── case_matrix
│       └── ...
├── Makefile
├── program
└── src├── camera_sample.c└── camera_sample.o

Makefile:

CROSS_COMPILE = aarch64-none-linux-gnu-
OUTPUT_HBROOTFS_DIR = /usr/lib/sdkCXX := ${CROSS_COMPILE}gccINC_DIR := ${OUTPUT_HBROOTFS_DIR}/usr/hobot/include
INC_DIR += ${OUTPUT_HBROOTFS_DIR}/include
LIB_DIR := ${OUTPUT_HBROOTFS_DIR}/usr/hobot/lib 
LIB_DIR += ${OUTPUT_HBROOTFS_DIR}/usr/lib/aarch64-linux-gnu
LIBS += -lvio -lpthread -lalog -lhbmem -lvpf
LIBS += -lhbplayer -lcam -lcjson -lgdcbin
CXXFLAGS := -Wall -O2 $(foreach dir,$(INC_DIR),-I$(dir))
CXXFLAGS += -DENABLE_HBPLAYER
LDFLAGS := $(addprefix -L, $(LIB_DIR)) $(LIBS)SRC_DIR := src
TARGET := program
SRCS := $(wildcard $(SRC_DIR)/*.c)OBJS := $(SRCS:.c=.o)$(TARGET): $(OBJS)$(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@
%.o: %.c$(CXX) $(CXXFLAGS) -c $< -o $@
clean:rm -f $(OBJS) $(TARGET)

执行 make 完成编译,生成的文件为。/program

image

使用 WinScp 将 program 和 cfg 文件夹都传输到单板上。

*WinScp 使用方法请参考征程 6E/M 底软开发 Sample-IPC 2.1.2

硬件连接:

image

image

RX 口 LINK 端子模组描述 RX0ALCE-OVX8B Fov1203840x2160 RAW12CLCE-OVX8B Fov303840x2160 RAW12DLCE-OVX3C Fov601920x1280 RAW12RX1A-DLCE-OVX3C Fov1001920x1280 RAW12

chmod +x program
#camera
#1V_OVX8B_RX0
./program -c ./cfg/case_matrix/1V_OVX8B_RX0/hb_j6dev.json -v cfg/case_matrix/1V_OVX8B_RX0/vpm_config.json -r 10
#2V_OVX8B_OVX3C_RX0
./program -c ./cfg/case_matrix/2V_OVX8B_OVX3C_RX0/hb_j6dev.json -v cfg/case_matrix/2V_OVX8B_OVX3C_RX0/vpm_config.json -r 10
#3V_2xOVX8B_1xOVX3C_RX0
./program -c ./cfg/case_matrix/3V_2xOVX8B_1xOVX3C_RX0/hb_j6dev.json -v cfg/case_matrix/3V_2xOVX8B_1xOVX3C_RX0/vpm_config.json -r 10
#4V_4xOVX3C_RX1
./program -c ./cfg/case_matrix/4V_4xOVX3C_RX1/hb_j6dev.json -v cfg/case_matrix/4V_4xOVX3C_RX1/vpm_config.json -r 10
#4V_4xISX031_RX4
./program -c ./cfg/case_matrix/3V_2xOVX8B_1xOVX3C_RX0/hb_j6dev.json -v cfg/case_matrix/3V_2xOVX8B_1xOVX3C_RX0/vpm_config.json -r 10

Sample 运行时日志:*1V

[camera_sample]:cam_cfg_file = ./cfg/case_matrix/1V_OVX8B_RX0/hb_j6dev.json
[camera_sample]:vio_cfg_file = cfg/case_matrix/1V_OVX8B_RX0/vpm_config.json
[camera_sample]:run_time = 10
[camera_sample]:camera_sample start
[camera_sample]:hb_vio_init(cfg/case_matrix/1V_OVX8B_RX0/vpm_config.json) ...
[camera_sample]:hb_cam_init(0, ./cfg/case_matrix/1V_OVX8B_RX0/hb_j6dev.json) ...
[camera_sample]:  auto get 1 pipe mask 0x1
[camera_sample]:hb_vio_start_pipeline(0) ...
[camera_sample]:thread cam0:CIM_RAW work
[camera_sample]:camera flow0:t24-CIM_RAW frame 25: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 50: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 75: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 100: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 125: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 150: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 175: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 200: fps 25.00
[camera_sample]:camera flow0:t24-CIM_RAW frame 225: fps 25.00
[camera_sample]:thread cam0:CIM_RAW exit
[camera_sample]:hb_vio_stop_pipeline(0) ...
[camera_sample]:hb_cam_deinit() ...
[camera_sample]:hb_vio_deinit() ...
[camera_sample]:camera_sample end 0 --> PASS

运行过程中还可通过以下命令查看帧率信息:

cat /sys/class/vps/flow/fps

sample 支持将数据 dump 到文件系统,供查看验证,只需在运行命令加上:-d 10 (dump 前 10 帧)。

#1V_OVX8B_RX0
./program -c ./cfg/case_matrix/1V_OVX8B_RX0/hb_j6dev.json -v cfg/case_matrix/1V_OVX8B_RX0/vpm_config.json -d 10 -r 10

image

可取上述 raw 数据查看使用。

hbplayer 显示:

本 sample 支持将数据通过网络发送到 PC 端,配合 hbplayer 工具,在线查看数据流接入,只需在运行命令加上:-s 1 (若要长时间运行,可通过-r 调整运行时间)。

./program -c ./cfg/case_matrix/1V_OVX8B_RX0/hb_j6dev.json -v cfg/case_matrix/1V_OVX8B_RX0/vpm_config.json -r 100 -s 1

之后运行,将自动获取图像并发送给 hbplayer。

PC 打开 hbplayer\out\hbplayer.exe:*获取的为 raw 数据

image

*如果出现监视窗口缩放系数错误的问题请尝试修改主机分辨率为 100%:

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/65534.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

章15——泛型generic

泛型的引入泛型引入前后代码的比较 public static void main(String[] args) {ArrayList arrayList = new ArrayList();arrayList.add(new Dog("wang",10));arrayList.add(new Dog("xin",1));arrayList.add(new Dog("ran",5));//遍历for (Object…

QGIS 操作

qgis 两个shp 文件 合并 去重,导出新的shp qgis 导出shp

IDA pro

网上可以找多许多讲解IDA pro的使用教程,想着自己能写一个尽量全一点的,于是补写了本片文章(本篇文章只讲解使用,默认大家都会下载与安装) 参考: https://lazzzaro.github.io/2020/05/12/reverse-IDA/ https://www.cnblogs.com/Chary/p/17195663.html页面介绍 静态分析界面…

深度讲解-APP安全评估报告(APP上架必备)

随着《具有舆论属性或社会动员能力的互联网信息服务安全评估规定》(以下简称《评估规定》)的发布,互联网信息服务提供者在开展具有舆论属性或社会动员能力的App服务时,必须遵循相应的安全评估流程。以下是详细的App安全评估申请流程,帮助您顺利完成评估,确保应用合规与安…

[转]boost使用之编译库及遇到的问题

最近因为在学习网络编程相关的东西,准备学习一下boost,毕竟原生的网络编程太麻烦。看了一下其实windows下想使用起来很简单,就是下载库,然后运行脚本,然后运行exe库就出来。在把头文件和库的目录包含进去就可以了。在此详细记录一下: 0、预装准备 电脑WIN10系统,已经安装…

字符编码发展史4 — Unicode与UTF-8

上一篇《字符编码发展史3 — GB2312/Big5/GBK/GB18030》我们讲解了ANSI编码中的GB2312/Big5/GBK/GB18030。本篇我们将继续讲解字符编码的第三个发展阶段中的Unicode与UTF-8。 2.3. 第三个阶段 国际化 前面提到的第二个阶段,各个国家和地区各自为政,纷纷制定了适用于自己国家语…

sql注入常见绕过方法

sql注入可以说是非常成熟的攻击手段了 对其的防御体系也很完善 据owasp统计 存在注入类漏洞的网站不超过10% 首先我们了解下sql注入的类型: 分为直接有回显的:联合注入: 通过联合查询语句进行信息的查询 需要页面回显数据 报错注入: 需要页面存在查询语句报错回显 堆叠注入: 需…

Volcano新版本发布:10大功能提升统一调度和细粒度资源管理能力

Volcano是业界首个云原生批量计算社区,也是 CNCF 首个及唯一孵化级批量计算项目。Volcano主要用于 AI、大数据、基因、渲染等诸多高性能计算场景,对主流通用计算框架均有很好的支持。本文分享自华为云社区《Volcano v1.10.0 版本正式发布!10大功能全面提升统一调度和细粒度资…