视频解码分为软解和硬解两种,简单的来说纯粹依靠CPU来解码的称为软解,而使用GPU/VPU解码的称为硬解。常规地直接用CPU解码会极大地消耗CPU的运算能力,硬件解码是通过显卡的视频加速功能对高清视频进行解码,能够将CPU从繁重的视频解码运算中释放出来。
RIoTBoard使用的芯片是i.mx6 solo,芯片中包含一个VPU (video processing unit),可以进行硬件编解码加速,心血来潮,折腾一下视频硬件解码加速。


NXP官方提供了一个libimxvpuapi lib封装了vpu的使用方法,libimxvpuapi 又依赖libimxdmabuffer,所以只要编译出libimxvpuapi和libimxdmabuffer,运行libimxvpuapi 的testcase 就可以实现硬件编解码。

1 交叉编译libimxdmabuffer

libimxdmabuffer代码下载地址:

git clone https://github.com/Freescale/libimxdmabuffer.git

git 仓库里的readme有简单的说明,支持那些平台、如何编译等等,可以进行参考。
编译前需要配置toolchain以及imx-linux-headers-path,imx-linux-headers-path指向BSP中的linux-imx/include/即可。

./waf configure CC=arm-none-linux-gnueabi-gcc \
--imx-linux-headers-path=/home/zhy/code/mypc/linux/linux-imx/include/ \
--prefix=/home/zhy/code/rIoTboard/libimxdmabuffer

配置的过程中出现了linux/mxcfb.h not found的error:

Setting top to                           : /home/zhy/code/mypc/gstreamer/third_lib/libimxdmabuffer
Setting out to                           : /home/zhy/code/mypc/gstreamer/third_lib/libimxdmabuffer/build
Checking for 'gcc' (C compiler)          : arm-none-linux-gnueabi-gcc
Checking for compiler switch -O2         : yes
Checking for compiler switch -DPIC       : yes
Checking for compiler switch -fPIC       : yes
Checking for compiler switch -pedantic   : yes
Checking for compiler switch -std=gnu99  : yes
Checking for compiler switch -Wall       : yes
Checking for compiler switch -Wextra     : yes
Checking for header linux/mxcfb.h        : not found
Could not find linux/mxcfb.h in path "/home/zhy/code/mypc/linux/linux-imx/include/" specified by --imx-linux-headers-path

查看log发现是这个头文件中uint未定义。

../../../../../../linux/linux-imx/include/linux/mxcfb.h:113:2: error: unknown type name 'uint'

解决方法把uint更改unsigned int 即可。

unsigned int flags;

重新配置,这次就可以配置成功,会输出如下log:

checking for linux/fb.h and the IPU header linux/ipu.h                    : yes
Checking for library g2d                                                  : not found
Checking for header g2d.h                                                 : not found
G2D not found (library found: 0 header found: 0); disabling G2D allocator
checking for linux/pxp_device.h                                           : no
linux/pxp_device.h was not found in i.MX linux headers path; disabling PxP allocator
libimxdmabuffer version 1.0.1
'configure' finished successfully (0.662s)

配置好后执行编译命令进行编译:

./waf

编译成功后显示如下log:

