gstreamer虽然是一个很强大的多媒体框架,不过用的人是真的少,最近在用英伟达的显卡做硬编码,于是百度了一下,顿时就懵圈了,一点资料都没有。。。倒是ffmpeg的资料挺多,而且本人尝试编了一下ffmpeg的硬编版本,确实可以调用英伟达的显卡资源,毕竟坑基本都被踩平了。可惜项目用gstreamer为主,只能摸索着整一下。
1.准备源码
先把gstreamer的源码下载下来,解压好,gstreamer的源码很多,主要用到它的本体,和几个插件库
支持英伟达显卡硬编码的插件叫nvenc,位于bad中,所以good和ugly其实可以不要,不过这里还是都下下来了。
2.准备编译环境
3.安装cuda驱动
到英伟达官网上下载最新的cuda驱动,注意驱动区分平台,需要下载对应的版本,安装完成后重启机子。
4.编译
先编译本体,进入gstreamer-1.16.2目录,执行
./configure --prefix="/xxx/gst-source/build/" --bindir="/xxx/gst-source/bin"
make -j6
make install
这里通过prefix和bindir选项指定了安装目录,因为本人的环境已经装了其他的gstreamer,不想覆盖掉,这个视具体情况而定。
接着编译base,插件依赖于本体,因此需要告知它们本体的位置,就是编译生成的pkgconfig目录
export PKG_CONFIG_PATH="/xxx/gst-source/build/lib/pkgconfig/"
同样的,进入gst-plugins-base-1.16.2目录,执行
./configure --prefix="/xxx/gst-source/buid-base/" --bindir="/xxx/gst-source/bin"
make -j6
make install
由于其他的插件依赖于base,因此如法炮制,告知它们base的位置
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/xxx/gst-source/buid-base/lib/pkgconfig/
然后用上面类似的命令,编译good,bad,ugly。
5.使能nvenc插件
上述只是默认的编译过程,默认的情况下,在编译bad的时候,nvenc插件是不会被编译的,这个可以在config时输出的日志查看到
但是如何让它编译nvenc呢?先尝试一下加选项吧
./configure --prefix="/xxx/gst-source/buid-bad/" --bindir="/xxx/gst-source/bin" --disable-nvdec --enable-nvenc
这里增加--disable-nvdec是因为nvdec居然是默认使能的,但本人的环境会报错,所以直接禁用掉了。关键是后面的--enable-nvenc,添加后发现并不可行,猜测是因为插件没有跟cuda驱动关联起来,所以nvenc不能生效。
查看一下config的输出信息,发现了相关报错,证实了上述的想法
因为找不到cuda的api,所以无法使能nvenc。但是怎么把它们关联起来,这个一直找不到相关的资料,实在没办法,只能看看configure的源码看能不能找到些信息。然后在config cuda的地方发现了一个选项--with-cuda-prefix,结合上下文来看可以确定这个选项可用,于是修改config
./configure --prefix="/xxx/gst-source/buid-bad/" --bindir="/xxx/gst-source/bin" --disable-nvdec --enable-nvenc --with-cuda-prefix="/usr/local/cuda-11.4/"
加上cuda的路径后,终于使能了nvenc,重新执行make -j6 && make install即可 。
插件编译出来就是一个so,位于指定的prefix中,把路径告知本体,这样本体就可以使用相应的插件了
export GST_PLUGIN_PATH="/xxx/gst-source/buid-bad/lib/"
因为其他的插件用不上,所以就只导出bad的路径,测试一下可以找到nvenc插件。
6.编码测试
gst-launch-1.0 filesrc location=/test.yuv blocksize=3110400 ! video/x-raw,format=I420, framerate=25/1,width=1920,height=1080,interlace-mode=progressive ! nvh264enc ! filesink location=hw.h264
同时在另一个窗口执行一下nvidia-smi查看显卡信息
可以看出gst正在使用GPU资源。
然后找了很久才发现的查看帧率的方法
gst-launch-1.0 -v filesrc location=/test.yuv blocksize=3110400 ! video/x-raw,format=I420,framerate=25/1,width=1920,height=1080,interlace-mode=progressive ! nvh264enc ! fpsdisplaysink video-sink=fakesink sync=false signal-fps-measurements=true text-overlay=false
*题外
上述gstreamer用了fakesink来阻止输出,换成ffmpeg的话,可以用【-f null -】来阻止输出,非常适合调试。