Attaching metadata to message meta in nvosd source
This commit is contained in:
parent
31caf133d9
commit
5dde223640
@ -57,7 +57,7 @@
|
||||
"msgconv": {
|
||||
"msgconv_config_file": "../data/nvmsgconv_configs/msgconv_config.txt",
|
||||
"payload_generation_library": "../data/nvmsgconv_configs/libnvds_msgconv.so",
|
||||
"msgconv_frame_interval": 30
|
||||
"msgconv_frame_interval": 5
|
||||
},
|
||||
"msgbroker": {
|
||||
"msgbroker_config_file": "../data/nvmsgboker_configs/msgbroker_config.txt",
|
||||
|
||||
@ -15,7 +15,8 @@ bool NvMessageBroker::create_message_broker() {
|
||||
msgbroker = gst_element_factory_make("nvmsgbroker", "nvmsg-broker");
|
||||
|
||||
g_object_set(G_OBJECT(msgbroker), "proto-lib",
|
||||
protocol_adaptor_library.c_str(), "conn-str", conn_str.c_str(),
|
||||
protocol_adaptor_library.c_str(),
|
||||
// "conn-str", conn_str.c_str(),
|
||||
"sync", FALSE, NULL);
|
||||
g_object_set(G_OBJECT(msgbroker), "config", msgbroker_config_file.c_str(),
|
||||
NULL);
|
||||
|
||||
@ -1,5 +1,32 @@
|
||||
#include "nv_osd_manager.hpp"
|
||||
|
||||
// #define ENABLE_DUMP_FILE
|
||||
#ifdef ENABLE_DUMP_FILE
|
||||
FILE *fp;
|
||||
char fileObjNameString[1024];
|
||||
#endif
|
||||
|
||||
// #define MEASURE_ENCODE_TIME
|
||||
#ifdef MEASURE_ENCODE_TIME
|
||||
#include <sys/time.h>
|
||||
#define START_PROFILE \
|
||||
{ \
|
||||
struct timeval t1, t2; \
|
||||
double elapsedTime = 0; \
|
||||
gettimeofday(&t1, NULL);
|
||||
|
||||
#define STOP_PROFILE(X) \
|
||||
gettimeofday(&t2, NULL); \
|
||||
elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0; \
|
||||
elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0; \
|
||||
printf("%s ElaspedTime=%f ms\n", X, elapsedTime); \
|
||||
}
|
||||
|
||||
#else
|
||||
#define START_PROFILE
|
||||
#define STOP_PROFILE(X)
|
||||
#endif
|
||||
|
||||
#define SET_GPU_ID(object, gpu_id) \
|
||||
g_object_set(G_OBJECT(object), "gpu-id", gpu_id, NULL);
|
||||
#define GPU_ID 0
|
||||
@ -8,9 +35,15 @@
|
||||
// OSD_PROCESS_MODE set to 1
|
||||
#define OSD_DISPLAY_TEXT 1
|
||||
#define MAX_DISPLAY_LEN 64
|
||||
#define MAX_TIME_STAMP_LEN 32
|
||||
#define PGIE_CLASS_ID_PERSON 0
|
||||
#define FACE_CLASS_ID 1
|
||||
|
||||
gint msg2p_meta =
|
||||
0; //"Type of message schema (0=Full, 1=minimal, 2=protobuf), default=0
|
||||
|
||||
gint NvOsdManager::frame_number = 0;
|
||||
gint NvOsdManager::frame_interval = 0;
|
||||
bool NvOsdManager::write_full_frame_to_disk = false;
|
||||
bool NvOsdManager::write_cropped_objects_to_disk = false;
|
||||
|
||||
@ -20,6 +53,7 @@ NvOsdManager::NvOsdManager() {
|
||||
config.at("write_full_frame_to_disk").get<bool>();
|
||||
write_cropped_objects_to_disk =
|
||||
config.at("write_cropped_objects_to_disk").get<bool>();
|
||||
frame_interval = config["msgconv"]["msgconv_frame_interval"];
|
||||
}
|
||||
|
||||
bool NvOsdManager::create_nv_osd() {
|
||||
@ -38,17 +72,18 @@ bool NvOsdManager::create_nv_osd() {
|
||||
}
|
||||
|
||||
// Attach probe to a pad in the pipeline
|
||||
void NvOsdManager::attach_probe_to_src_nvosd(
|
||||
void NvOsdManager::attach_probe_to_sink_nvosd(
|
||||
NvDsObjEncCtxHandle obj_ctx_handle) {
|
||||
GstPad *src_pad = gst_element_get_static_pad(nvosd, "src");
|
||||
if (!src_pad) {
|
||||
std::cerr << "Unable to get nvosd src pad\n";
|
||||
GstPad *sink_pad = gst_element_get_static_pad(nvosd, "sink");
|
||||
if (!sink_pad) {
|
||||
std::cerr << "Unable to get nvosd sink pad\n";
|
||||
return;
|
||||
}
|
||||
|
||||
gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER,
|
||||
osd_src_pad_buffer_probe, (gpointer)obj_ctx_handle, NULL);
|
||||
gst_object_unref(src_pad);
|
||||
gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
|
||||
osd_sink_pad_buffer_probe, (gpointer)obj_ctx_handle,
|
||||
NULL);
|
||||
gst_object_unref(sink_pad);
|
||||
}
|
||||
|
||||
void NvOsdManager::save_full_frame(NvDsFrameMeta *frame_meta) {
|
||||
@ -85,7 +120,7 @@ void NvOsdManager::save_cropped_objects(NvDsFrameMeta *frame_meta,
|
||||
char fileObjNameString[FILE_NAME_SIZE];
|
||||
|
||||
/* For Demonstration Purposes we are writing metadata to jpeg images of
|
||||
* vehicles or persons for the first 100 frames only.
|
||||
* faces or persons for the first 100 frames only.
|
||||
* The files generated have a 'OSD' prefix. */
|
||||
NvDsUserMetaList *usrMetaList = obj_meta->obj_user_meta_list;
|
||||
FILE *file;
|
||||
@ -114,9 +149,9 @@ void NvOsdManager::save_cropped_objects(NvDsFrameMeta *frame_meta,
|
||||
* of the OSD element. All the infer elements in the pipeline shall attach
|
||||
* their metadata to the GstBuffer, here we will iterate & process the metadata
|
||||
* forex: class ids to strings, counting of class_id objects etc. */
|
||||
GstPadProbeReturn NvOsdManager::osd_src_pad_buffer_probe(GstPad *pad,
|
||||
GstPadProbeInfo *info,
|
||||
gpointer u_data) {
|
||||
GstPadProbeReturn NvOsdManager::osd_sink_pad_buffer_probe(GstPad *pad,
|
||||
GstPadProbeInfo *info,
|
||||
gpointer u_data) {
|
||||
(void)pad;
|
||||
(void)u_data;
|
||||
GstBuffer *buf = (GstBuffer *)info->data;
|
||||
@ -179,25 +214,500 @@ GstPadProbeReturn NvOsdManager::osd_src_pad_buffer_probe(GstPad *pad,
|
||||
// "Person Count = %d\n",
|
||||
// frame_number, person_count);
|
||||
|
||||
frame_number++;
|
||||
// frame_number++;
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
// Attach probe to a pad in the pipeline
|
||||
void NvOsdManager::attach_probe_to_sink_nvosd() {
|
||||
GstPad *sink_pad = gst_element_get_static_pad(nvosd, "sink");
|
||||
if (!sink_pad) {
|
||||
void NvOsdManager::attach_probe_to_src_nvosd(
|
||||
NvDsObjEncCtxHandle obj_ctx_handle) {
|
||||
GstPad *src_pad = gst_element_get_static_pad(nvosd, "src");
|
||||
if (!src_pad) {
|
||||
std::cerr << "Unable to get nvosd src pad\n";
|
||||
return;
|
||||
}
|
||||
|
||||
gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
|
||||
osd_sink_pad_buffer_probe, NULL, NULL);
|
||||
gst_object_unref(sink_pad);
|
||||
if (msg2p_meta == 0) { // generate payload using eventMsgMeta
|
||||
gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER,
|
||||
osd_src_pad_buffer_metadata_probe, NULL, NULL);
|
||||
} else { // generate payload using NVDS_CUSTOM_MSG_BLOB
|
||||
gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER,
|
||||
osd_src_pad_buffer_image_probe,
|
||||
(gpointer)obj_ctx_handle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
GstPadProbeReturn NvOsdManager::osd_sink_pad_buffer_probe(GstPad *,
|
||||
GstPadProbeInfo *,
|
||||
gpointer) {
|
||||
GstPadProbeReturn NvOsdManager::osd_src_pad_buffer_probe(GstPad *,
|
||||
GstPadProbeInfo *,
|
||||
gpointer) {
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void NvOsdManager::meta_free_func(gpointer data, gpointer user_data) {
|
||||
(void)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_FACE) {
|
||||
NvDsFaceObject *obj = (NvDsFaceObject *)srcMeta->extMsg;
|
||||
if (obj->cap) g_free(obj->cap);
|
||||
if (obj->eyecolor) g_free(obj->eyecolor);
|
||||
if (obj->facialhair) g_free(obj->facialhair);
|
||||
if (obj->gender) g_free(obj->gender);
|
||||
if (obj->glasses) g_free(obj->glasses);
|
||||
if (obj->hair) g_free(obj->hair);
|
||||
if (obj->name) g_free(obj->name);
|
||||
} 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);
|
||||
}
|
||||
g_free(srcMeta->extMsg);
|
||||
srcMeta->extMsgSize = 0;
|
||||
}
|
||||
g_free(user_meta->user_meta_data);
|
||||
user_meta->user_meta_data = NULL;
|
||||
}
|
||||
|
||||
gpointer NvOsdManager::meta_copy_func(gpointer data, gpointer user_data) {
|
||||
(void)user_data;
|
||||
NvDsUserMeta *user_meta = (NvDsUserMeta *)data;
|
||||
NvDsEventMsgMeta *srcMeta = (NvDsEventMsgMeta *)user_meta->user_meta_data;
|
||||
NvDsEventMsgMeta *dstMeta = NULL;
|
||||
|
||||
dstMeta = (NvDsEventMsgMeta *)g_memdup2(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 = (gdouble *)g_memdup2(
|
||||
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_FACE) {
|
||||
NvDsFaceObject *srcObj = (NvDsFaceObject *)srcMeta->extMsg;
|
||||
NvDsFaceObject *obj =
|
||||
(NvDsFaceObject *)g_malloc0(sizeof(NvDsFaceObject));
|
||||
if (srcObj->age) obj->age = srcObj->age;
|
||||
if (srcObj->cap) obj->cap = g_strdup(srcObj->cap);
|
||||
if (srcObj->eyecolor) obj->eyecolor = g_strdup(srcObj->eyecolor);
|
||||
if (srcObj->facialhair)
|
||||
obj->facialhair = g_strdup(srcObj->facialhair);
|
||||
if (srcObj->gender) obj->gender = g_strdup(srcObj->gender);
|
||||
if (srcObj->glasses) obj->glasses = g_strdup(srcObj->glasses);
|
||||
if (srcObj->hair) obj->hair = g_strdup(srcObj->hair);
|
||||
// if (srcObj->mask)
|
||||
// obj->mask = g_strdup (srcObj->mask);
|
||||
if (srcObj->name) obj->name = g_strdup(srcObj->name);
|
||||
|
||||
dstMeta->extMsg = obj;
|
||||
dstMeta->extMsgSize = sizeof(NvDsFaceObject);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
return dstMeta;
|
||||
}
|
||||
|
||||
void NvOsdManager::generate_ts_rfc3339(char *buf, int buf_size) {
|
||||
time_t tloc;
|
||||
struct tm tm_log;
|
||||
struct timespec ts;
|
||||
char strmsec[6]; //.nnnZ\0
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
memcpy(&tloc, (void *)(&ts.tv_sec), sizeof(time_t));
|
||||
gmtime_r(&tloc, &tm_log);
|
||||
strftime(buf, buf_size, "%Y-%m-%dT%H:%M:%S", &tm_log);
|
||||
int ms = ts.tv_nsec / 1000000;
|
||||
g_snprintf(strmsec, sizeof(strmsec), ".%.3dZ", ms);
|
||||
strncat(buf, strmsec, buf_size);
|
||||
}
|
||||
|
||||
void NvOsdManager::generate_face_meta(gpointer data) {
|
||||
NvDsFaceObjectExt *obj = (NvDsFaceObjectExt *)data;
|
||||
|
||||
obj->age = 25;
|
||||
obj->cap = g_strdup("cap");
|
||||
obj->eyecolor = g_strdup("eyecolor");
|
||||
obj->facialhair = g_strdup("facialhair");
|
||||
obj->gender = g_strdup("gender");
|
||||
obj->glasses = g_strdup("glasses");
|
||||
obj->hair = g_strdup("hair");
|
||||
// obj->mask = g_strdup ("mask");
|
||||
obj->name = g_strdup("name");
|
||||
}
|
||||
|
||||
void NvOsdManager::generate_person_meta(gpointer data) {
|
||||
NvDsPersonObject *obj = (NvDsPersonObject *)data;
|
||||
obj->age = 45;
|
||||
obj->cap = g_strdup("none");
|
||||
obj->hair = g_strdup("black");
|
||||
obj->gender = g_strdup("male");
|
||||
obj->apparel = g_strdup("formal");
|
||||
// obj->mask = g_strdup ("formal");
|
||||
}
|
||||
|
||||
void NvOsdManager::generate_event_msg_meta(gpointer data, gint class_id,
|
||||
NvDsObjectMeta *obj_params) {
|
||||
NvDsEventMsgMeta *meta = (NvDsEventMsgMeta *)data;
|
||||
meta->sensorId = 0;
|
||||
meta->placeId = 0;
|
||||
meta->moduleId = 0;
|
||||
meta->sensorStr = g_strdup("sensor-0");
|
||||
|
||||
meta->ts = (gchar *)g_malloc0(MAX_TIME_STAMP_LEN + 1);
|
||||
meta->objectId = (gchar *)g_malloc0(MAX_LABEL_SIZE);
|
||||
|
||||
strncpy(meta->objectId, obj_params->obj_label, MAX_LABEL_SIZE);
|
||||
|
||||
generate_ts_rfc3339(meta->ts, MAX_TIME_STAMP_LEN);
|
||||
|
||||
/*
|
||||
* This demonstrates how to attach custom objects.
|
||||
* Any custom object as per requirement can be generated and attached
|
||||
* like NvDsFaceObject / NvDsPersonObject. Then that object should
|
||||
* be handled in payload generator library (nvmsgconv.cpp) accordingly.
|
||||
*/
|
||||
if (class_id == FACE_CLASS_ID) {
|
||||
meta->type = NVDS_EVENT_MOVING;
|
||||
meta->objType = NVDS_OBJECT_TYPE_FACE;
|
||||
meta->objClassId = FACE_CLASS_ID;
|
||||
|
||||
NvDsFaceObject *obj =
|
||||
(NvDsFaceObject *)g_malloc0(sizeof(NvDsFaceObject));
|
||||
generate_face_meta(obj);
|
||||
|
||||
meta->extMsg = obj;
|
||||
meta->extMsgSize = sizeof(NvDsFaceObject);
|
||||
} else if (class_id == PGIE_CLASS_ID_PERSON) {
|
||||
meta->type = NVDS_EVENT_ENTRY;
|
||||
meta->objType = NVDS_OBJECT_TYPE_PERSON;
|
||||
meta->objClassId = PGIE_CLASS_ID_PERSON;
|
||||
|
||||
NvDsPersonObject *obj =
|
||||
(NvDsPersonObject *)g_malloc0(sizeof(NvDsPersonObject));
|
||||
generate_person_meta(obj);
|
||||
|
||||
meta->extMsg = obj;
|
||||
meta->extMsgSize = sizeof(NvDsPersonObject);
|
||||
}
|
||||
}
|
||||
|
||||
/* osd_sink_pad_buffer_probe will extract metadata received on OSD sink pad
|
||||
* and update params for drawing rectangle, object information etc. */
|
||||
GstPadProbeReturn NvOsdManager::osd_src_pad_buffer_metadata_probe(
|
||||
GstPad *pad, GstPadProbeInfo *info, gpointer u_data) {
|
||||
(void)pad;
|
||||
(void)u_data;
|
||||
GstBuffer *buf = (GstBuffer *)info->data;
|
||||
NvDsFrameMeta *frame_meta = NULL;
|
||||
NvOSD_TextParams *txt_params = NULL;
|
||||
(void)txt_params;
|
||||
guint face_count = 0;
|
||||
guint person_count = 0;
|
||||
gboolean is_first_object = TRUE;
|
||||
NvDsMetaList *l_frame, *l_obj;
|
||||
|
||||
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf);
|
||||
if (!batch_meta) {
|
||||
// No batch meta attached.
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
for (l_frame = batch_meta->frame_meta_list; l_frame;
|
||||
l_frame = l_frame->next) {
|
||||
frame_meta = (NvDsFrameMeta *)l_frame->data;
|
||||
|
||||
if (frame_meta == NULL) {
|
||||
// Ignore Null frame meta.
|
||||
continue;
|
||||
}
|
||||
|
||||
is_first_object = TRUE;
|
||||
|
||||
for (l_obj = frame_meta->obj_meta_list; l_obj; l_obj = l_obj->next) {
|
||||
NvDsObjectMeta *obj_meta = (NvDsObjectMeta *)l_obj->data;
|
||||
|
||||
if (obj_meta == NULL) {
|
||||
// Ignore Null object.
|
||||
continue;
|
||||
}
|
||||
|
||||
// txt_params = &(obj_meta->text_params);
|
||||
// if (txt_params->display_text)
|
||||
// g_free (txt_params->display_text);
|
||||
|
||||
// txt_params->display_text = (char *)g_malloc0 (MAX_DISPLAY_LEN);
|
||||
|
||||
// g_snprintf (txt_params->display_text, MAX_DISPLAY_LEN, "%s ",
|
||||
// pgie_classes_str[obj_meta->class_id]);
|
||||
|
||||
// if (obj_meta->class_id == FACE_CLASS_ID)
|
||||
// face_count++;
|
||||
// if (obj_meta->class_id == PGIE_CLASS_ID_PERSON)
|
||||
// person_count++;
|
||||
|
||||
// /* Now set the offsets where the string should appear */
|
||||
// txt_params->x_offset = obj_meta->rect_params.left;
|
||||
// txt_params->y_offset = obj_meta->rect_params.top - 25;
|
||||
|
||||
// /* Font , font-color and font-size */
|
||||
// txt_params->font_params.font_name = (char *) "Serif";
|
||||
// txt_params->font_params.font_size = 10;
|
||||
// txt_params->font_params.font_color.red = 1.0;
|
||||
// txt_params->font_params.font_color.green = 1.0;
|
||||
// txt_params->font_params.font_color.blue = 1.0;
|
||||
// txt_params->font_params.font_color.alpha = 1.0;
|
||||
|
||||
// /* Text background color */
|
||||
// txt_params->set_bg_clr = 1;
|
||||
// txt_params->text_bg_clr.red = 0.0;
|
||||
// txt_params->text_bg_clr.green = 0.0;
|
||||
// txt_params->text_bg_clr.blue = 0.0;
|
||||
// txt_params->text_bg_clr.alpha = 1.0;
|
||||
|
||||
/*
|
||||
* Ideally NVDS_EVENT_MSG_META should be attached to buffer by the
|
||||
* component implementing detection / recognition logic.
|
||||
* Here it demonstrates how to use / attach that meta data.
|
||||
*/
|
||||
if (is_first_object && !(frame_number % frame_interval)) {
|
||||
/* Frequency of messages to be send will be based on use case.
|
||||
* Here message is being sent for first object every
|
||||
* frame_interval(default=30).
|
||||
*/
|
||||
|
||||
NvDsEventMsgMeta *msg_meta =
|
||||
(NvDsEventMsgMeta *)g_malloc0(sizeof(NvDsEventMsgMeta));
|
||||
msg_meta->bbox.top = obj_meta->rect_params.top;
|
||||
msg_meta->bbox.left = obj_meta->rect_params.left;
|
||||
msg_meta->bbox.width = obj_meta->rect_params.width;
|
||||
msg_meta->bbox.height = obj_meta->rect_params.height;
|
||||
msg_meta->frameId = frame_number;
|
||||
msg_meta->trackingId = obj_meta->object_id;
|
||||
msg_meta->confidence = obj_meta->confidence;
|
||||
generate_event_msg_meta(msg_meta, obj_meta->class_id, obj_meta);
|
||||
|
||||
NvDsUserMeta *user_event_meta =
|
||||
nvds_acquire_user_meta_from_pool(batch_meta);
|
||||
if (user_event_meta) {
|
||||
user_event_meta->user_meta_data = (void *)msg_meta;
|
||||
user_event_meta->base_meta.meta_type = NVDS_EVENT_MSG_META;
|
||||
user_event_meta->base_meta.copy_func =
|
||||
(NvDsMetaCopyFunc)meta_copy_func;
|
||||
user_event_meta->base_meta.release_func =
|
||||
(NvDsMetaReleaseFunc)meta_free_func;
|
||||
nvds_add_user_meta_to_frame(frame_meta, user_event_meta);
|
||||
} else {
|
||||
g_print("Error in attaching event meta to buffer\n");
|
||||
}
|
||||
is_first_object = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_print(
|
||||
"Frame Number = %d "
|
||||
"Face Count = %d Person Count = %d\n",
|
||||
frame_number, face_count, person_count);
|
||||
frame_number++;
|
||||
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
gpointer NvOsdManager::meta_copy_func_custom(gpointer data,
|
||||
gpointer user_data) {
|
||||
(void)user_data;
|
||||
NvDsUserMeta *user_meta = (NvDsUserMeta *)data;
|
||||
NvDsCustomMsgInfo *srcMeta = (NvDsCustomMsgInfo *)user_meta->user_meta_data;
|
||||
NvDsCustomMsgInfo *dstMeta = NULL;
|
||||
|
||||
dstMeta =
|
||||
(NvDsCustomMsgInfo *)g_memdup2(srcMeta, sizeof(NvDsCustomMsgInfo));
|
||||
|
||||
if (srcMeta->message)
|
||||
dstMeta->message = (gpointer)g_strdup((const char *)srcMeta->message);
|
||||
dstMeta->size = srcMeta->size;
|
||||
|
||||
return dstMeta;
|
||||
}
|
||||
|
||||
void NvOsdManager::meta_free_func_custom(gpointer data, gpointer user_data) {
|
||||
(void)user_data;
|
||||
NvDsUserMeta *user_meta = (NvDsUserMeta *)data;
|
||||
NvDsCustomMsgInfo *srcMeta = (NvDsCustomMsgInfo *)user_meta->user_meta_data;
|
||||
|
||||
if (srcMeta->message) g_free(srcMeta->message);
|
||||
srcMeta->size = 0;
|
||||
|
||||
g_free(user_meta->user_meta_data);
|
||||
}
|
||||
|
||||
GstPadProbeReturn NvOsdManager::osd_src_pad_buffer_image_probe(
|
||||
GstPad *pad, GstPadProbeInfo *info, gpointer u_data) {
|
||||
(void)pad;
|
||||
(void)u_data;
|
||||
GstBuffer *buf = (GstBuffer *)info->data;
|
||||
NvDsFrameMeta *frame_meta = NULL;
|
||||
gboolean is_first_object = TRUE;
|
||||
NvDsMetaList *l_frame, *l_obj;
|
||||
gchar *encoded_data;
|
||||
gchar *message_data;
|
||||
gchar *width, *height;
|
||||
gchar *ts = (gchar *)g_malloc0(MAX_TIME_STAMP_LEN + 1);
|
||||
|
||||
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf);
|
||||
if (!batch_meta) {
|
||||
// No batch meta attached.
|
||||
g_free(ts);
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
for (l_frame = batch_meta->frame_meta_list; l_frame;
|
||||
l_frame = l_frame->next) {
|
||||
frame_meta = (NvDsFrameMeta *)l_frame->data;
|
||||
|
||||
if (frame_meta == NULL) {
|
||||
// Ignore Null frame meta.
|
||||
continue;
|
||||
}
|
||||
|
||||
is_first_object = TRUE;
|
||||
|
||||
for (l_obj = frame_meta->obj_meta_list; l_obj; l_obj = l_obj->next) {
|
||||
NvDsObjectMeta *obj_meta = (NvDsObjectMeta *)l_obj->data;
|
||||
|
||||
if (obj_meta == NULL) {
|
||||
// Ignore Null object.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_first_object && !(frame_number % frame_interval)) {
|
||||
/* Frequency of images to be send will be based on use case.
|
||||
* Here images is being sent for first object every
|
||||
* frame_interval(default=30).
|
||||
*/
|
||||
NvDsUserMetaList *usrMetaList = obj_meta->obj_user_meta_list;
|
||||
while (usrMetaList != NULL) {
|
||||
NvDsUserMeta *user_event_meta_custom =
|
||||
nvds_acquire_user_meta_from_pool(batch_meta);
|
||||
NvDsCustomMsgInfo *msg_custom_meta =
|
||||
(NvDsCustomMsgInfo *)g_malloc0(
|
||||
sizeof(NvDsCustomMsgInfo));
|
||||
|
||||
NvDsUserMeta *usrMetaData =
|
||||
(NvDsUserMeta *)usrMetaList->data;
|
||||
if (usrMetaData->base_meta.meta_type ==
|
||||
NVDS_CROP_IMAGE_META) {
|
||||
NvDsObjEncOutParams *enc_jpeg_image =
|
||||
(NvDsObjEncOutParams *)usrMetaData->user_meta_data;
|
||||
START_PROFILE;
|
||||
encoded_data = g_base64_encode(
|
||||
enc_jpeg_image->outBuffer, enc_jpeg_image->outLen);
|
||||
generate_ts_rfc3339(ts, MAX_TIME_STAMP_LEN);
|
||||
width = g_strdup_printf(
|
||||
"%f",
|
||||
obj_meta->detector_bbox_info.org_bbox_coords.width);
|
||||
height =
|
||||
g_strdup_printf("%f", obj_meta->detector_bbox_info
|
||||
.org_bbox_coords.height);
|
||||
/* Image message fields are separated by ";".
|
||||
* Specific Format:
|
||||
* "image;image_format;image_widthximage_height;time;encoded
|
||||
* data;" For Example:
|
||||
* "image;jpg;640x480;2023-07-31T10:20:13;xxxxxxxxxxx"
|
||||
*/
|
||||
message_data =
|
||||
g_strconcat("image;jpg;", width, "x", height, ";",
|
||||
ts, ";", encoded_data, ";", NULL);
|
||||
STOP_PROFILE("Base64 Encode Time ");
|
||||
msg_custom_meta->size = strlen(message_data);
|
||||
msg_custom_meta->message = g_strdup(message_data);
|
||||
if (user_event_meta_custom) {
|
||||
user_event_meta_custom->user_meta_data =
|
||||
(void *)msg_custom_meta;
|
||||
user_event_meta_custom->base_meta.meta_type =
|
||||
NVDS_CUSTOM_MSG_BLOB;
|
||||
user_event_meta_custom->base_meta.copy_func =
|
||||
(NvDsMetaCopyFunc)meta_copy_func_custom;
|
||||
user_event_meta_custom->base_meta.release_func =
|
||||
(NvDsMetaReleaseFunc)meta_free_func_custom;
|
||||
nvds_add_user_meta_to_frame(frame_meta,
|
||||
user_event_meta_custom);
|
||||
} else {
|
||||
g_print(
|
||||
"Error in attaching event meta custom to "
|
||||
"buffer\n");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DUMP_FILE
|
||||
gsize size = 0;
|
||||
snprintf(fileObjNameString, 1024, "%s_%d_%d_%s.jpg", ts,
|
||||
frame_number, frame_meta->batch_id,
|
||||
obj_meta->obj_label);
|
||||
guchar *decoded_data =
|
||||
g_base64_decode(encoded_data, &size);
|
||||
fp = fopen(fileObjNameString, "wb");
|
||||
if (fp) {
|
||||
fwrite(decoded_data, size, 1, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
g_printerr("Could not open file!\n");
|
||||
}
|
||||
g_free(decoded_data);
|
||||
#endif
|
||||
g_free(encoded_data);
|
||||
g_free(message_data);
|
||||
g_free(width);
|
||||
g_free(height);
|
||||
usrMetaList = NULL;
|
||||
} else {
|
||||
usrMetaList = usrMetaList->next;
|
||||
}
|
||||
}
|
||||
is_first_object = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free(ts);
|
||||
frame_number++;
|
||||
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
@ -6,24 +6,39 @@
|
||||
#include "gstnvdsmeta.h"
|
||||
#include "config_manager.hpp"
|
||||
#include "custom_gstnvdsinfer.hpp"
|
||||
#include "nvdsmeta_schema.h"
|
||||
|
||||
class NvOsdManager {
|
||||
private:
|
||||
public:
|
||||
GstElement *nvosd = NULL;
|
||||
static gint frame_interval;
|
||||
static bool write_full_frame_to_disk, write_cropped_objects_to_disk;
|
||||
NvOsdManager();
|
||||
bool create_nv_osd();
|
||||
~NvOsdManager();
|
||||
static gint frame_number;
|
||||
void attach_probe_to_sink_nvosd(NvDsObjEncCtxHandle);
|
||||
static GstPadProbeReturn osd_sink_pad_buffer_probe(GstPad *,
|
||||
GstPadProbeInfo *,
|
||||
gpointer);
|
||||
void attach_probe_to_src_nvosd(NvDsObjEncCtxHandle);
|
||||
static GstPadProbeReturn osd_src_pad_buffer_probe(GstPad *,
|
||||
GstPadProbeInfo *,
|
||||
gpointer);
|
||||
void attach_probe_to_sink_nvosd();
|
||||
static GstPadProbeReturn osd_sink_pad_buffer_probe(GstPad *,
|
||||
GstPadProbeInfo *,
|
||||
gpointer);
|
||||
static void save_full_frame(NvDsFrameMeta *);
|
||||
static void save_cropped_objects(NvDsFrameMeta *, NvDsObjectMeta *, guint);
|
||||
static GstPadProbeReturn osd_src_pad_buffer_metadata_probe(
|
||||
GstPad *, GstPadProbeInfo *, gpointer);
|
||||
static GstPadProbeReturn osd_src_pad_buffer_image_probe(GstPad *,
|
||||
GstPadProbeInfo *,
|
||||
gpointer);
|
||||
static void generate_event_msg_meta(gpointer, gint, NvDsObjectMeta *);
|
||||
static gpointer meta_copy_func(gpointer, gpointer);
|
||||
static void meta_free_func(gpointer, gpointer);
|
||||
static void generate_ts_rfc3339(char *, int);
|
||||
static gpointer meta_copy_func_custom(gpointer, gpointer);
|
||||
static void meta_free_func_custom(gpointer, gpointer);
|
||||
static void generate_face_meta(gpointer);
|
||||
static void generate_person_meta(gpointer);
|
||||
};
|
||||
@ -623,9 +623,9 @@ bool PipelineManager::create_pipeline_elements(int num_sources,
|
||||
|
||||
face_nv_infer_server_manager->create_face_nv_infer_server(num_sources);
|
||||
|
||||
nv_osd_manager->attach_probe_to_src_nvosd(
|
||||
nv_osd_manager->attach_probe_to_sink_nvosd(
|
||||
obj_ctx_handle); // nvinfer Or use "nvtracker" if after
|
||||
|
||||
nv_osd_manager->attach_probe_to_src_nvosd(obj_ctx_handle);
|
||||
nv_message_converter_manager->attach_probe_to_sink_msgconv();
|
||||
|
||||
message_handling->create_message_handler(pipeline, g_run_forever, loop);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user