[5/8] Compiling libimxdmabuffer.pc.in
[6/8] Linking build/libimxdmabuffer.so
[7/8] Linking build/test-alloc
[8/8] Symlinking build/libimxdmabuffer.so
Waf: Leaving directory `/home/zhy/code/mypc/gstreamer/third_lib/libimxdmabuffer/build'
'build' finished successfully (0.422s)

执行install命令,install目录为prefix指定的路径:

./waf install

测试一下能不能链接到limxdmabuffer这个lib:

 arm-none-linux-gnueabi-gcc -L/home/zhy/code/rIoTboard/libimxdmabuffer/lib -limxdmabuffer

输出一下log就代表可以链接到,编译OK。

/usr/local/complie_tool/fsl-linaro-toolchain/bin/../arm-fsl-linux-gnueabi/multi-libs/default/usr/lib/crt1.o: In function `_start':
init.c:(.text+0x34): undefined reference to `main'
collect2: ld returned 1 exit status

最后将编译好的lib 打包一下,方便以后使用,这一步不是必须的。

tar czvf libimxdmabuffer.tar.gz libimxdmabuffer/

2 编译libimxvpuapi

编译好libimxdmabuffer就可以编译libimxvpuapi,首先下载代码下载:

git clone https://github.com/Freescale/libimxvpuapi.git

libimxvpuapi编译依赖libimxdmabuffer和libvpu这两个lib ,libimxdmabuffer已经编译好了,在libimxvpuapi目录新建一个third_lib文件夹,把libimxdmabuffer编译好的so和头文件放进取。至于libvpu的头文件和so,可以到开发板的里面去copy,需要copy ipu.h、vpu_io.h、vpu_lib.h这三个头文件以及libvpu.so、libvpu.so.4这两个so,同样把这写放到third_lib 下面。最后在third_lib/lib/pkgconfig目录下放上libimxdmabuffer.pc和 vpu_lib.pc这两个pkg-config文件,最终third_lib下面的目录结构:

├── include
│   ├── imxdmabuffer
│   │   ├── imxdmabuffer_config.h
│   │   ├── imxdmabuffer.h
│   │   ├── imxdmabuffer_ipu_allocator.h
│   │   └── imxdmabuffer_physaddr.h
│   ├── ipu.h
│   ├── vpu_io.h
│   └── vpu_lib.h
└── lib├── libimxdmabuffer.so -> libimxdmabuffer.so.1.0.1├── libimxdmabuffer.so.1 -> libimxdmabuffer.so.1.0.1├── libimxdmabuffer.so.1.0.1├── libvpu.a├── libvpu.so├── libvpu.so.4└── pkgconfig├── libimxdmabuffer.pc└── vpu_lib.pc

其中libimxdmabuffer.pc中内容,这里面的路径根据自己的目录可以进行修改:

prefix=/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/third_lib
exec_prefix=/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/third_lib
libdir=${prefix}/lib
includedir=${prefix}/includelibimxdmabuffer_ion=0Name: libimxdmabuffer
Description: library for allocating and managing physically contiguous memory ("DMA memory" or "DMA buffers") on i.MX devices
Version: 1.0.1
Libs: -L${libdir} -limxdmabuffer
Cflags: -I${includedir}

vpu_lib.pc中内容:

prefix=/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/third_lib
exec_prefix=/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/third_lib
libdir=${prefix}/lib
includedir=${prefix}/includeName: vpu
Description: libvpu
Version: 1.0.1
Libs: -L${libdir} -lvpu
Cflags: -I${includedir}

准备工作完成后进行编译配置:

./waf configure CC=arm-none-linux-gnueabi-gcc \
--sysroot-path=/home/zhy/code/mypc/linux/linux-imx/include/ \
--prefix=/home/zhy/code/rIoTboard/libimxvpuapi \
--imx-platform=imx6
--imx-headers=/home/zhy/code/mypc/linux/linux-imx/include/

配置的时候显示找不到libimxdmabuffer 这个lib:

Checking if this combination works       : yes
Checking for program 'pkg-config'        : /usr/bin/pkg-config
Checking for 'libimxdmabuffer >= 0.9.0'  : not found
The configuration failed
(complete log in /home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/build/config.log)

查看log 发现是没有找到libimxdmabuffer的pkg-config文件,

----------------------------------------
Checking for program 'pkg-config'
/usr/bin/pkg-config
find program=['pkg-config'] paths=['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games', '/snap/bin', '/usr/local/complie_tool/fsl-linaro-toolchain/bin'] var='PKGCONFIG' -> ['/usr/bin/pkg-config']
----------------------------------------
Checking for 'libimxdmabuffer >= 0.9.0'
['/usr/bin/pkg-config', '--cflags', '--libs', 'libimxdmabuffer', '>=', '0.9.0']
err: Package libimxdmabuffer was not found in the pkg-config search path.
Perhaps you should add the directory containing `libimxdmabuffer.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libimxdmabuffer' found

