Hi everyone, I’m trying to combine deepstream-nvdsanalytics-app and deepstream-test4-app, to send custom nvdsanalytics result to kafka, for example, I want to send the number of rois to kafka, to notify us how many people in the area.
When I compile the app, error raised:
g++ -c -o deepstream_line_crossing_msgconv.o -DPLATFORM_TEGRA -I../../../includes `pkg-config --cflags gstreamer-1.0` deepstream_line_crossing_msgconv.cpp
deepstream_line_crossing_msgconv.cpp: In function ‘void* meta_copy_func(gpointer, gpointer)’:
deepstream_line_crossing_msgconv.cpp:130:22: error: invalid conversion from ‘gpointer {aka void*}’ to ‘NvDsEventMsgMeta*’ [-fpermissive]
dstMeta = g_memdup (srcMeta, sizeof(NvDsEventMsgMeta));
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
deepstream_line_crossing_msgconv.cpp:139:48: error: invalid conversion from ‘gpointer {aka void*}’ to ‘gdouble* {aka double*}’ [-fpermissive]
dstMeta->objSignature.signature = g_memdup (srcMeta->objSignature.signature,
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
srcMeta->objSignature.size);
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Makefile:56: recipe for target 'deepstream_line_crossing_msgconv.o' failed
make: *** [deepstream_line_crossing_msgconv.o] Error 1
What I’ve done:
- Modify the official
deepstream_nvdsanalytics_app.cpp
, adding the msgconv and msgbroker plugin fromdeepstream_test4_app.c
- Create a new
NvDsPersonInROIObject
innvdsmeta_schema.h
, something like:
/**
* Holds parameters that a person in roi area.
*/
typedef struct NvDsPersonInROIObject {
gint *num_roi; /**< Holds a pointer to the number of person in roi area. */
} NvDsPersonInROIObject;
- Modify
nvds_msg2p_generate
innvmsgconv.cpp
:
NvDsPayload*
nvds_msg2p_generate (NvDsMsg2pCtx *ctx, NvDsEvent *events, guint size)
{
gchar *message = NULL;
gint len = 0;
NvDsPayload *payload = (NvDsPayload *) g_malloc0 (sizeof (NvDsPayload));
if (ctx->payloadType == NVDS_PAYLOAD_DEEPSTREAM) {
message = generate_schema_message (ctx, events->metadata);
if (message) {
len = strlen (message);
// Remove '\0' character at the end of string and just copy the content.
payload->payload = g_memdup (message, len);
payload->payloadSize = len;
g_free (message);
}
} else if (ctx->payloadType == NVDS_PAYLOAD_DEEPSTREAM_MINIMAL) {
message = generate_deepstream_message_minimal (ctx, events, size);
if (message) {
len = strlen (message);
// Remove '\0' character at the end of string and just copy the content.
payload->payload = g_memdup (message, len);
payload->payloadSize = len;
g_free (message);
}
} else if (ctx->payloadType == NVDS_PAYLOAD_CUSTOM) {
// payload->payload = (gpointer) g_strdup ("CUSTOM Schema");
// payload->payloadSize = strlen ((char *)payload->payload) + 1;
message = generate_deepstream_message_minimal (ctx, events, size); /*My custom parsing method here.*/
if (message) {
len = strlen (message);
// Remove '\0' character at the end of string and just copy the content.
payload->payload = g_memdup (message, len);
payload->payloadSize = len;
g_free (message);
}
} else
payload->payload = NULL;
return payload;
}
- Copy the message meta copy func and meta release func from
deepstream_test4_app.c
todeepstream_nvdsanalytics_app.cpp
:
static gpointer meta_copy_func (gpointer data, gpointer user_data)
{
NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
NvDsEventMsgMeta *srcMeta = (NvDsEventMsgMeta *) user_meta->user_meta_data;
NvDsEventMsgMeta *dstMeta = NULL;
dstMeta = g_memdup (srcMeta, sizeof(NvDsEventMsgMeta));
if (srcMeta->ts)
dstMeta->ts = g_strdup (srcMeta->ts);
if (srcMeta->sensorStr)
dstMeta->sensorStr = g_strdup (srcMeta->sensorStr);
if (srcMeta->objSignature.size > 0) {
dstMeta->objSignature.signature = g_memdup (srcMeta->objSignature.signature,
srcMeta->objSignature.size);
dstMeta->objSignature.size = srcMeta->objSignature.size;
}
if(srcMeta->objectId) {
dstMeta->objectId = g_strdup (srcMeta->objectId);
}
if (srcMeta->extMsgSize > 0) {
if (srcMeta->objType == NVDS_OBJECT_TYPE_VEHICLE) {
NvDsVehicleObject *srcObj = (NvDsVehicleObject *) srcMeta->extMsg;
NvDsVehicleObject *obj = (NvDsVehicleObject *) g_malloc0 (sizeof (NvDsVehicleObject));
if (srcObj->type)
obj->type = g_strdup (srcObj->type);
if (srcObj->make)
obj->make = g_strdup (srcObj->make);
if (srcObj->model)
obj->model = g_strdup (srcObj->model);
if (srcObj->color)
obj->color = g_strdup (srcObj->color);
if (srcObj->license)
obj->license = g_strdup (srcObj->license);
if (srcObj->region)
obj->region = g_strdup (srcObj->region);
dstMeta->extMsg = obj;
dstMeta->extMsgSize = sizeof (NvDsVehicleObject);
} else if (srcMeta->objType == NVDS_OBJECT_TYPE_PERSON) {
NvDsPersonObject *srcObj = (NvDsPersonObject *) srcMeta->extMsg;
NvDsPersonObject *obj = (NvDsPersonObject *) g_malloc0 (sizeof (NvDsPersonObject));
obj->age = srcObj->age;
if (srcObj->gender)
obj->gender = g_strdup (srcObj->gender);
if (srcObj->cap)
obj->cap = g_strdup (srcObj->cap);
if (srcObj->hair)
obj->hair = g_strdup (srcObj->hair);
if (srcObj->apparel)
obj->apparel = g_strdup (srcObj->apparel);
dstMeta->extMsg = obj;
dstMeta->extMsgSize = sizeof (NvDsPersonObject);
} else if (srcMeta->objType == NVDS_OBJECT_TYPE_CUSTOM) {
NvDsPersonInROIObject *srcObj = (NvDsPersonInROIObject *) srcMeta->extMsg;
NvDsPersonInROIObject *obj = (NvDsPersonInROIObject *) g_malloc0 (sizeof (NvDsPersonInROIObject));
if (srcObj->num_roi)
obj->num_roi = srcObj->num_roi;
dstMeta->extMsg = obj;
dstMeta->extMsgSize = sizeof (NvDsPersonInROIObject);
}
}
return dstMeta;
}
static void meta_free_func (gpointer data, gpointer user_data)
{
NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
NvDsEventMsgMeta *srcMeta = (NvDsEventMsgMeta *) user_meta->user_meta_data;
g_free (srcMeta->ts);
g_free (srcMeta->sensorStr);
if (srcMeta->objSignature.size > 0) {
g_free (srcMeta->objSignature.signature);
srcMeta->objSignature.size = 0;
}
if(srcMeta->objectId) {
g_free (srcMeta->objectId);
}
if (srcMeta->extMsgSize > 0) {
if (srcMeta->objType == NVDS_OBJECT_TYPE_VEHICLE) {
NvDsVehicleObject *obj = (NvDsVehicleObject *) srcMeta->extMsg;
if (obj->type)
g_free (obj->type);
if (obj->color)
g_free (obj->color);
if (obj->make)
g_free (obj->make);
if (obj->model)
g_free (obj->model);
if (obj->license)
g_free (obj->license);
if (obj->region)
g_free (obj->region);
} else if (srcMeta->objType == NVDS_OBJECT_TYPE_PERSON) {
NvDsPersonObject *obj = (NvDsPersonObject *) srcMeta->extMsg;
if (obj->gender)
g_free (obj->gender);
if (obj->cap)
g_free (obj->cap);
if (obj->hair)
g_free (obj->hair);
if (obj->apparel)
g_free (obj->apparel);
} else if (srcMeta->objType == NVDS_OBJECT_TYPE_CUSTOM) {
NvDsPersonInROIObject *obj = (NvDsPersonInROIObject *) srcMeta->extMsg;
if (obj->num_roi)
g_free (obj->num_roi);
}
g_free (srcMeta->extMsg);
srcMeta->extMsgSize = 0;
}
g_free (user_meta->user_meta_data);
user_meta->user_meta_data = NULL;
}
most of the code haven’t changed, just add a case to handle NVDS_OBJECT_TYPE_CUSTOM
.
- Makefile:
APP:= deepstream-line-crossing-msgconv
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=5.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
APP_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/bin/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
SRCS:= $(wildcard *.cpp)
INCS:= $(wildcard *.h)
PKGS:= gstreamer-1.0
OBJS:= $(SRCS:.cpp=.o)
CFLAGS+= -I../../../includes
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS:= `pkg-config --libs $(PKGS)`
LIBS+= -L$(LIB_INSTALL_DIR) -lnvdsgst_meta -lnvds_meta -lnvdsgst_helper -lm -lrt \
-Wl,-rpath,$(LIB_INSTALL_DIR)
all: $(APP)
%.o: %.cpp $(INCS) Makefile
$(CXX) -c -o $@ $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CXX) -o $(APP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP)
Is it the C++ code cannot be compiled like C code? Because the deepsteram-texst4-app and deepsteram-texst5-app can be compiled correctly, and the message meta copy/release function are almost the same.
Please provide complete information as applicable to your setup.
• Hardware Platform (Jetson / GPU) Jetson AGX Xavier
• DeepStream Version 5.0
• JetPack Version (valid for Jetson only) 4.4 DP
• TensorRT Version 7.0
• NVIDIA GPU Driver Version (valid for GPU only)