在 DeepStream 的示例程序中,deepstream-server-app 是一个很有代表性的样例。它的核心目的,是演示如何通过 nvmultiurisrcbin 使用 REST API 动态管理视频流。
官方 README 里有一句话非常关键:
The deepstream-server-app uses nvmultiurisrcbin to demonstrate REST API server functionality.
也就是说,这个 sample 并不是单纯展示一个固定输入的视频分析 pipeline,而是展示一个可以在运行时通过 HTTP 请求添加、删除、配置视频流的 DeepStream 服务。
nvmultiurisrcbin 是什么?
nvmultiurisrcbin 是 DeepStream 提供的一个 GStreamer Bin。它把几个常用能力封装在一起:
nvurisrcbin:负责处理单路 URI 输入,比如本地文件、RTSP 流等。nvstreammux:负责把多路输入 batch 到一起。nvds_rest_server:提供 REST API 服务,用于运行时控制 pipeline。
因此,使用 nvmultiurisrcbin 后,应用不需要自己手动创建每一路 source bin,也不需要自己处理 streammux sink pad 的申请和释放。应用只需要配置 nvmultiurisrcbin,然后通过 REST API 动态添加或删除 stream。
deepstream-server-app 的整体 pipeline
这个 sample 的主程序在:
apps/deepstream/sample_apps/deepstream-server/deepstream_server_app.cpp
默认 pipeline 大致是:
nvmultiurisrcbin
-> queue
-> nvdspreprocess
-> nvinfer / nvinferserver
-> nvdsanalytics / identity
-> nvdslogger
-> nvmultistreamtiler
-> nvvideoconvert
-> nvdsosd
-> sink
其中最重要的入口就是 nvmultiurisrcbin。它负责输出已经 batch 好的 buffer,后面的推理、分析、显示都和普通 DeepStream 多路 pipeline 类似。
REST Server 默认运行在 nvmultiurisrcbin 内部
配置文件是:
apps/deepstream/sample_apps/deepstream-server/dsserver_config.yml
默认配置里有:
rest-server:
within_multiurisrcbin: 1
这表示 REST server 由 nvmultiurisrcbin 自己内部启动和管理。同时,multiurisrcbin 配置里指定了监听端口、初始输入源、batch size、mux 分辨率等:
multiurisrcbin:
uri-list: file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
port: 9000
live-source: 1
width: 1920
height: 1080
batched-push-timeout: 33333
max-batch-size: 8
drop-pipeline-eos: 1
这里的 port: 9000 表示 REST API 服务监听在 localhost:9000。
通过 REST API 动态添加视频流
sample README 中给出的添加 stream 请求如下:
curl -XPOST 'http://localhost:9000/api/v1/stream/add' -d '{
"key": "sensor",
"value": {
"camera_id": "uniqueSensorID1",
"camera_name": "front_door",
"camera_url": "file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4",
"change": "camera_add",
"metadata": {
"resolution": "1920 x1080",
"codec": "h264",
"framerate": 30
}
},
"headers": {
"source": "vst",
"created_at": "2021-06-01T14:34:13.417Z"
}
}'
其中真正关键的字段是:
camera_id:唯一的 sensor ID。camera_url:视频源地址,可以是本地文件,也可以是 RTSP。change:动作类型,比如camera_add。
在 nvmultiurisrcbin 内部,只要 change 字符串包含 add 或 streaming,就会走添加 source 的逻辑。
也就是说,source 类型不是由 camera_add 或 camera_streaming 决定的,而是由 camera_url 决定的:
file:///... -> 本地文件
rtsp://... -> RTSP 实时流
http://... -> HTTP URL
通过 REST API 删除视频流
删除 stream 的请求如下:
curl -XPOST 'http://localhost:9000/api/v1/stream/remove' -d '{
"key": "sensor",
"value": {
"camera_id": "uniqueSensorID1",
"camera_name": "front_door",
"camera_url": "file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4",
"change": "camera_remove"
}
}'
删除时,nvmultiurisrcbin 会根据 camera_id 和 camera_url 查找对应的 source,然后调用内部 creator API 移除该 source。
这个 sample 还演示了什么?
除了添加和删除 stream,deepstream-server-app 还展示了很多运行时控制能力,例如:
- 更新 ROI。
- 修改 decoder 的
drop-frame-interval和skip-frames。 - 修改
nvinfer/nvinferserver的 interval。 - 修改 encoder 的 bitrate、force-idr、force-intra。
- 修改
nvstreammux的batched-push-timeout。 - 修改
nvvideoconvert的 crop、flip、interpolation。 - 修改
nvdsosd的 process mode。 - 查询 stream info、metrics、liveness、readiness。
- 通过 REST API 让应用退出。
这些能力说明 deepstream-server-app 不只是一个视频分析 demo,而是一个"服务化 DeepStream pipeline"的参考实现。
两种 REST Server 模式
这个 sample 支持两种模式。
第一种是默认模式:
rest-server:
within_multiurisrcbin: 1
REST server 在 nvmultiurisrcbin 内部运行。这也是官方更推荐的简单用法。
第二种是:
rest-server:
within_multiurisrcbin: 0
这时应用自己启动 nvds_rest_server,并使用:
rest_server_callbacks.cpp
里的 callback 来处理 REST 请求。
需要注意的是,这个 app-owned REST callback 版本里,stream add 只检查 change 是否包含 add,不像 nvmultiurisrcbin 内部实现那样同时接受 streaming。所以默认模式下 camera_streaming 可以添加流,但 app-owned callback 模式下可能不行。
总结
deepstream-server-app 展示的是一种更接近生产服务的 DeepStream 使用方式:pipeline 启动后,不再局限于固定输入源,而是可以通过 REST API 动态添加、删除和配置视频流。
nvmultiurisrcbin 是这个能力的核心。它把 source 管理、streammux batch、REST API 服务封装在一起,让应用层可以专注于后续的推理、分析、显示或消息输出逻辑。
如果你想构建一个支持多路摄像头动态接入的 DeepStream 服务,deepstream-server-app 是最值得先读的 sample。