通过PKG_CONFIG_PATH关键字增加pkg-config文件的路径即可。

./waf configure CC=arm-none-linux-gnueabi-gcc \
PKG_CONFIG_PATH=/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/third_lib/lib/pkgconfig \
--imx-platform=imx6 \
--sysroot-path=/home/zhy/code/mypc/linux/linux-imx/include/ \
--prefix=/home/zhy/code/rIoTboard/libimxvpuapi \
--imx-headers=/home/zhy/code/mypc/linux/linux-imx/include/

再次配置,有以下log印出则代表配置成功:

Setting top to                           : /home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi
Setting out to                           : /home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/build
Checking for 'gcc' (C compiler)          : arm-none-linux-gnueabi-gcc
Checking for compiler switch -Wextra     : yes
Checking for compiler switch -Wall       : yes
Checking for compiler switch -pedantic   : yes
Checking for compiler switch -fPIC       : yes
Checking for compiler switch -DPIC       : yes
Checking for compiler switch -O2         : yes
Checking for compiler switch -std=gnu99  : yes
Now checking the combination of CFLAGS -Wextra -Wall -pedantic -fPIC -DPIC -O2 -std=gnu99
Checking if this combination works       : yes
Checking for compiler switch -std=c99    : yes
Now checking the combination of CFLAGS -Wextra -Wall -pedantic -fPIC -DPIC -O2 -std=c99
Checking if this combination works       : yes
Checking for program 'pkg-config'        : /usr/bin/pkg-config
Checking for 'libimxdmabuffer >= 0.9.0'  : yes
Using "/home/zhy/code/mypc/linux/linux-imx/include" as sysroot path
Checking for library vpu                 : yes
checking if ENC_ENABLE_SOF_STUFF exists  : no
i.MX linux headers path: /home/zhy/code/mypc/linux/linux-imx/include/
checking for the IPU header linux/ipu.h  : yes
libimxvpuapi version 2.2.0
'configure' finished successfully (0.692s)

执行以下命令进行编译

./waf

编译时出现了’IPU_PIX_FMT_NV16’ undeclared的error。

../imxvpuapi2/imxvpuapi2_imx6_coda_ipu.c: In function 'get_ipu_pixel_format':
../imxvpuapi2/imxvpuapi2_imx6_coda_ipu.c:33:76: error: 'IPU_PIX_FMT_NV16' undeclared (first use in this function)

ipu.h里面没有定义这个format,目前不需要NV12这个color format,在get_ipu_pixel_format函数中注释掉IPU_PIX_FMT_NV16 这个color_format即可。

