本文为作者【码农而已】在CSDN原创。如需转载,请注明来源。
目录
环境准备
Nvidia驱动及CUDA库
这个就不多讲了,下载回来安装就行。
编译依赖库
看到不需要的,也可以不安装
# gstreamer
sudo apt-get install automake unzip python3-pip
sudo apt-get install cmake git autoconf autopoint
sudo apt-get install gtk-doc-tools
sudo apt-get install bison flex
sudo apt-get install libunwind-dev libdw-dev libgtk-3-dev
sudo apt-get install libx11-dev xorg-dev libglu1-mesa-dev freeglut3-dev libglew1.5 libglew1.5-dev libglu1-mesa libglu1-mesa-dev libgl1-mesa-glx libgl1-mesa-dev libtool libreadline-dev
# gst-plugins-base
# theora
sudo apt-get install libtheora-bin libtheora-dev libtheora-doc
# vorbis
sudo apt-get install libvorbis-dev
# cdparanoia
sudo apt-get install libcdparanoia-dev
sudo apt-get install alsa-base alsa-tools
sudo apt-get install libasound2-dev
sudo apt-get install libopus-dev libvisual-0.4-dev
# gst-plugins-good
sudo apt-get install libwavpack-dev libspeex-dev qt libjack-sdk libjpeg-dev libdv-dev libsoup2.4-dev qtdeclarative5-dev
# gst-plugins-bad
sudo apt-get install x265 x264
# gst-plugins-ugly
sudo apt-get install libx264-dev
# gst-libav
sudo apt-get install yasm nasm libbz2-dev liblzma-dev
# other lib
sudo apt install libbsd-dev
pango和cairo,甚至 glib2.0都不需要安装。(u16安装的时候,会带来一个版本不对的问题)
让meson自动去下载git编译,更好。
Install git and python 3.5+
apt install git
Install meson and ninja
因为gst是使用meson和ninja作为构建工具的。所以需要安装 meson > 0.52。
如果需要交叉编译,则 meson > 0.54。
不要用 apt安装,一般版本都太低。可以用pip安装。
pip3 install --user meson
用这个命令安装的meson会安装到 ~/.local/bin 这个目录里。
ninja可以去官网下载:
Releases · ninja-build/ninja · GitHub
开始编译
构建编译编译环境
这个过程中,会自动下载代码库。因为是私有gitlab,会很慢
$HOME/.local/bin/meson build/
配置编译条件
我们的重点是编译nvcodec插件
$HOME/.local/bin/meson configure build/ -Dgst-plugins-bad:nvcodec=enabled
开始编译过程
ninja -C build/
-
如果发现ELG库找不到。可以看看你的机器上不是有libELG.so.1.1.0等其他版本的库,把软连接改过来就行。
-
如果提示需要打开 c++11的设置。可以编辑项目文件夹中的 meson.build,添加c++11的支持
add_project_arguments('-std=c++11', language: 'cpp')
-
如果你的系统提示 reallocarray相关的错误。说明你的系统是不是基于openbsd构建的(非 redhat/centos系)。需要修改代码。编辑文件 【subprojects/sysprof/src/libsysprof-capture/sysprof-version.h.in 】。在末尾添加
#include <bsd/stdlib.h>
-
sysprof模块需要reallocarray函数,所以还需要 编辑 subprojects/sysprof/src/libsysprof-capture/meson.build。43行的位置,添加bsd库依赖
dependency('bsd'),
-
提示 OPENSSL_VERSION 及 OpenSSL_version 找不到的。我看新版的openssl已经没有这个OpenSSL_version函数了。可以找到错误提示的文件,把 OpenSSL_version(OPENSSL_VERSION) 换成 OPENSSL_VERSION_TEXT。
-
我的ubuntu16.04安装的QT版本是5.5,会引起videoitem.cpp编译时缺少 Q_FALLTHROUGH符号。所以需要在 videoitem.h上,添加这一宏定义。定义如下:
// compat for Q_FALLTHROUGH
#if QT_VERSION < QT_VERSION_CHECK(5,8,0)
#if defined(__has_cpp_attribute)
# if __has_cpp_attribute(fallthrough)
# define Q_FALLTHROUGH() [[fallthrough]]
# elif __has_cpp_attribute(clang::fallthrough)
# define Q_FALLTHROUGH() [[clang::fallthrough]]
# elif __has_cpp_attribute(gnu::fallthrough)
# define Q_FALLTHROUGH() [[gnu::fallthrough]]
# endif
#endif
#ifndef Q_FALLTHROUGH
# if defined(__GNUC__) && !defined(__INTEL_COMPILER) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 700)
# define Q_FALLTHROUGH() __attribute__((fallthrough))
# else
# define Q_FALLTHROUGH() (void)0
# endif
#endif
#endif
-
Qt5.5 也不支持 QVariant::fromValue(nullptr)。会提示 "Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system"。此时需要修改代码,增加一个类型转义:
QVariant::fromValue((QObject * const)nullptr)
安装到系统
cd build/sudo $HOME/.local/bin/meson install
使用测试
插件查看
运行查看插件情况
gst-inspect-1.0 nvcodec
![](https://img-blog.csdnimg.cn/9e036d208e4c42259e2b22ea728fe583.png)
-
执行时如果出现错误 【 symbol lookup error: /usr/local/lib/x86_64-linux-gnu/libgobject-2.0.so.0: undefined symbol: g_date_copy】,说明编译用glib和执行时不一样,可以把【build/subprojects/gstreamer/tools/./../../glib/glib/libglib-2.0.so.0.6800.4】文件,替换到 【/usr/local/lib/x86_64-linux-gnu/】下。
尝试rstp拉流解码
设置RTSPURL为rtsp地址
gst-launch-1.0 rtspsrc location=$RTSPURL ! rtph264depay ! h264parse ! nvh264dec ! videoconvert ! videoscale ! video/x-raw,width=640,height=480 ! nvh264enc ! h264parse ! rtph264pay name=pay0 pt=96
因为rtsp流中有rtp控制信息,decodebin不能正确处理。故需要添加 capsfilter在 decodebin前面,自动识别编码:
gst-launch-1.0 -e rtspsrc location=$RTSPURL ! capsfilter caps='application/x-rtp, media=(string)video' ! decodebin ! jpegenc ! multifilesink location="img_%06d.jpg"
不过默认 gst-libav和nv264dec nv265dec的权重都是 256,每次解码都是使用了 libav插件。如果自己组程序的时候,是可以不带 libav插件。如果用命令行的话,最好还是改下代码,把几个dec的权重 + 10。
修改代码:
subprojects/gst-plugins-bad/sys/nvcodec/gstnvdec.c- gst_nvdec_subclass_register (plugin, GST_TYPE_NVDEC, codec,
subprojects/gst-plugins-bad/sys/nvcodec/gstnvdec.c: codec_name, device_index, GST_RANK_PRIMARY+10, sink_template, src_template);
--
subprojects/gst-plugins-bad/sys/nvcodec/gstnvenc.c- gst_nv_enc_register (plugin, NV_ENC_CODEC_H264_GUID,
subprojects/gst-plugins-bad/sys/nvcodec/gstnvenc.c: "h264", GST_RANK_PRIMARY * 2, device_index, cuda_ctx);
subprojects/gst-plugins-bad/sys/nvcodec/gstnvenc.c- gst_nv_enc_register (plugin, NV_ENC_CODEC_HEVC_GUID,
subprojects/gst-plugins-bad/sys/nvcodec/gstnvenc.c: "h265", GST_RANK_PRIMARY * 2, device_index, cuda_ctx);
--
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c- gst_nv_h264_dec_register (plugin,
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c: i, GST_RANK_PRIMARY+10, sink_template, src_template, TRUE);
--
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c- gst_nv_h265_dec_register (plugin,
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c: i, GST_RANK_PRIMARY+10, sink_template, src_template, TRUE);
--
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c- gst_nv_vp8_dec_register (plugin,
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c: i, GST_RANK_PRIMARY+10, sink_template, src_template, TRUE);
--
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c- gst_nv_vp9_dec_register (plugin,
subprojects/gst-plugins-bad/sys/nvcodec/plugin.c: i, GST_RANK_PRIMARY+10, sink_template, src_template, TRUE);
再用 gst-inspect-1.0 nvh264dec 命令,可以看到权重已经加10了
![](https://img-blog.csdnimg.cn/660d1987c6f546a6942e640a3c30e7c3.png)
重新执行解码流程,
过程中可以用 nvidia-smi dmon 查看编解码器使用率。已经成功使用硬件解码了。
![](https://img-blog.csdnimg.cn/a4b15da892e64ce99bbb2be8989865e7.png)