问题背景与现状分析
- python使用opencv软解码1080p视频解码播放帧率只有25帧,CPU开销在35%
-
Average FPS: 25.3
- python使用OpenCV+GStreamer硬解码在1080p视频解码播放帧率只有7帧,CPU开销在26%
-
Average FPS: 7.3
-
gst_str = ( f"rtspsrc location={uri} latency={rtsp_latency} ! " "rtph264depay ! queue max-size-buffers=1 leaky=downstream ! " "h264parse ! queue max-size-buffers=1 leaky=downstream ! " "mppvideodec ! queue max-size-buffers=1 leaky=downstream ! " "videoconvert ! video/x-raw,format=BGR ! " "appsink drop=1 max-buffers=1 sync=false" ) cap = cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
帧率低下可能的原因
- GStreamer彩色空间是使用YUY,YUY转换成BGR这一步GS默认使用的CPU转换率低,帧堆积才导致帧率低下。
- 测试过程
-
"video/x-raw(memory:DMABuf),format=NV12 ! " 帧率正常25 "videoconvert ! video/x-raw,format=BGR ! " | 场景 | 性能表现 | 原因说明 | | -------------------- | ------------ | ----------------------- | | DMABuf NV12 + MPP | ~25 FPS | 没有颜色空间转换直接传给opencv | | videoconvert → BGR | ~7 FPS | 颜色空间,全靠 CPU |
为什么使用GStreamer确实正常播放的?
硬件解码 + 高效渲染
-
GStreamer 调用了 Rockchip 的
mppvideodec
插件,它使用 MPP (Media Process Platform) 中间件直接操作 VPU(Video Processing Unit)进行硬件加速解码,性能高、CPU 占用低。解码后的视频帧送往显示模块直接渲染,而不是传递到 CPU 进行色彩转换
无需 CPU videoconvert
-
如果 pipeline 未插入
videoconvert
或 RGB/BGR 转换环节,GStreamer 对 NV12 等格式处理原封不动,走硬件路径。这样一来就不会触发 CPU 开销巨大的颜色空间转换,因此可以稳定达到高帧率
解决方案使用RGA 硬件加速
参考博主的上一篇文章安装GStreamer插件,opencv启用支持GStreamer完成后回到本文章基于rk3588编译opencv支持GStreamer硬件加速-CSDN博客
环境变量启用 RGA 加速
通过环境变量让 videoconvert
或其他转换操作走 RGA 硬件:
export GST_VIDEO_CONVERT_USE_RGA=1
export GST_VIDEO_FLIP_USE_RGA=1 # 用于翻转相关场景
测试Demo
import cv2
import sys
import time
# RTSP 参数
uri = "rtsp://admin:tfe12345@10.168.1.65/media/video1"
rtsp_latency = 10
gst_str = (
f"rtspsrc location={uri} latency={rtsp_latency} ! "
"rtph264depay ! queue max-size-buffers=1 leaky=downstream ! "
"h264parse ! queue max-size-buffers=1 leaky=downstream ! "
"mppvideodec ! queue max-size-buffers=1 leaky=downstream ! "
"videoconvert ! video/x-raw,format=BGR ! "
"appsink drop=1 max-buffers=1 sync=false"
)
cap = cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
if not cap.isOpened():
print("Error: 无法打开 RTSP 流,请检查 URI、网络和插件。", file=sys.stderr)
sys.exit(1)
# 输出管道确认信息
fps_prop = cap.get(cv2.CAP_PROP_FPS)
print(f"管道声明帧率:(CAP_PROP_FPS) = {fps_prop}")
# 简单跑帧测速
count = 0
start = time.time()
while True:
ret, frame = cap.read()
if not ret or frame is None:
print("Warning: 读取帧失败,流可能中断。", file=sys.stderr)
break
count += 1
if count % 25 == 0:
elapsed = time.time() - start
print(f"Average FPS: {count/elapsed:.1f}")
# 重置
count = 0
start = time.time()
cv2.imshow("RTSP Stream", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
性能监控
- 工具:
gst-top
监控各元件负载 -
RK芯片专用命令:watch -n 1 cat /sys/kernel/debug/rkrga/load RGA负载查询
结论在opencv+GStreamer,使用RGA进行颜色空间转换能有效降低CPU开销提升帧率
三路1080p25帧摄像头同时播放开销