How to add confidence in NvMsgConv (modify nvmsgconv payload)

DeepStream Version - 7.1
• JetPack Version (valid for Jetson only)
• TensorRT Version - 10.3.0.26
• NVIDIA GPU Driver Version (valid for GPU only) - 565.57.01

• Issue Type( questions, new requirements, bugs) - question about best practices
• How to reproduce the issue ? I wrote my thoughts

I want to add a confidence score for message in NvMsgConv, for this I modified generate_dsmeta_message_minimal (I moved line 459 outside the loop: ss << “|” << obj_meta->confidence; ) in /opt/nvidia/deepstream/deepstream-7.1/sources/libs/nvmsgconv/deepstream_schema/dsmeta_payload.cpp and then in nvmsgconv dir do: make clean, make and delete old lib from deepstream-7-1/lib

in Python Api I set msgconv config:
configure msgconv/msgbroker from config (per-stream or global fallback)

        msg_cfg = config.get('msg', {})
        msgconv_cfg = msg_cfg.get('msgconv_config')
        msgconv.set_property("config", msgconv_cfg)
        msgconv.set_property("msg2p-lib", "/opt/nvidia/deepstream/deepstream-7.1/sources/libs/nvmsgconv/libnvds_msgconv.so")
        msgconv.set_property("payload-type", 1)
        msgconv.set_property("msg2p-newapi", 1)

my probe func according deepstream-python-apps:

def tracker_src_pad_buffer_probe(pad, info, u_data):
    gst_buffer = info.get_buffer()
    if not gst_buffer:
        # nothing to do
        return Gst.PadProbeReturn.OK

    batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
    if not batch_meta:
        return Gst.PadProbeReturn.OK

    l_frame = batch_meta.frame_meta_list
    while l_frame is not None:
        try:
            frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
        except StopIteration:
            break

        # iterate objects; use first detected object as representative for the event meta
        l_obj = frame_meta.obj_meta_list
        first_obj = None
        while l_obj is not None:
            try:
                obj_meta = pyds.NvDsObjectMeta.cast(l_obj.data)
            except StopIteration:
                break
            # pick the first object (you can change logic to pick highest confidence, etc.)
            if first_obj is None:
                first_obj = obj_meta
            try:
                l_obj = l_obj.next
            except StopIteration:
                break

        if first_obj is not None:
            try:
                # create user meta from pool
                user_event_meta = pyds.nvds_acquire_user_meta_from_pool(batch_meta)
                if not user_event_meta:
                    print("tracker_probe: failed to acquire user meta pool")
                else:
                    # allocate and populate standard NvDsEventMsgMeta
                    msg_meta = pyds.alloc_nvds_event_msg_meta(user_event_meta)

                    # bbox from the representative object
                    msg_meta.bbox.top = first_obj.rect_params.top
                    msg_meta.bbox.left = first_obj.rect_params.left
                    msg_meta.bbox.width = first_obj.rect_params.width
                    msg_meta.bbox.height = first_obj.rect_params.height

                    # basic identifiers
                    msg_meta.frameId = int(frame_meta.frame_num)
                    msg_meta.trackingId = long_to_uint64(first_obj.object_id)
                    msg_meta.confidence = first_obj.confidence

                    #msg_meta = generate_event_msg_meta(msg_meta, first_obj.class_id)

                    # attach user meta to frame
                    user_event_meta.user_meta_data = msg_meta
                    #user_event_meta.base_meta.meta_type = pyds.NvDsMetaType.NVDS_EVENT_MSG_META
                    pyds.nvds_add_user_meta_to_frame(frame_meta, user_event_meta)

                    # debug print (can be removed in production)
            except Exception as e:
                print("tracker_probe: exception while attaching meta:", e)

        try:
            l_frame = l_frame.next
        except StopIteration:
            break

    return Gst.PadProbeReturn.OK

but in Kafka I get this meta w/o conf score:
{
“version” : “4.0”,
“id” : “960”,
“@timestamp” : “2025-09-26T05:55:45.116Z”,
“sensorId” : “CAMERA_ID”,
“objects” : [
“19|1056.27|657.234|1110.12|751.874|stand”,
“17|1493.18|833.343|1553.01|957.265|stand”,
“16|1671.83|768.431|1716.31|869.007|stand”,
“117|949.721|649.175|996.772|758.584|stand”,
“13|695.136|653.893|735.54|758.206|stand”,
“115|1154.05|685.037|1200.15|769.459|stand”,
“113|1315.21|685.173|1348.9|765.867|stand”,
“116|1835.21|821.016|1896|939.054|stand”,
“6|1752.94|730.052|1781.99|798.052|stand”,
“112|1012.29|478.827|1024.21|502.087|stand”,
“11|840.972|613.001|867.966|686.484|stand”,
“178|1026.75|672.024|1056.9|759.738|stand”,
“152|1757.16|785.023|1790.23|888.523|stand”,
“166|910.033|418.79|919.629|436.27|stand”,
“174|1846.03|435.906|1853.97|447.75|stand”,
“172|719.526|386.228|727.254|395.62|stand”,
“175|1120.86|400.209|1127.34|415.126|stand”,
“154|1798.42|788.723|1828.05|879.592|stand”,
“5|807.599|621.115|841.085|703.009|stand”,
“168|1899.9|788.942|1919.9|891.003|stand”,
“2|853.553|383.861|859.053|395.372|stand”,
“180|1778.99|804.382|1807.99|881.569|stand”,
“159|1732.97|899.458|1817.93|1010.49|sit”
]
}
How I can correctly change message?

