Skip to content
This repository has been archived by the owner on Jul 30, 2022. It is now read-only.

Commit

Permalink
up version to 4.27, fix deadlock in UE5
Browse files Browse the repository at this point in the history
  • Loading branch information
wongfei committed Apr 14, 2022
1 parent ee8bb6d commit d904e08
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 12 deletions.
2 changes: 1 addition & 1 deletion MediaPipeDemo.uproject
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"FileVersion": 3,
"EngineAssociation": "4.26",
"EngineAssociation": "4.27",
"Category": "",
"Description": "",
"Modules": [
Expand Down
2 changes: 1 addition & 1 deletion Plugins/MediaPipe/MediaPipe.uplugin
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 1,
"EngineVersion": "4.26.0",
"EngineVersion": "4.27.0",
"VersionName": "0.1",
"FriendlyName": "MediaPipe",
"Description": "Unreal MediaPipe integration",
Expand Down
29 changes: 20 additions & 9 deletions Plugins/MediaPipe/Source/MediaPipe/Private/DynamicTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,27 @@ void FDynamicTexture::RenderCmd_UpdateTexture(FPixelBuffer* InBuffer)
{
Resize(InBuffer->Width, InBuffer->Height, InBuffer->Format);

auto Tex = GetTextureObject();
if (Tex && Tex->Resource)
auto* Tex = GetTextureObject();
if (Tex)
{
RHIUpdateTexture2D(
Tex->Resource->GetTexture2DRHI(),
0,
FUpdateTextureRegion2D(0, 0, 0, 0, InBuffer->Width, InBuffer->Height),
InBuffer->Pitch,
(const uint8*)InBuffer->Data
);
#if (ENGINE_MAJOR_VERSION == 5)
#define TMP_TEX_RES Tex->GetResource()
#else
#define TMP_TEX_RES Tex->Resource
#endif

if (TMP_TEX_RES)
{
RHIUpdateTexture2D(
TMP_TEX_RES->GetTexture2DRHI(),
0,
FUpdateTextureRegion2D(0, 0, 0, 0, InBuffer->Width, InBuffer->Height),
InBuffer->Pitch,
(const uint8*)InBuffer->Data
);
}

#undef TMP_TEX_RES
}

if (FuncBufferSubmitted)
Expand Down
129 changes: 129 additions & 0 deletions Plugins/MediaPipe/Source/MediaPipe/Private/Hakz.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#pragma once

#include <algorithm>
#include <vector>
#include <memory>

inline uint8_t CkParseHex(uint8_t Val)
{
if (Val >= '0' && Val <= '9') return (Val - '0');
if (Val >= 'a' && Val <= 'f') return (Val - 'a') + 10;
if (Val >= 'A' && Val <= 'F') return (Val - 'A') + 10;
return 0;
}

inline uint8_t CkParseByte(const char* Str)
{
uint8_t hi = CkParseHex((uint8_t)Str[0]);
uint8_t lo = CkParseHex((uint8_t)Str[1]);
return ((hi << 4) | lo);
}

inline std::vector<uint8_t> CkParseByteArray(const char* Str)
{
std::vector<uint8_t> Result;
if (Str)
{
const size_t Len = strlen(Str);
if (Len)
{
std::vector<uint8_t> Tmp;
Tmp.reserve(Len);

for (size_t i = 0; i < Len; i++)
{
if (isalnum(Str[i]))
Tmp.push_back(Str[i]);
}

const size_t NumBytes = Tmp.size() / 2;
if (NumBytes)
{
Result.resize(NumBytes);
for (size_t i = 0; i < NumBytes; i++)
{
uint8_t hi = CkParseHex(Tmp[i*2]);
uint8_t lo = CkParseHex(Tmp[(i*2)+1]);
Result[i] = ((hi << 4) | lo);
}
}
}
}
return std::move(Result);
}

template<const uint8_t Wildcard>
struct CkWildcard
{
inline bool operator()(const uint8_t &a, const uint8_t &b) const
{
return (a == b || b == Wildcard);
}
};

typedef CkWildcard<0xCC> CkWildcardCC; // Interrupt Type 3
typedef CkWildcard<0xCE> CkWildcardCE; // Interrupt if Overflow

#define CK_PAGE_EXECUTE_RWC (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)

template<typename TCompare>
inline DWORD CkFindPatternIntern(HANDLE Process, const std::vector<uint8_t>& Pattern, size_t Limit, std::vector<uint8_t*>& Result)
{
if (!Process)
Process = GetCurrentProcess();

SYSTEM_INFO SysInfo;
ZeroMemory(&SysInfo, sizeof(SysInfo));
GetSystemInfo(&SysInfo);

uint8_t* MaxAddress = (uint8_t*)SysInfo.lpMaximumApplicationAddress;
uint8_t* Ptr = (uint8_t*)SysInfo.lpMinimumApplicationAddress;

TCompare Compare;

while (Ptr < MaxAddress)
{
MEMORY_BASIC_INFORMATION MemInfo;
if (VirtualQueryEx(Process, Ptr, &MemInfo, sizeof(MemInfo)) != sizeof(MemInfo))
{
return GetLastError();
}

if ((MemInfo.Protect & CK_PAGE_EXECUTE_RWC) && ((MemInfo.Protect & PAGE_GUARD) == 0) && ((MemInfo.Protect & PAGE_NOACCESS) == 0))
{
uint8_t* RegionPos = (uint8_t*)MemInfo.BaseAddress;
uint8_t* RegionEnd = RegionPos + MemInfo.RegionSize;

while ((RegionPos = std::search(RegionPos, RegionEnd, Pattern.begin(), Pattern.end(), Compare)) != RegionEnd)
{
Result.push_back(RegionPos);

if (Limit && Result.size() >= Limit)
return 0;

RegionPos++;
}
}

Ptr += MemInfo.RegionSize;
}

return 0;
}

inline DWORD CkProtectWriteMemory(HANDLE Process, const std::vector<uint8_t>& Data, PVOID Addr, SIZE_T Offset)
{
if (!Process)
Process = GetCurrentProcess();

DWORD Prot = 0;
if (!VirtualProtectEx(Process, Addr, Data.size(), PAGE_EXECUTE_READWRITE, &Prot))
return GetLastError();

memcpy((PVOID)((UINT64)Addr + (UINT64)Offset), &Data[0], Data.size());

DWORD Prot2 = 0;
VirtualProtectEx(Process, Addr, Data.size(), Prot, &Prot2);

return 0;
}
33 changes: 33 additions & 0 deletions Plugins/MediaPipe/Source/MediaPipe/Private/MediaPipeModule.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
#include "MediaPipeModule.h"
#include "MediaPipeShared.h"
#include "Misc/Paths.h"
#include "Runtime/Launch/Resources/Version.h"

#if PLATFORM_WINDOWS
#include "Windows/WindowsPlatformProcess.h"
#include "Windows/AllowWindowsPlatformTypes.h"
#include <windows.h>
#include "Windows/HideWindowsPlatformTypes.h"
#include "Hakz.h"
#endif

DEFINE_LOG_CATEGORY(LogMediaPipe);
Expand All @@ -29,6 +34,28 @@ class UmpLog : public IUmpLog

static UmpLog UmpLogger;

// fix deadlock in FModuleTrace::OnDllLoaded (hello EPIC?)
void FixDeadlock()
{
#if (ENGINE_MAJOR_VERSION == 5)

auto Process = GetCurrentProcess();
auto Pattern = CkParseByteArray("48 89 5C 24 08 55 56 57 41 54 41 55 41 56 41 57 48 8D 6C 24 D9 48 81 EC B0 00 00 00 48 8B 05 B5 C6 B5 00");

std::vector<uint8_t*> Loc;
auto Status = CkFindPatternIntern<CkWildcardCC>(Process, Pattern, 0, Loc);

if (Status == 0 && Loc.size() == 1)
{
PLUGIN_LOG_INFO(TEXT("FModuleTrace::OnDllLoaded -> %p"), Loc[0]);
auto Fix = CkParseByteArray("C3");
Status = CkProtectWriteMemory(GetCurrentProcess(), Fix, Loc[0], 0);
PLUGIN_LOG_INFO(TEXT("WriteMemory -> %u"), (unsigned int)Status);
}

#endif
}

void FMediaPipeModule::StartupModule()
{
PLUGIN_TRACE;
Expand All @@ -43,6 +70,8 @@ void FMediaPipeModule::StartupModule()
#define UMP_LIB_EXT ".so"
#endif

FixDeadlock();

auto Plugin = IPluginManager::Get().FindPlugin(TEXT(PLUGIN_NAME));
auto PluginBaseDir = FPaths::ConvertRelativePathToFull(Plugin->GetBaseDir());
PLUGIN_LOG_INFO(TEXT("PluginBaseDir: %s"), *PluginBaseDir);
Expand All @@ -59,7 +88,11 @@ void FMediaPipeModule::StartupModule()
PLUGIN_LOG_INFO(TEXT("DataDir: %s"), *DataDir);

FString LibPath = FPaths::Combine(*BinariesDir, TEXT(UMP_LIB_NAME) TEXT(UMP_LIB_EXT));

PLUGIN_LOG_INFO(TEXT("GetDllHandle: %s"), *LibPath);
LibUmp = FPlatformProcess::GetDllHandle(*LibPath);
PLUGIN_LOG_INFO(TEXT("-> %p"), LibUmp);

if (!LibUmp)
{
PLUGIN_LOG(Error, TEXT("Unable to load: %s"), *LibPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ inline FVector ShuffleAxes(const FVector& V, int X, int Y, int Z)
constexpr int Id[] = {0, 1, 2, 0, 1, 2};
constexpr float Sign[] = {1, 1, 1, -1, -1, -1};

const float* Vptr = &V.X;
const auto* Vptr = &V.X;
FVector Out;
Out.X = Vptr[Id[X]] * Sign[X];
Out.Y = Vptr[Id[Y]] * Sign[Y];
Expand Down

0 comments on commit d904e08

Please sign in to comment.