Message ID | 20231124054348.3115276-1-haihao.xiang@intel.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/3] lavu/hwcontext_d3d11va: Add option vendor_id | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
Quoting Xiang, Haihao (2023-11-24 06:43:46) > From: Artem Galin <artem.galin@intel.com> > > User may choose the hardware via option vendor_id when multiple hardware > are available. > > Signed-off-by: Artem Galin <artem.galin@intel.com> > Signed-off-by: Haihao Xiang <haihao.xiang@intel.com> > --- > libavutil/hwcontext_d3d11va.c | 67 ++++++++++++++++++++++++++++++++++- > 1 file changed, 66 insertions(+), 1 deletion(-) > > diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c > index cc8c97d2b6..a6777b70a1 100644 > --- a/libavutil/hwcontext_d3d11va.c > +++ b/libavutil/hwcontext_d3d11va.c > @@ -552,6 +552,55 @@ static void d3d11va_device_uninit(AVHWDeviceContext *hwdev) > } > } > > +static int d3d11va_device_find_adapter_by_vendor_id(AVHWDeviceContext *ctx, uint32_t flags, const char *vendor_id) > +{ > + HRESULT hr; > + IDXGIAdapter *adapter = NULL; > + IDXGIFactory2 *factory; > + int adapter_id = 0; > + long int id = strtol(vendor_id, NULL, 0); > + > + hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&factory); > + if (FAILED(hr)) { > + av_log(ctx, AV_LOG_ERROR, "CreateDXGIFactory returned error\n"); > + return -1; > + } > + > + while (IDXGIFactory2_EnumAdapters(factory, adapter_id++, &adapter) != DXGI_ERROR_NOT_FOUND) { > + ID3D11Device* device = NULL; > + DXGI_ADAPTER_DESC adapter_desc; > + > + hr = mD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &device, NULL, NULL); > + if (FAILED(hr)) { > + av_log(ctx, AV_LOG_ERROR, "D3D11CreateDevice returned error\n"); This should not be AV_LOG_ERROR, since it does not result in failure. > + > + if (adapter) I'd expect adapter to be always non-NULL here. Same below, also for device..
On So, 2023-11-26 at 11:49 +0100, Anton Khirnov wrote: > Quoting Xiang, Haihao (2023-11-24 06:43:46) > > From: Artem Galin <artem.galin@intel.com> > > > > User may choose the hardware via option vendor_id when multiple hardware > > are available. > > > > Signed-off-by: Artem Galin <artem.galin@intel.com> > > Signed-off-by: Haihao Xiang <haihao.xiang@intel.com> > > --- > > libavutil/hwcontext_d3d11va.c | 67 ++++++++++++++++++++++++++++++++++- > > 1 file changed, 66 insertions(+), 1 deletion(-) > > > > diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c > > index cc8c97d2b6..a6777b70a1 100644 > > --- a/libavutil/hwcontext_d3d11va.c > > +++ b/libavutil/hwcontext_d3d11va.c > > @@ -552,6 +552,55 @@ static void d3d11va_device_uninit(AVHWDeviceContext > > *hwdev) > > } > > } > > > > +static int d3d11va_device_find_adapter_by_vendor_id(AVHWDeviceContext *ctx, > > uint32_t flags, const char *vendor_id) > > +{ > > + HRESULT hr; > > + IDXGIAdapter *adapter = NULL; > > + IDXGIFactory2 *factory; > > + int adapter_id = 0; > > + long int id = strtol(vendor_id, NULL, 0); > > + > > + hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&factory); > > + if (FAILED(hr)) { > > + av_log(ctx, AV_LOG_ERROR, "CreateDXGIFactory returned error\n"); > > + return -1; > > + } > > + > > + while (IDXGIFactory2_EnumAdapters(factory, adapter_id++, &adapter) != > > DXGI_ERROR_NOT_FOUND) { > > + ID3D11Device* device = NULL; > > + DXGI_ADAPTER_DESC adapter_desc; > > + > > + hr = mD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, > > flags, NULL, 0, D3D11_SDK_VERSION, &device, NULL, NULL); > > + if (FAILED(hr)) { > > + av_log(ctx, AV_LOG_ERROR, "D3D11CreateDevice returned > > error\n"); > > This should not be AV_LOG_ERROR, since it does not result in failure. > > > + > > + if (adapter) > > I'd expect adapter to be always non-NULL here. Same below, also for > device.. Thanks for the comments, I'll update the patch BRs Haihao >
diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index cc8c97d2b6..a6777b70a1 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -552,6 +552,55 @@ static void d3d11va_device_uninit(AVHWDeviceContext *hwdev) } } +static int d3d11va_device_find_adapter_by_vendor_id(AVHWDeviceContext *ctx, uint32_t flags, const char *vendor_id) +{ + HRESULT hr; + IDXGIAdapter *adapter = NULL; + IDXGIFactory2 *factory; + int adapter_id = 0; + long int id = strtol(vendor_id, NULL, 0); + + hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&factory); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "CreateDXGIFactory returned error\n"); + return -1; + } + + while (IDXGIFactory2_EnumAdapters(factory, adapter_id++, &adapter) != DXGI_ERROR_NOT_FOUND) { + ID3D11Device* device = NULL; + DXGI_ADAPTER_DESC adapter_desc; + + hr = mD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &device, NULL, NULL); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "D3D11CreateDevice returned error\n"); + + if (adapter) + IDXGIAdapter_Release(adapter); + + continue; + } + + hr = IDXGIAdapter2_GetDesc(adapter, &adapter_desc); + + if (device) + ID3D11Device_Release(device); + + if (adapter) + IDXGIAdapter_Release(adapter); + + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "IDXGIAdapter2_GetDesc returned error\n"); + continue; + } else if (adapter_desc.VendorId == id) { + IDXGIFactory2_Release(factory); + return adapter_id - 1; + } + } + + IDXGIFactory2_Release(factory); + return -1; +} + static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags) { @@ -563,6 +612,7 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; int is_debug = !!av_dict_get(opts, "debug", NULL, 0); int ret; + int adapter = -1; // (On UWP we can't check this.) #if !HAVE_UWP @@ -581,10 +631,25 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, } if (device) { + adapter = atoi(device); + } else { + AVDictionaryEntry *e = av_dict_get(opts, "vendor_id", NULL, 0); + if (e && e->value) { + adapter = d3d11va_device_find_adapter_by_vendor_id(ctx, creationFlags, e->value); + if (adapter < 0) { + av_log(ctx, AV_LOG_ERROR, "Failed to find d3d11va adapter by " + "vendor id %s\n", e->value); + return AVERROR_UNKNOWN; + } + } + } + + if (adapter >= 0) { IDXGIFactory2 *pDXGIFactory; + + av_log(ctx, AV_LOG_VERBOSE, "Selecting d3d11va adapter %d\n", adapter); hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory); if (SUCCEEDED(hr)) { - int adapter = atoi(device); if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter))) pAdapter = NULL; IDXGIFactory2_Release(pDXGIFactory);