K230 图像实战-开机视频和开机logo
硬件要求:
- DshanPI-CanMV开发板
- MIPI屏
- Type-C数据线 x2
开发环境:
- Ubuntu20.04
注意:在学习前请按照《K230 SDK环境搭建》搭建好K230的开发环境或者直接获取资料光盘中搭建好环境的Ubuntu虚拟机。
1. Sensor架构
Sensor模块是VICAP捕获图像的数据源之一,负责配置图像感光单元的运行参数及工作模式。
K230平台支持多种接口类型的sensor,我们以当前最常用的MIPI CSI接口Sensor为例进行说明。Sensor与主控平台的硬件连接示意图如下:
主控通过I2C接口下发配置寄存器控制sensor的工作方式,sensor通过MIPI CSI接口将图像数据发送至主控SOC。
Sensor模块系统架构如下图所示:
从上到下依次是:媒体接口层,硬件驱动层以及硬件层
- 媒体接口层:提供kd_mpi_sensor_xxx接口给外部模块操作和访问sensor设备。
- 驱动层:该层主要包两部分,分别是:sensor_dev,sensor_drv。
- sensor_dev:负责设备驱动文件的注册,提供文件操作接口的实现流程。通过注册设备文件节点/dev/sensorxx供用户空间的程序访问内核驱动。
- sensor_drv:具体sensor的硬件驱动,并将针对sensor的操作封装为统一的接口。
- 硬件层:sensor模组硬件,当前系统中最多同时支持三路硬件sensor。
2. 软件环境
k230_sdk中提供了工具链,分别在如下路径。
- 大核rt-samrt工具链
k230_sdk/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu
- 小核linux工具链
k230_sdk/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0
也可通过以下链接下载工具链
wget https://download.rt-thread.org/rt-smart/riscv64/riscv64-unknown-linux-musl-rv64imafdcv-lp64d-20230222.tar.bz2
wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1659325511536/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0-20220715.tar.gz
3. 源码位置
SDK中包含一个用户态解码demo,路径位于k230_sdk/src/big/mpp/userapps/sample/sample_vdec
。编译生成的可执行文件在k230_sdk/src/big/mpp/userapps/sample/elf/sample_vdec.elf
,默认没有加载到大核镜像中,需要按照执行方式章节修改Makefile才能在大核启动后的/mnt
目录中生成可执行文件。
4. 源码解析
代码流程图如下所示:
4.1 打开输入文件
FILE *input_file = fopen(argv[2], “rb”);
4.2 初始化视频缓冲区
memset(&config, 0, sizeof(config));
config.max_pool_cnt = 2;
// 设置视频缓冲区配置
ret = kd_mpi_vb_set_config(&config);
4.3 创建视频缓冲区池
k_vb_pool_config pool_config;
memset(&pool_config, 0, sizeof(pool_config));
pool_config.blk_cnt = INPUT_BUF_CNT; // 设置输入缓冲区池的块数量
pool_config.blk_size = STREAM_BUF_SIZE; // 设置输入缓冲区池的块大小
pool_config.mode = VB_REMAP_MODE_NOCACHE; // 设置输入缓冲区池的映射模式
g_vdec_conf[ch].input_pool_id = kd_mpi_vb_create_pool(&pool_config); // 创建输入缓冲区池
vdec_debug(“input_pool_id %d\n”, g_vdec_conf[ch].input_pool_id);
memset(&pool_config, 0, sizeof(pool_config));
pool_config.blk_cnt = OUTPUT_BUF_CNT; // 设置输出缓冲区池的块数量
pool_config.blk_size = FRAME_BUF_SIZE; // 设置输出缓冲区池的块大小
pool_config.mode = VB_REMAP_MODE_NOCACHE; // 设置输出缓冲区池的映射模式
g_vdec_conf[ch].output_pool_id = kd_mpi_vb_create_pool(&pool_config); // 创建输出缓冲区池
4.4 创建视频解码通道
ret = kd_mpi_vdec_create_chn(ch, &attr);
4.5 设置视频解码通道属性
attr.pic_width = MAX_WIDTH; // 设置图片最大宽度
attr.pic_height = MAX_HEIGHT; // 设置图片最大高度
attr.frame_buf_cnt = OUTPUT_BUF_CNT; // 设置帧缓冲区数量
attr.frame_buf_size = FRAME_BUF_SIZE; // 设置帧缓冲区大小
attr.stream_buf_size = STREAM_BUF_SIZE; // 设置流缓冲区大小
4.6 根据文件扩展名确定视频类型
char *ptr = strrchr(argv[2], ‘.’);
if (ptr!= NULL) {
if (strcmp(ptr, “.h264”) == 0 || strcmp(ptr, “.264”) == 0) {
type = K_PT_H264;
vdec_debug(“file type is H264\n”);
} else if (strcmp(ptr, “.jpeg”) == 0 || strcmp(ptr, “.mjpeg”) == 0 || strcmp(ptr, “.jpg”) == 0) {
type = K_PT_JPEG;
vdec_debug(“file type is JPEG\n”);
} else if (strcmp(ptr, “.h265”) == 0 || strcmp(ptr, “.hevc”) == 0 || strcmp(ptr, “.265”) == 0) {
type = K_PT_H265;
vdec_debug(“file type is H265\n”);
} else {
vdec_debug(“Error input type\n”);
return -1;
}
}
4.7 启动视频解码通道
ret = kd_mpi_vdec_start_chn(ch);
4.8 将视频解码绑定到显示层
sample_vdec_bind_vo(BIND_VO_LAYER);
5. 程序执行
- 修改
k230_sdk/Makefile
中mpp-apps
的编译脚本。 将
cp userapps/sample/fastboot_elf/* $(RTSMART_SRC_DIR)/userapps/root/bin/; \
改为
cp userapps/sample/elf/sample_vdec.elf $(RTSMART_SRC_DIR)/userapps/root/bin/; \
- 将需要显示的H.264/H.265/MJPEG/JPEG文件拷贝到
k230_sdk/src/big/rt-smart/userapps/root/bin
目录中 - 修改
k230_sdk/src/big/rt-smart/init.sh
为如下命令:
/bin/sample_vdec -i [-t ]
<filename>
为上一步中拷贝的视频文件-t
仅在显示图片时使用,为显示图片的时间。
- 在
k230_sdk
目录下挂载工具链目录sudo mount --bind $(pwd)/toolchain /opt/toolchain
后执行make CONF=k230_canmv_dongshanpi_defconfig
编译SDK。 - 将编译生成的
k230_sdk/output/k230_canmv_dongshanpi_defconfig/images/sysimage-sdcard.img
烧写到开发板中,即可实现开机显示视频。