本文介绍deepstream-test1 样例工程。在Nvidia 官方文档中对DeepStream-test1的描述是一个DeepStream 版本的“Hello World”。
在下图中,展示了deepstream-test1,test2,test3,test4 四个样例。
- test1: DeepStream的Hello World。介绍如何基于多种DeepStream 插件来构建一个Gstream 管道。这个样例中输入的是一个视频文件,经过解码、批处理、目标检测,并将检测信息显示在屏幕中。
- test2: 在test1的基础上,将二级网络级联到一级网络。图中我们也能看到,在目标检测之后多了一个图像分类的模块。
- test3: 在test1的基础上,如何实现多数据源。比如同时接入4路视频,实现对4路视频数据的同时推理。
- test4: 在test1的基础上,展示如何使用message broker插件创建物联网服务。
可见,test1 是样例中的基础,同时它又是一个完整的流程。将这个样例学明白,再学习其他样例就会事半功倍。
本文分为三个部分来介绍,第一部分介绍test1样例的整体流程,第二部分介绍test1样例代码,会尽可能的详细。第三部分是样例运行效果。
一、 test1样例整体流程
test1样例的整体流程: 首先数据源元件负责从磁盘上读取视频数据,解析器元件负责对数据进行解析,编码器元件负责对数据进行解码,流多路复用器元件负责批处理帧以实现最佳推理性能,推理元件负责实现加速推理,转换器元件负责将数据格式转换为输出显示支持的格式,可视化元件负责将边框与文本等信息绘制到图像中,渲染元件和接收器元件负责输出到屏幕上。
二、样例代码详解
test1的样例代码就只有一个文件,即deepstream_test1_app.c。这个文件位于opt\nvidia\deepstream\deepstream-5.0\sources\apps\sample_apps\deepstream-test1文件夹内。
下面我们从main 函数开始介绍。
2.1 main 函数
首先定义了需要用到的所有变量。因为所有GStreamer元件都具有相同的基类GstElement,因此能够采用GstElement类型对所有的元件进行定义。以及定义了负责数据消息的传输的GstBus类别变量。
GMainLoop *loop = NULL;
GstElement *pipeline = NULL, *source = NULL, *h264parser = NULL,
*decoder = NULL, *streammux = NULL, *sink = NULL, *pgie = NULL, *nvvidconv = NULL,
*nvosd = NULL;
#ifdef PLATFORM_TEGRA
GstElement *transform = NULL;
#endif
GstBus *bus = NULL;
guint bus_watch_id;
GstPad *osd_sink_pad = NULL;
然后在主函数中调用gst_init()来完成相应的初始化工作,以便将用户从命令行输入的参数传递给GStreamer函数库。
gst_init (&argc, &argv);
创建主循环,在执行 g_main_loop_run后正式开始循环
loop = g_main_loop_new (NULL, FALSE);
在GStreamer框架中管道是用来容纳和管理元件的,下面将创建一条名为pipeline的管道:
pipeline = gst_pipeline_new ("dstest1-pipeline");
创建管理中需要使用的所有元件。最后检查所有元件是否创建成功
// 创建一个gstreamer element, 类型为filesrc,名称为file-source。
source = gst_element_factory_make ("filesrc", "file-source");
// 创建一个gstreamer element, 类型为h264parse,名称为h264-parser。
// 因为输入文件中的数据格式是基本的h264流,所以我们需要一个h264解析器
h264parser = gst_element_factory_make ("h264parse", "h264-parser");
// 创建一个gstreamer element, 类型为nvv4l2decoder,名称为nvv4l2-decoder。
// 调用GPU硬件加速来解码h264文件
decoder = gst_element_factory_make ("nvv4l2decoder", "nvv4l2-decoder");
// 创建一个gstreamer element, 类型为nvstreammux,名称为stream-muxer。
// 从一个或多个源中来组成batches
streammux = gst_element_factory_make ("nvstreammux", "stream-muxer");
// 若管道元件为空或者流复用器元件为空, 报错
if (!pipeline || !streammux) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
// 创建一个gstreamer element, 类型为nvinfer,名称为primary-nvinference-engine。
// 使用nvinfer在解码器的输出上运行推理,推理过程的参数是通过配置文件设置的
pgie = gst_element_factory_make ("nvinfer", "primary-nvinference-engine");
// 创建一个gstreamer element, 类型为nvvideoconvert