Fatal error after deleting a component with media texture: A FRenderResource was deleted without being released first!

After I deleting a component with media texture (Actually I destroyed an actor, and the component is attached to the root component of this actor), the game crash with follow reports:

Fatal error: [File:D:\Build++UE4+Release-4.13+Compile\Sync\Engine\Source\Runtime\RenderCore\Private\RenderResource.cpp] [Line: 118]
A FRenderResource was deleted without being released first!

someProject!FDebug::AssertFailed()
someProject!FMediaTextureResource::~FMediaTextureResource()
someProject!FMediaTextureResource::`scalar deleting destructor’()
someProject!UTexture::FinishDestroy()
someProject!UObject::ConditionalFinishDestroy()
someProject!IncrementalPurgeGarbage()
someProject!UWorld::Tick()
someProject!UGameEngine::Tick()
someProject!FEngineLoop::Tick()
someProject!GuardedMain()
someProject!GuardedMainWrapper()
someProject!WinMain()
someProject!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:264]
kernel32
ntdll

BTW. This only happens in packaged game. When I play it in Editor, everything works fine.

Some more information, the material is created dynamic during runtime.

Hi Adcentury,

I was unable to reproduce your issue. Here is a list of steps that I tried.

  1. Opened a blank 4.13 project
  2. Added a sample mp4 video to the content folder
  3. Created a Media source and Media Player asset and associated the Media source to the sample video
  4. Played the Media Player so that a media texture was generated and create a material using the media texture
  5. Create an Actor BP with a static mesh component
  6. In the construct script create a dynamic material instance using the Media Texture Material as a base
  7. In the even graph on begin play apply the dynamic material to the static mesh
  8. Place the Actor BP in the level
  9. In the level BP get a reference to the Actor BP placed in the level then delete the actor on event begin play
  10. Package Project for windows 64 bit

It would be useful to know what platform you are packaging on as well as if you can reproduce this issue in a blank project.

,

SampleProject

Hi,

I have uploaded a minimal project to reproduce the issue. You can follow these steps to reproduce it:

  1. Package this project for windows 64 bit
  2. Copy “[PROJECT_DIR]/Saved/users/sample.wmv” to “[PACAKGE_GAME_DIR]/MediaTextureCrash/Saved/users/sample.wmv”
  3. Open the game and wait for 5 seconds. A cube with a video playing will appear (and you can hear the sound). Wait another 10 seconds, the cube will disappear (because the actor is destroyed).
  4. Wait for about 2 min, then the game will crash and show the crash report.

The project only contain 3 cpp class.

MyLevelScriptActor

This is used to create MyActor at begin play.

MyActor

a), Create MyStaticMeshComponent after about 5 seconds. Attach the component to self root component. and then LoadMedia of the component.

if (!bComponentAdded)
{
	if (count < 500)
	{
		count++;
	}
	else
	{
		MyComponent = UMyStaticMeshComponent::CreateComponent(this);
		MyComponent->RegisterComponent();
		MyComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetIncludingScale);

		MyComponent->LoadMedia();

		bComponentAdded = true;
		count = 0;
	}
}

b). Destroy self after another 10 seconds.

else
{
	if (count < 1000)
	{
		count++;
	}
	else
	{
		Destroy();
	}
}

MyStaticMeshComponent

a). A factory to create itself

UMyStaticMeshComponent* UMyStaticMeshComponent::CreateComponent(UObject* InOuter)
{
	UMyStaticMeshComponent* component = NewObject<UMyStaticMeshComponent>(InOuter);
	
	UStaticMesh* mesh = LoadObject<UStaticMesh>(NULL, TEXT("StaticMesh'/Game/Temp/SM_Mesh.SM_Mesh'"));

	component->SetStaticMesh(mesh);
	component->SetMobility(EComponentMobility::Movable);

	return component;
}

b). In LoadMedia method, it create a UFileMediaSource from local file (which is sample.wmv)

IFileManager& fileManager = IFileManager::Get();
FString videoPath = FPaths::ConvertRelativePathToFull(FPaths::GameSavedDir() + "users/sample.wmv");  
UFileMediaSource* fileSource = NewObject<UFileMediaSource>(this);
fileSource->FilePath = videoPath;

c). Create a UMediaPlayer and its UMediaSoundWave and UMediaTexture. Then Open file media source.

UMediaPlayer* mediaPlayer = NewObject<UMediaPlayer>(this);
mediaPlayer->SetLooping(true);

UMediaSoundWave* sound = NewObject<UMediaSoundWave>(this);
mediaPlayer->SetSoundWave(sound);

UMediaTexture* texture = NewObject<UMediaTexture>(this);
texture->UpdateResource();
mediaPlayer->SetVideoTexture(texture);

mediaPlayer->PlayOnOpen = true;

mediaPlayer->OpenSource(fileSource);

d). Dynamic create a material instance and set texture.

UMaterial* material = LoadObject<UMaterial>(NULL, TEXT("Material'/Game/Temp/M_Media.M_Media'"));

UMaterialInstanceDynamic* materialInstance = UMaterialInstanceDynamic::Create(material, this);

materialInstance->SetTextureParameterValue(FName("MediaTexture"), mediaPlayer->GetVideoTexture());

e). Set material to self and spawn a sound

SetMaterial(0, materialInstance);

UGameplayStatics::SpawnSoundAttached(mediaPlayer->GetSoundWave(), this, NAME_None, FVector::ZeroVector, FRotator::ZeroRotator,
	EAttachLocation::KeepRelativeOffset, true);

BTW, I’m using Windows 7 sp1 and UE 4.13.0

for replying.

Thank you for submitting a bug report. I have reproduced this issue and logged a report for it here: Unreal Engine Issues and Bug Tracker (UE-36321)

You can track the report’s status as the issue is reviewed by our development staff.

Cheers,

I added a temporary fix for the upcoming 4.13.1 hotfix. In 4.14 this is not a problem anymore, because the MediaTexture works slightly different there. In the meantime, if you want to unblock yourself, add the following at the top of UMediaTexture::Tick:

    if (HasAnyFlags(RF_BeginDestroyed))
	{
		return false;
	}

for your minimal repro project!

By the way, you don’t have to create a FileMediaSource at run-time. You can simply use UMediaPlayer::OpenUrl instead. It expects an URL scheme, so you have to prefix your path with file://, for example:

mediaPlayer->OpenUrl(FString(TEXT("file://")) + videoPath);

In 4.14 I also added the new OpenFile method, which makes this a little more convenient:

mediaPlayer->OpenFile(videoPath);

a lot!