Advertisement

Unreal Memory Allocation

Started by January 09, 2018 02:45 PM
4 comments, last by SillyCow 6 years, 10 months ago

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?

My Oculus Rift Game: RaiderV

My Android VR games: Time-Rider& Dozer Driver

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown & Killer Bees

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)

Advertisement

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.

My Oculus Rift Game: RaiderV

My Android VR games: Time-Rider& Dozer Driver

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown & Killer Bees

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)

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?)

My Oculus Rift Game: RaiderV

My Android VR games: Time-Rider& Dozer Driver

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown & Killer Bees

This topic is closed to new replies.

Advertisement