Hi,
I know this is a classic issue but I can’t find a viable solution.
I need to send a Texture2D content from C# to Java to have access to libs, like ffmpeg or MediaCodec. The problem is that, on the C# side, I can get the raw texture content easily, I can quickly transcode it to YUV420P (using unsafe). I then need to pass the byte[ ] to Java. If I call the JNI passing the byte[ ] (Unity automatic solution) it takes lots of time to convert it to Java array. The other solution is to encode in base64 and send a String to Java, then, on Java, decode the base64 and use the byte[ ]. This is way is much faster than Unity’s byte[ ] conversion, but not fast enough, this overhead compromises the solution. The last solution would be to have a JNI array created on C# and populate it, also too slow. So, among these 3 solutions, the best one is using base64, but not close to good enough. To have an idea of the performance:
One frame (image of 912x576), the byte[ ] from Texture is a 912x576x3 bytes of rgb. I then transcode to YUV420P, encode base64, call java, decode base64, append to video file (with MediaCodec or ffmpeg). The performance is:
— Unity C#
GetTexture+Convert to YUV: ~30ms
Encode base64: ~30ms
— Java
Decode base64: ~30ms
Media encoding: ~30ms
A total of around ~120ms per frame. But 1/2 of this time is due to base64 encoding/decoding.
Is there another possible solution? A lower level solution? I could try using storage to pass the data, but I would like to avoid unnecessary overheads. Having the byte[ ] in memory and being able to access it on both sides I believe is the only viable solution for a high performance need.
I am using IL2CPP, so, after all, we are talking about C++, data between Java and CPP shouldn’t be that separated, am I right?
Unity is 2018.4LTS
Anyone could give me more ideas to check? Someone from Unity?
Thanks!
Fernando