RockChip3568 MPP硬解码和gstreamer1.0编译

MPP视频硬件解码编译

一、配置rock sdk的环境

当前使用的rockchip 给的rk3568的sdk包,版本不详,应该比较新。
编译前配置环境:

source  envsetup.sh
选择rk3568配置 (67 rockchip_rk3568)

注意

每次在skd目录进行make编译时,都要运行source envsetup.sh。它配置了一些环境变量。

特别注意

当选则是否使用默认配置覆盖当前配置时,选则n。不进行覆盖。快点操作,否则系统直接覆盖。

二、配置buildroot的编译选项

buildroot是一个开源的编译套件,rockchip的sdk发布借助了buildroot这个编译套件,来进行包的管理和编译。细节参考buildroot说明文档。

2.1 进入buildroot配置页面

cd buildroot
make menuconfig
    该命令用来配置buildroot编译的全过程。基础配置有编译工具链,编译基础库的版本(libc等),选中编译哪些包。

2.2 添加2.28 版本的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.

2.3 选中需要编译的包

选中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  --->                                       

三、编译

3.1 buildroot编译MPP目标

在第一次编译,或者切换工具链,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

3.2 编译开源的库gstreamer-rgaconvert

这个是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 /

4.2 报错原因与解决

如果报错,符号找不到,最大可能是相同系统库,在目标环境存在两份。目前使用旧的那一份动态库。
解决办法)

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中,但是要执行删除操作。

4.3 总结

重点重点重点重点重点重点重点重点重点 :

注意注意注意注意注意注意注意注意注意

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++.*

五、 调试与测试

5.1 如何打开MPP库日志

我简单编译了一下mpp,发现日志打印使用的是 vsyslog 打印的,我们环境syslog未运行,所以看不到。可以替换成普通打印vfprintf(stdout, line, list)即可。mpp_set_log_level(MPP_LOG_VERBOSE);用来设置日志打印最低等级。

5.2 测试mpp代码

测试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打印。

5.3 测试gstreamer1

测试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

你可能感兴趣的:(linux,嵌入式硬件,rockchip,gstreamer)