diff --git a/source/ffmpeg/hwapi/d3d11.cpp b/source/ffmpeg/hwapi/d3d11.cpp index 1d2bb38..5f80a61 100644 --- a/source/ffmpeg/hwapi/d3d11.cpp +++ b/source/ffmpeg/hwapi/d3d11.cpp @@ -102,10 +102,9 @@ std::list d3d11::enumerate_adapters() std::shared_ptr d3d11::create(const device& target) { - std::shared_ptr inst; - ATL::CComPtr device; - ATL::CComPtr context; - IDXGIAdapter1* adapter = nullptr; + std::shared_ptr inst; + ATL::CComPtr device; + IDXGIAdapter1* adapter = nullptr; // Find the correct "Adapter" (device). IDXGIAdapter1* dxgi_adapter = nullptr; @@ -125,12 +124,11 @@ std::shared_ptr 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(feature_levels.size()), D3D11_SDK_VERSION, &device, NULL, - &context))) { + static_cast(feature_levels.size()), D3D11_SDK_VERSION, &device, NULL, NULL))) { throw std::runtime_error("Failed to create D3D11 device for target."); } - return std::make_shared(device, context); + return std::make_shared(device); } std::shared_ptr d3d11::create_from_obs() @@ -143,21 +141,24 @@ std::shared_ptr d3d11::create_from_obs() ATL::CComPtr device = ATL::CComPtr(reinterpret_cast(gs_get_device_obj())); - ATL::CComPtr context; - device->GetImmediateContext(&context); - return std::make_shared(device, context); + return std::make_shared(device); } struct D3D11AVFrame { ATL::CComPtr handle; }; -d3d11_instance::d3d11_instance(ATL::CComPtr device, ATL::CComPtr context) - : _device(device), _context(context) -{} +d3d11_instance::d3d11_instance(ATL::CComPtr 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(dctx_ref->data); - AVD3D11VADeviceContext* d3d11va = reinterpret_cast(dctx->hwctx); + AVHWDeviceContext* hwdev = reinterpret_cast(dctx_ref->data); + AVD3D11VADeviceContext* device_hwctx = reinterpret_cast(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."); diff --git a/source/ffmpeg/hwapi/d3d11.hpp b/source/ffmpeg/hwapi/d3d11.hpp index b7b36f8..44a5ec1 100644 --- a/source/ffmpeg/hwapi/d3d11.hpp +++ b/source/ffmpeg/hwapi/d3d11.hpp @@ -62,7 +62,7 @@ namespace streamfx::ffmpeg::hwapi { ATL::CComPtr _context; public: - d3d11_instance(ATL::CComPtr device, ATL::CComPtr context); + d3d11_instance(ATL::CComPtr device); virtual ~d3d11_instance(); virtual AVBufferRef* create_device_context() override;