deepstream学习笔记1.数据结构篇

注意,了解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;

你可能感兴趣的:(数据结构)