How to use the UserMetadataTemplate in service maker

Please provide complete information as applicable to your setup.

• Laptop Y9000 with RTX 3060
• DeepStream 7.0
• JetPack Version (valid for Jetson only)
• TensorRT 8.6.1.6
• NVIDIA GPU Driver 550.107
• questions
Hi, I want to add a usermeta to framemeta using service maker UserMetadataTemplate. This is my test program.

namespace deepstream {

class DummyData{
public :
int m_sourceid;
public:
DummyData() : m_sourceid(88) {}
// DummyData(int sourceid) : m_sourceid(sourceid) {
// cout << "In dymmydata 1 param constructor sourceid = " << m_sourceid << endl;
// }
DummyData(const DummyData& other){
m_sourceid = other.m_sourceid;
}

DummyData& operator=(const DummyData& other){
if (this != &other){
m_sourceid = other.m_sourceid;
}
return *this;
}

static int getDsMetaType() { return NVDSINFER_TENSOR_OUTPUT_META ;}
};

class MyUserMetaData : public UserMetadataTemplate {
public:
MyUserMetaData(void data = nullptr) : UserMetadataTemplate(data) { data_ = data; }
virtual ~MyUserMetaData() {
if (data_ != nullptr) {
delete (DummyData
) data_;
data_ = nullptr;
}
}

void generate(const FrameMetadata &frameMeta, int sourceid) {
data_ = new DummyData();
((DummyData*)data_)->m_sourceid = sourceid;
cout << “In generate: sensorid=” << ((DummyData*)data_)->m_sourceid << " \tsourid: " << sourceid << endl;
}
};

class DummyMetaGenerator : public BufferProbe::IBatchMetadataOperator {
public:
DummyMetaGenerator() {}
virtual ~DummyMetaGenerator() {}

virtual probeReturn handleData(BufferProbe &probe, BatchMetadata &data) {
FrameMetadata::Iterator frame_iter;
for (data.initiateIterator(frame_iter); !frame_iter->done(); frame_iter->next()) {
// DummyData *dummyDataPtr = new DummyData();
MyUserMetaData dummy_meta;
if (data.acquire(dummy_meta)){
dummy_meta.generate((*frame_iter)->get(), (*frame_iter)->sourceId());
// cout << “已生成dummy_meta. sensorid:” << dummy_meta.get().m_sourceid << endl;
(*frame_iter)->append(dummy_meta);
}

}
return deepstream::probeReturn::Probe_Ok;

}
};

class DummyMetaObserver : public BufferProbe::IBatchMetadataObserver {
public:
DummyMetaObserver() {}
virtual ~DummyMetaObserver() {}

virtual probeReturn handleData(BufferProbe &probe, const BatchMetadata &data) {
FrameMetadata::Iterator frame_smmeta;
for (data.initiateIterator(frame_smmeta); !frame_smmeta->done(); frame_smmeta->next()) {
const NvDsFrameMeta* frame_meta = static_cast<NvDsFrameMeta *>(frame_smmeta->get().get());
if (frame_meta != nullptr && frame_meta->frame_user_meta_list != NULL) {
for (NvDsUserMetaList *l_user_meta = frame_meta->frame_user_meta_list; l_user_meta != NULL;
l_user_meta = l_user_meta->next) {
NvDsUserMeta *user_meta = (NvDsUserMeta *)l_user_meta->data;
MyUserMetaData *dummy_data = (MyUserMetaData *)user_meta->user_meta_data;

      cout << " In Oberser: sourceid=" << dummy_data->get().m_sourceid << endl;

    }
  }
}
return probeReturn::Probe_Ok;

}
};

}// namespace deepstream

I user it in main.cpp below.

int main(int argc, char *argv) {
if (argc < 2) {
cout << “Usage: " << argv[0] << " ” << endl;
return -1;
}
string config_file = argv[1];
const string suffix = “yaml”;
try{
Pipeline pipeline(“usermeta_test”, config_file);
pipeline.attach(“nvvideoconvert”, new BufferProbe(“dummy_producer”, new DummyMetaGenerator))
.attach(“nvdsosd”, new BufferProbe(“dummy_consumer”, new DummyMetaObserver));
pipeline.start().wait();

} catch (const exception& e){
cout << "Error: " << e.what() << endl;
return -1;
}
return 0;
}


The app raise SIGNAL SIGSEGV: ADDRESS NOT MAPPED TO OBJECT error. Could you tell me what wrong with it, and how to use the UserMetadataTemplate in my program?

It may take some time to check your code. Will be back soon when we got any clue.

There are lots of errors in your code, it failed to be built. How can you run your code?

