On Fri, 3 Feb 2017 10:02:44 +0000 Stève Lhomme <[email protected]> wrote:
> On Thu, Feb 2, 2017 at 11:27 AM, wm4 <[email protected]> wrote: > > D3D9Ex uses different driver paths. This helps with "headless" > > configurations when no user logs in. Plain D3D9 device creation will > > fail if no user is logged in, while it works with D3D9Ex. > > --- > > libavutil/hwcontext_dxva2.c | 61 > > ++++++++++++++++++++++++++++++++++----------- > > 1 file changed, 47 insertions(+), 14 deletions(-) > > > > diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c > > index ccf03c8e9f..b9c26a84f4 100644 > > --- a/libavutil/hwcontext_dxva2.c > > +++ b/libavutil/hwcontext_dxva2.c > > @@ -38,6 +38,7 @@ > > #include "pixfmt.h" > > > > typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); > > +typedef HRESULT WINAPI pDirect3DCreate9Ex(UINT, IDirect3D9Ex **); > > typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, > > IDirect3DDeviceManager9 **); > > > > typedef struct DXVA2Mapping { > > @@ -418,6 +419,7 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, > > const char *device, > > DXVA2DevicePriv *priv; > > > > pDirect3DCreate9 *createD3D = NULL; > > + pDirect3DCreate9Ex *createD3DEx = NULL; > > pCreateDeviceManager9 *createDeviceManager = NULL; > > D3DPRESENT_PARAMETERS d3dpp = {0}; > > D3DDISPLAYMODE d3ddm; > > @@ -453,6 +455,7 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, > > const char *device, > > av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); > > return AVERROR_UNKNOWN; > > } > > + createD3DEx = (pDirect3DCreate9Ex *)GetProcAddress(priv->d3dlib, > > "Direct3DCreate9Ex"); > > createDeviceManager = (pCreateDeviceManager9 > > *)GetProcAddress(priv->dxva2lib, > > > > "DXVA2CreateDirect3DDeviceManager9"); > > if (!createDeviceManager) { > > @@ -460,27 +463,57 @@ static int dxva2_device_create(AVHWDeviceContext > > *ctx, const char *device, > > return AVERROR_UNKNOWN; > > } > > > > - priv->d3d9 = createD3D(D3D_SDK_VERSION); > > - if (!priv->d3d9) { > > - av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); > > - return AVERROR_UNKNOWN; > > - } > > - > > - IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); > > d3dpp.Windowed = TRUE; > > d3dpp.BackBufferWidth = 640; > > d3dpp.BackBufferHeight = 480; > > d3dpp.BackBufferCount = 0; > > - d3dpp.BackBufferFormat = d3ddm.Format; > > d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; > > d3dpp.Flags = D3DPRESENTFLAG_VIDEO; > > > > - hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, > > GetShellWindow(), > > - D3DCREATE_SOFTWARE_VERTEXPROCESSING | > > D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, > > - &d3dpp, &priv->d3d9device); > > - if (FAILED(hr)) { > > - av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); > > - return AVERROR_UNKNOWN; > > + if (createD3DEx) { > > + IDirect3D9Ex *d3d9ex = NULL; > > + > > + hr = createD3DEx(D3D_SDK_VERSION, &d3d9ex); > > + if (!FAILED(hr)) { > > + D3DDISPLAYMODEEX modeex = {0}; > > + IDirect3DDevice9Ex *exdev = NULL; > > + > > + IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, adapter, &modeex, > > NULL); > > + d3dpp.BackBufferFormat = modeex.Format; > > + > > + hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, adapter, > > D3DDEVTYPE_HAL, GetShellWindow(), > > + > > D3DCREATE_SOFTWARE_VERTEXPROCESSING | > > + D3DCREATE_MULTITHREADED | > > + D3DCREATE_FPU_PRESERVE, > > + &d3dpp, NULL, &exdev); > > + if (FAILED(hr)) { > > + // Retry with "classic" d3d9 below > > + IDirect3D9_Release(d3d9ex); > > + } else { > > + av_log(ctx, AV_LOG_VERBOSE, "Using D3D9Ex device.\n"); > > + priv->d3d9 = d3d9ex; > > + priv->d3d9device = exdev; > > In this code path you don't release d3d9ex. Once exdev is created you > don't need to keep a reference. So it can be done right after the > IDirect3D9Ex_CreateDeviceEx() call. The reference goes to priv->d3d9. > > + } > > + } > > + } > > + > > + if (!priv->d3d9device) { > > + priv->d3d9 = createD3D(D3D_SDK_VERSION); > > + if (!priv->d3d9) { > > + av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D > > object\n"); > > + return AVERROR_UNKNOWN; > > + } > > + > > + IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); > > + d3dpp.BackBufferFormat = d3ddm.Format; > > + > > + hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, > > GetShellWindow(), > > + D3DCREATE_SOFTWARE_VERTEXPROCESSING | > > D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, > > Maybe the flags value can be factorize to avoid mismatches in the future. I'll make a define. > > + &d3dpp, &priv->d3d9device); > > + if (FAILED(hr)) { > > + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D > > device\n"); > > + return AVERROR_UNKNOWN; > > d3d9 should probably be released. This is taken care by dxva2_device_free, which should be called by the common hwcontext code if device creation returns with an error. _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
