OpenCV + gstreamer 管道问题

OpenCV + gstreamer pipline issue

我有这条管道,运行我的 Jetson 相机使用命令行没有问题:

gst-launch-1.0 udpsrc port=5000 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)\"Z0JAKpWgHgCJ+VA\=\,aM48gA\=\=\",payload=(int)96" ! rtph264depay ! decodebin ! autovideosink sync=false

我想从 python 脚本中 运行 它,所以我使用了这段代码(我之前用我电脑上的示例视频测试过它并且可以正常工作)。

import cv2
import numpy as np

print(cv2.__version__)
width = 640
height = 480

#pipeline='videotestsrc ! videoconvert ! appsink'
#pipeline = 'filesrc location = sample.mp4 ! qtdemux ! queue ! h264parse ! omxh264dec !nvvidconv ! video/x-raw, format=BGRx ! queue ! videoconvert ! queue ! video/x-raw, format=BGR ! appsink'

pipeline = 'udpsrc port=5000 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)\"Z0JAKpWgHgCJ+VA\=\,aM48gA\=\\=\", payload=(int)96" ! rtph264depay ! decodebin ! appsink'
print("pipeline defined")

#'udpsrc port=5000 caps=\"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)\"Z0JAKpWgHgCJ+VA\=\,aM48gA\=\\=\",payload=(int)96" ! rtph264depay ! decodebin ! appsink'
caps = cv2.CAP_GSTREAMER
cam = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
print("pipeline passed to video capture")
if cam.isOpened():
    print("yes")
else: 
    print("no")
while cam.isOpened():
    _,frame = cam.read()
    cv2.imshow('myCam',frame)
    #cv2.moveWindow('myCam',0,0)
    if cv2.waitKey(1) == ord('q'):
        break

cam.release()
cv2.destroyAllWindows()

如何正确表示管道中的“大写字母”部分,因为我认为这是导致错误的原因。我尝试在每个 " 符号之前添加一个 \ 或在中间使用双引号,但它没有用。我还尝试将大写字母设置为管道中的单独阶段,如下所示:

udpsrc port=5000 ! application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)\"Z0JAKpWgHgCJ+VA\=\,aM48gA\=\\=\", payload=(int)96" ! rtph264depay ! decodebin ! appsink'

谢谢

decodebin 在内部为每种类型的 parsing/decoding 选择子插件。 有一个排名允许选择何时有多个插件可用于一种解码。 对于 H264 解码,在 Jetsons 上最高级别是 nvv4l2decoder,它输出到 NVMM 内存(除非另有说明,否则为 NV12 格式)适用于 autovideosink,它将实例化插件 nvoverlaysink 从 NVMM 内存读取。

要从 OpenCv 应用程序读取,您需要系统内存中的帧,最好是 BGR 格式的彩色帧。 因此,您首先将解码器的 NVMM 内存输出中的 NV12 转换为 BGRx 格式,然后使用插件 nvvidconv 复制到系统内存中。然后使用 CPU-based 插件 videoconvert 转换成 BGR:

pipeline = 'udpsrc port=5000 ! application/x-rtp,media=video,encoding-name=H264 ! rtph264depay ! decodebin ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1'
cam = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)

您可以将 sprop-parameter-sets 属性 添加到 udpsrc 和 rtpjitterbuufer 之间的大写字母中(我已在此处添加,否则它可能无法 运行 而不禁用同步)如果 SPS和 PPS 未插入到流中:

pipeline = 'udpsrc port=5000 ! application/x-rtp, media=video,encoding-name=H264, sprop-parameter-sets="Z0JAKpWgHgCJ+VA\=\,aM48gA\=\=" ! rtpjitterbuffer latency=500 ! rtph264depay ! decodebin ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1 ' 
#or
pipeline = 'udpsrc port=5000 ! application/x-rtp, media=video,encoding-name=H264, sprop-parameter-sets="Z0JAKpWgHgCJ+VA\=\,aM48gA\=\=" ! rtpjitterbuffer latency=500 ! rtph264depay ! decodebin ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1 '