static uint32_t get_ipu_pixel_format(ImxVpuApiColorFormat color_format)
{switch (color_format){case IMX_VPU_API_COLOR_FORMAT_FULLY_PLANAR_YUV420_8BIT: return IPU_PIX_FMT_YUV420P;case IMX_VPU_API_COLOR_FORMAT_SEMI_PLANAR_YUV420_8BIT:  return IPU_PIX_FMT_NV12;case IMX_VPU_API_COLOR_FORMAT_FULLY_PLANAR_YUV411_8BIT: return IPU_PIX_FMT_YUV410P;case IMX_VPU_API_COLOR_FORMAT_FULLY_PLANAR_YUV422_HORIZONTAL_8BIT: return IPU_PIX_FMT_YUV422P;//case IMX_VPU_API_COLOR_FORMAT_SEMI_PLANAR_YUV422_HORIZONTAL_8BIT: return IPU_PIX_FMT_NV16;case IMX_VPU_API_COLOR_FORMAT_FULLY_PLANAR_YUV444_8BIT: return IPU_PIX_FMT_YUV444P;case IMX_VPU_API_COLOR_FORMAT_YUV400_8BIT: return IPU_PIX_FMT_GREY;default: return 0;}
}

修改后编译成功,会有以下log印出,并在build 目录会生成libimxvpuapi2.so。

[14/19] Linking build/libimxvpuapi2.so
[15/19] Linking build/example/decode-example
[16/19] Linking build/example/encode-example
[17/19] Linking build/example/jpeg-dec-example
[18/19] Linking build/example/jpeg-enc-example
[19/19] Symlinking build/libimxvpuapi2.so
Waf: Leaving directory `/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/build'
'build' finished successfully (1.970s)

测试一下能否动态链接到libimxvpuapi:

 arm-none-linux-gnueabi-gcc -L/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/build -limxvpuapi2

有以下log印出则代表链接OK:

zhy@zhy-ThinkPad-E480:~/code/mypc/gstreamer/third_lib/libimxvpuapi/build$  arm-none-linux-gnueabi-gcc -L/home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/build -limxvpuapi2
/usr/local/complie_tool/fsl-linaro-toolchain/bin/../lib/gcc/arm-fsl-linux-gnueabi/4.6.2/../../../../arm-fsl-linux-gnueabi/bin/ld: warning: libimxdmabuffer.so.1, needed by /home/zhy/code/mypc/gstreamer/third_lib/libimxvpuapi/build/libimxvpuapi2.so, not found (try using -rpath or -rpath-link)
/usr/local/complie_tool/fsl-linaro-toolchain/bin/../arm-fsl-linux-gnueabi/multi-libs/default/usr/lib/crt1.o: In function `_start':
init.c:(.text+0x34): undefined reference to `main'

将编译好的lib进行打包,以便后续使用,这一部分为非必要步骤。

mkdir libimxvpuapi
mkdir -p libimxvpuapi/lib libimxvpuapi/include/imxvpuapi2 libimxvpuapi/pkgconfig
cp -rf  build/*.so.* libimxvpuapi/lib/
cp -rf  imxvpuapi2/*.h libimxvpuapi/include/imxvpuapi2
cp -rf build/libimxvpuapi2.pc libimxvpuapi/lib/pkgconfig

然后在更改一下libimxvpuapi2.pc ,将libdir和includedir改成可根据prefix动态配置。

prefix=/home/zhy/code/rIoTboard/libimxvpuapi
exec_prefix=/home/zhy/code/rIoTboard/libimxvpuapi
libdir=${prefix}/lib
includedir=${prefix}/include

最后打包lib:

tar czvf libimxvpuapi.tar.gz libimxvpuapi/

3 开发板上测试使用vpu解码

libimxvpuapi编译好后在build/example 下面后生成可执行文件,将example整个文件夹复制到开放板上,同时还要复制libimxvpuapi和libimxdmabuffer编译好的so到开放板的/lib/目录下,下载一个h264码流,用mediainfo看一下信息:

把这个码流也复制到开发板上libimxvpuapi/example目录,在example执行以测试使用vpu解码h264。

./decode-example -i ./ds.h264 -o out.yuv

用手机拍了一下执行结果:

把解码后的out.yuv复制到PC 上,再用mediainfo查看,已经解码成yuv数据了,解码前190kb,解码后18.7M。

用VLC也可以播放out.yuv:

RIoTBoard开发板系列笔记(四)—— 使用VPU硬件解码相关推荐

  1. RIoTBoard开发板系列笔记(十二)—— gstreamer + vpu实现视频硬件解码播放

    i.mx6 solo芯片中包含一个VPU (video processing unit),可以进行视频硬件编解码加速,之前RIoTBoard开发板系列笔记(四)-- 使用VPU硬件解码文章简单的记录了 ...

  2. RIoTBoard开发板系列笔记(三)—— 移植Gstreamer

    之前arm-linux-cc 4.4.3 交叉编译gstreamer1.18博客里搞了一下Gstreamer的交叉编译,本来想试一下gstreamer移植到友善之臂2416开发板上的效果,奈何开发板资 ...

  3. 华清远见fs4412开发板学习笔记(四)

    fs4412开发板学习笔记(四) 今天的课程安排 1.复习 1.1 VIM 编辑器 [1] vim + filename 打开 [2] 工作模式 命令模式 编辑模式 底行模式 [3] 模式切换 命令- ...

  4. 阿里云HaaS100物联网开发板学习笔记(二)硬件控制初步--让小灯闪烁起来

    摘要:无论是哪种开发板,要想开发特定的功能,必先从GPIO开始,HaaS100开发也是一样.如果仅仅利用HaaS100的联网功能,那简直是太浪费了.HaaS100拥有其他开发板所具备的所有的功能,比如 ...

  5. 物联网开发板设计笔记 (2/7)__ 硬件原理图设计

    原理图就是按照前面的思路,把各个主要模块搭配组合起来.电路图是提供下载的,这里就把其中几个关键地方说明一下. 电源部分,12V转5V.3.8V.3.3V 电源采用 TPS5430 做的 DCDC,这个 ...

  6. 阿里云HaaS100物联网开发板学习笔记(六)做个智能灯---一个完整的开发例子

    摘要:本篇文章将前期几个专题综合起来,基于阿里云HaaS100的新固件设计制作一个智能灯.这个智能灯由云平台.手机APP端和设备端组成,基本上涵盖了一个物联网小项目所需的主要步骤. 目录 1.在阿里云 ...

  7. 阿里云HaaS100物联网开发板学习笔记(三)轻应用初步--用js让小灯闪烁起来

    摘要:能让JavaScript应用运行在haas100开发板上,这实在是太酷了,这种方式被阿里云称之为"轻应用".本文带各位从零开始,先了解啥是轻应用,然后搭建环境,再一步步将一个 ...

  8. 阿里云HaaS100物联网开发板学习笔记(四)轻应用初步--用javascript连接阿里云物联网平台

    摘要:本篇文章讲解如何使用JavaScript"轻应用"连接阿里云物联网平台并上报一个数据.仍然延续前几篇文章的结构,从安装软件环境开始讲,以使零基础的同学看了本篇文章之后,也能够 ...

  9. esp8266舵机驱动_arduino开发ESP8266学习笔记四—–舵机

    arduino开发ESP8266学习笔记四-–舵机 使用时发现会有ESP8266掉电的情况,应该是板上的稳压芯片的限流导致的,观测波形,发现当舵机运转时,电源线3.3V不再是稳定的3.3V,大概是在3 ...

最新文章

  1. redis启动问题:/var/redis/run/redis_6379.pid exists, process is already running or crashed
  2. 2016 大数据版图
  3. dijkstra算法c++_Matlab 二维模拟退火算法最优路径(主程序)
  4. php7.0 cli,PHP-7.1 源代码学习:php-cli 启动流程
  5. 视频播放器for android
  6. 安卓camera总体框架
  7. 流畅的Python 5. 函数
  8. 错误描述: plugin scala is incompatible
  9. ASP.NET MVC 随想录——探索ASP.NET Identity 身份验证和基于角色的授权,中级篇
  10. 俄罗斯独立自主的计算机技术和计算机网络
  11. Windows11系统引导修复(因EasyBCD误删win11启动)
  12. CRM客户关系管理系统的设计与实现
  13. b站首页banner景深移动特效 bilibili秋
  14. 19年全国电赛 H题电磁炮硬件电路+可控硅
  15. 安利三个工具,教你如何把英语翻译成中文
  16. HTML笔记(课堂笔记整合)
  17. 国外渗透教学——CBT 国外的道德黑客Nuggets
  18. Android设计一个app,穆易天气app设计尝试效果
  19. 前端:简述表单提交前如何进行数据验证
  20. Java并发编程—并发和并行、线程上下文

热门文章

  1. 【项目实战】Java POI之Word导出经典案例一
  2. 计算机电源接口在哪,电脑电源接口定义图解
  3. java版溺尸哪里有_我的世界基岩版1.3新增生物大全 新增珊瑚/幻翼/溺尸等
  4. 我的世界服务器修改武器伤害,我的世界:8张特性图,武器伤害没上限,物品全靠刷,老mc秒懂!...
  5. 激光钎焊的主要工艺参数
  6. ESP32产品系列之智能插座(一),框架及硬件设计
  7. 短视频内容创作:内容发给谁?为什么发?发什么?以什么形式发?
  8. 用HTML5写ZZULI官网(八)
  9. Java---多线程入门
  10. 东华助手 v1.6.5