0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 21:13:04 +02:00
obs-studio/plugins/obs-qsv11/obs-qsv-test/obs-qsv-test.cpp
Jim eaf243bca7 obs-qsv11: Add startup process to test QSV support
This simplifies encoder initialization and prevents it from requiring
any sort of unnecessary Direct3D or encoder initiazation tests while OBS
is actually running.
2022-11-21 19:08:02 -08:00

127 lines
3.0 KiB
C++

#include "mfxstructures.h"
#include "mfxadapter.h"
#include "mfxvideo++.h"
#include "../common_utils.h"
#include <util/windows/ComPtr.hpp>
#include <dxgi.h>
#include <d3d11.h>
#include <d3d11_1.h>
#include <string>
#include <map>
#ifdef _MSC_VER
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 1;
extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#endif
#define INTEL_VENDOR_ID 0x8086
struct adapter_caps {
bool is_intel = false;
bool is_dgpu = false;
};
static std::map<uint32_t, adapter_caps> adapter_info;
static bool has_encoder(mfxIMPL impl, mfxU32 codec_id)
{
MFXVideoSession session;
mfxInitParam init_param = {};
init_param.Implementation = impl;
init_param.Version.Major = 1;
init_param.Version.Minor = 0;
mfxStatus sts = session.InitEx(init_param);
mfxVideoParam video_param;
memset(&video_param, 0, sizeof(video_param));
video_param.mfx.CodecId = codec_id;
video_param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
video_param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
video_param.mfx.FrameInfo.Width = MSDK_ALIGN16(1280);
video_param.mfx.FrameInfo.Height = MSDK_ALIGN16(720);
sts = MFXVideoENCODE_Query(session, &video_param, &video_param);
session.Close();
return sts == MFX_ERR_NONE;
}
static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
{
HRESULT hr;
ComPtr<IDXGIAdapter> adapter;
hr = factory->EnumAdapters(adapter_idx, &adapter);
if (FAILED(hr))
return false;
adapter_caps &caps = adapter_info[adapter_idx];
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
if (desc.VendorId != INTEL_VENDOR_ID)
return true;
bool dgpu = desc.DedicatedVideoMemory > 512 * 1024 * 1024;
mfxIMPL impl = dgpu ? MFX_IMPL_HARDWARE : MFX_IMPL_HARDWARE2;
caps.is_intel = true;
caps.is_dgpu = dgpu;
return true;
}
DWORD WINAPI TimeoutThread(LPVOID param)
{
HANDLE hMainThread = (HANDLE)param;
DWORD ret = WaitForSingleObject(hMainThread, 5000);
if (ret == WAIT_TIMEOUT)
TerminateProcess(GetCurrentProcess(), STATUS_TIMEOUT);
CloseHandle(hMainThread);
return 0;
}
int main(void)
try {
ComPtr<IDXGIFactory> factory;
HRESULT hr;
HANDLE hMainThread;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &hMainThread, 0, FALSE,
DUPLICATE_SAME_ACCESS);
DWORD threadId;
HANDLE hThread;
hThread =
CreateThread(NULL, 0, TimeoutThread, hMainThread, 0, &threadId);
CloseHandle(hThread);
/* --------------------------------------------------------- */
/* query qsv support */
hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), (void **)&factory);
if (FAILED(hr))
throw "CreateDXGIFactory1 failed";
uint32_t idx = 0;
while (get_adapter_caps(factory, idx++))
;
for (auto &[idx, caps] : adapter_info) {
printf("[%u]\n", idx);
printf("is_intel=%s\n", caps.is_intel ? "true" : "false");
printf("is_dgpu=%s\n", caps.is_dgpu ? "true" : "false");
}
return 0;
} catch (const char *text) {
printf("[error]\nstring=%s\n", text);
return 0;
}