Gst-nvdsxfer#
Gst-nvdsxfer
插件执行离散 GPU 之间的数据传输。目前仅在 x86 平台上支持。它使用 CUDA API 来利用 NVIDIA NVLINK 技术,实现高速、直接的 GPU 到 GPU 互连,从而优化离散 GPU 之间的数据传输。
该插件接受来自上游组件的基于 CUDA 内存(NvBufSurface
分配)的视频 Gst
缓冲区。它使用优化的基于 NVLINK 的数据复制将输入数据传输到基于 CUDA 内存(NvBufSurface
分配)的视频输出 Gst
缓冲区。
注意
Gst-nvdsxfer
插件目前支持基于多 dGPU 设置的用例管道的单节点、单应用场景。在两个离散 GPU 之间进行数据复制时,不支持视频格式转换或缩放。多 dGPU 使用 NVLINK 桥接连接器连接。用户必须在使用 gst-pipeline 中的 nvdsxfer
插件之前,确认两个离散 GPU 之间的 NVLINK 状态(活动/非活动 - 使用命令 “nvidia-smi nvlink -s
” 检查)。
如下图所示,输入视频数据通过 NVLINK 连接的离散 GPU 复制到输出。

输入和输出#
本节总结了 Gst-nvdsxfer
插件的输入和输出。
输入
Gst 缓冲区批处理缓冲区
NvDsBatchMeta
原始视频格式:NV12、I420、RGBA (NVMM)
控制参数
gpu-id
p2p-gpu-id
batch-size
buffer-pool-size
nvbuf-memory-type
输出
Gst 缓冲区批处理缓冲区
NvDsBatchMeta
原始视频格式:NV12、I420、RGBA (NVMM)
Gst 属性#
下表描述了 Gst-nvdsxfer
插件的 Gst
属性。
属性 |
含义 |
类型和范围 |
示例注释 |
---|---|---|---|
batch-size |
批处理中缓冲区的最大数量 |
无符号整数。范围:0 - 4294967295 默认值:1 |
batch-size=2 |
buffer-pool-size |
muxer 内部池中缓冲区的最大数量 |
无符号整数。范围:2 - 16 默认值:4 |
buffer-pool-size=2 |
gpu-id |
设置 GPU 设备 ID |
无符号整数。范围:0 - 4294967295 默认值:0 |
gpu-id=1 |
p2p-gpu-id |
设置 P2P GPU ID 以启用 P2P 访问。默认情况下,禁用 GPU 之间的 P2P 访问。 |
整数。范围:-1 - 1024 默认值:-1 |
p2p-gpu-id=0 |
nvbuf-memory-type |
为输出缓冲区分配的 NvBufSurface 内存类型 |
枚举 “GstNvBufMemoryType” 默认值:0, “nvbuf-mem-default” (0): nvbuf-mem-default - 默认分配的内存,特定于特定平台 (1): nvbuf-mem-cuda-pinned - 分配固定/主机 CUDA 内存 (2): nvbuf-mem-cuda-device - 分配设备 CUDA 内存 (3): nvbuf-mem-cuda-unified - 分配统一 CUDA 内存 |
nvbuf-memory-type=2 |
如何测试#
nvdsxfer
目前仅支持 X86。尚不支持 “Jetson + dGPU”。多 dGPU 使用 NVLINK 桥接连接器连接。如果准备好使用,请使用以下命令确认 NVLINK 状态(活动/非活动)。
nvidia-smi nvlink -s
nvdsxfer
插件目前仅使用 2 个独立的 dGPU(离散 GPU)进行验证。下面列出的 gst-launch-1.0 pipelines 模拟了一些使用 2 个独立的 dGPU(离散 GPU)的参考用例管道。如果允许离散 GPU 之间的对等 (P2P) 访问,请设置属性
p2p_gpu_id=0
。如果 P2P 访问不可用,则管道将失败,删除
p2p_gpu_id=0
属性使其在没有 P2P 访问的情况下运行。下面提到的参考 gst-launch-1.0 pipelines 默认使用旧的
streammux
。新的nvstreammux
也可以通过启用 USE_NEW_NVSTREAMMUX=yes 环境变量并为新的streammux
插件设置适当的属性来使用。
注意
gst-launch-1.0 pipelines 在 用例 部分中提到的,虽然不是最佳管道,但可以演示 nvdsxfer
插件在各种用例中的用法,以实现更好的性能和 GPU 利用率。
注意
deepstream-multigpu-nvlink-test
示例应用程序可以演示基于 nvdsxfer 插件的 gstreamer 管道。有关用法和应用程序支持的功能,请参阅 /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-multigpu-nvlink-test/README
。
用例#
以下参考 gst-launch-1.0 命令使用 h265 基本码流作为输入。为了使用 DeepStream SDK 提供的示例 mp4 码流,请使用以下命令将 mp4 容器文件转换为 h265 基本码流。
cd /opt/nvidia/deepstream/deepstream/
gst-launch-1.0 filesrc location= samples/streams/sample_1080p_h265.mp4 ! qtdemux ! h265parse ! 'video/x-h265,stream-format=byte-stream' ! filesink location= samples/streams/sample_1080p.h265
单码流 + 多 dGPU 设置#
在单独的 dGPU 上运行 “解码 + StreamMux + PGIE” 和 “Tracker + SGIE (多个)”
gst-launch-1.0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_0 nvstreammux name=m batch-size=1 gpu-id=0 \
width=1920 height=1080 nvbuf-memory-type=2 ! queue ! nvinfer gpu-id=0 batch-size=1 \
config-file-path=samples/configs/deepstream-app/config_infer_primary.txt ! queue ! \
nvdsxfer gpu-id=1 p2p_gpu_id=0 ! queue ! nvtracker gpu-id=1 enable-batch-process=1 \
ll-lib-file=lib/libnvds_nvmultiobjecttracker.so ll-config-file=samples/configs/deepstream-app/config_tracker_NvDCF_perf.yml ! \
queue ! nvinfer gpu-id=1 batch-size=16 unique-id=2 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehiclemake.txt ! \
queue ! nvinfer gpu-id=1 batch-size=16 unique-id=3 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehicletypes.txt ! \
queue ! fpsdisplaysink video-sink=fakesink sync=0 -e -v
在单独的 dGPU 上运行 “解码 + StreamMux” 和 “PGIE + Tracker + SGIE (多个)”
gst-launch-1.0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \ nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_0 nvstreammux name=m batch-size=1 gpu-id=0 \ width=1920 height=1080 nvbuf-memory-type=2 ! queue ! nvdsxfer gpu-id=1 p2p_gpu_id=0 ! queue ! \ nvinfer gpu-id=1 batch-size=1 config-file-path= samples/configs/deepstream-app/config_infer_primary.txt ! queue ! \ nvtracker gpu-id=1 enable-batch-process=1 ll-lib-file=lib/libnvds_nvmultiobjecttracker.so \ ll-config-file=samples/configs/deepstream-app/config_tracker_NvDCF_perf.yml ! queue ! nvinfer gpu-id=1 batch-size=16 unique-id=2 \ config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehiclemake.txt ! queue ! nvinfer gpu-id=1 batch-size=16 unique-id=3 \ config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehicletypes.txt ! queue ! fpsdisplaysink video-sink=fakesink sync=0 -e -v
多码流 + 多 dGPU 设置#
在单个 dGPU 上运行 “多实例 (4) 解码 + Streammux + PGIE”,在单独的 dGPU 上运行 “tracker + SGIE - 多个模型”
gst-launch-1.0 nvstreammux name=m batch-size=4 gpu-id=0 width=1920 height=1080 nvbuf-memory-type=2 ! queue ! \
nvinfer gpu-id=0 batch-size=4 config-file-path=samples/configs/deepstream-app/config_infer_primary.txt ! queue ! \
nvdsxfer gpu-id=1 p2p_gpu_id=0 ! queue ! nvtracker gpu-id=1 enable-batch-process=1 \
ll-lib-file=lib/libnvds_nvmultiobjecttracker.so ll-config-file=samples/configs/deepstream-app/config_tracker_NvDCF_perf.yml ! queue ! \
nvinfer gpu-id=1 batch-size=16 unique-id=2 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehiclemake.txt ! queue ! \
nvinfer gpu-id=1 batch-size=16 unique-id=3 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehicletypes.txt ! queue ! \
fpsdisplaysink video-sink=fakesink sync=0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_1 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_2 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_3 -e -v
在单个 dGPU 上运行 “多实例 (4) 解码 + StreamMux”,在单独的 dGPU 上运行 “PGIE + Tracker + SGIE(多个)”
gst-launch-1.0 nvstreammux name=m batch-size=4 gpu-id=0 width=1920 height=1080 nvbuf-memory-type=2 ! queue ! \
nvdsxfer gpu-id=1 p2p_gpu_id=0 ! queue ! nvinfer gpu-id=1 batch-size=4 config-file-path=samples/configs/deepstream-app/config_infer_primary.txt ! queue ! \
nvtracker gpu-id=1 enable-batch-process=1 ll-lib-file=lib/libnvds_nvmultiobjecttracker.so \
ll-config-file=samples/configs/deepstream-app/config_tracker_NvDCF_perf.yml ! queue ! nvinfer gpu-id=1 batch-size=16 unique-id=2 \
config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehiclemake.txt ! queue ! nvinfer gpu-id=1 batch-size=16 unique-id=3 \
config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehicletypes.txt ! queue ! fpsdisplaysink video-sink=fakesink sync=0 \
multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_0 \
multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_1 \
multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_2 \
multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_3 -e -v
在多 dGPU 上运行 “多实例 (8) 解码”,在任何一个 dGPU 上运行 “StreamMux + PGIE + Tracker + SGIE(多个)”
gst-launch-1.0 nvstreammux name=m batch-size=8 gpu-id=0 width=1920 height=1080 nvbuf-memory-type=2 ! queue ! nvinfer gpu-id=0 batch-size=8 \
config-file-path=samples/configs/deepstream-app/config_infer_primary.txt ! queue ! nvtracker gpu-id=0 enable-batch-process=1 \
ll-lib-file=lib/libnvds_nvmultiobjecttracker.so ll-config-file=samples/configs/deepstream-app/config_tracker_NvDCF_perf.yml ! queue ! \
nvinfer gpu-id=0 batch-size=16 unique-id=2 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehiclemake.txt ! queue ! \
nvinfer gpu-id=0 batch-size=16 unique-id=3 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehicletypes.txt ! queue ! \
fpsdisplaysink video-sink=fakesink sync=0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_1 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_2 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_3 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_4 multifilesrc \
location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! \
nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_5 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_6 multifilesrc \
location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! \
nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_7 -e -v
在多 dGPU 上运行 “多实例 (8) 解码”,在单独的 dGPU 上运行 “StreamMux + PGIE” 和 “Tracker + SGIE(多个)”
gst-launch-1.0 nvstreammux name=m batch-size=8 gpu-id=0 width=1920 height=1080 nvbuf-memory-type=2 ! queue ! nvinfer gpu-id=0 batch-size=8 \
config-file-path=samples/configs/deepstream-app/config_infer_primary.txt ! queue ! nvdsxfer gpu-id=1 p2p_gpu_id=0 ! queue ! nvtracker gpu-id=1 \
enable-batch-process=1 ll-lib-file=lib/libnvds_nvmultiobjecttracker.so ll-config-file=samples/configs/deepstream-app/config_tracker_NvDCF_perf.yml ! \
queue ! nvinfer gpu-id=1 batch-size=16 unique-id=2 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehiclemake.txt ! \
queue ! nvinfer gpu-id=1 batch-size=16 unique-id=3 config-file-path=samples/configs/deepstream-app/config_infer_secondary_vehicletypes.txt ! \
queue ! fpsdisplaysink video-sink=fakesink sync=0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! \
queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_0 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! \
queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_1 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! \
queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_2 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! \
queue ! nvv4l2decoder gpu-id=0 cudadec-memtype=0 ! queue ! m.sink_3 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! \
queue ! nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_4 multifilesrc \
location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! \
nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_5 multifilesrc location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! \
nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_6 multifilesrc \
location=samples/streams/sample_1080p.h265 loop=true ! h265parse ! queue ! nvv4l2decoder gpu-id=1 cudadec-memtype=0 ! queue ! \
nvdsxfer gpu-id=0 p2p_gpu_id=1 ! queue ! m.sink_7 -e -v