obs-qsv-test.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "mfxstructures.h"
  2. #include "mfxadapter.h"
  3. #include "mfxvideo++.h"
  4. #include "../common_utils.h"
  5. #include <util/windows/ComPtr.hpp>
  6. #include <dxgi.h>
  7. #include <d3d11.h>
  8. #include <d3d11_1.h>
  9. #include <string>
  10. #include <map>
  11. #ifdef _MSC_VER
  12. extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 1;
  13. extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
  14. #endif
  15. #define INTEL_VENDOR_ID 0x8086
  16. struct adapter_caps {
  17. bool is_intel = false;
  18. bool is_dgpu = false;
  19. bool supports_av1 = false;
  20. bool supports_hevc = false;
  21. };
  22. static std::map<uint32_t, adapter_caps> adapter_info;
  23. static bool has_encoder(mfxIMPL impl, mfxU32 codec_id)
  24. {
  25. MFXVideoSession session;
  26. mfxInitParam init_param = {};
  27. init_param.Implementation = impl;
  28. init_param.Version.Major = 1;
  29. init_param.Version.Minor = 0;
  30. mfxStatus sts = session.InitEx(init_param);
  31. mfxVideoParam video_param;
  32. memset(&video_param, 0, sizeof(video_param));
  33. video_param.mfx.CodecId = codec_id;
  34. video_param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
  35. video_param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
  36. video_param.mfx.FrameInfo.Width = MSDK_ALIGN16(1280);
  37. video_param.mfx.FrameInfo.Height = MSDK_ALIGN16(720);
  38. sts = MFXVideoENCODE_Query(session, &video_param, &video_param);
  39. session.Close();
  40. return sts == MFX_ERR_NONE;
  41. }
  42. static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
  43. {
  44. HRESULT hr;
  45. ComPtr<IDXGIAdapter> adapter;
  46. hr = factory->EnumAdapters(adapter_idx, &adapter);
  47. if (FAILED(hr))
  48. return false;
  49. adapter_caps &caps = adapter_info[adapter_idx];
  50. DXGI_ADAPTER_DESC desc;
  51. adapter->GetDesc(&desc);
  52. if (desc.VendorId != INTEL_VENDOR_ID)
  53. return true;
  54. bool dgpu = desc.DedicatedVideoMemory > 512 * 1024 * 1024;
  55. mfxIMPL impl = dgpu ? MFX_IMPL_HARDWARE : MFX_IMPL_HARDWARE2;
  56. caps.is_intel = true;
  57. caps.is_dgpu = dgpu;
  58. caps.supports_av1 = has_encoder(impl, MFX_CODEC_AV1);
  59. #if ENABLE_HEVC
  60. caps.supports_hevc = has_encoder(impl, MFX_CODEC_HEVC);
  61. #endif
  62. return true;
  63. }
  64. DWORD WINAPI TimeoutThread(LPVOID param)
  65. {
  66. HANDLE hMainThread = (HANDLE)param;
  67. DWORD ret = WaitForSingleObject(hMainThread, 8000);
  68. if (ret == WAIT_TIMEOUT)
  69. TerminateProcess(GetCurrentProcess(), STATUS_TIMEOUT);
  70. CloseHandle(hMainThread);
  71. return 0;
  72. }
  73. int main(void)
  74. try {
  75. ComPtr<IDXGIFactory> factory;
  76. HRESULT hr;
  77. HANDLE hMainThread;
  78. DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
  79. GetCurrentProcess(), &hMainThread, 0, FALSE,
  80. DUPLICATE_SAME_ACCESS);
  81. DWORD threadId;
  82. HANDLE hThread;
  83. hThread =
  84. CreateThread(NULL, 0, TimeoutThread, hMainThread, 0, &threadId);
  85. CloseHandle(hThread);
  86. /* --------------------------------------------------------- */
  87. /* query qsv support */
  88. hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), (void **)&factory);
  89. if (FAILED(hr))
  90. throw "CreateDXGIFactory1 failed";
  91. uint32_t idx = 0;
  92. while (get_adapter_caps(factory, idx++))
  93. ;
  94. for (auto &[idx, caps] : adapter_info) {
  95. printf("[%u]\n", idx);
  96. printf("is_intel=%s\n", caps.is_intel ? "true" : "false");
  97. printf("is_dgpu=%s\n", caps.is_dgpu ? "true" : "false");
  98. printf("supports_av1=%s\n",
  99. caps.supports_av1 ? "true" : "false");
  100. printf("supports_hevc=%s\n",
  101. caps.supports_hevc ? "true" : "false");
  102. }
  103. return 0;
  104. } catch (const char *text) {
  105. printf("[error]\nstring=%s\n", text);
  106. return 0;
  107. }