Freezing of the Image when trying to Capture the Scene (UE5.3.2)

Hello!

I am capturing a scene with help of USceneCaptureComponent2D.
When there appear an event that tells me to capture I run this code below:

// SceneCaptureComp is a UCameraCaptureComponent2D
SceneCaptureComp->CaptureScene();

TArray<FColor> Bitmap;

FTextureRenderTargetResource* renderTargetResource = SceneCaptureComp->TextureTarget->GameThread_GetRenderTargetResource();

renderTargetResource->ReadPixels(Bitmap);

IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(static_cast<EImageFormat>(CurrentImgFormat));

ImageWrapper->SetRaw(&Bitmap[0], Bitmap.Num() * sizeof(FColor), renderTargetSize.X, renderTargetSize.Y, ERGBFormat::BGRA, 8);
const TArray64<uint8>& compressedBitmap = ImageWrapper->GetCompressed(JpegQuality);
const TArray<uint8> img(compressedBitmap);

// Then I just broadcast a delegate with TArray<uint8> arg
OnBitmapReady.Broadcast(img);

This code works fine when I am debugging a game inside UEditor or as a vscode project.

But here is what happens when I am packaging:

  • It works nice with ubuntu 22.04 and rtx 3070.
  • The game itself works with ubuntu 20.04 and gtx 950 but when I am trying to capture the scene the image on a screen freezes and nothing happens. I get this warnings in my console:

LogRendererCore: Warning: FlushRenderingCommands called recursively! 2 calls on the stack.

And it happens on each frame.

Probably I should mention it: the ReadPixels function is not overriden, I use default USceneCaptureComponent2D, so everything happens on a Game Thread.

I also checked if ram is not enough but the game consumes 3 gb of ram when running according to htop.
Also I noticed that almost all of 2 GBs of VRAM are used: 1927 out of 2048 MB - maybe that’s the reason?

p.s. Everything unfreezes when I stop capturing the scene.
p.p.s. I don’t save those images on a disk.

the freeze is expected with that code path. ReadPixels calls FlushRenderingCommands internally, so the game thread stops until the gpu finishes the copy, and calling it right after capture is what triggers the recursive flush warning in your packaged log. the fix is to not wait: enqueue the copy on the render thread and pick up the pixels a frame or two later once the fence completes, and dont capture and read in the same tick.
you can also try Async Render Target Reader, a readback plugin for Unreal Engine that wraps that fenced gpu copy in two blueprint nodes with On Success and On Failure events: Async Render Target Reader — Non-Blocking GPU Pixel Readback for Blueprints | Fab