How do I change JSON payload output?

• Hardware Platform (Jetson / GPU)
Xavier NX
• DeepStream Version
6.0
• JetPack Version (valid for Jetson only)
4.6
• TensorRT Version
8.0.1

How do I change the json payload output for Gst-nvmsgconv?
Right now the default PAYLOAD_DEEPSTREAM_MINIMAL output is in the format of

{
    "version": "4.0",
    "id": "frame-id",
    "@timestamp": "2018-04-11T04:59:59.828Z",
    "sensorId": "sensor-id",
    "objects": [
        "957|1834|150|1918|215|Vehicle",
        "..........."
    ]
  }

but I would like it to output something like this instead

{
    "version": "4.0",
    "id": "frame-id",
    "@timestamp": "2018-04-11T04:59:59.828Z",
    "sensorId": "sensor-id",
    "objects": [
          id: "957":[
               left: "1834"
               top: "150"
               width: "1918"
               height: "215"
               label: "Vehicle"
      ]
    ]
  }

I narrowed down to the file deepstream/sources/libs/nvmsgconv/deepstream-schema/dsmeta_payload.cpp and the following function

gchar* generate_dsmeta_message_minimal (void *privData, void *frameMeta)
{
  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();
    ss << "|" << left << "|" << top         //the part that I've changed (removed object_id)
       << "|" << left + width << "|" << top + height
       << "|" << 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_int_member (jobject, "id", frame_meta->frame_num);
  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((const char *) 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;
}

This is the output I get even after changing parts of the code above,
image

However, when I make changes to the segment of the code above no changes that I made will be reflected when I run the app. I did rebuild the library with “make” and “make install”. I’m running deepStream-test5-app through the official deepstream-l4t:6.0-iot docker image. Tried building my own docker image but the issue is still there. Am I just editing the wrong part of the code? Been stuck on this for awhile please assist me, thank you.

did you copy the output so to /opt/nvidia/deepstream/deepstream/lib/?

Yes I did. The changes are still not reflected. Also I noticed that I’m only getting object_ID, left, top, width, height, label but not the confidence despite having this line in the “stock” code

ss << "|" << obj_meta->confidence;

you must edit in eventmsg_payload.cpp file

does PhoneNT 's suggestion help? you can add logs to narrow down.

Yes, it is edited from eventmsg_payload.cpp and not dsmeta_payload.cpp.

Also, I had to rebuilt the docker image and include an additional line in dockerFile to copy the output libnvds_msgconv.so file to inside the container’s /opt/nvidia/deepstream/deepstream/lib/

After switching over to run the container on the new image, I can finally see the changes I made in the payload. Thank you all for your help