注意,了解gobject是deepstream的学习前提。了解就好,可以看看这位作者的博客.
deepstream依托于gstreamer框架,可以认为deepstream其实就是设计了几个插件,只不过这几个插件比较复杂,可以定制许多参数,用于控制视频流的推理逻辑和推理算法的选择。
其核心插件是 nvinfer插件,且已经部分开源。从代码实现的角度插件由两部分构成,第一部分为媒体流控制相关操作,代码位于 gst-nvinfer目录内,另外一部分为推理引擎部分的代码,该部分则是调用tensorrt的api实现。
打算在这里首先梳理一下,媒体流控制部分的代码。
在gstreamer框架中,gstBuffer是在不同插件流动的基础数据结构。
这里是gstBuffer的官方文档,阅读第一段你可以对gstBuffer的设计有个大致的理解。当然刚接触时,你可能因为对于概念的不熟悉,而感到困惑,实际上
下面是 gstreamer-1.14.5中gstBuffer的数据结构:
struct _GstBuffer {
GstMiniObject mini_object;
/*< public >*/ /* with COW */
GstBufferPool *pool;
/* timestamp */
GstClockTime pts;
GstClockTime dts;
GstClockTime duration;
/* media specific offset */
guint64 offset;
guint64 offset_end;
};
上面可以认为是gstBuffer的public属性,其内部的私有属性包含在一个名为GstBufferImpl的数据结构之中,(其首字节必定为GstBuffer,很关键,这是gobect继承体系的核心其实)
typedef struct
{
GstBuffer buffer;
gsize slice_size;
/* the memory blocks */
guint len;
GstMemory *mem[GST_BUFFER_MEM_MAX];
/* memory of the buffer when allocated from 1 chunk */
GstMemory *bufmem;
/* FIXME, make metadata allocation more efficient by using part of the
* GstBufferImpl */
GstMetaItem *item;
} GstBufferImpl;
我们通过查看gstBuffer的创建源码,体会是怎么实现的,可以看到实际包含了多个gstMemory
//创建一个gstbuffer对象
GstBuffer *
gst_buffer_new (void)
{
GstBufferImpl *newbuf;
newbuf = g_slice_new (GstBufferImpl);
GST_CAT_LOG (GST_CAT_BUFFER, "new %p", newbuf);
gst_buffer_init (newbuf, sizeof (GstBufferImpl));
return GST_BUFFER_CAST (newbuf);
}
//初始化
static void
gst_buffer_init (GstBufferImpl * buffer, gsize size)
{
gst_mini_object_init (GST_MINI_OBJECT_CAST (buffer), 0, _gst_buffer_type,
(GstMiniObjectCopyFunction) _gst_buffer_copy,
(GstMiniObjectDisposeFunction) _gst_buffer_dispose,
(GstMiniObjectFreeFunction) _gst_buffer_free);
GST_BUFFER_SLICE_SIZE (buffer) = size;
GST_BUFFER (buffer)->pool = NULL;
GST_BUFFER_PTS (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DTS (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_MEM_LEN (buffer) = 0;
GST_BUFFER_META (buffer) = NULL;
}
gstnvinfer插件通过继承gstbuffer的allocator进行更改,
// GstInferMem
/** Structure allocated internally by the allocator. */
typedef struct
{
/** Should be the first member of a structure extending GstMemory. */
GstMemory mem;
GstNvInferMemory mem_infer;
} GstNvInferMem;
/**
* Holds the pointer for the allocated memory.
*/
typedef struct
{
NvBufSurface *surf;
#ifdef IS_TEGRA
/** Vector of cuda resources created by registering the above egl images in CUDA. */
std::vector<CUgraphicsResource> cuda_resources;
/** Vector of CUDA eglFrames created by mapping the above cuda resources. */
std::vector<CUeglFrame> egl_frames;
#else
/** Pointer to the memory allocated for the batch of frames (DGPU). */
void *dev_memory_ptr;
#endif
/** Vector of pointer to individual frame memories in the batch memory */
std::vector<void *> frame_memory_ptrs;
} GstNvInferMemory;
typedef struct
{
NvBufSurface *surf;
#ifdef IS_TEGRA
/** Vector of cuda resources created by registering the above egl images in CUDA. */
std::vector<CUgraphicsResource> cuda_resources;
/** Vector of CUDA eglFrames created by mapping the above cuda resources. */
std::vector<CUeglFrame> egl_frames;
#else
/** Pointer to the memory allocated for the batch of frames (DGPU). */
void *dev_memory_ptr;
#endif
/** Vector of pointer to individual frame memories in the batch memory */
std::vector<void *> frame_memory_ptrs;
} GstNvInferMemory;
版权声明:本文为HongyoHu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。