obs-amf-test.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "../external/AMF/include/core/Factory.h"
  2. #include "../external/AMF/include/core/Trace.h"
  3. #include "../external/AMF/include/components/VideoEncoderVCE.h"
  4. #include "../external/AMF/include/components/VideoEncoderHEVC.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. using namespace amf;
  12. #ifdef _MSC_VER
  13. extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
  14. #endif
  15. #define AMD_VENDOR_ID 0x1002
  16. struct adapter_caps {
  17. bool is_amd = false;
  18. bool supports_avc = false;
  19. bool supports_hevc = false;
  20. };
  21. static AMFFactory *amf_factory = nullptr;
  22. static std::map<uint32_t, adapter_caps> adapter_info;
  23. static bool has_encoder(AMFContextPtr &amf_context, const wchar_t *encoder_name)
  24. {
  25. AMFComponentPtr encoder;
  26. AMF_RESULT res = amf_factory->CreateComponent(amf_context, encoder_name,
  27. &encoder);
  28. return res == AMF_OK;
  29. }
  30. static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
  31. {
  32. AMF_RESULT res;
  33. HRESULT hr;
  34. ComPtr<IDXGIAdapter> adapter;
  35. hr = factory->EnumAdapters(adapter_idx, &adapter);
  36. if (FAILED(hr))
  37. return false;
  38. adapter_caps &caps = adapter_info[adapter_idx];
  39. DXGI_ADAPTER_DESC desc;
  40. adapter->GetDesc(&desc);
  41. if (desc.VendorId != AMD_VENDOR_ID)
  42. return true;
  43. caps.is_amd = true;
  44. ComPtr<IDXGIOutput> output;
  45. hr = adapter->EnumOutputs(0, &output);
  46. if (FAILED(hr))
  47. return true;
  48. ComPtr<ID3D11Device> device;
  49. ComPtr<ID3D11DeviceContext> context;
  50. hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0,
  51. nullptr, 0, D3D11_SDK_VERSION, &device, nullptr,
  52. &context);
  53. if (FAILED(hr))
  54. return true;
  55. AMFContextPtr amf_context;
  56. res = amf_factory->CreateContext(&amf_context);
  57. if (res != AMF_OK)
  58. return true;
  59. res = amf_context->InitDX11(device);
  60. if (res != AMF_OK)
  61. return true;
  62. caps.supports_avc = has_encoder(amf_context, AMFVideoEncoderVCE_AVC);
  63. caps.supports_hevc = has_encoder(amf_context, AMFVideoEncoder_HEVC);
  64. return true;
  65. }
  66. int main(void)
  67. try {
  68. ComPtr<IDXGIFactory> factory;
  69. AMF_RESULT res;
  70. HRESULT hr;
  71. /* --------------------------------------------------------- */
  72. /* try initializing amf, I guess */
  73. HMODULE amf_module = LoadLibraryW(AMF_DLL_NAME);
  74. if (!amf_module)
  75. throw "Failed to load AMF lib";
  76. auto init =
  77. (AMFInit_Fn)GetProcAddress(amf_module, AMF_INIT_FUNCTION_NAME);
  78. if (!init)
  79. throw "Failed to get init func";
  80. res = init(AMF_FULL_VERSION, &amf_factory);
  81. if (res != AMF_OK)
  82. throw "AMFInit failed";
  83. hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), (void **)&factory);
  84. if (FAILED(hr))
  85. throw "CreateDXGIFactory1 failed";
  86. uint32_t idx = 0;
  87. while (get_adapter_caps(factory, idx++))
  88. ;
  89. for (auto &[idx, caps] : adapter_info) {
  90. printf("[%d]\n", idx);
  91. printf("is_amd=%s\n", caps.is_amd ? "true" : "false");
  92. printf("supports_avc=%s\n",
  93. caps.supports_avc ? "true" : "false");
  94. printf("supports_hevc=%s\n",
  95. caps.supports_hevc ? "true" : "false");
  96. }
  97. return 0;
  98. } catch (const char *text) {
  99. printf("[error]\nstring=%s\n", text);
  100. return 0;
  101. }