Ubuntu 20.04下GStreamer nvcodec安装及nvdec到appsink管线搭建
问题解决指南
一、nvcodec插件的安装方法
Ubuntu 20.04官方apt源没有预编译的nvcodec插件,得手动编译安装:
- 先装依赖:
sudo apt install git build-essential meson ninja-build libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libnvidia-encode1 libnvidia-decode1 - 克隆gstreamer-plugins-bad源码(nvcodec属于bad插件子集,官方包没包含):
git clone https://gitlab.freedesktop.org/gstreamer/gstreamer-plugins-bad.git - 切换到和你当前GStreamer版本匹配的分支(比如你用的是1.18.x就切到1.18分支):
cd gstreamer-plugins-bad && git checkout 1.18 - 配置编译参数,启用nvcodec:
这里meson setup build -Dnvcodec=enabled -Dprefix=/usr-Dprefix=/usr是为了让系统能自动识别插件,避免路径问题 - 编译并安装:
ninja -C build && sudo ninja -C build install - 注销重登后,用
gst-inspect-1.0 nvcodec验证是否安装成功
二、无需nvcodec,搭建nvdec转appsink的硬件加速管线
不想编译插件的话,用现有nvdec+硬件转换插件也能实现需求,核心是处理nvdec输出的硬件格式,转成appsink能接收的格式:
Python示例代码(GStreamer原生实现)
import gi gi.require_version('Gst', '1.0') from gi.repository import Gst, GLib import numpy as np Gst.init(None) # 管线逻辑:文件源 -> 解封装 -> 码流解析 -> 硬件解码 -> 硬件格式转换 -> 软件格式适配 -> appsink pipeline_str = """ filesrc location=your_video.mp4 ! qtdemux ! h264parse ! nvh264dec ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink name=sink emit-signals=True sync=False """ pipeline = Gst.parse_launch(pipeline_str) appsink = pipeline.get_by_name('sink') def handle_new_frame(sink): sample = sink.emit('pull-sample') if not sample: return Gst.FlowReturn.EOS buffer = sample.get_buffer() caps = sample.get_caps() width = caps.get_structure(0).get_value('width') height = caps.get_structure(0).get_value('height') # 提取BGR帧数据,转成numpy数组供OpenCV处理 success, map_info = buffer.map(Gst.MapFlags.READ) if success: frame = np.ndarray(shape=(height, width, 3), dtype=np.uint8, buffer=map_info.data) # 这里直接加OpenCV处理逻辑就行,比如cv2.imshow("Frame", frame) print(f"收到帧:{width}x{height}") buffer.unmap(map_info) return Gst.FlowReturn.OK appsink.connect('new-sample', handle_new_frame) # 启动管线并运行主循环 pipeline.set_state(Gst.State.PLAYING) loop = GLib.MainLoop() try: loop.run() except KeyboardInterrupt: pass # 清理资源 pipeline.set_state(Gst.State.NULL)
关键细节:
- 不同编码格式用对应nvdec插件,比如H265用
nvh265dec nvvidconv是Nvidia硬件转换插件,避免软件转格式的性能损耗videoconvert做最后一步格式调整,输出OpenCV兼容的BGR格式
三、结合OpenCV的硬件加速解码方案
如果想用OpenCV直接调用GStreamer管线,把管线字符串传给VideoCapture即可:
import cv2 # 构建GStreamer管线字符串 gst_pipeline = "filesrc location=your_video.mp4 ! qtdemux ! h264parse ! nvh264dec ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink" cap = cv2.VideoCapture(gst_pipeline, cv2.CAP_GSTREAMER) if not cap.isOpened(): print("管线启动失败") exit() while cap.isOpened(): ret, frame = cap.read() if not ret: break # 帧处理逻辑 cv2.imshow('硬件加速解码帧', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
注意事项:
- 用
print(cv2.getBuildInformation())确认你的OpenCV编译时开启了WITH_GSTREAMER选项 - 如果格式不兼容,可调整管线中的格式参数,比如把
BGRx换成RGBA再转BGR
内容的提问来源于stack exchange,提问作者Scrimpy
相关产品推荐
相关产品推荐