I had simplified the code and deleted the part of class MyUserMetaData. But it also report the SIGSEGV error of ADDRESS NOT MAPPED TO OBJECT at the DummyMetaObserver part of UserMetadataTemplate::get() funciton.

/** DummyData class */
class DummyData{
public :
int m_sourceid;
public:
DummyData() : m_sourceid(88) {}
DummyData(int sourceid) : m_sourceid(sourceid) {
cout << "In dymmydata 1 param constructor sourceid = " << m_sourceid << endl;
}
DummyData(const DummyData& other){
m_sourceid = other.m_sourceid;
}

DummyData& operator=(const DummyData& other){
if (this != &other){
m_sourceid = other.m_sourceid;
}
return *this;
}

void setValue(int val) { m_sourceid = val; }
static int getDsMetaType() { return NVDSINFER_TENSOR_OUTPUT_META ;}
};
/** end of DummyData class */

/** DummyMetaGenerator class */
class DummyMetaGenerator : public BufferProbe::IBatchMetadataOperator {
public:
DummyMetaGenerator() {}
virtual ~DummyMetaGenerator() {}

virtual probeReturn handleData(BufferProbe &probe, BatchMetadata &data) {
FrameMetadata::Iterator frame_iter;
for (data.initiateIterator(frame_iter); !frame_iter->done(); frame_iter->next()) {
// DummyData *dummyDataPtr = new DummyData();
UserMetadataTemplate dummy_meta;
if (data.acquire(dummy_meta)){
dummy_meta.get().setValue(100);
cout << “已生成dummy_meta. sensorid:” << dummy_meta.get().m_sourceid << endl;
(*frame_iter)->append(dummy_meta);
}

}
return deepstream::probeReturn::Probe_Ok;

}
};
/** end of DummyMetaGenerator class */

/** DummyMetaObserver class */
class DummyMetaObserver : public BufferProbe::IBatchMetadataObserver {
public:
DummyMetaObserver() {}
virtual ~DummyMetaObserver() {}

virtual probeReturn handleData(BufferProbe &probe, const BatchMetadata &data) {
FrameMetadata::Iterator frame_smmeta;
for (data.initiateIterator(frame_smmeta); !frame_smmeta->done(); frame_smmeta->next()) {
const NvDsFrameMeta* frame_meta = static_cast<NvDsFrameMeta *>(frame_smmeta->get().get());
if (frame_meta != nullptr && frame_meta->frame_user_meta_list != NULL) {
for (NvDsUserMetaList *l_user_meta = frame_meta->frame_user_meta_list; l_user_meta != NULL;
l_user_meta = l_user_meta->next) {
NvDsUserMeta *user_meta = (NvDsUserMeta *)l_user_meta->data;
UserMetadataTemplate *dummy_meta =
(UserMetadataTemplate *)user_meta->user_meta_data;

      cout << " In Oberser: sourceid=" << dummy_meta->get().m_sourceid << endl;

    }
  }
}
return probeReturn::Probe_Ok;

}
};
/** endof DummyMetaObserver */

/** main */
int main(int argc, char *argv) {
if (argc < 2) {
cout << “Usage: " << argv[0] << " ” << endl;
return -1;
}
string config_file = argv[1];
const string suffix = “yaml”;
try{
Pipeline pipeline(“usermeta_test”, config_file);
pipeline.attach(“nvvideoconvert”, new BufferProbe(“dummy_producer”, new DummyMetaGenerator))
.attach(“nvdsosd”, new BufferProbe(“dummy_consumer”, new DummyMetaObserver));
pipeline.start().wait();

} catch (const exception& e){
cout << "Error: " << e.what() << endl;int main(int argc, char *argv) {
if (argc < 2) {
cout << “Usage: " << argv[0] << " ” << endl;
return -1;
}
string config_file = argv[1];
const string suffix = “yaml”;
try{
Pipeline pipeline(“usermeta_test”, config_file);
pipeline.attach(“nvvideoconvert”, new BufferProbe(“dummy_producer”, new DummyMetaGenerator))
.attach(“nvdsosd”, new BufferProbe(“dummy_consumer”, new DummyMetaObserver));
pipeline.start().wait();

} catch (const exception& e){
cout << "Error: " << e.what() << endl;
return -1;
}
return 0;
}
return -1;
}
return 0;
}
/** endof main */

The template shouldn’t be used in this way.

But how to use it to load the custom user data?

What do you mean by load? Do you mean to define a new user meta and attach the user meta to frame meta?

Yes. I want to attach the usermeta to the framemeta at the srcpad of nvstreammux, and read the usermeta by the downstream element such as nvmsgconv. How can I do it in the service-make framework?