Jump to content
  • Advertisement
SillyCow

Unreal Memory Allocation

Recommended Posts

I am pretty new to Unreal development.

I am trying to fix some memory allocation issues that I have.

I am streaming jpegs to a texture at ~5FPS on an Android app. (the texture updates at 5FPS)

To unpack the texture jpeg, I am using this code:

const TArray<uint8>* UncompressedBGRA = NULL;
    if (!ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))

However, as far as I can tell this allocates a new bit buffer every time. 

And my app eventually grinds to a halt and crashes.

This is "partially fixed" if I call:

GetWorld()->ForceGarbageCollection(true);

"Partially fixed":  Meaning the app doesn't crash anymore, but the app still stutters.

Is there some way to get Unreal to unpack a jpeg in place?

Or do I need to compile some other C++ jpeg decoder?

Share this post


Link to post
Share on other sites
Advertisement

As it points in the Unreal Docs

bool GetRaw
(
    const ERGBFormat::Type InFormat,
    int32 InBitDepth,
    const TArray < uint8 > *& OutRawData
)

your passed array is an out parameter so this function is creating a new array on every call and that slowly leads to a memory overflow. You should call the destructor when you are done with the uncompressed image or better find a way to handle the same memory on every call so you wont need to do a costly reallocation of new memory blocks.

These memory reallocation is what makes your app slow during runtime and leads to the crashes after some time. Garbage collection is also a very slow operation because Unreal Engine needs to find all unused resources in memory and give them back to the OS (I dont know how they manage memory but I think they use some kind of memory block management to prevent memory fragmentation)

Share this post


Link to post
Share on other sites

The memory is released when ImageWrapper is destroyed. That is not my current problem.

However, I do not see how can gain control of when ImageWrapper allocates this memory.

  1. I downloading mage,
  2. The I call IImageWrapperPtr->SetCompressed with some jpeg data.
  3. IImageWrapperPtr does some magic and decompresses this some buffer that is allocated internally.
    1. This is by far the biggest memory allocation, because the uncompressed image data is the largest data
  4. I get a pointer to this data using GetRaw().

What I would like to do is prevent IImageWrapperPtr from allocating this uncompressed data buffer in the first place. If possible, I would like to feed it a pre-allocated work area, and reuse this work area for every subsequent image that I need to decompress.

Edited by SillyCow

Share this post


Link to post
Share on other sites

I don't think you should expect to get that sort of low level access to the engine's memory management.

I suspect that you will either need to use a different JPEG decoder, or find a different way to achieve your aims here (e.g. decompress the images ahead of time, use a video codec, etc)

Share this post


Link to post
Share on other sites
On 10/01/2018 at 12:58 PM, Kylotan said:

use a video codec

This was actually my next step.

Does unreal have a realtime (live) video codec for android? Or should I go about compiling FFMPEG? (Is there a mobile FFMPEG plugin allready available?)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!