Please run "make install " or copy the so to deepstream-7-1/lib. you can also add logs in generate_dsmeta_message_minimal to check if the modification takes effect.

I tried, but I haven’t any effects, the code of func below:

gchar*
generate_dsmeta_message_minimal(void* privData, void* frameMeta)
{
    /*
    The JSON structure of the frame
    {
     "version": "4.0",
     "id": "frame-id",
     "@timestamp": "2018-04-11T04:59:59.828Z",
     "sensor": "sensor-id",
     "objects": [
        ".......object-1 attributes...........",
        ".......object-2 attributes...........",
        ".......object-3 attributes..........."
      ]
    }
    */

    /*
    An example object with Vehicle object-type
    {
      "version": "4.0",
      "id": "frame-id",
      "@timestamp": "2018-04-11T04:59:59.828Z",
      "sensorId": "sensor-id",
      "objects": [
          "957|1834|150|1918|215|Vehicle|#|sedan|Bugatti|M|blue|CA 444|California|0.8",
          "..........."
      ]
    }
     */

    JsonNode* rootNode;
    JsonObject* jobject;
    JsonArray* jArray;
    stringstream ss;
    gchar* message = NULL;

    jArray = json_array_new();

    NvDsFrameMeta* frame_meta = (NvDsFrameMeta*)frameMeta;
    for (NvDsObjectMetaList* obj_l = frame_meta->obj_meta_list; obj_l; obj_l = obj_l->next) {
        NvDsObjectMeta* obj_meta = (NvDsObjectMeta*)obj_l->data;
        if (obj_meta == NULL) {
            // Ignore Null object.
            continue;
        }

        // bbox sub object
        float scaleW =
            (float)frame_meta->source_frame_width / (frame_meta->pipeline_width == 0) ? 1 : frame_meta->pipeline_width;
        float scaleH = (float)frame_meta->source_frame_height / (frame_meta->pipeline_height == 0)
                           ? 1
                           : frame_meta->pipeline_height;

        float left = obj_meta->rect_params.left * scaleW;
        float top = obj_meta->rect_params.top * scaleH;
        float width = obj_meta->rect_params.width * scaleW;
        float height = obj_meta->rect_params.height * scaleH;

        ss.str("");
        ss.clear();
       // Modify here
        ss << obj_meta->object_id << "|" << left << "|" << top << "|" << left + width << "|" << top + height << "|"
           << obj_meta->obj_label << "|" << obj_meta->confidence;
        g_print("CUSTOM_PAYLOAD_DEBUG: Processing Object ID %lu (Conf: %f, Label: %s)\n",
            obj_meta->object_id, obj_meta->confidence, obj_meta->obj_label);
        if (g_list_length(obj_meta->classifier_meta_list) > 0) {
            ss << "|#";
            // Add classifiers for the object, if any
            for (NvDsClassifierMetaList* cl = obj_meta->classifier_meta_list; cl; cl = cl->next) {
                NvDsClassifierMeta* cl_meta = (NvDsClassifierMeta*)cl->data;
                for (NvDsLabelInfoList* ll = cl_meta->label_info_list; ll; ll = ll->next) {
                    NvDsLabelInfo* ll_meta = (NvDsLabelInfo*)ll->data;
                    ss << "|" << ll_meta->result_label;
                }
            }
            ss << "|" << obj_meta->confidence;
        }
        json_array_add_string_element(jArray, ss.str().c_str());
    }

    // generate timestamp
    char ts[MAX_TIME_STAMP_LEN + 1];
    generate_ts_rfc3339(ts, MAX_TIME_STAMP_LEN);

    // fetch sensor id
    string sensorId = "0";
    NvDsPayloadPriv* privObj = (NvDsPayloadPriv*)privData;
    auto idMap = privObj->sensorObj.find(frame_meta->source_id);
    if (idMap != privObj->sensorObj.end()) {
        NvDsSensorObject& obj = privObj->sensorObj[frame_meta->source_id];
        sensorId = obj.id;
    }

    jobject = json_object_new();
    json_object_set_string_member(jobject, "version", "4.0");
    json_object_set_string_member(jobject, "id", to_string(frame_meta->frame_num).c_str());
    json_object_set_string_member(jobject, "@timestamp", ts);
    json_object_set_string_member(jobject, "sensorId", sensorId.c_str());

    json_object_set_array_member(jobject, "objects", jArray);

    JsonArray* custMsgjArray = json_array_new();
    // Search for any custom message blob within frame usermeta list
    for (NvDsUserMetaList* l = frame_meta->frame_user_meta_list; l; l = l->next) {
        NvDsUserMeta* frame_usermeta = (NvDsUserMeta*)l->data;
        if (frame_usermeta && frame_usermeta->base_meta.meta_type == NVDS_CUSTOM_MSG_BLOB) {
            NvDsCustomMsgInfo* custom_blob = (NvDsCustomMsgInfo*)frame_usermeta->user_meta_data;
            string msg = string((constchar*)custom_blob->message, custom_blob->size);
            json_array_add_string_element(custMsgjArray, msg.c_str());
        }
    }
    if (json_array_get_length(custMsgjArray) > 0)
        json_object_set_array_member(jobject, "customMessage", custMsgjArray);
    else
        json_array_unref(custMsgjArray);

    rootNode = json_node_new(JSON_NODE_OBJECT);
    json_node_set_object(rootNode, jobject);

    message = json_to_string(rootNode, TRUE);
    json_node_free(rootNode);
    json_object_unref(jobject);

    return message;
}

As written in my last comment, you can print message, which is the complete information to send, in generate_dsmeta_message_minimal to check if the library is replaced, this function is called, the message is expected.