二、Deepsrtream 元数据

1 Basic Metadata Structures

1.1 基础的元数据结构体

  Gst Buffer是GStreamer中数据传输的基本单位。每个Gst Buffer都有关联的元数据。DeepStream SDK附加了DeepStream元数据对象NvDsBatchMeta,如下所述。要了解更多关于Gst Buffer的信息,请参阅GStreamer文档

  DeepStreamDeepStream为元数据使用了可扩展的标准结构。基本的元数据结构NvDsBatchMeta从批处理级元数据开始,它是在Gst-nvstreammux插件中创建的。附属元数据结构保存有frame、object、classifier和label数据。DeepStream还提供了一种在batch、frame或object级别添加用户特定元数据的机制。DeepStream通过附加NvDsBatchMeta结构和设置GstNvDsMetaType来将元数据附加到Gst缓冲区。在Gst-nvstreammux插件中的meta_type为NVDS_BATCH_GST_META。当应用程序处理Gst Buffer时,它可以遍历附加的元数据来找到NVDS_BATCH_GST_META。函数gst_buffer_get_nvds_batch_meta()从Gst缓冲区中提取NvDsBatchMeta。(参见sources/include/gstnvdsmeta.h中的声明。)有关此函数的使用示例,请参阅deepstream-test1示例应用程序。更多详细信息,请参阅DeepStream API指南中的DeepStream SDK API参考文档

在这里插入图片描述

1.2 在NvDsBatchMeta中添加用户/自定义元数据

  要在NvDsBatchMeta中以批处理、帧或对象级别附加用户特定的元数据,你必须通过调用nvds_acquire_user_meta_from_pool()从用户元数据池中获取一个NvDsUserMeta实例。(详情请参见sources/includes/nvdsmeta.h。)然后必须初始化NvDsUserMeta。必须设置的成员是user_meta_data、meta_type、copy_func和release_func。有关更多详细信息,请参见sources/apps/sample_apps/deepstream-user-metadata-test/deepstream_user_metadata_app.c中的示例应用程序源代码。

1.3 从Gst-nvstreammux上游在Gst插件中添加自定义元数据

  暂时保留

2 nvdsmeta.h 基本结构

2.1 typedef GList

  因为输入流N个、一帧里检测到的对象、用户数据、display、标签信息等都是N个的原因,使用了GList列表。

typedef struct _GList GList;

struct _GList
{
  gpointer data;
  GList *next;
  GList *prev;
};
/* NvDsFrameMetaList *list; 
 * NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);  */
typedef GList NvDsFrameMetaList; 
/* NvDsUserMeta */
typedef GList NvDsUserMetaList;
/* NvDsObjectMeta */
typedef GList NvDsObjectMetaList;
/* NvDisplayMeta */
typedef GList NvDisplayMetaList;
/* NvDsClassifierMeta */
typedef GList NvDsClassifierMetaList;
/* NvDsLabelInfo */
typedef GList NvDsLabelInfoList;
typedef GList NvDsMetaList;

2.2 NvDsBaseMeta

  NvDsBaseMeta是DeepStream SDK中所有元数据对象的基类。它定义了元数据对象的基本属性和方法,是其他各种类型的元数据对象的基础。

  在DeepStream SDK中,元数据是以NvDsMeta对象的形式存在的。NvDsMeta对象包含了描述特定对象的信息,例如目标检测结果、分类结果、属性等。NvDsBaseMeta类是所有NvDsMeta对象的基类,它包含了一些通用的属性和方法

/**
 * Holds information about base metadata of a given metadata type.
 */
typedef struct _NvDsBaseMeta {
  /** Holds a pointer to batch_meta @ref NvDsBatchMeta. */
  struct _NvDsBatchMeta *batch_meta;
  /** Holds the metadata type of this metadata element. */
  NvDsMetaType meta_type;
  /** Holds a pointer to a user context. */
  void * uContext;
  /** Holds a user-defined copy function. The function is called to copy
   or transform metadata from one buffer to another. @a meta_data and
   @a user_data are passed as arguments. */
  NvDsMetaCopyFunc copy_func;
  /** Holds a user-defined release function. The function is called
   when @a meta_data is to be released. */
  NvDsMetaReleaseFunc release_func;
} NvDsBaseMeta;

2.3 NvDsMetaPool

  元数据是以NvDsMeta对象的形式存在的,每个NvDsMeta对象包含了描述特定对象的信息,例如目标检测结果、分类结果、属性等。

  NvDsMetaPool维护着一个可用的NvDsMeta对象池,它可以避免频繁的内存分配和释放(避免内存碎片),从而提高系统的性能和稳定性。当需要创建新的NvDsMeta对象时,可以通过NvDsMetaPool来分配内存,而不是通过常规的内存分配方式(如malloc函数)。

