Multiple output types from single DLL / Info CHOP performance

Hello!

I’m working on face tracking / analysis / recognition with the Visage SDK and I’m struggling a bit with the amount and different types of data that I want to export from a single C++ operator.

Since most of the output is numerical information, I started with a C++ CHOP, outputting channels and supplemental (textual) information in an info DAT.

But then came the idea to also export the face mesh for each tracked face. Since I’d also be outputting geometry, I decided to refactor everything to a C++ SOP and just output the numeric data in an info CHOP.

In theory this works fine. However, if for some reason you want to get everything from the Visage SDK, this also includes a lot of feature points for per face, 154, which all have an x, y and z. This totals to 462 channels per face for the feature points. If you track 4 faces, this would be 1848 channels.

Outputting this amount of channels from a C++ CHOP didn’t seem to have much impact on performance. However using this many channels in an info CHOP does have heavy impact on performance, the info CHOP has a cook time of over 4ms.

This can be easily replicated by creating any C++ OP and returning 2000 for getNumInfoCHOPChans and just settings the value for each channel to 0.0f in getInfoCHOPChan.

I have some ways of working around this for now, but is there any good approach for outputting this many channels in an info CHOP?

Thanks for your thoughts! I’m happy to supply more information if necessary.

Thijs

So the trick to solving this is using the fact that a single process will only load a single copy of a .dll into itself. What you do is create another .dll project separate from your SOP/CHOP/DAT .dlls. This .dll is what interfaces with the SDK and gathers all of it’s information. It should export a static class that the other SOP/CHOP/DAT .dlls can access and extract the information they care about to be output from themselves. Since there is only one copy of this root .dll loaded into the process, all the .dlls will be accessing the same static class, so all the information is shared.

2 Likes

Hi Malcolm,

Thanks, this is very interesting! I never developed an application like this before, sharing a static class from a single DLL between multiple processes, but it makes sense as you explain it.

I assume it’s still possible to use one operator (a TOP maybe), that passes the new frame to the DLL and configures the settings for the tracker.

I’m going to have a go at it!

I’ll have to give that a shot sometimes, sounds better than Multiple c++ ops in the same DLL ? :smiley: though I did get to work at the time with passing a pointer through a string hehe

Just an update on this, I’ve finished the implementation of what I was doing, now using a CHOP, TOP, DAT and SOP, sharing the same DLL in the background. Using every part of the Visage SDK.

It works like a charm, thanks again for the suggestion @malcolm!

And @vinz99 haha yes, I suppose you have a bit more flexibility with this approach, especially if your data needs to be thread-safe as well :wink: Definitely worth to give it a shot!

2 Likes

The YouTubeTOP has code for this subject, but I’m not able to transfer it to my own plugins.

SharedData has a static variable for a map of strings to YouTubeTOP pointers.
When a YouTubeTOP is created, it adds itself to this map.
When a YouTubeCHOP is created (to get the audio), it queries the SharedData’s map with an op path as the key.

I’m working with classes similar to the YouTubeTOP and YouTubeCHOP, so I have a separate DLL built for each but both in the same visual studio solution. With debug build, I can see that my YouTubeTOP is adding itself to the shareddata map, but when my YouTubeCHOP queries the map, the map is empty. So evidently I’m not using these static vars correctly. What might be my mistake?

My build folder includes both
YouTubeTOP/Debug/shared_data.obj and YouTubeCHOP/Debug/shared_data.obj so that seems like a red flag. Maybe it’s necessary to build shared_data into a third dll? But I think that’s not how YouTubeTOP did it.

Ya, the shared data needs to be in it’s own .dll. Right now each of your .dlls has their own copy of the shared data. If the shared data is living in it’s own .dll, then the process will only load one copy of that .dll, and they’ll work on the same memory

Thanks. My project is working now. Perhaps the audio side of YouTubeTOP isn’t working as is.