Port twistero's DivaMovie from testing

This commit is contained in:
nastys
2019-10-10 00:49:15 +02:00
parent 2e6f3b256c
commit 42e5d97d72
5 changed files with 237 additions and 10 deletions
@@ -85,6 +85,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
<ClInclude Include="PluginConfigApi.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
@@ -5,5 +5,6 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
<ClInclude Include="PluginConfigApi.h" />
</ItemGroup>
</Project>
@@ -0,0 +1,168 @@
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <vector>
// resolution class to store and sort the width and height easily
class resolution
{
public:
unsigned int width;
unsigned int height;
resolution()
{
width = 0;
height = 0;
}
resolution(unsigned int width, unsigned int height)
{
resolution::width = width;
resolution::height = height;
}
bool operator ==(const resolution &res2)
{
return width == res2.width && height == res2.height;
}
// in comparisons width takes priority because it's usually displayed first
bool operator <(const resolution &res2)
{
if (width == res2.width)
return height < res2.height;
else
return width < res2.width;
}
bool operator >(const resolution &res2)
{
if (width == res2.width)
return height > res2.height;
else
return width > res2.width;
}
};
namespace PluginConfig
{
#pragma pack(push, 1)
enum ConfigType {
CONFIG_BOOLEAN,
CONFIG_NUMERIC,
CONFIG_STRING,
CONFIG_DROPDOWN_INDEX,
CONFIG_DROPDOWN_TEXT,
CONFIG_DROPDOWN_NUMBER,
CONFIG_RESOLUTION,
CONFIG_GROUP_START,
CONFIG_GROUP_END,
CONFIG_BUTTON,
CONFIG_SPACER
};
struct PluginConfigBooleanData {
LPCWSTR iniVarName;
LPCWSTR iniSectionName;
LPCWSTR iniFilePath;
LPCWSTR friendlyName;
LPCWSTR description;
bool defaultVal;
bool saveAsString;
};
struct PluginConfigNumericData {
LPCWSTR iniVarName;
LPCWSTR iniSectionName;
LPCWSTR iniFilePath;
LPCWSTR friendlyName;
LPCWSTR description;
int defaultVal;
int minVal;
int maxVal;
};
struct PluginConfigStringData {
LPCWSTR iniVarName;
LPCWSTR iniSectionName;
LPCWSTR iniFilePath;
LPCWSTR friendlyName;
LPCWSTR description;
LPCWSTR defaultVal;
bool useUtf8;
};
struct PluginConfigDropdownIndexData {
LPCWSTR iniVarName;
LPCWSTR iniSectionName;
LPCWSTR iniFilePath;
LPCWSTR friendlyName;
LPCWSTR description;
int defaultVal;
std::vector<LPCWSTR> valueStrings;
};
struct PluginConfigDropdownTextData {
LPCWSTR iniVarName;
LPCWSTR iniSectionName;
LPCWSTR iniFilePath;
LPCWSTR friendlyName;
LPCWSTR description;
LPCWSTR defaultVal;
std::vector<LPCWSTR> valueStrings;
bool editable;
bool useUtf8;
};
struct PluginConfigDropdownNumberData {
LPCWSTR iniVarName;
LPCWSTR iniSectionName;
LPCWSTR iniFilePath;
LPCWSTR friendlyName;
LPCWSTR description;
int defaultVal;
std::vector<int> valueInts;
bool editable;
};
struct PluginConfigResolutionData {
LPCWSTR iniVarName;
LPCWSTR iniVarName2;
LPCWSTR iniSectionName;
LPCWSTR iniFilePath;
LPCWSTR friendlyName;
LPCWSTR description;
resolution defaultVal;
std::vector<resolution> valueResolutions;
bool editable;
};
struct PluginConfigGroupData
{
LPCWSTR name;
int height;
};
struct PluginConfigButtonData {
LPCWSTR friendlyName;
LPCWSTR description;
void(*func)();
};
struct PluginConfigSpacerData {
int height;
};
struct PluginConfigOption
{
ConfigType cfgType;
void* data;
};
struct PluginConfigArray
{
int len;
PluginConfigOption* options;
};
#pragma pack(pop)
}
@@ -1,4 +1,5 @@
#include "framework.h"
#include "PluginConfigApi.h"
#include <evr.h>
@@ -10,6 +11,8 @@
#include <mferror.h>
#include <mftransform.h>
bool forceSoftwareDecoding;
IDirect3DDeviceManager9* deviceManager;
IMFTransform* mfTransform;
@@ -124,14 +127,28 @@ end:
VTABLE_HOOK(HRESULT, IMFTransform, ProcessMessage, MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam)
{
HRESULT result = originalProcessMessage(This, eMessage, ulParam);
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == MF_E_UNSUPPORTED_D3D_TYPE)
if (forceSoftwareDecoding)
{
result = originalProcessMessage(This, eMessage, NULL);
if (SUCCEEDED(result))
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER) {
PRINT("[DivaMovie] Force Software Decoding enabled\n");
INSTALL_VTABLE_HOOK(This, ProcessOutput, 25);
return S_OK;
}
return originalProcessMessage(This, eMessage, ulParam);
}
return result;
else
{
HRESULT result = originalProcessMessage(This, eMessage, ulParam);
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == MF_E_UNSUPPORTED_D3D_TYPE)
{
PRINT("[DivaMovie] This system does not support DXVA hardware decoding\n");
result = originalProcessMessage(This, eMessage, NULL);
if (SUCCEEDED(result))
INSTALL_VTABLE_HOOK(This, ProcessOutput, 25);
}
return result;
}
}
HOOK(void*, IMFTransformInitializer, 0x140420B90, void* a1, void* a2, IMFTransform** transform)
@@ -158,13 +175,37 @@ HOOK(HRESULT, DXVA2CreateDirect3DDeviceManager, PROC_ADDRESS("dxva2.dll", "DXVA2
return result;
}
void loadConfig() {
forceSoftwareDecoding = GetPrivateProfileIntW(L"general", L"force_software_decoding", 0, CONFIG_FILE) > 0 ? true : false;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
loadConfig();
INSTALL_HOOK(DXVA2CreateDirect3DDeviceManager);
INSTALL_HOOK(IMFTransformInitializer);
}
return TRUE;
}
PluginConfig::PluginConfigOption config[] = {
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"force_software_decoding", L"general", CONFIG_FILE, L"Force Software Decoding", L"Use software decoding even on systems that support DXVA hardware decoding.", false } },
};
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
{
return L"DivaMovie";
}
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
{
return L"DivaMovie Plugin by Skyth\n\nDivaMovie enables movies on systems that does not support DXVA hardware decoding.";
}
extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void)
{
return PluginConfig::PluginConfigArray{ _countof(config), config };
}
@@ -5,12 +5,28 @@
#include <cstdio>
#include <windows.h>
#include <detours.h>
#include <string>
#if _DEBUG
std::wstring ExePath() {
WCHAR buffer[MAX_PATH];
GetModuleFileNameW(NULL, buffer, MAX_PATH);
return std::wstring(buffer);
}
std::wstring DirPath() {
std::wstring exepath = ExePath();
std::wstring::size_type pos = exepath.find_last_of(L"\\/");
return exepath.substr(0, pos);
}
std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\DivaMovie.ini";
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
//#if _DEBUG
#define PRINT(value, ...) printf(value, __VA_ARGS__);
#else
#define PRINT(value, ...)
#endif
//#else
//#define PRINT(value, ...)
//#endif
#define PROC_ADDRESS(libraryName, procName) \
GetProcAddress(LoadLibrary(TEXT(libraryName)), procName)
@@ -59,4 +75,4 @@
else \
{ \
PRINT("[DivaMovie] %s succeeded\n", #function); \
}
}