hwapi/d3d11: Implement new HWAPI code
This commit is contained in:
+25
-18
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user