hwapi/d3d11: Implement new HWAPI code

This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-10-03 19:19:20 +02:00
parent 650b397ced
commit 4836f9dda6
2 changed files with 35 additions and 23 deletions
+25 -18
View File
@@ -157,20 +157,31 @@ AVBufferRef* obsffmpeg::hwapi::d3d11_instance::create_device_context()
return dctx_ref; return dctx_ref;
} }
std::shared_ptr<AVFrame> obsffmpeg::hwapi::d3d11_instance::avframe_from_obs(AVBufferRef* frames, uint32_t handle, std::shared_ptr<AVFrame> obsffmpeg::hwapi::d3d11_instance::allocate_frame(AVBufferRef* frames)
uint64_t lock_key, uint64_t* next_lock_key) {
auto frame = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame* frame) {
av_frame_unref(frame);
av_frame_free(&frame);
});
if (av_hwframe_get_buffer(frames, frame.get(), 0) < 0) {
throw std::runtime_error("Failed to create AVFrame.");
}
return frame;
}
void obsffmpeg::hwapi::d3d11_instance::copy_from_obs(AVBufferRef* frames, uint32_t handle, uint64_t lock_key,
uint64_t* next_lock_key, std::shared_ptr<AVFrame> frame)
{ {
AVFrame* frame = av_frame_alloc();
ATL::CComPtr<IDXGIKeyedMutex> mutex; ATL::CComPtr<IDXGIKeyedMutex> mutex;
ATL::CComPtr<ID3D11Texture2D> input; ATL::CComPtr<ID3D11Texture2D> input;
D3D11_TEXTURE2D_DESC input_desc;
D3D11_TEXTURE2D_DESC output_desc;
//ATL::CComPtr<ID3D11Texture2D> output;
if (FAILED(_device->OpenSharedResource(reinterpret_cast<HANDLE>(static_cast<uintptr_t>(handle)), if (FAILED(_device->OpenSharedResource(reinterpret_cast<HANDLE>(static_cast<uintptr_t>(handle)),
__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&input)))) { __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&input)))) {
throw std::runtime_error("Failed to open shared texture resource."); throw std::runtime_error("Failed to open shared texture resource.");
} }
if (FAILED(input->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast<void**>(&mutex)))) { if (FAILED(input->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast<void**>(&mutex)))) {
throw std::runtime_error("Failed to retrieve mutex for texture resource."); throw std::runtime_error("Failed to retrieve mutex for texture resource.");
} }
@@ -182,13 +193,6 @@ std::shared_ptr<AVFrame> obsffmpeg::hwapi::d3d11_instance::avframe_from_obs(AVBu
// Set some parameters on the input texture, and get its description. // Set some parameters on the input texture, and get its description.
UINT evict = input->GetEvictionPriority(); UINT evict = input->GetEvictionPriority();
input->SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM); input->SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM);
input->GetDesc(&input_desc);
if (av_hwframe_get_buffer(frames, frame, 0) < 0) {
throw std::runtime_error("Failed to create AVFrame.");
}
reinterpret_cast<ID3D11Texture2D*>(frame->data[0])->GetDesc(&output_desc);
// Clone the content of the input texture. // Clone the content of the input texture.
_context->CopyResource(reinterpret_cast<ID3D11Texture2D*>(frame->data[0]), input); _context->CopyResource(reinterpret_cast<ID3D11Texture2D*>(frame->data[0]), input);
@@ -202,9 +206,12 @@ std::shared_ptr<AVFrame> obsffmpeg::hwapi::d3d11_instance::avframe_from_obs(AVBu
// TODO: Determine if this is necessary. // TODO: Determine if this is necessary.
mutex->ReleaseSync(*next_lock_key); mutex->ReleaseSync(*next_lock_key);
}
return std::shared_ptr<AVFrame>(frame, [](AVFrame* frame) {
av_frame_unref(frame); std::shared_ptr<AVFrame> obsffmpeg::hwapi::d3d11_instance::avframe_from_obs(AVBufferRef* frames, uint32_t handle,
av_frame_free(&frame); uint64_t lock_key, uint64_t* next_lock_key)
}); {
auto frame = this->allocate_frame(frames);
this->copy_from_obs(frames, handle, lock_key, next_lock_key, frame);
return frame;
} }
+8 -3
View File
@@ -21,13 +21,13 @@
#include <atlutil.h> #include <atlutil.h>
#include <d3d11.h> #include <d3d11.h>
#include <d3d11_1.h>
#include <dxgi.h> #include <dxgi.h>
#include <windows.h>
#include "base.hpp" #include "base.hpp"
namespace obsffmpeg { namespace obsffmpeg {
namespace hwapi { namespace hwapi {
class d3d11 : public base { class d3d11 : public ::obsffmpeg::hwapi::base {
typedef HRESULT(__stdcall* CreateDXGIFactory_t)(REFIID, void**); typedef HRESULT(__stdcall* CreateDXGIFactory_t)(REFIID, void**);
typedef HRESULT(__stdcall* CreateDXGIFactory1_t)(REFIID, void**); typedef HRESULT(__stdcall* CreateDXGIFactory1_t)(REFIID, void**);
typedef HRESULT(__stdcall* D3D11CreateDevice_t)(_In_opt_ IDXGIAdapter*, D3D_DRIVER_TYPE, typedef HRESULT(__stdcall* D3D11CreateDevice_t)(_In_opt_ IDXGIAdapter*, D3D_DRIVER_TYPE,
@@ -55,7 +55,7 @@ namespace obsffmpeg {
create(obsffmpeg::hwapi::device target) override; create(obsffmpeg::hwapi::device target) override;
}; };
class d3d11_instance : public instance { class d3d11_instance : public ::obsffmpeg::hwapi::instance {
ATL::CComPtr<ID3D11Device> _device; ATL::CComPtr<ID3D11Device> _device;
ATL::CComPtr<ID3D11DeviceContext> _context; ATL::CComPtr<ID3D11DeviceContext> _context;
@@ -65,6 +65,11 @@ namespace obsffmpeg {
virtual AVBufferRef* create_device_context() override; virtual AVBufferRef* create_device_context() override;
virtual std::shared_ptr<AVFrame> allocate_frame(AVBufferRef* frames) override;
virtual void copy_from_obs(AVBufferRef* frames, uint32_t handle, uint64_t lock_key,
uint64_t* next_lock_key, std::shared_ptr<AVFrame> frame) override;
virtual std::shared_ptr<AVFrame> avframe_from_obs(AVBufferRef* frames, uint32_t handle, virtual std::shared_ptr<AVFrame> avframe_from_obs(AVBufferRef* frames, uint32_t handle,
uint64_t lock_key, uint64_t lock_key,
uint64_t* next_lock_key) override; uint64_t* next_lock_key) override;