MPP视频硬件解码编译
当前使用的rockchip 给的rk3568的sdk包,版本不详,应该比较新。
编译前配置环境:
source envsetup.sh
选择rk3568配置 (67 rockchip_rk3568)
注意:
每次在skd目录进行make编译时,都要运行source envsetup.sh。它配置了一些环境变量。
特别注意:
当选则是否使用默认配置覆盖当前配置时,选则n。不进行覆盖。快点操作,否则系统直接覆盖。
buildroot是一个开源的编译套件,rockchip的sdk发布借助了buildroot这个编译套件,来进行包的管理和编译。细节参考buildroot说明文档。
cd buildroot
make menuconfig
该命令用来配置buildroot编译的全过程。基础配置有编译工具链,编译基础库的版本(libc等),选中编译哪些包。
因为我们开发板后台使用的libc2.28的环境,为了让gstreamer运行起来。所有我们要编译libc2.28的libc库。奈何现在的buildroot没有支持2.28。那我们就手动添加一个2.28的libc库。
buildroot libc连接http://sources.buildroot.net/glibc/glibc-glibc-2.28-50-gb8dd0f42780a3133c02f064a2c0c5c4e7ab61aaa.tar.gz
修改如下文件:
buildroot/package/glibc/Config.in
buildroot/package/glibc/glibc.hash
buildroot/package/glibc/glibc.mk
patch 如下:
diff --git a/package/glibc/Config.in b/package/glibc/Config.in
index 1fcf30a5..c9810073 100644
--- a/package/glibc/Config.in
+++ b/package/glibc/Config.in
@@ -20,6 +20,10 @@ config BR2_PACKAGE_GLIBC_LATEST
config BR2_PACKAGE_GLIBC_2_29
bool "glibc 2.29"
+
+config BR2_PACKAGE_GLIBC_2_28
+ bool "glibc 2.28"
+
endchoice
config BR2_PACKAGE_GLIBC_KERNEL_COMPAT
diff --git a/package/glibc/glibc.hash b/package/glibc/glibc.hash
index e0bbf341..b476e7c9 100644
--- a/package/glibc/glibc.hash
+++ b/package/glibc/glibc.hash
@@ -1,5 +1,6 @@
# Locally calculated (fetched from Github)
sha256 fc3c1d25640fd4cd09fbf7e17eafcc7943731e901cc0a3686503ae8adfb11d31 glibc-2.35-96-g2c4fc8e5ca742c6a3a1933799495bb0b00a807f0.tar.gz
+sha256 b070f746f932cfce107bb9be2d59ded5b44b25ddafb480c9110c52b88cc2dec1 glibc-glibc-2.28-50-gb8dd0f42780a3133c02f064a2c0c5c4e7ab61aaa.tar.gz
# Hashes for license files
sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 COPYING
diff --git a/package/glibc/glibc.mk b/package/glibc/glibc.mk
index d43de7d4..e1afe762 100644
--- a/package/glibc/glibc.mk
+++ b/package/glibc/glibc.mk
@@ -10,8 +10,12 @@
ifeq ($(BR2_PACKAGE_GLIBC_2_29),y)
GLIBC_VERSION = 2.29-11-ge28ad442e73b00ae2047d89c8cc7f9b2a0de5436
else
+ifeq ($(BR2_PACKAGE_GLIBC_2_28),y)
+GLIBC_VERSION = 2.28-50-gb8dd0f42780a3133c02f064a2c0c5c4e7ab61aaa
+else
GLIBC_VERSION = 2.35-96-g2c4fc8e5ca742c6a3a1933799495bb0b00a807f0
endif
+endif
# Upstream doesn't officially provide an https download link.
# There is one (https://sourceware.org/git/glibc.git) but it's not reliable,
# sometimes the connection times out. So use an unofficial github mirror.
选中glibc 2.28版 (经过2.2操作后才有2.28选项)
Toolchain --->
glibc version (glibc 2.28)
选中(在配置页面使用搜索下面关键词,可快速进入)
BR2_PACKAGE_RKMEDIA
BR2_PACKAGE_RKMEDIA_MPP
BR2_PACKAGE_RKMEDIA_MPP_ENCODER
BR2_PACKAGE_RKMEDIA_MPP_DECODER
BR2_PACKAGE_RKMEDIA_RKRGA
BR2_PACKAGE_RKMEDIA_RKNN
Target packages --->
[*] Rockchip BSP packages --->
-> Rockchip BSP packages (BR2_PACKAGE_ROCKCHIP [=y])
[*] rkmedia --->
[*] rk mpp wrapper
[*] rk mpp encoder
[*] rk mpp decoder
[ ] audio capture and playback
[ ] audio encoder and decoder
[*] rkrga
[*] rknn
选中
BR2_PACKAGE_GSTREAMER1 版本选中 gstreamer-1.20
BR2_PACKAGE_GST1_PLUGINS_BASE
BR2_PACKAGE_GST1_PLUGINS_GOOD
BR2_PACKAGE_GST1_PLUGINS_BAD
BR2_PACKAGE_GST1_PLUGINS_UGLY
Target packages --->
Audio and video applications --->
[*] gstreamer 1.x
Gstreamer version (gstreamer-1.20) --->
[ ] enable unit test libraries
[*] enable command-line parser
[*] enable tracing subsystem
[*] enable gst-debug trace support
[*] enable plugin registry
[*] install tools
-*- gst1-plugins-base --->
[*] gst1-plugins-good --->
[*] gst1-plugins-bad --->
[*] gst1-plugins-ugly --->
在第一次编译,或者切换工具链,glibc 等重要系统库时进行一下清理工作 make clean。make clean将会把编译好的工具链,host工具,libc等基础系统库统统删掉,把编译路径都删掉,配置还在。
在rockchip sdk 顶层目录下,进行
make gstreamer1 -j8
make rockchip-mpp -j8
make rockchip-rga -j8
make gstreamer1-rockchip -j8
make gst1-plugins-base -j8
make gst1-plugins-good -j8
make gst1-plugins-bad -j8
make gst1-plugins-ugly -j8
重新编译
make gstreamer1-rebuild -j8
make rockchip-mpp-rebuild -j8
make gstreamer1-rockchip-rebuild -j8
make gst1-plugins-base-rebuild -j8
make gst1-plugins-good-rebuild -j8
make gst1-plugins-bad-rebuild -j8
make gst1-plugins-ugly-rebuild -j8
这个是gstreamer的一个插件,该插件会使用rock chip 的rga 进行二维图像操作或OSD,本来应该放置在buildroot下,但时间有限和我们整体不使用buildroot进行固件构建,暂时就手动编译。
下载地址:https://github.com/higithubhi/gstreamer-rgaconvert
编译脚本内容如下:
#just for fast test
set -x
export TMP_STAGING=/xx/your_sdk_root/buildroot/output/rockchip_rk3568/staging
/xx/your_sdk_root/buildroot/output/rockchip_rk3568/host/bin/aarch64-linux-gcc -fPIC -shared plugins/gstrgaconvert.c -o librgaconvert.so -I plugins/ -lrga -lgstallocators-1.0 -lgstreamer-1.0 -lglib-2.0 -lgobject-2.0 -lgstbase-1.0 -lgstvideo-1.0 -lgstaudio-1.0 --sysroot=$TMP_STAGING -I $TMP_STAGING/usr/include/gstreamer-1.0 -I $TMP_STAGING/usr/include/glib-2.0/ -I $TMP_STAGING/usr/lib/glib-2.0/include/
unset TMP_STAGING
##4.1 跟新说明
如何快速将对应库拷贝到目标板上,使用find 在target目录(与开发板/目录对齐) 然后进行压缩。后来我发现太多库了,直接将buildroot的target目录下urs/lib和usr/bin进行压缩。
由于依赖库太多和依赖库使用的系统库版本要求不一,直接将usr/lib usr/bin 全部进行压缩成tar包,然后直接解压到目标环境。
cd /xx/your_sdk_root/buildroot/output/rockchip_rk3568/target
tar -cvf build_root_mpp.tar usr/bin/ usr/lib lib/libudev.*
将生成的build_root_mpp.tar 包拷贝到目标板。然后进行环境检测,需要将之前的对应gstream,rockchip,gst等库进行删除。然后进行解压,直接解压到根目录中,命令如下。
tar -xvf build_root_mpp.tar -C /
如果报错,符号找不到,最大可能是相同系统库,在目标环境存在两份。目前使用旧的那一份动态库。
解决办法)
1)可以删除旧的相同库。
2)可以使用export LD_LIBRARY_PATH=/new/library/path:/old/library/path
LD_LIBRARY_PATH的优先级高于默认的动态库路径(如/usr/lib)
样例:
【报错1】 运行如果包这个错,就查看一下这个库是否重复了
(gst-launch-1.0:6532): GStreamer-WARNING **: 14:59:35.512: Failed to load plugin '/usr/lib/gstreamer-1.0/libgstcamerabin.so':
/usr/lib/librga.so.2: symbol _ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev version GLIBCXX_3.4.26
not defined in file libstdc++.so.6 with link time reference
(gst-launch-1.0:6532): GStreamer-WARNING **: 14:59:35.513: Failed to load plugin
'/usr/lib/gstreamer-1.0/libgstencoding.so': /usr/lib/librga.so.2: symbol _ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev
version GLIBCXX_3.4.26 not defined in file libstdc++.so.6 with link time reference
查了一下果然重复了,删掉/lib/libstdc++.*
[root@edge:/]# find / -name "libstdc++*"
/lib/libstdc++.so.6
/lib/libstdc++.so.6.0.25
/lib/libstdc++.so
/usr/lib/libstdc++.so.6.0.28
/usr/lib/libstdc++.so.6
/usr/lib/libstdc++.so
/usr/lib/libstdc++.so.6.0.28-gdb.py
【报错2】
(gst-launch-1.0:11221): GStreamer-WARNING **: 15:12:32.473: Failed to load plugin
'/usr/lib/gstreamer-1.0/libgstvideo4linux2.so': libudev.so.1: cannot open shared object file:
No such file or directory
编译环境
target$ find ./ -name "libudev*"
./usr/lib/pkgconfig/libudev.pc
./usr/lib/libudev.so
./usr/lib/libudev.la
./usr/include/libudev.h
./lib/libudev.so.1
./lib/libudev.so.1.6.3
设备环境
/usr/lib/libudev.so.0
/usr/lib/libudev.so
/usr/lib/libudev.so.0.13.1
需要将/usr/lib/libudev.so.0 /usr/lib/libudev.so.0.13.1删除。把打包环境下的 ./lib/libudev.so.1 ./lib/libudev.so.1.6.3拷贝到/lib路径
rm /usr/lib/libudev.so.0 /usr/lib/libudev.so.0.13.1
我们已经将这几个文件追加到build_root_mppp.tar中,但是要执行删除操作。
重点重点重点重点重点重点重点重点重点 :
注意注意注意注意注意注意注意注意注意 :
buildroot target的目录虽然和busybox的目录很像,但不是根文件系统的目录结构。 所以上述跟新方法仅供快速调试使用。在制作根文件系统时,需要进行拷贝调整,裁剪。
最终操作总结
cd /xx/your_sdk_root/buildroot/output/rockchip_rk3568/target
tar -cvf build_root_mpp.tar usr/bin/ usr/lib lib/libudev.*
将生成的build_root_mpp.tar 包拷贝到目标板。
tar -xvf build_root_mpp.tar -C /
rm /usr/lib/libudev.so.0 /usr/lib/libudev.so.0.13.1
rm /lib/libstdc++.*
我简单编译了一下mpp,发现日志打印使用的是 vsyslog 打印的,我们环境syslog未运行,所以看不到。可以替换成普通打印vfprintf(stdout, line, list)即可。mpp_set_log_level(MPP_LOG_VERBOSE);用来设置日志打印最低等级。
测试mpp库
mpi_dec_test -i 128x128.264 -t 7 -n 10 -o out.yuv
mpi_dec_test: /lib/libstdc++.so.6: no version information available (required by /usr/lib/librockchip_mpp.so.1)
mpi_dec_test: /lib/libstdc++.so.6: no version information available (required by /usr/lib/librockchip_mpp.so.1)
mpi_dec_test: /lib/libstdc++.so.6: no version information available (required by /usr/lib/librockchip_mpp.so.1)
mpi_dec_utils: input file 128x128.264 size 174416
mpi_dec_utils: cmd parse result:
mpi_dec_utils: input file name: 128x128.264
mpi_dec_utils: output file name: out.yuv
mpi_dec_utils: width : 0
mpi_dec_utils: height : 0
mpi_dec_utils: type : 7
mpi_dec_utils: max frames : 10
mpi_dec_test: mpi_dec_test start
mpp_info: mpp version: 188dfb5d author: Herman Chen 2022-06-17 [mpp_enc]: Add intra flag on slice output mode
mpi_dec_test: 0x1f64f480 mpi_dec_test decoder test start w 0 h 0 type 7
mpi_dec_test: 0x1f64f480 decode_get_frame get info changed found
mpi_dec_test: 0x1f64f480 decoder require buffer w:h [128:128] stride [128:128] buf_size 32768
mpi_dec_test: 0x1f64f480 decode get frame 0
mpi_dec_test: 0x1f64f480 decode get frame 1
mpi_dec_test: 0x1f64f480 decode get frame 2
mpi_dec_test: 0x1f64f480 decode get frame 3
mpi_dec_test: 0x1f64f480 decode get frame 4
mpi_dec_test: 0x1f64f480 decode get frame 5
mpi_dec_test: 0x1f64f480 decode get frame 6
mpi_dec_test: 0x1f64f480 decode get frame 7
mpi_dec_test: 0x1f64f480 decode get frame 8
mpi_dec_test: 0x1f64f480 decode get frame 9
mpi_dec_test: decode 10 frames time 12 ms delay 7 ms fps 817.53
mpi_dec_test: test success max memory 0.22 MB
这里有打印输出的原因就是我修改打印将vsyslog 修改成了vfprintf打印。
测试gstreamer1.0,运行不报错,说明移植基本成功了。
gst-launch-1.0 rtspsrc location="rtsp://admin:[email protected]:554/cam/realmonitor?channel=1&subtype=0" latency=0 ! rtph264depay ! h264parse ! mppvideodec ! rgaconvert ! video/x-raw,format=BGR,width=640,height=640 ! fakesink sync=false
gst-launch-1.0 rtspsrc location="rtsp://admin:[email protected]:554/cam/realmonitor?channel=1&subtype=0" latency=0 ! rtph264depay ! h264parse ! mppvideodec ! fakesink sync=false
gst-launch-1.0 rtspsrc location="rtsp://admin:[email protected]:554/cam/realmonitor?channel=1&subtype=0" ! rtph264depay ! h264parse ! mp4mux ! filesink location=file.mp4
gst-launch-1.0 rtspsrc location="rtsp://admin:[email protected]:554/cam/realmonitor?channel=1&subtype=0" ! rtph264depay ! h264parse ! mp4mux ! filesink location=file.mp4