typedef struct _NvDsMetaPool {
  NvDsMetaType meta_type;
  guint max_elements_in_pool;
  guint element_size;
  guint num_empty_elements;
  guint num_full_elements;
  NvDsMetaList * empty_list;
  NvDsMetaList * full_list;
  NvDsMetaCopyFunc copy_func;
  NvDsMetaReleaseFunc release_func;
}NvDsMetaPool;
GstPadProbeReturn
osd_sink_pad_buffer_probe (GstPad * pad, 
                           GstPadProbeInfo * info,
                           gpointer u_data) {
	NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
	for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
	    l_frame = l_frame->next) {
	    NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
    
    g_print ("*****************************************************\n");
    g_print ("batch_meta->frame_meta_pool->max_elements_in_pool = %d\n", batch_meta->frame_meta_pool->max_elements_in_pool);
    g_print ("batch_meta->frame_meta_pool->element_size = %d\n", batch_meta->frame_meta_pool->element_size);
    g_print ("batch_meta->frame_meta_pool->num_empty_elements = %d\n", batch_meta->frame_meta_pool->num_empty_elements);
    g_print ("batch_meta->frame_meta_pool->num_full_elements = %d\n", batch_meta->frame_meta_pool->num_full_elements);
    g_print ("batch_meta->frame_meta_pool->empty_list = %p\n", batch_meta->frame_meta_pool->empty_list);
    g_print ("batch_meta->frame_meta_pool->full_list = %p\n", batch_meta->frame_meta_pool->full_list);
    g_print ("batch_meta->frame_meta_pool->full_list->data = %p\n", batch_meta->frame_meta_pool->full_list->data);
    g_print ("batch_meta->frame_meta_pool->copy_func = %p\n", batch_meta->frame_meta_pool->copy_func);
    g_print ("batch_meta->frame_meta_pool->release_func = %p\n", batch_meta->frame_meta_pool->release_func);

    g_print ("batch_meta->frame_meta_list = %p\n", batch_meta->frame_meta_list);
    g_print ("batch_meta->frame_meta_list->data= %p\n", batch_meta->frame_meta_list->data);

batch_meta->frame_meta_pool->max_elements_in_pool = 1
batch_meta->frame_meta_pool->element_size = 200
batch_meta->frame_meta_pool->num_empty_elements = 0
batch_meta->frame_meta_pool->num_full_elements = 1
batch_meta->frame_meta_pool->empty_list = (nil)
batch_meta->frame_meta_pool->full_list = 0xffff3c04e6e0
batch_meta->frame_meta_pool->full_list->data = 0xffff60007370
batch_meta->frame_meta_pool->copy_func = (nil)
batch_meta->frame_meta_pool->release_func = 0xffff8861ae30
batch_meta->frame_meta_list = 0xffff3c04e760
batch_meta->frame_meta_list->data= 0xffff60007370

for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;
            l_obj = l_obj->next) {
      obj_meta = (NvDsObjectMeta *) (l_obj->data);
      g_print ("*****************************************************\n");
      g_print ("batch_meta->obj_meta_pool->max_elements_in_pool = %d\n", batch_meta->obj_meta_pool->max_elements_in_pool);
      g_print ("batch_meta->obj_meta_pool->element_size = %d\n", batch_meta->obj_meta_pool->element_size);
      g_print ("batch_meta->obj_meta_pool->num_empty_elements = %d\n", batch_meta->obj_meta_pool->num_empty_elements);
      g_print ("batch_meta->obj_meta_pool->num_full_elements = %d\n", batch_meta->obj_meta_pool->num_full_elements);
      g_print ("batch_meta->obj_meta_pool->empty_list = %p\n", batch_meta->obj_meta_pool->empty_list);
      g_print ("batch_meta->obj_meta_pool->full_list = %p\n", batch_meta->obj_meta_pool->full_list);
      g_print ("batch_meta->obj_meta_pool->full_list->data = %p\n", batch_meta->obj_meta_pool->full_list->data);
      g_print ("batch_meta->obj_meta_pool->copy_func = %p\n", batch_meta->obj_meta_pool->copy_func);
      g_print ("batch_meta->obj_meta_pool->release_func = %p\n", batch_meta->obj_meta_pool->release_func);
      g_print ("frame_meta->obj_meta_list = %p\n", frame_meta->obj_meta_list);
      g_print ("frame_meta->obj_meta_list->data = %p\n", frame_meta->obj_meta_list->data);

batch_meta->obj_meta_pool->max_elements_in_pool = 8
batch_meta->obj_meta_pool->element_size = 544
batch_meta->obj_meta_pool->num_empty_elements = 7
batch_meta->obj_meta_pool->num_full_elements = 1
batch_meta->obj_meta_pool->empty_list = 0xfffe7c0032c0
batch_meta->obj_meta_pool->full_list = 0xffff64012b80
batch_meta->obj_meta_pool->full_list->data = 0xffff600a5e10
batch_meta->obj_meta_pool->copy_func = (nil)
batch_meta->obj_meta_pool->release_func = 0xffff8b103f40
frame_meta->obj_meta_list = 0xfffe7c002e80
frame_meta->obj_meta_list->data = 0xffff600a5e10

   在_NvDsBatchMeta中的NvDsFrameMetaList *frame_meta_list和 NvDsMetaPool *frame_meta_pool最终的NvDsFrameMeta地址是一样的,也就是说NvDsFrameMetaList和frame_meta_pool->full_list列表对象不一样,但是列表对象指向的data是一致的。一般管理数据,都是通过NvDsFrameMetaList *frame_meta_list,自己添加数据子类才会通过pool请求内存。

3 NvDsBatchMeta

  其中nvstreammux会创建一个NvDsBatchMeta,这一个NvDsBatchMeta包含了Frame、User、Object、Display、Classifier、LabelInfo等数据。
  最主要的

NvDsFrameMeta #(链表中的data)
├── NvDsObjectMetaList *obj_meta_list; #(obj_meta_list->data)
│   ├── NvDsClassifierMetaList *classifier_meta_list;
│	└── ... #(识别对象的一些基本信息)
├── NvDisplayMetaList *display_meta_list;
├── NvDsUserMetaList *frame_user_meta_list;
└── ....#(一帧里面一些基本的信息)

请添加图片描述

typedef struct _NvDsBatchMeta {
  NvDsBaseMeta base_meta;
  /** Holds the maximum number of frames in the batch. */
  guint max_frames_in_batch;
  /** Holds the number of frames now in the batch. */
  guint num_frames_in_batch;
  /** Holds a pointer to a pool of pointers of type @ref NvDsFrameMeta,
   representing a pool of frame metas. */
  NvDsMetaPool *frame_meta_pool;
  /** Holds a pointer to a pool of pointers of type NvDsObjMeta,
   representing a pool of object metas. */
  NvDsMetaPool *obj_meta_pool;
  /** Holds a pointer to a pool of pointers of type @ref NvDsClassifierMeta,
   representing a pool of classifier metas. */
  NvDsMetaPool *classifier_meta_pool;
  /** Holds a pointer to a pool of pointers of type @ref NvDsDisplayMeta,
   representing a pool of display metas. */
  NvDsMetaPool *display_meta_pool;
  /** Holds a pointer to a pool of pointers of type @ref NvDsUserMeta,
   representing a pool of user metas. */
  NvDsMetaPool *user_meta_pool;
  /** Holds a pointer to a pool of pointers of type @ref NvDsLabelInfo,
   representing a pool of label metas. */
  NvDsMetaPool *label_info_meta_pool;
  /** Holds a pointer to a list of pointers of type NvDsFrameMeta
   or NvDsAudioFrameMeta (when the batch represent audio batch),
   representing frame metas used in the current batch.
   */
  NvDsFrameMetaList *frame_meta_list;
  /** Holds a pointer to a list of pointers of type NvDsUserMeta,
   representing user metas in the current batch. */
  NvDsUserMetaList *batch_user_meta_list;
  /** Holds a lock to be set before accessing metadata to avoid
   simultaneous update by multiple components. */
  GRecMutex meta_mutex;
  /** Holds an array of user-specific batch information. */
  gint64 misc_batch_info[MAX_USER_FIELDS];
  /** For internal use. */
  gint64 reserved[MAX_RESERVED_FIELDS];
} NvDsBatchMeta;

4 Metadata Extension Structures

#include<nvdsmeta_schema.h>

typedef struct NvDsEventMsgMeta {
  /** 枚举类型,用来记录事件的类型 */
  NvDsEventType type;
  /** 枚举类型,对象类型,如 vehicle, person, face等等 */
  NvDsObjectType objType;
  /** 结构体,存有bounding box(坐标位置(x、y)、长、宽) */
  NvDsRect bbox;
  /** 结构体,地理信息(经纬度,海拔) */
  NvDsGeoLocation location;
  /** 结构体,坐标(x,y,z) */
  NvDsCoordinate coordinate;
  /** 结构体,存放特征signature字符串和长度 */
  NvDsObjectSignature objSignature;
  /** 对象ID */
  gint objClassId;
  /** 记录传感器ID */
  gint sensorId;
  /** 单元ID */
  gint moduleId;
  /** 位置ID */
  gint placeId;
  /** 组件ID */
  gint componentId;
  /** 视频帧ID */
  gint frameId;
  /** 推理置信度 */
  gdouble confidence;
  /** 跟踪ID. */
  gint trackingId;
  /** 指针,时间戳 */
  gchar *ts;
  /** 指针,推理对象的描述信息 */
  gchar *objectId;
  /** 指针,传感器描述信息 */
  gchar *sensorStr;
  /** 指针,对象的其他描述信息 */
  gchar *otherAttrs;
  /** 指针,视频文件的名字 */
  gchar *videoPath;
  /** 扩展信息 */
  gpointer extMsg;
  /** 扩展信息大小*/
  guint extMsgSize;
} NvDsEventMsgMeta;

5 相关操作函数

  参考DeepStream提供的文件,待更

参考1:NvDsBatchMeta: Basic Metadata Structure

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值