The functionality you want is achievable.
You can refer to my patch, add user metadata in dsexample
, and access it in test1(python).
For your code, if you want to add a custom NVDS_USER_META
type, you need to implement the corresponding python bindings, otherwise it will not be accessible in python. You can refer to the cpp file bindnvdsmeta.cpp
diff --git a/sources/gst-plugins/gst-dsexample/gstdsexample.cpp b/sources/gst-plugins/gst-dsexample/gstdsexample.cpp
index d5399c7..5050401 100644
--- a/sources/gst-plugins/gst-dsexample/gstdsexample.cpp
+++ b/sources/gst-plugins/gst-dsexample/gstdsexample.cpp
@@ -318,6 +318,65 @@ gst_dsexample_get_property (GObject * object, guint prop_id,
}
}
+//#define NVDS_GST_META_BEFORE_DECODER_EXAMPLE (nvds_get_user_meta_type((char *)"NVIDIA.DECODER.GST_META_BEFORE_DECODER"))
+guint parsed_frame_number = 0;
+
+typedef struct _H264parseMeta
+{
+ guint parser_frame_num;
+} H264parseMeta;
+
+/* gst meta copy function set by user */
+static gpointer h264parse_meta_copy_func(gpointer data, gpointer user_data)
+{
+ NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
+ H264parseMeta *src_h264parse_meta = (H264parseMeta *)user_meta->user_meta_data;
+ H264parseMeta *dst_h264parse_meta = (H264parseMeta*)g_malloc0(
+ sizeof(H264parseMeta));
+ memcpy(dst_h264parse_meta, src_h264parse_meta, sizeof(H264parseMeta));
+ return (gpointer)dst_h264parse_meta;
+}
+
+/* gst meta release function set by user */
+static void h264parse_meta_release_func(gpointer data, gpointer user_data)
+{
+ NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
+ H264parseMeta *h264parse_meta = (H264parseMeta *)user_meta->user_meta_data;
+ if(h264parse_meta) {
+ g_free(h264parse_meta);
+ h264parse_meta = NULL;
+ }
+ user_meta->user_meta_data = NULL;
+}
+
+void attach_frame_custom_metadata (NvDsBatchMeta *batch_meta, NvDsFrameMeta *frame_meta)
+{
+ H264parseMeta *h264parse_meta = (H264parseMeta *)g_malloc0(sizeof(H264parseMeta));
+ if(h264parse_meta == NULL)
+ {
+ g_print("no buffer abort !!!! \n");
+ abort();
+ }
+ /* Add dummy metadata */
+ h264parse_meta->parser_frame_num = parsed_frame_number++;
+
+ NvDsUserMeta *user_meta =
+ nvds_acquire_user_meta_from_pool (batch_meta);
+ if (user_meta) {
+ user_meta->user_meta_data = (void *) h264parse_meta;
+ user_meta->base_meta.meta_type = NVDS_USER_META;
+ user_meta->base_meta.copy_func =
+ (NvDsMetaCopyFunc) h264parse_meta_copy_func;
+ user_meta->base_meta.release_func =
+ (NvDsMetaReleaseFunc) h264parse_meta_release_func;
+ nvds_add_user_meta_to_frame (frame_meta, user_meta);
+ }
+
+ g_print("GST H264parse Meta attached for Frame_Num = %d\n",
+ h264parse_meta->parser_frame_num);
+ g_print("Attached Metadata before decoder: Parsed frame_num = %d\n\n", h264parse_meta->parser_frame_num);
+}
+
/**
* Initialize all resources and start the output thread
*/
@@ -759,6 +818,7 @@ gst_dsexample_transform_ip (GstBaseTransform * btrans, GstBuffer * inbuf)
#endif
/* Attach the metadata for the full frame */
attach_metadata_full_frame (dsexample, frame_meta, scale_ratio, output, i);
+ attach_frame_custom_metadata(batch_meta, frame_meta);
i++;
free (output);
}
diff --git a/apps/deepstream-test1/deepstream_test_1.py b/apps/deepstream-test1/deepstream_test_1.py
index 861cefc..187ddd6 100755
--- a/apps/deepstream-test1/deepstream_test_1.py
+++ b/apps/deepstream-test1/deepstream_test_1.py
@@ -47,6 +47,7 @@ def osd_sink_pad_buffer_probe(pad,info,u_data):
# Note that pyds.gst_buffer_get_nvds_batch_meta() expects the
# C address of gst_buffer as input, which is obtained with hash(gst_buffer)
batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
+
l_frame = batch_meta.frame_meta_list
while l_frame is not None:
try:
@@ -82,6 +83,19 @@ def osd_sink_pad_buffer_probe(pad,info,u_data):
except StopIteration:
break
+ l_user=frame_meta.frame_user_meta_list
+ while l_user is not None:
+ try:
+ # Casting l_obj.data to pyds.NvDsUserMeta
+ user_meta=pyds.NvDsUserMeta.cast(l_user.data)
+ if (user_meta and user_meta.base_meta.meta_type == pyds.NvDsMetaType.NVDS_USER_META):
+ print("got user meta.....")
+ except StopIteration:
+ break
+ try:
+ l_user=l_user.next
+ except StopIteration:
+ break
# Acquiring a display meta object. The memory ownership remains in
# the C code so downstream plugins can still access it. Otherwise
# the garbage collector will claim it when this probe function exits.
@@ -167,6 +181,10 @@ def main(args):
if not pgie:
sys.stderr.write(" Unable to create pgie \n")
+ dsexample = Gst.ElementFactory.make("dsexample", "dsexample")
+ if not dsexample:
+ sys.stderr.write(" Unable to create dsexample \n")
+
# Use convertor to convert from NV12 to RGBA as required by nvosd
nvvidconv = Gst.ElementFactory.make("nvvideoconvert", "convertor")
if not nvvidconv:
@@ -186,7 +204,8 @@ def main(args):
sys.stderr.write(" Unable to create nv3dsink \n")
else:
print("Creating EGLSink \n")
- sink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer")
+ # sink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer")
+ sink = Gst.ElementFactory.make("fakesink", "nvvideo-renderer")
if not sink:
sys.stderr.write(" Unable to create egl sink \n")
@@ -206,6 +225,7 @@ def main(args):
pipeline.add(decoder)
pipeline.add(streammux)
pipeline.add(pgie)
+ pipeline.add(dsexample)
pipeline.add(nvvidconv)
pipeline.add(nvosd)
pipeline.add(sink)
@@ -225,7 +245,8 @@ def main(args):
sys.stderr.write(" Unable to get source pad of decoder \n")
srcpad.link(sinkpad)
streammux.link(pgie)
- pgie.link(nvvidconv)
+ pgie.link(dsexample)
+ dsexample.link(nvvidconv)
nvvidconv.link(nvosd)
nvosd.link(sink)