From patchwork Sat Feb 11 13:17:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wm4 X-Patchwork-Id: 2507 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp107611vsb; Sat, 11 Feb 2017 05:18:12 -0800 (PST) X-Received: by 10.223.169.112 with SMTP id u103mr11805890wrc.166.1486819092219; Sat, 11 Feb 2017 05:18:12 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o64si5111642wmi.143.2017.02.11.05.18.11; Sat, 11 Feb 2017 05:18:12 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@googlemail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 500A7689DB7; Sat, 11 Feb 2017 15:17:51 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D49DD689DA8 for ; Sat, 11 Feb 2017 15:17:45 +0200 (EET) Received: by mail-wm0-f67.google.com with SMTP id r18so10915723wmd.3 for ; Sat, 11 Feb 2017 05:17:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=U1Aj9AjgVVGS/ZcmnPX+M+HPtwxdxdb29MnAJD0Dhek=; b=txIN1xmkeTpRd356PjSrC8zvZz7shyL84aLP72DJxfpxFP+HYrZ8RBeowc7qEGVDXE bN9fxQihXaU5UQ/BDgBUR6i7wc+1DMN1oMOSKRENhSslHbQ4AxJVgr2MnVl5bgmUuzP6 vTdu5chPYlD8jP+0c5LyvR988GiFPzj7Vu+xTAuFZt8DgK6E/p1WtdN7AHQ40hZihZsN GuQvSah3DTJqIHlurhHtBHHQ5QyqF17IJ1jqKVqKY+H4TLmuYd548aAmKJ+ZUQ57iXa+ sJApEZ329HB/Ar6NApdRMkwaDOz7kzAq5ym3aSvtLUIzcLs1iAx1S/RnCp4lbzvfpmFg ifyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=U1Aj9AjgVVGS/ZcmnPX+M+HPtwxdxdb29MnAJD0Dhek=; b=RIpxRBCblzXnRVm8jZO3+sCl8Gr4pfFB3MMj/FLm+UMoOo54Pweg5v9b15nFNww5q0 fQNl9mv0+CPuhltq/iwoWsl3d3GR+7SlWCfj/8yp/D6Z1QNTnz8BaiLAMfcUtEn/IggP ZywSihRhIJhhOAKZ2JQV0tcwcuTs55Fa/DE0/qx+r/RSKdrU2ZLDGVC+v91Z0KGTHrB4 eirHKmuqgY2iu6/Jnp5RpOxh59C+tFc+noeZRuCQlXXnOz6ubyrtkzuDMFsBXGbr+aQD qiabwHq23D9zZ2EC5uuiUetco0BZyISYQFYQdbA372ZFlUzHxvavKHovVdA37hJTRqU6 n8VA== X-Gm-Message-State: AMke39lkb/5qlbZazYmmDKUPifdUglJfmVcEDHTwqOa1iVcxw1JNoFWAF10crRfDGz2ajQ== X-Received: by 10.28.31.130 with SMTP id f124mr10926053wmf.130.1486819069820; Sat, 11 Feb 2017 05:17:49 -0800 (PST) Received: from localhost.localdomain ([79.240.12.67]) by smtp.googlemail.com with ESMTPSA id o143sm5207404wmd.3.2017.02.11.05.17.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 11 Feb 2017 05:17:49 -0800 (PST) From: wm4 To: ffmpeg-devel@ffmpeg.org Date: Sat, 11 Feb 2017 14:17:37 +0100 Message-Id: <20170211131737.18139-3-nfxjfg@googlemail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170211131737.18139-1-nfxjfg@googlemail.com> References: <20170211131737.18139-1-nfxjfg@googlemail.com> Subject: [FFmpeg-devel] [PATCH 2/2] hwcontext_dxva2: support D3D9Ex X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: wm4 , Anton Khirnov MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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. Signed-off-by: Anton Khirnov Merges Libav commit c2f97f0508708. --- libavutil/hwcontext_dxva2.c | 117 ++++++++++++++++++++++++++++++++------------ 1 file changed, 87 insertions(+), 30 deletions(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 02632b7dae..4feb0a7306 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -40,8 +40,22 @@ #include "compat/w32dlfcn.h" typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); +typedef HRESULT WINAPI pDirect3DCreate9Ex(UINT, IDirect3D9Ex **); typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); +#define FF_D3DCREATE_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING | \ + D3DCREATE_MULTITHREADED | \ + D3DCREATE_FPU_PRESERVE) + +static const D3DPRESENT_PARAMETERS dxva2_present_params = { + .Windowed = TRUE, + .BackBufferWidth = 640, + .BackBufferHeight = 480, + .BackBufferCount = 0, + .SwapEffect = D3DSWAPEFFECT_DISCARD, + .Flags = D3DPRESENTFLAG_VIDEO, +}; + typedef struct DXVA2FramesContext { IDirect3DSurface9 **surfaces_internal; int nb_surfaces_used; @@ -317,19 +331,83 @@ static void dxva2_device_free(AVHWDeviceContext *ctx) av_freep(&ctx->user_opaque); } +static int dxva2_device_create9(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODE d3ddm; + HRESULT hr; + pDirect3DCreate9 *createD3D = (pDirect3DCreate9 *)dlsym(priv->d3dlib, "Direct3DCreate9"); + if (!createD3D) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); + 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.BackBufferFormat = d3ddm.Format; + + hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, &priv->d3d9device); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int dxva2_device_create9ex(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODEEX modeex = {0}; + IDirect3D9Ex *d3d9ex = NULL; + IDirect3DDevice9Ex *exdev = NULL; + HRESULT hr; + pDirect3DCreate9Ex *createD3DEx = (pDirect3DCreate9Ex *)dlsym(priv->d3dlib, "Direct3DCreate9Ex"); + if (!createD3DEx) + return AVERROR(ENOSYS); + + hr = createD3DEx(D3D_SDK_VERSION, &d3d9ex); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + + IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, adapter, &modeex, NULL); + + d3dpp.BackBufferFormat = modeex.Format; + + hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, NULL, &exdev); + if (FAILED(hr)) { + IDirect3D9Ex_Release(d3d9ex); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Using D3D9Ex device.\n"); + priv->d3d9 = (IDirect3D9 *)d3d9ex; + priv->d3d9device = (IDirect3DDevice9 *)exdev; + return 0; +} + static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags) { AVDXVA2DeviceContext *hwctx = ctx->hwctx; DXVA2DevicePriv *priv; - - pDirect3DCreate9 *createD3D = NULL; pCreateDeviceManager9 *createDeviceManager = NULL; - D3DPRESENT_PARAMETERS d3dpp = {0}; - D3DDISPLAYMODE d3ddm; unsigned resetToken = 0; UINT adapter = D3DADAPTER_DEFAULT; HRESULT hr; + int err; if (device) adapter = atoi(device); @@ -354,11 +432,6 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, return AVERROR_UNKNOWN; } - createD3D = (pDirect3DCreate9 *)dlsym(priv->d3dlib, "Direct3DCreate9"); - if (!createD3D) { - av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); - return AVERROR_UNKNOWN; - } createDeviceManager = (pCreateDeviceManager9 *)dlsym(priv->dxva2lib, "DXVA2CreateDirect3DDeviceManager9"); if (!createDeviceManager) { @@ -366,27 +439,11 @@ 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, GetDesktopWindow(), - 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 (dxva2_device_create9ex(ctx, adapter) < 0) { + // Retry with "classic" d3d9 + err = dxva2_device_create9(ctx, adapter); + if (err < 0) + return err; } hr = createDeviceManager(&resetToken, &hwctx->devmgr);