该篇文章转自大疆开发论坛:https://bbs.dji.com/forum.php?mod=viewthread&tid=260759
各位论坛的小伙伴们,好久不见!
今天准备给大家分享一个 H264 的硬件解码 sample
在分享之前先说说问题的背景
不知道你之前在使用 DJI OSDK 获取视频流时是否会有这样的苦恼
我不就是跑个视频流 Sample 吗,为啥 CPU 占用率都上 200% 了
或者遇到这样的情况
这延迟得有 400 多毫秒了吧,比我手机玩 DOTA 延迟高了五六倍不止
好吧,仔细分析,你会发现造成延迟和占用率高的主要原因都是 H264 进行 CPU 软件解码造成的
为了不让 CPU 作为背锅侠,我们今天我们试着一起来跑一下 H264 硬件解码的 sample
废话不多说,Sample 开源代码我丢这里了
camera_h264_hardware_decode_sample.zip (16.99 KB, 下载次数: 19)
1. Sample 运行环境
OSDK :OSDK 4.0.1 或者更高版本 https://github.com/dji-sdk/Onboard-SDK
平 台:妙算2-G https://www.dji.com/cn/manifold-2
飞行器:M200 V2, M300 RTK https://www.dji.com/cn/matrice-300
相 机:H20, Z30 https://www.dji.com/cn/zenmuse-h20-series
2. 安装依赖工具
2.1 安装 gstreamer
妙算2-G 已经安装有 gstreamer,并支持硬件解码,所以本步骤可以跳过
2.2 安装 gstreamer lib
sudo apt-get install libgstreamer-plugins-base1.0
2.3 检查 gst-inspect 是否安装成功
gst-inspect-1.0 | grep -E "h264parse|omxh264dec|nveglglessink"
3. 准备Sample
3.1 将本例的 Sample 复制到 OSDK 的代码包中
复制的目标位置 onboard-sdk/sample/platform/linux/advanced-sensing/
3.2 修改 CMakeLists.txt
文件位置 onboard-sdk/sample/platform/linux/advanced-sensing/CMakeLists.txt
在 46 行后添加 add_subdirectory(camera_h264_hardware_decode_sample)
3.3 编译
cd onboard-sdk/
mkdir build
cd build
cmake ..
make -j6 camera-h264-hardware-decode-sample
正常情况下,编译成功,如上图提示。
4. 运行和验证 Sample
4.1 复制 UserConfig.txt 到 onboard-sdk/build/bin 当中
cp ../sample/platform/linux/common/UserConfig.txt ./bin
编辑该文件
添加一行 acm_port : /dev/ttyACM0
添加 APP ID 和 APP Key
关于环境搭建和硬件连接可以参考如下链接:
https://developer.dji.com/cn//32bc1c7e-6c55-421f-afc9-fc99437b5392
4.2 运行 Sample 观察结果
./camera-h264-hardware-decode-sample ./UserConfig.txt
选择云台挂载的位置,一般我们都会挂载在1号位,可以选择 a
CPU 占用率骤降 140%
延迟骤降 200+ms !
接下来我们 简单分析下 Sample 的代码内容
Sample 总共 只有9个文件,主要由三部分组成,如上图红框所示
红框1:负责H264的硬件解码
红框2:负责解码后的RGB显示
红框3:IDR帧的十六进制编码表
其余文件
camera_h264_hardware_decode_sample.cpp: sample 代码运行入口
README.md:操作和使用介绍
CMakeLists.txt:Cmake配置文件
关于代码的运行流程,我这里 贴一张程序流程图
其实,硬件解码已经交给 Gstreamer 去做了,我们只需要在 init 阶段配置下解码参数即可
关于 Gstreamer 的使用可以参考 https://gstreamer.freedesktop.org/ 这里我们不做过多阐述
开发者更应该关注的 核心点在于 怎么解码 GDR 格式的 H264 码流
最新的 Z30 固件和 H20 输出的 H264 码流都是 GDR 编码格式,所以普通的 IDR 解码方式在这里不适用。
如果你还不是很了解什么是 GDR 或者 IDR,可以参考 Winddoing 网友的分享
https://winddoing.github.io/post/35564.html
这里我们介绍一种 “Insert the black I frame” 的方法
让 Gstreamer 也能解码 GDR 编码格式的 H264 码流
核心要领就是造一个 black I frame 的二进制编码表
Sample 里面已经分别提供了 Z30 和 H20 在拍照和录像模式下的两种 black I frame
然后在相机开始的第一帧,或者在相机切换拍照/录像模式后的第一帧,灌入 black I frame
上图表示对应的程序流程图位置
对应的代码位置如下图
完成了这一步,接下来就是正常解码 P 帧的操作了~
至此,大功告成!