海思3403-SS928 yolov5 c++开发日记(3)

前两天都是记录了4.8T哪个核的yolov5 的转换和推理,今天补充记录一下关于海思3403-SS928这个芯片的开发环境和其中的一些坑。其中个人觉得关于环境、编译最坑的是关于视频硬解码器的开发和编译。

海思3403-SS928这个芯片我们从供应商哪里拿到的(据称)官方的SDK包里,里面是有个 aarch64-mix210-linux 的编译器。按照官方的文档说,这是个交叉编译器,可以安装在x86 的linux上,然后使用export 等 环境 配置后,就可调用。但这里有两个坑。一个是在这个包的 readme.txt 这个文档上说使用 source 调用这个 aarch64-mix210-linux.install 文件。以下是这个readme.txt 的原文 :

There is two files in the folder: aarch64-mix210-linux.tar.bz2 and aarch64-mix210-linux.install.

The aarch64-mix210-linux.install is a shell script to install the aarch64-mix210-linux toolchain.

You can use
source ./aarch64-mix210-linux.install
command line to install toolchain in /opt/linux/x86-arm.

Or you can use
source ./aarch64-mix210-linux.install dirname
command line to install toolchain in the “dirname” which you Specified.

For now, you can use toolchain like aarch64-mix210-linux-xxx in everywhere.

但在另一个文档,《ATC 工具使用指南》上说,这是得 chmod 777 后直接运行,然后再用export 把C/C++编译器指向安装后目录的。这是两种完全不同的方法,后我使用了《ATC 工具使用指南》上的方法,证实这个方法是可行的。可以安装这个编译器,并使用这个编译器进行编译。但,这还是有个问题,就是这个编译器的命令行调用与一般的 gcc 和 g++ 有一些不同,这样导致如果使用这个编译器编译 ffmpeg 和 opencv 的话有一些麻烦。因为视频和图像处理需要用到 ffmpeg 和 opencv 而 ffmpeg 的现成编译版本不能直接在这板上使用,并且opencv 也需要做一些在版本上加入 freetype 等库,需要自行编译,所以我们使用了另一个方法。

方法并不复杂,就是使用一个arm 版本的 ubuntu 18.04的镜像的docker 容器。在容器里安装 gcc 7.5.0 的编译器,然后在这个容器里进行开发就可以了。虽然 aarch64-mix210-linux 包的编译器应该是 7.3.0 的,但区别应该不大。经测试,在这个容器里使用gcc 7.5.0 编译出的程序能在 这个海思 3403-ss928 上完美运行的。

说到这里就要说到这个3403-SS928编译关联的第二个坑。就是这个芯片的视频硬解码库并不能编译进 ffmpeg 里,只能手写调用ffmpeg 取流程序,在程序里取得流数据后,再把数据传进提供的硬 解码库,调用相关接口进行解码,然后取得解码后的数据,再转成需要的格式,例如:cv:Mat 类型。这相比起同类芯片,例如 瑞芯微rk3588 实在太。。。(#¥!)麻烦了。这需要对h264 / h265 编解码的和rtsp 流有比较深入的了解才能把这整个过程实现。rk3588 是有对应 可以编译进 ffmpeg 的库的。在调用ffmpeg 时直接就能调用对应的硬解码,而无需额外编写硬解码的调用处理代码。然后,还有一个更坑的是,3403-SS928的硬解码库的程序编译是不能使用上面说的 ubuntu18.04+ gcc7.5.0 组合的docker 容器。在容器里编译时会报 glibc 版本没找到的问题。 必须使用官方的哪个 aarch64-mix210-linux 编译器才能编译成功。

最后,为了解决上面的哪个问题,想到了先写一个调用他硬解码的库,在 aarch64-mix210-linux 编译后。再在容器中写一个通过动态加载的方式加载这个硬解码库并调用解码接口的方式,解决编译上不兼容的这个问题。

编译opencv-4.8.1+ffmpeg的一些问题和解决方法

1、此版opencv貌似存在图片处理上的bug,在arm类的CPU上编译时会在photo上报错,所以得加上 -DBUILD_opencv_xphoto=OFF -DBUILD_opencv_optflow=OFF -DBUILD_opencv_rgbd=OFF 参数,把xphoto屏蔽掉。

2、在arm类的cpu上的linux 编译是不会下载ffmpeg库,即使添加了–DWITH_FFMPEG=ON 也一样,得使用系统APT或YUM下载的 ffmpeg 和相关库并安装才能找到并编译,但如果是有裁剪和嵌入的FFMPEG的需要,就需要自行编译FFMPEG.

3、编译FFMPEG不能使用静态库,并且需要把avresample 加入ffmpeg的编译,否则在编译OPENCV时,会提示找不到avresample 的引用而导致编译报错

4、需要加入-DOPENCV_EXTRA_MODULES_PATH 扩展库,否则在编译OPENCV时会报缺少引用而编译失败

5、怀疑是因为旧版本的编译器的关系,例如是在SS928(即海思3403)的交叉编译器上编译,在编译测试程序时会报错。需要加入-DBUILD_TESTS=OFF 强制不编译OPENCV的测试程序

最后,以下是我在SS928(即海思3403)编译环境上使用的完整OPENCV和FFMPEG的预编译命令:

cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_opencv_world=ON -DCMAKE_INSTALL_PREFIX=./install -DBUILD_opencv_xphoto=OFF -DBUILD_opencv_optflow=OFF -DBUILD_opencv_rgbd=OFF -DWITH_FFMPEG=ON -DOPENCV_EXTRA_MODULES_PATH=../../modules -DBUILD_TESTS=OFF ..

./configure –enable-gpl –enable-libx264 –prefix=./install –enable-pic –enable-avresample –enable-shared –disable-static