Files
UnrealEngineUWP/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderCommon.h
Andriy Tylychko 9f65ad43a6 Merging //UE4/Private-3Lateral_Streaming to Main (//UE4/Main)
This mainly covers the new Pixel Streaming plugin version along with minor changes to other parts of the engine:
* removed multiple copies of FThread as it's now a part of Core
* changes to SlateUser required to fix user input in Pixel Streaming

This wasn't formally reviewed due to the size of Pixel Streaming changes, but was skimmed over by Zack Letters before integration

#rb zack.letters

[CL 9486237 by Andriy Tylychko in Main branch]
2019-10-09 08:21:27 -04:00

286 lines
6.9 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Stats/Stats.h"
#include "Logging/LogMacros.h"
#include "RHIStaticStates.h"
#include "HAL/ThreadSafeBool.h"
#include "HAL/ThreadSafeCounter.h"
#include "HAL/Thread.h"
#include "HAL/Event.h"
#include "Misc/ScopeExit.h"
#include "ShaderCore.h"
#include "ProfilingDebugging/CsvProfiler.h"
#include "RHI.h"
#include "RHIResources.h"
//
// Macros to control some things during development
// #RVF : Remove this when cleaning up
//
#define WRITE_TO_FILE 0
#define LIVESTREAMING 0
#if UE_BUILD_SHIPPING
#define GAMEPLAYMEDIAENCODER_DEBUG 0
#else
#define GAMEPLAYMEDIAENCODER_DEBUG 0
#endif
//
// Includes common to Windows and XboxOne
//
#if PLATFORM_WINDOWS || PLATFORM_XBOXONE
#include "Templates/RefCounting.h"
#endif
//
// Windows only include
//
#if PLATFORM_WINDOWS
#include "Windows/AllowWindowsPlatformTypes.h"
#include "Windows/PreWindowsApi.h"
#include <d3d11.h>
#include <mftransform.h>
#include <mfapi.h>
#include <mferror.h>
#include <mfidl.h>
#include <codecapi.h>
#include <shlwapi.h>
#include <mfreadwrite.h>
#include "Windows/PostWindowsApi.h"
#include "Windows/HideWindowsPlatformTypes.h"
#include "D3D11State.h"
#include "D3D11Resources.h"
#endif
//
// XboxOne only includes
//
#if PLATFORM_XBOXONE
#include "XboxOne/XboxOneAllowPlatformTypes.h"
#include "XboxOne/XboxOnePreApi.h"
#include <d3d11_x.h>
#include <d3d12_x.h>
#include <d3dcompiler_x.h>
#include <d3dx12_x.h>
#include <mftransform.h>
#include <mfapi.h>
#include <mferror.h>
#include <mfidl.h>
#include <codecapi.h>
#include <mfreadwrite.h>
#include "XboxOne/XboxOnePostApi.h"
#include "XboxOne/XboxOneHidePlatformTypes.h"
#endif
#if GAMEPLAYMEDIAENCODER_DEBUG
#define GAMEPLAYMEDIAENCODER_START PRAGMA_DISABLE_OPTIMIZATION
#define GAMEPLAYMEDIAENCODER_END PRAGMA_ENABLE_OPTIMIZATION
#else
#define GAMEPLAYMEDIAENCODER_START
#define GAMEPLAYMEDIAENCODER_END
#endif
#define WMFMEDIA_SUPPORTED_PLATFORM (PLATFORM_WINDOWS && (WINVER >= 0x0600 /*Vista*/) && !UE_SERVER)
DECLARE_LOG_CATEGORY_EXTERN(GameplayMediaEncoder, Log, VeryVerbose);
//
// Windows and XboxOne common code/macros
//
#if PLATFORM_WINDOWS || PLATFORM_XBOXONE
inline const FString GetComErrorDescription(HRESULT Res)
{
const uint32 BufSize = 4096;
WIDECHAR buffer[4096];
if (::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
nullptr,
Res,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
buffer,
sizeof(buffer) / sizeof(*buffer),
nullptr))
{
return buffer;
}
else
{
return TEXT("[cannot find error description]");
}
}
#if PLATFORM_WINDOWS
#include "Windows/AllowWindowsPlatformTypes.h"
#elif PLATFORM_XBOXONE
#include "XboxOne/XboxOneAllowPlatformTypes.h"
#endif
// macro to deal with COM calls inside a function that returns `false` on error
#define CHECK_HR(COM_call)\
{\
HRESULT Res = COM_call;\
if (FAILED(Res))\
{\
UE_LOG(GameplayMediaEncoder, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\
return false;\
}\
}
// macro to deal with COM calls inside COM method (that returns HRESULT)
#define CHECK_HR_COM(COM_call)\
{\
HRESULT Res = COM_call;\
if (FAILED(Res))\
{\
UE_LOG(GameplayMediaEncoder, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\
return Res;\
}\
}
// macro to deal with COM calls inside COM method (that simply returns)
#define CHECK_HR_VOID(COM_call)\
{\
HRESULT Res = COM_call;\
if (FAILED(Res))\
{\
UE_LOG(GameplayMediaEncoder, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\
return;\
}\
}
#if PLATFORM_WINDOWS
#include "Windows/HideWindowsPlatformTypes.h"
#elif PLATFORM_XBOXONE
#include "XboxOne/XboxOneHidePlatformTypes.h"
#endif
// following commented include causes name clash between UE4 and Windows `IMediaEventSink`,
// we just need a couple of GUIDs from there so the solution is to duplicate them below
//#include "wmcodecdsp.h"
const GUID CLSID_AACMFTEncoder = { 0x93AF0C51, 0x2275, 0x45d2, { 0xA3, 0x5B, 0xF2, 0xBA, 0x21, 0xCA, 0xED, 0x00 } };
const GUID CLSID_CMSH264EncoderMFT = { 0x6ca50344, 0x051a, 0x4ded, { 0x97, 0x79, 0xa4, 0x33, 0x05, 0x16, 0x5e, 0x35 } };
const GUID CLSID_VideoProcessorMFT = { 0x88753b26, 0x5b24, 0x49bd, { 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82 } };
// `MF_LOW_LATENCY` is defined in "mfapi.h" for >= WIN8
// UE4 supports lower Windows versions at the moment and so `WINVER` is < `_WIN32_WINNT_WIN8`
// to be able to use `MF_LOW_LATENCY` with default UE4 build we define it ourselves and check actual
// Windows version in runtime
#if (WINVER < _WIN32_WINNT_WIN8)
const GUID MF_LOW_LATENCY = { 0x9c27891a, 0xed7a, 0x40e1,{ 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee } };
#endif
#endif
//
// Windows only utility code/macros
//
#if PLATFORM_WINDOWS
ID3D11Device* GetUE4DxDevice();
// scope-disable particular DX11 Debug Layer errors
class FScopeDisabledDxDebugErrors final
{
private:
public:
FScopeDisabledDxDebugErrors(TArray<D3D11_MESSAGE_ID>&& ErrorsToDisable)
{
TRefCountPtr<ID3D11Debug> Debug;
HRESULT HRes = GetUE4DxDevice()->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(Debug.GetInitReference()));
if (HRes == E_NOINTERFACE)
{
// Debug Layer is not enabled, so no need to disable its errors
return;
}
if (!SUCCEEDED(HRes) ||
!SUCCEEDED(HRes = Debug->QueryInterface(__uuidof(ID3D11InfoQueue), reinterpret_cast<void**>(InfoQueue.GetInitReference()))))
{
UE_LOG(GameplayMediaEncoder, VeryVerbose, TEXT("Failed to get ID3D11InfoQueue: 0x%X - %s"), HRes, *GetComErrorDescription(HRes));
return;
}
D3D11_INFO_QUEUE_FILTER filter = {};
filter.DenyList.NumIDs = ErrorsToDisable.Num();
filter.DenyList.pIDList = ErrorsToDisable.GetData();
bSucceeded = SUCCEEDED(InfoQueue->PushStorageFilter(&filter));
}
~FScopeDisabledDxDebugErrors()
{
if (bSucceeded)
{
InfoQueue->PopStorageFilter();
}
}
private:
TRefCountPtr<ID3D11InfoQueue> InfoQueue;
bool bSucceeded = false;
};
#endif
//
// XboxOne only utility code/macros
//
#if PLATFORM_XBOXONE
ID3D12Device* GetUE4DxDevice();
#endif
template<typename F>
inline void ExecuteRHICommand(F&& Functor)
{
FRHICommandList& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList();
if (RHICmdList.Bypass())
{
Functor();
}
else
{
FRHICOMMAND_MACRO(FLocalRHICommand)
{
F Functor;
FLocalRHICommand(F InFunctor)
: Functor(MoveTemp(InFunctor))
{}
void Execute(FRHICommandListBase& CmdList)
{
Functor();
}
};
new (RHICmdList.AllocCommand<FLocalRHICommand>()) FLocalRHICommand(Functor);
}
}
// #RVF : Remove this once the code is production ready.
struct FMemoryCheckpoint
{
FString Name;
float UsedPhysicalMB;
float DeltaMB;
float AccumulatedMB;
};
extern TArray<FMemoryCheckpoint> gMemoryCheckpoints;
uint64 MemoryCheckpoint(const FString& Name);
void LogMemoryCheckpoints(const FString& Name);