ffmpeg/hwapi/d3d11: Only Release() the immediate ID3D11DeviceContext once

While this had no actual effect due to the immediate ID3D11DeviceContext being tied to the ID3D11Device itself, it shouldn't have occured at all. With this there should now only be a single Release() call for every AddRef() call.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2022-09-23 02:56:04 +02:00
parent 0b23d28164
commit 4236c28c58
2 changed files with 26 additions and 24 deletions

View File

@ -102,10 +102,9 @@ std::list<device> d3d11::enumerate_adapters()
std::shared_ptr<instance> d3d11::create(const device& target)
{
std::shared_ptr<d3d11_instance> inst;
ATL::CComPtr<ID3D11Device> device;
ATL::CComPtr<ID3D11DeviceContext> context;
IDXGIAdapter1* adapter = nullptr;
std::shared_ptr<d3d11_instance> inst;
ATL::CComPtr<ID3D11Device> device;
IDXGIAdapter1* adapter = nullptr;
// Find the correct "Adapter" (device).
IDXGIAdapter1* dxgi_adapter = nullptr;
@ -125,12 +124,11 @@ std::shared_ptr<instance> d3d11::create(const device& target)
D3D_FEATURE_LEVEL_11_1};
if (FAILED(_D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, NULL, device_flags, feature_levels.data(),
static_cast<UINT>(feature_levels.size()), D3D11_SDK_VERSION, &device, NULL,
&context))) {
static_cast<UINT>(feature_levels.size()), D3D11_SDK_VERSION, &device, NULL, NULL))) {
throw std::runtime_error("Failed to create D3D11 device for target.");
}
return std::make_shared<d3d11_instance>(device, context);
return std::make_shared<d3d11_instance>(device);
}
std::shared_ptr<instance> d3d11::create_from_obs()
@ -143,21 +141,24 @@ std::shared_ptr<instance> d3d11::create_from_obs()
ATL::CComPtr<ID3D11Device> device =
ATL::CComPtr<ID3D11Device>(reinterpret_cast<ID3D11Device*>(gs_get_device_obj()));
ATL::CComPtr<ID3D11DeviceContext> context;
device->GetImmediateContext(&context);
return std::make_shared<d3d11_instance>(device, context);
return std::make_shared<d3d11_instance>(device);
}
struct D3D11AVFrame {
ATL::CComPtr<ID3D11Texture2D> handle;
};
d3d11_instance::d3d11_instance(ATL::CComPtr<ID3D11Device> device, ATL::CComPtr<ID3D11DeviceContext> context)
: _device(device), _context(context)
{}
d3d11_instance::d3d11_instance(ATL::CComPtr<ID3D11Device> device) : _device(device)
{
// Acquire immediate rendering context.
device->GetImmediateContext(&_context);
}
d3d11_instance::~d3d11_instance() {}
d3d11_instance::~d3d11_instance()
{
//_context.Release(); // Automatically performed by ATL::CComPtr.
}
AVBufferRef* d3d11_instance::create_device_context()
{
@ -165,17 +166,18 @@ AVBufferRef* d3d11_instance::create_device_context()
if (!dctx_ref)
throw std::runtime_error("Failed to allocate AVHWDeviceContext.");
AVHWDeviceContext* dctx = reinterpret_cast<AVHWDeviceContext*>(dctx_ref->data);
AVD3D11VADeviceContext* d3d11va = reinterpret_cast<AVD3D11VADeviceContext*>(dctx->hwctx);
AVHWDeviceContext* hwdev = reinterpret_cast<AVHWDeviceContext*>(dctx_ref->data);
AVD3D11VADeviceContext* device_hwctx = reinterpret_cast<AVD3D11VADeviceContext*>(hwdev->hwctx);
// TODO: Determine if these need an additional reference.
d3d11va->device = _device;
d3d11va->device->AddRef();
d3d11va->device_context = _context;
d3d11va->device_context->AddRef();
d3d11va->lock = [](void*) { obs_enter_graphics(); };
d3d11va->unlock = [](void*) { obs_leave_graphics(); };
// Provide the base device information only.
device_hwctx->device = _device;
device_hwctx->device->AddRef();
// And a way to lock/unlock the device.
device_hwctx->lock = [](void*) { obs_enter_graphics(); };
device_hwctx->unlock = [](void*) { obs_leave_graphics(); };
// Then let FFmpeg do the rest for us.
int ret = av_hwdevice_ctx_init(dctx_ref);
if (ret < 0)
throw std::runtime_error("Failed to initialize AVHWDeviceContext.");

View File

@ -62,7 +62,7 @@ namespace streamfx::ffmpeg::hwapi {
ATL::CComPtr<ID3D11DeviceContext> _context;
public:
d3d11_instance(ATL::CComPtr<ID3D11Device> device, ATL::CComPtr<ID3D11DeviceContext> context);
d3d11_instance(ATL::CComPtr<ID3D11Device> device);
virtual ~d3d11_instance();
virtual AVBufferRef* create_device_context() override;