Added patch for MPEG2/H264 DXVA2 video decoding through vaapi.

This commit is contained in:
Michael Müller
2015-02-22 04:08:15 +01:00
parent 8f19269b34
commit 44ea94f633
13 changed files with 6016 additions and 459 deletions

View File

@ -38,7 +38,7 @@ Wine. All those differences are also documented on the
Included bug fixes and improvements
===================================
**Bugfixes and features included in the next upcoming release [16]:**
**Bugfixes and features included in the next upcoming release [18]:**
* Add semi-stub for GetFileVersionInfoExA/W ([Wine Bug #38098](https://bugs.winehq.org/show_bug.cgi?id=38098))
* Add semi-stub for GetFileVersionInfoSizeExA/W ([Wine Bug #38090](https://bugs.winehq.org/show_bug.cgi?id=38090))
@ -55,6 +55,8 @@ Included bug fixes and improvements
* Implement ntoskrnl.KeInitializeMutex
* Improve stubs for AEV_{Get,Set}MasterVolumeLevel
* Improve stubs for AEV_{Get,Set}Mute
* Support for H264 DXVA2 GPU video decoding through vaapi
* Support for MPEG2 DXVA2 GPU video decoding through vaapi
* Support for non-blocking SIO_ADDRESS_LIST_CHANGE requests ([Wine Bug #38062](https://bugs.winehq.org/show_bug.cgi?id=38062))

1
debian/changelog vendored
View File

@ -20,6 +20,7 @@ wine-staging (1.7.37) UNRELEASED; urgency=low
* Added patch to add stub for ntoskrnl.Mm{Map,Unmap}LockedPages.
* Added patch to implement ntoskrnl.KeInitializeMutex.
* Added patch for support of non-blocking SIO_ADDRESS_LIST_CHANGE requests.
* Added patch for MPEG2/H264 DXVA2 video decoding through vaapi.
* Removed patches for UTF7 support (accepted upstream).
* Removed patches for SIO_ADDRESS_LIST_CHANGE ioctl (accepted upstream).
* Removed patch for IApplicationAssociationRegistration::QueryCurrentDefault (accepted upstream).

View File

@ -0,0 +1,302 @@
From 65f573c73dbb07f534c66fa7a6738576872cf322 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 10 Feb 2015 16:34:05 +0100
Subject: dxva2: Implement semi-stub for Direct3DDeviceManager9 interface.
---
dlls/dxva2/Makefile.in | 4 +-
dlls/dxva2/devicemanager.c | 212 +++++++++++++++++++++++++++++++++++++++++++++
dlls/dxva2/dxva2_private.h | 21 +++++
dlls/dxva2/main.c | 7 +-
4 files changed, 241 insertions(+), 3 deletions(-)
create mode 100644 dlls/dxva2/devicemanager.c
create mode 100644 dlls/dxva2/dxva2_private.h
diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in
index 7b9ef6f..ffa7fe8 100644
--- a/dlls/dxva2/Makefile.in
+++ b/dlls/dxva2/Makefile.in
@@ -1,4 +1,6 @@
MODULE = dxva2.dll
+IMPORTS = ole32
C_SRCS = \
- main.c
+ main.c \
+ devicemanager.c
diff --git a/dlls/dxva2/devicemanager.c b/dlls/dxva2/devicemanager.c
new file mode 100644
index 0000000..15d78aa
--- /dev/null
+++ b/dlls/dxva2/devicemanager.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2014 Sebastian Lackner for Pipelight
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+
+#include "wine/debug.h"
+
+#define COBJMACROS
+#include "d3d9.h"
+#include "dxva2api.h"
+#include "dxva2_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dxva2);
+
+typedef struct
+{
+ IDirect3DDeviceManager9 IDirect3DDeviceManager9_iface;
+ LONG refCount;
+ UINT token;
+ IDirect3DDevice9 *device;
+} Direct3DDeviceManager9Impl;
+
+static inline Direct3DDeviceManager9Impl *impl_from_Direct3DDeviceManager9( IDirect3DDeviceManager9 *iface )
+{
+ return CONTAINING_RECORD(iface, Direct3DDeviceManager9Impl, IDirect3DDeviceManager9_iface);
+}
+
+/*****************************************************************************
+ * IDirect3DDeviceManager9 interface
+ */
+
+static HRESULT WINAPI Direct3DDeviceManager9_QueryInterface( IDirect3DDeviceManager9 *iface, REFIID riid, LPVOID *ppv )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+ TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_guid(riid), ppv);
+
+ *ppv = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirect3DDeviceManager9))
+ *ppv = &This->IDirect3DDeviceManager9_iface;
+
+ if (*ppv)
+ {
+ IUnknown_AddRef((IUnknown *)(*ppv));
+ return S_OK;
+ }
+
+ FIXME("No interface for %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Direct3DDeviceManager9_AddRef( IDirect3DDeviceManager9 *iface )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+ ULONG refCount = InterlockedIncrement(&This->refCount);
+
+ TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
+
+ return refCount;
+}
+
+static ULONG WINAPI Direct3DDeviceManager9_Release( IDirect3DDeviceManager9 *iface )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+ ULONG refCount = InterlockedDecrement(&This->refCount);
+
+ TRACE("(%p)->() Release from %d\n", This, refCount + 1);
+
+ if (!refCount)
+ {
+ TRACE("Destroying\n");
+
+ if (This->device)
+ IDirect3DDevice9_Release(This->device);
+
+ CoTaskMemFree(This);
+ }
+
+ return refCount;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_ResetDevice( IDirect3DDeviceManager9 *iface, IDirect3DDevice9 *pDevice, UINT resetToken )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+ FIXME("(%p)->(%p, %u): semi-stub\n", This, pDevice, resetToken);
+
+ if (This->device)
+ return E_FAIL;
+
+ if (resetToken != This->token)
+ return E_INVALIDARG;
+
+ This->device = pDevice;
+ IDirect3DDevice9_AddRef(This->device);
+
+ /* TODO: Reset the device, verify token ... */
+
+ return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_OpenDeviceHandle( IDirect3DDeviceManager9 *iface, HANDLE *phDevice )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+ FIXME("(%p)->(%p): semi-stub\n", This, phDevice);
+
+ *phDevice = (HANDLE)This->device;
+ return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_CloseDeviceHandle( IDirect3DDeviceManager9 *iface, HANDLE hDevice )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+ FIXME("(%p)->(%p): stub\n", This, hDevice);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_TestDevice( IDirect3DDeviceManager9 *iface, HANDLE hDevice )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+ static int once = 0;
+
+ if (!once++)
+ FIXME("(%p)->(%p): stub\n", This, hDevice);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_LockDevice( IDirect3DDeviceManager9 *iface, HANDLE hDevice, IDirect3DDevice9 **ppDevice, BOOL fBlock )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+ FIXME("(%p)->(%p, %p, %d): semi-stub\n", This, hDevice, ppDevice, fBlock);
+
+ *ppDevice = (IDirect3DDevice9 *)hDevice;
+ return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_UnlockDevice( IDirect3DDeviceManager9 *iface, HANDLE hDevice, BOOL fSaveState )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+ FIXME("(%p)->(%p, %d): stub\n", This, hDevice, fSaveState);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_GetVideoService( IDirect3DDeviceManager9 *iface, HANDLE hDevice, REFIID riid, void **ppService )
+{
+ Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+ FIXME("(%p)->(%p, %p, %p): stub\n", This, hDevice, riid, ppService);
+
+ return E_NOTIMPL;
+}
+
+static const IDirect3DDeviceManager9Vtbl Direct3DDeviceManager9_VTable =
+{
+ Direct3DDeviceManager9_QueryInterface,
+ Direct3DDeviceManager9_AddRef,
+ Direct3DDeviceManager9_Release,
+ Direct3DDeviceManager9_ResetDevice,
+ Direct3DDeviceManager9_OpenDeviceHandle,
+ Direct3DDeviceManager9_CloseDeviceHandle,
+ Direct3DDeviceManager9_TestDevice,
+ Direct3DDeviceManager9_LockDevice,
+ Direct3DDeviceManager9_UnlockDevice,
+ Direct3DDeviceManager9_GetVideoService
+};
+
+HRESULT devicemanager_create( UINT *resetToken, void **ppv )
+{
+ Direct3DDeviceManager9Impl *devicemanager;
+
+ if (!resetToken || !ppv)
+ return E_INVALIDARG;
+
+ *ppv = NULL;
+
+ devicemanager = CoTaskMemAlloc(sizeof(Direct3DDeviceManager9Impl));
+ if (!devicemanager)
+ return E_OUTOFMEMORY;
+
+ devicemanager->IDirect3DDeviceManager9_iface.lpVtbl = &Direct3DDeviceManager9_VTable;
+ devicemanager->refCount = 1;
+ devicemanager->token = 0xdeadbeef; /* FIXME: provide some better value? */
+ devicemanager->device = NULL;
+
+ *resetToken = devicemanager->token;
+ *ppv = devicemanager;
+ return S_OK;
+}
diff --git a/dlls/dxva2/dxva2_private.h b/dlls/dxva2/dxva2_private.h
new file mode 100644
index 0000000..d6e59fc
--- /dev/null
+++ b/dlls/dxva2/dxva2_private.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2014 Michael Müller for Pipelight
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "dxva2api.h"
+
+extern HRESULT devicemanager_create( UINT *resetToken, void **ppv ) DECLSPEC_HIDDEN;
diff --git a/dlls/dxva2/main.c b/dlls/dxva2/main.c
index b4704f0..e9d43d3 100644
--- a/dlls/dxva2/main.c
+++ b/dlls/dxva2/main.c
@@ -19,8 +19,11 @@
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
+
+#define INITGUID
#include "d3d9.h"
#include "dxva2api.h"
+#include "dxva2_private.h"
#include "physicalmonitorenumerationapi.h"
#include "lowlevelmonitorconfigurationapi.h"
#include "highlevelmonitorconfigurationapi.h"
@@ -39,9 +42,9 @@ BOOL WINAPI CapabilitiesRequestAndCapabilitiesReply( HMONITOR monitor, LPSTR buf
HRESULT WINAPI DXVA2CreateDirect3DDeviceManager9( UINT *resetToken, IDirect3DDeviceManager9 **dxvManager )
{
- FIXME("(%p, %p): stub\n", resetToken, dxvManager);
+ TRACE("(%p, %p)\n", resetToken, dxvManager);
- return E_NOTIMPL;
+ return devicemanager_create( resetToken, (void **)dxvManager );
}
HRESULT WINAPI DXVA2CreateVideoService( IDirect3DDevice9 *device, REFIID riid, void **ppv )
--
2.1.0

View File

@ -0,0 +1,25 @@
From 7fda9638073cbf136c87bfcac507a067c2159b3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 21 Feb 2015 14:49:30 +0100
Subject: include: Fix an invalid UUID in dxva2api.idl.
---
include/dxva2api.idl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/dxva2api.idl b/include/dxva2api.idl
index ebd508b..7a29157 100644
--- a/include/dxva2api.idl
+++ b/include/dxva2api.idl
@@ -434,7 +434,7 @@ interface IDirectXVideoDecoder : IUnknown
*/
[
object,
- uuid(fc51a551-d5e7-11d9-af55-00054e43ff02),
+ uuid(fc51a552-d5e7-11d9-af55-00054e43ff02),
local
]
interface IDirectXVideoProcessorService : IDirectXVideoAccelerationService
--
2.1.0

View File

@ -0,0 +1,310 @@
From 7cc3c032cb2c18e5adf1f4cb6da3c2f731a092c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 21 Feb 2015 15:06:03 +0100
Subject: dxva2: Implement stubbed DirectX Software VideoProcessor interface.
---
dlls/dxva2/Makefile.in | 3 +-
dlls/dxva2/dxva2_private.h | 3 +
dlls/dxva2/softwareprocessor.c | 209 +++++++++++++++++++++++++++++++++++++++++
dlls/dxva2/videoservices.c | 17 +++-
include/dxva2api.idl | 5 +
5 files changed, 234 insertions(+), 3 deletions(-)
create mode 100644 dlls/dxva2/softwareprocessor.c
diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in
index 02c9758..4af9dc0 100644
--- a/dlls/dxva2/Makefile.in
+++ b/dlls/dxva2/Makefile.in
@@ -4,4 +4,5 @@ IMPORTS = ole32
C_SRCS = \
main.c \
videoservices.c \
- devicemanager.c
+ devicemanager.c \
+ softwareprocessor.c
diff --git a/dlls/dxva2/dxva2_private.h b/dlls/dxva2/dxva2_private.h
index a88809c..f0068b6 100644
--- a/dlls/dxva2/dxva2_private.h
+++ b/dlls/dxva2/dxva2_private.h
@@ -20,3 +20,6 @@
extern HRESULT videoservice_create( IDirect3DDevice9 *device, REFIID riid, void **ppv ) DECLSPEC_HIDDEN;
extern HRESULT devicemanager_create( UINT *resetToken, void **ppv ) DECLSPEC_HIDDEN;
+extern HRESULT processor_software_create( IDirectXVideoProcessorService *processor_service, IDirect3DDevice9 *device,
+ const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT RenderTargetFormat,
+ UINT MaxNumSubStreams, IDirectXVideoProcessor **processor ) DECLSPEC_HIDDEN;
diff --git a/dlls/dxva2/softwareprocessor.c b/dlls/dxva2/softwareprocessor.c
new file mode 100644
index 0000000..d396248
--- /dev/null
+++ b/dlls/dxva2/softwareprocessor.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2015 Michael Müller for Pipelight
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+
+#include "wine/debug.h"
+
+#define COBJMACROS
+#include "d3d9.h"
+#include "dxva2api.h"
+#include "dxva2_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dxva2);
+
+typedef struct
+{
+ IDirectXVideoProcessor IDirectXVideoProcessor_iface;
+ LONG refCount;
+
+ IDirectXVideoProcessorService *service;
+ IDirect3DDevice9 *device;
+} DirectXVideoProcessorImpl;
+
+static inline DirectXVideoProcessorImpl *impl_from_IDirectXVideoProcessor( IDirectXVideoProcessor *iface )
+{
+ return CONTAINING_RECORD(iface, DirectXVideoProcessorImpl, IDirectXVideoProcessor_iface);
+}
+
+static HRESULT WINAPI DirectXVideoProcessor_QueryInterface( IDirectXVideoProcessor *iface, REFIID riid, LPVOID *ppv )
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+ TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_guid(riid), ppv);
+
+ *ppv = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectXVideoProcessor))
+ *ppv = (LPVOID)iface;
+
+ if (*ppv)
+ {
+ IUnknown_AddRef((IUnknown *)(*ppv));
+ return S_OK;
+ }
+
+ FIXME("No interface for %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI DirectXVideoProcessor_AddRef( IDirectXVideoProcessor *iface )
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+ ULONG refCount = InterlockedIncrement(&This->refCount);
+
+ TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
+
+ return refCount;
+}
+
+static ULONG WINAPI DirectXVideoProcessor_Release( IDirectXVideoProcessor *iface )
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+ ULONG refCount = InterlockedDecrement(&This->refCount);
+
+ TRACE("(%p)->() Release from %d\n", This, refCount + 1);
+
+ if (!refCount)
+ {
+ TRACE("Destroying\n");
+
+ IDirectXVideoProcessorService_Release(This->service);
+ IDirect3DDevice9_Release(This->device);
+
+ CoTaskMemFree(This);
+ }
+
+ return refCount;
+}
+
+static HRESULT WINAPI DirectXVideoProcessor_GetVideoProcessorService(IDirectXVideoProcessor *iface,
+ IDirectXVideoProcessorService** ppService)
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+
+ FIXME("(%p)->(%p): stub\n", This, ppService);
+
+ if (!ppService)
+ return E_INVALIDARG;
+
+ IDirectXVideoProcessorService_AddRef(This->service);
+ *ppService = This->service;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI DirectXVideoProcessor_GetCreationParameters(IDirectXVideoProcessor *iface,
+ GUID* pDeviceGuid, DXVA2_VideoDesc* pVideoDesc,
+ D3DFORMAT* pRenderTargetFormat,
+ UINT* pMaxNumSubStreams)
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+
+ FIXME("(%p)->(%p, %p, %p, %p): stub\n", This, pDeviceGuid, pVideoDesc, pRenderTargetFormat, pMaxNumSubStreams);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DirectXVideoProcessor_GetVideoProcessorCaps(IDirectXVideoProcessor *iface,
+ DXVA2_VideoProcessorCaps* pCaps)
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+
+ FIXME("(%p)->(%p): stub\n", This, pCaps);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DirectXVideoProcessor_GetProcAmpRange(IDirectXVideoProcessor *iface, UINT ProcAmpCap,
+ DXVA2_ValueRange* pRange)
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+
+ FIXME("(%p)->(%u, %p): stub\n", This, ProcAmpCap, pRange);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DirectXVideoProcessor_GetFilterPropertyRange(IDirectXVideoProcessor *iface,
+ UINT FilterSetting, DXVA2_ValueRange* pRange)
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+
+ FIXME("(%p)->(%u, %p): stub\n", This, FilterSetting, pRange);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DirectXVideoProcessor_VideoProcessBlt(IDirectXVideoProcessor *iface, IDirect3DSurface9* pRenderTarget,
+ const DXVA2_VideoProcessBltParams* pBltParams,
+ const DXVA2_VideoSample* pSamples, UINT NumSamples,
+ HANDLE* complete)
+{
+ DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);
+
+ TRACE("(%p)->(%p, %p, %p, %u, %p)\n", This, pRenderTarget, pBltParams, pSamples, NumSamples, complete);
+
+ if (!pRenderTarget || !pBltParams || !pSamples)
+ return E_INVALIDARG;
+
+ if (NumSamples > 1)
+ FIXME("Deinterlacing not implemented, expect horrible video output!\n");
+
+ return IDirect3DDevice9_StretchRect(This->device, pSamples[0].SrcSurface, &pSamples[0].SrcRect,
+ pRenderTarget, &pSamples[0].DstRect, D3DTEXF_LINEAR);
+}
+
+static const IDirectXVideoProcessorVtbl DirectXVideoProcessor_VTable =
+{
+ DirectXVideoProcessor_QueryInterface,
+ DirectXVideoProcessor_AddRef,
+ DirectXVideoProcessor_Release,
+ DirectXVideoProcessor_GetVideoProcessorService,
+ DirectXVideoProcessor_GetCreationParameters,
+ DirectXVideoProcessor_GetVideoProcessorCaps,
+ DirectXVideoProcessor_GetProcAmpRange,
+ DirectXVideoProcessor_GetFilterPropertyRange,
+ DirectXVideoProcessor_VideoProcessBlt
+};
+
+HRESULT processor_software_create( IDirectXVideoProcessorService *processor_service, IDirect3DDevice9 *device,
+ const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT RenderTargetFormat,
+ UINT MaxNumSubStreams, IDirectXVideoProcessor **processor )
+{
+ DirectXVideoProcessorImpl *software_processor;
+
+ if (!processor_service || !pVideoDesc)
+ return E_INVALIDARG;
+
+ software_processor = CoTaskMemAlloc(sizeof(*software_processor));
+ if (!software_processor)
+ return E_OUTOFMEMORY;
+
+ software_processor->IDirectXVideoProcessor_iface.lpVtbl = &DirectXVideoProcessor_VTable;
+ software_processor->refCount = 1;
+ software_processor->service = processor_service;
+ software_processor->device = device;
+
+ IDirectXVideoProcessorService_AddRef(processor_service);
+ IDirect3DDevice9_AddRef(device);
+
+ *processor = &software_processor->IDirectXVideoProcessor_iface;
+ return S_OK;
+}
diff --git a/dlls/dxva2/videoservices.c b/dlls/dxva2/videoservices.c
index 936aa37..46e431a 100644
--- a/dlls/dxva2/videoservices.c
+++ b/dlls/dxva2/videoservices.c
@@ -341,10 +341,20 @@ static HRESULT WINAPI DirectXVideoProcessorService_GetVideoProcessorDeviceGuids(
const DXVA2_VideoDesc *pVideoDesc, UINT *pCount, GUID **pGuids )
{
DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
+ GUID *guids;
FIXME("(%p/%p)->(%p, %p, %p): stub\n", iface, This, pVideoDesc, pCount, pGuids);
- return E_NOTIMPL;
+ guids = CoTaskMemAlloc(sizeof(GUID));
+ if(!guids)
+ return E_OUTOFMEMORY;
+
+ memcpy(guids, &DXVA2_VideoProcSoftwareDevice, sizeof(GUID));
+
+ *pGuids = guids;
+ *pCount = 1;
+
+ return S_OK;
}
static HRESULT WINAPI DirectXVideoProcessorService_GetVideoProcessorRenderTargets( IDirectXVideoProcessorService *iface,
@@ -407,9 +417,12 @@ static HRESULT WINAPI DirectXVideoProcessorService_CreateVideoProcessor( IDirect
{
DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
- FIXME("(%p/%p)->(%s, %#x, %u, %p): stub\n",
+ FIXME("(%p/%p)->(%s, %#x, %u, %p): semi-stub\n",
iface, This, debugstr_guid(VideoProcDeviceGuid), RenderTargetFormat, MaxNumSubStreams, ppVidProcess);
+ if (IsEqualIID(VideoProcDeviceGuid, &DXVA2_VideoProcSoftwareDevice))
+ return processor_software_create(iface, This->device, pVideoDesc, RenderTargetFormat, MaxNumSubStreams, ppVidProcess);
+
return E_NOTIMPL;
}
diff --git a/include/dxva2api.idl b/include/dxva2api.idl
index 7a29157..7388b37 100644
--- a/include/dxva2api.idl
+++ b/include/dxva2api.idl
@@ -86,6 +86,11 @@ cpp_quote("#define DXVA2_ModeVC1_VLD DXVA2_ModeVC1_D")
/* Encryption */
cpp_quote("DEFINE_GUID(DXVA_NoEncrypt, 0x1b81bed0, 0xa0c7,0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);")
+/* Video Processor */
+cpp_quote("DEFINE_GUID(DXVA2_VideoProcProgressiveDevice, 0x5a54a0c9, 0xc7ec,0x4bd9, 0x8e, 0xde, 0xf3, 0xc7, 0x5d, 0xc4, 0x39, 0x3b);")
+cpp_quote("DEFINE_GUID(DXVA2_VideoProcBobDevice, 0x335aa36e, 0x7884,0x43a4, 0x9c, 0x91, 0x7f, 0x87, 0xfa, 0xf3, 0xe3, 0x7e);")
+cpp_quote("DEFINE_GUID(DXVA2_VideoProcSoftwareDevice, 0x4553d47f, 0xee7e,0x4e3f, 0x94, 0x75, 0xdb, 0xf1, 0x37, 0x6c, 0x48, 0x10);")
+
typedef LONGLONG REFERENCE_TIME;
enum
--
2.1.0

View File

@ -0,0 +1,247 @@
From a871b5881c5e01ec46f49cb181d504c61765558d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 22 Feb 2015 01:10:21 +0100
Subject: include: Add dxva.h header file.
---
include/Makefile.in | 1 +
include/dxva.h | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 216 insertions(+)
create mode 100644 include/dxva.h
diff --git a/include/Makefile.in b/include/Makefile.in
index 02d5d88..2b7943a 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -314,6 +314,7 @@ SRCDIR_INCLUDES = \
dxfile.h \
dxgiformat.h \
dxgitype.h \
+ dxva.h \
dyngraph.idl \
errorrep.h \
errors.h \
diff --git a/include/dxva.h b/include/dxva.h
new file mode 100644
index 0000000..e311488
--- /dev/null
+++ b/include/dxva.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2015 Michael Müller for Pipelight
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_DXVA_H
+#define __WINE_DXVA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DXVA_USUAL_BLOCK_WIDTH 8
+#define DXVA_USUAL_BLOCK_HEIGHT 8
+#define DXVA_USUAL_BLOCK_SIZE (DXVA_USUAL_BLOCK_WIDTH * DXVA_USUAL_BLOCK_HEIGHT)
+
+#include <pshpack1.h>
+
+typedef struct _DXVA_PictureParameters
+{
+ WORD wDecodedPictureIndex;
+ WORD wDeblockedPictureIndex;
+ WORD wForwardRefPictureIndex;
+ WORD wBackwardRefPictureIndex;
+ WORD wPicWidthInMBminus1;
+ WORD wPicHeightInMBminus1;
+ BYTE bMacroblockWidthMinus1;
+ BYTE bMacroblockHeightMinus1;
+ BYTE bBlockWidthMinus1;
+ BYTE bBlockHeightMinus1;
+ BYTE bBPPminus1;
+ BYTE bPicStructure;
+ BYTE bSecondField;
+ BYTE bPicIntra;
+ BYTE bPicBackwardPrediction;
+ BYTE bBidirectionalAveragingMode;
+ BYTE bMVprecisionAndChromaRelation;
+ BYTE bChromaFormat;
+ BYTE bPicScanFixed;
+ BYTE bPicScanMethod;
+ BYTE bPicReadbackRequests;
+ BYTE bRcontrol;
+ BYTE bPicSpatialResid8;
+ BYTE bPicOverflowBlocks;
+ BYTE bPicExtrapolation;
+ BYTE bPicDeblocked;
+ BYTE bPicDeblockConfined;
+ BYTE bPic4MVallowed;
+ BYTE bPicOBMC;
+ BYTE bPicBinPB;
+ BYTE bMV_RPS;
+ BYTE bReservedBits;
+ WORD wBitstreamFcodes;
+ WORD wBitstreamPCEelements;
+ BYTE bBitstreamConcealmentNeed;
+ BYTE bBitstreamConcealmentMethod;
+} DXVA_PictureParameters, *LPDXVA_PictureParameters;
+
+typedef struct _DXVA_SliceInfo
+{
+ WORD wHorizontalPosition;
+ WORD wVerticalPosition;
+ DWORD dwSliceBitsInBuffer;
+ DWORD dwSliceDataLocation;
+ BYTE bStartCodeBitOffset;
+ BYTE bReservedBits;
+ WORD wMBbitOffset;
+ WORD wNumberMBsInSlice;
+ WORD wQuantizerScaleCode;
+ WORD wBadSliceChopping;
+} DXVA_SliceInfo, *LPDXVA_SliceInfo;
+
+typedef struct _DXVA_QmatrixData
+{
+ BYTE bNewQmatrix[4];
+ WORD Qmatrix[4][DXVA_USUAL_BLOCK_WIDTH * DXVA_USUAL_BLOCK_HEIGHT];
+} DXVA_QmatrixData, *LPDXVA_QmatrixData;
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ UCHAR Index7Bits : 7;
+ UCHAR AssociatedFlag : 1;
+ };
+ UCHAR bPicEntry;
+ };
+} DXVA_PicEntry_H264;
+
+typedef struct
+{
+ USHORT wFrameWidthInMbsMinus1;
+ USHORT wFrameHeightInMbsMinus1;
+ DXVA_PicEntry_H264 CurrPic;
+ UCHAR num_ref_frames;
+ union
+ {
+ struct
+ {
+ USHORT field_pic_flag : 1;
+ USHORT MbaffFrameFlag : 1;
+ USHORT residual_colour_transform_flag : 1;
+ USHORT sp_for_switch_flag : 1;
+ USHORT chroma_format_idc : 2;
+ USHORT RefPicFlag : 1;
+ USHORT constrained_intra_pred_flag : 1;
+ USHORT weighted_pred_flag : 1;
+ USHORT weighted_bipred_idc : 2;
+ USHORT MbsConsecutiveFlag : 1;
+ USHORT frame_mbs_only_flag : 1;
+ USHORT transform_8x8_mode_flag : 1;
+ USHORT MinLumaBipredSize8x8Flag : 1;
+ USHORT IntraPicFlag : 1;
+ };
+ USHORT wBitFields;
+ };
+ UCHAR bit_depth_luma_minus8;
+ UCHAR bit_depth_chroma_minus8;
+ USHORT Reserved16Bits;
+ UINT StatusReportFeedbackNumber;
+ DXVA_PicEntry_H264 RefFrameList[16];
+ INT CurrFieldOrderCnt[2];
+ INT FieldOrderCntList[16][2];
+ CHAR pic_init_qs_minus26;
+ CHAR chroma_qp_index_offset;
+ CHAR second_chroma_qp_index_offset;
+ UCHAR ContinuationFlag;
+ CHAR pic_init_qp_minus26;
+ UCHAR num_ref_idx_l0_active_minus1;
+ UCHAR num_ref_idx_l1_active_minus1;
+ UCHAR Reserved8BitsA;
+ USHORT FrameNumList[16];
+
+ UINT UsedForReferenceFlags;
+ USHORT NonExistingFrameFlags;
+ USHORT frame_num;
+ UCHAR log2_max_frame_num_minus4;
+ UCHAR pic_order_cnt_type;
+ UCHAR log2_max_pic_order_cnt_lsb_minus4;
+ UCHAR delta_pic_order_always_zero_flag;
+ UCHAR direct_8x8_inference_flag;
+ UCHAR entropy_coding_mode_flag;
+ UCHAR pic_order_present_flag;
+ UCHAR num_slice_groups_minus1;
+ UCHAR slice_group_map_type;
+ UCHAR deblocking_filter_control_present_flag;
+ UCHAR redundant_pic_cnt_present_flag;
+ UCHAR Reserved8BitsB;
+ USHORT slice_group_change_rate_minus1;
+ UCHAR SliceGroupMap[810];
+} DXVA_PicParams_H264;
+
+typedef struct
+{
+ UCHAR bScalingLists4x4[6][16];
+ UCHAR bScalingLists8x8[2][64];
+} DXVA_Qmatrix_H264;
+
+typedef struct
+{
+ UINT BSNALunitDataLocation;
+ UINT SliceBytesInBuffer;
+ USHORT wBadSliceChopping;
+ USHORT first_mb_in_slice;
+ USHORT NumMbsForSlice;
+ USHORT BitOffsetToSliceData;
+ UCHAR slice_type;
+ UCHAR luma_log2_weight_denom;
+ UCHAR chroma_log2_weight_denom;
+
+ UCHAR num_ref_idx_l0_active_minus1;
+ UCHAR num_ref_idx_l1_active_minus1;
+ CHAR slice_alpha_c0_offset_div2;
+ CHAR slice_beta_offset_div2;
+ UCHAR Reserved8Bits;
+ DXVA_PicEntry_H264 RefPicList[2][32];
+ SHORT Weights[2][32][3][2];
+ CHAR slice_qs_delta;
+ CHAR slice_qp_delta;
+ UCHAR redundant_pic_cnt;
+ UCHAR direct_spatial_mv_pred_flag;
+ UCHAR cabac_init_idc;
+ UCHAR disable_deblocking_filter_idc;
+ USHORT slice_id;
+} DXVA_Slice_H264_Long;
+
+typedef struct
+{
+ UINT BSNALunitDataLocation;
+ UINT SliceBytesInBuffer;
+ USHORT wBadSliceChopping;
+} DXVA_Slice_H264_Short;
+
+#include <poppack.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_DXVA_H */
--
2.1.0

View File

@ -0,0 +1,416 @@
From d8850f844e13d73a850219a12b330bdbe3e995fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 22 Feb 2015 01:21:18 +0100
Subject: dxva2/tests: Add tests for dxva2 decoder.
---
configure.ac | 1 +
dlls/dxva2/tests/Makefile.in | 5 +
dlls/dxva2/tests/dxva2.c | 371 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 377 insertions(+)
create mode 100644 dlls/dxva2/tests/Makefile.in
create mode 100644 dlls/dxva2/tests/dxva2.c
diff --git a/configure.ac b/configure.ac
index f611fa5..22b46ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2941,6 +2941,7 @@ WINE_CONFIG_DLL(dxgi,,[implib])
WINE_CONFIG_TEST(dlls/dxgi/tests)
WINE_CONFIG_LIB(dxguid)
WINE_CONFIG_DLL(dxva2)
+WINE_CONFIG_TEST(dlls/dxva2/tests)
WINE_CONFIG_DLL(evr)
WINE_CONFIG_DLL(explorerframe,,[clean])
WINE_CONFIG_TEST(dlls/explorerframe/tests)
diff --git a/dlls/dxva2/tests/Makefile.in b/dlls/dxva2/tests/Makefile.in
new file mode 100644
index 0000000..10d6af5
--- /dev/null
+++ b/dlls/dxva2/tests/Makefile.in
@@ -0,0 +1,5 @@
+TESTDLL = dxva2.dll
+IMPORTS = d3d9 user32 ole32
+
+C_SRCS = \
+ dxva2.c
diff --git a/dlls/dxva2/tests/dxva2.c b/dlls/dxva2/tests/dxva2.c
new file mode 100644
index 0000000..dcbb990
--- /dev/null
+++ b/dlls/dxva2/tests/dxva2.c
@@ -0,0 +1,371 @@
+/*
+ * Unit tests for dxva2 functions
+ *
+ * Copyright 2015 Michael Müller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "wine/test.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+
+#define COBJMACROS
+#define INITGUID
+#include "d3d9.h"
+#include "dxva2api.h"
+#include "dxva.h"
+
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+
+struct decoder_name
+{
+ const GUID *guid;
+ const char *name;
+};
+
+struct decoder_name decoder_names[] =
+{
+ /* H.264 */
+ {&DXVA2_ModeH264_A, "H.264 MoComp"},
+ {&DXVA2_ModeH264_B, "H.264 MoComp, FGT"},
+ {&DXVA2_ModeH264_C, "H.264 IDCT"},
+ {&DXVA2_ModeH264_D, "H.264 IDCT, FGT"},
+ {&DXVA2_ModeH264_E, "H.264 VLD, no FGT"},
+ {&DXVA2_ModeH264_F, "H.264 VLD, FGT"},
+
+ /* MPEG 2 */
+ {&DXVA2_ModeMPEG2_IDCT, "MPEG-2 IDCT"},
+ {&DXVA2_ModeMPEG2_MoComp, "MPEG-2 MoComp"},
+ {&DXVA2_ModeMPEG2_VLD, "MPEG-2 VLD"},
+
+ /* VC-1 */
+ {&DXVA2_ModeVC1_A, "VC-1 post processing"},
+ {&DXVA2_ModeVC1_B, "VC-1 MoComp"},
+ {&DXVA2_ModeVC1_C, "VC-1 IDCT"},
+ {&DXVA2_ModeVC1_D, "VC-1 VLD"},
+
+ /* WMV8 */
+ {&DXVA2_ModeWMV8_A, "WMV 8 post processing"},
+ {&DXVA2_ModeWMV8_B, "WMV 8 MoComp"},
+
+ /* WMV9 */
+ {&DXVA2_ModeWMV9_A, "WMV 9 post processing"},
+ {&DXVA2_ModeWMV9_B, "WMV 9 MoComp"},
+ {&DXVA2_ModeWMV9_C, "WMV 9 IDCT"},
+};
+
+struct decoder_test
+{
+ const GUID *guid;
+ UINT width;
+ UINT height;
+ UINT surface_count;
+ BOOL supported;
+};
+
+struct decoder_test decoder_tests[] =
+{
+ {&DXVA2_ModeMPEG2_VLD, 720, 576, 3, FALSE},
+ {&DXVA2_ModeH264_E, 720, 576, 17, FALSE},
+};
+
+static const char* convert_decoderguid_to_str(const GUID *guid)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(decoder_names) / sizeof(decoder_names[0]); i++)
+ {
+ if (IsEqualGUID(guid, decoder_names[i].guid))
+ return decoder_names[i].name;
+ }
+
+ return wine_dbgstr_guid(guid);
+}
+
+HRESULT (WINAPI* pDXVA2CreateVideoService)(IDirect3DDevice9 *device, REFIID riid, void **ppv);
+
+static BOOL init_dxva2(void)
+{
+ HMODULE dxva2 = LoadLibraryA("dxva2.dll");
+ if (!dxva2)
+ {
+ win_skip("dxva2.dll not available\n");
+ return FALSE;
+ }
+
+ pDXVA2CreateVideoService = (void *)GetProcAddress(dxva2, "DXVA2CreateVideoService");
+ return TRUE;
+}
+
+static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window)
+{
+ D3DPRESENT_PARAMETERS present_parameters = {0};
+ IDirect3DDevice9 *device;
+ DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
+
+ present_parameters.BackBufferWidth = 640;
+ present_parameters.BackBufferHeight = 480;
+ present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
+ present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ present_parameters.hDeviceWindow = focus_window;
+ present_parameters.Windowed = TRUE;
+ present_parameters.EnableAutoDepthStencil = FALSE;
+
+ if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
+ behavior_flags, &present_parameters, &device)))
+ return device;
+
+ return NULL;
+}
+
+static BOOL create_video_service(HWND focus_window, REFIID riid, void **service)
+{
+ IDirect3DDevice9 *device;
+ IDirect3D9 *d3d9;
+ HRESULT hr;
+
+ d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+ if (!d3d9) return FALSE;
+
+ device = create_device(d3d9, focus_window);
+ IDirect3D9_Release(d3d9);
+ if(!device)
+ return FALSE;
+
+ hr = pDXVA2CreateVideoService(device, riid, service);
+ IDirect3DDevice9_Release(device);
+ if (hr) return FALSE;
+
+ return TRUE;
+}
+
+static inline void test_buffer(IDirectXVideoDecoder *decoder, UINT type, const char *name)
+{
+ void *buffer;
+ UINT size;
+ HRESULT hr;
+
+ hr = IDirectXVideoDecoder_GetBuffer(decoder, type, &buffer, &size);
+ ok(!hr, "Failed to get buffer %s: %x\n", name, hr);
+ if (!hr) IDirectXVideoDecoder_ReleaseBuffer(decoder, type);
+}
+
+static void test_decoding(IDirectXVideoDecoder *decoder, REFGUID const guid, IDirect3DSurface9 **surfaces)
+{
+ HRESULT hr;
+
+ hr = IDirectXVideoDecoder_BeginFrame(decoder, surfaces[0], NULL);
+ ok(!hr, "Failed to begin frame for: %s\n", convert_decoderguid_to_str(guid));
+ if (hr) return;
+
+ test_buffer(decoder, DXVA2_PictureParametersBufferType, "DXVA2_PictureParametersBuffer");
+ test_buffer(decoder, DXVA2_InverseQuantizationMatrixBufferType, "DXVA2_InverseQuantizationMatrixBuffer");
+ test_buffer(decoder, DXVA2_SliceControlBufferType, "DXVA2_SliceControlBuffer");
+ test_buffer(decoder, DXVA2_BitStreamDateBufferType, "DXVA2_BitStreamDateBuffer");
+
+ IDirectXVideoDecoder_EndFrame(decoder, NULL);
+}
+
+static void test_decoder_resolution(IDirectXVideoDecoderService *service, REFGUID const guid, D3DFORMAT format,
+ UINT width, UINT height, UINT surface_count)
+{
+ HRESULT hr;
+ DXVA2_VideoDesc desc;
+ UINT count;
+ DXVA2_ConfigPictureDecode *configs;
+ DXVA2_ConfigPictureDecode config;
+ IDirect3DSurface9 **surfaces;
+ IDirectXVideoDecoder *decoder;
+ unsigned int i;
+
+ trace("Analysing buffer sizes for: %s (%u x %u)\n", convert_decoderguid_to_str(guid), width, height);
+
+ memset(&desc, 0, sizeof(desc));
+
+ desc.SampleWidth = width;
+ desc.SampleHeight = height;
+ desc.Format = format;
+ desc.InputSampleFreq.Numerator = 25;
+ desc.InputSampleFreq.Denominator = 1;
+ desc.OutputFrameFreq.Numerator = 25;
+ desc.OutputFrameFreq.Denominator = 1;
+
+ if (0) /* crashes on windows */
+ {
+ hr = IDirectXVideoDecoderService_GetDecoderConfigurations(service, guid, &desc, NULL, NULL, NULL);
+ ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr);
+
+ hr = IDirectXVideoDecoderService_GetDecoderConfigurations(service, guid, &desc, NULL, &count, NULL);
+ ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr);
+
+ hr = IDirectXVideoDecoderService_GetDecoderConfigurations(service, guid, &desc, NULL, NULL, &configs);
+ ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr);
+ }
+
+ hr = IDirectXVideoDecoderService_GetDecoderConfigurations(service, &GUID_NULL, &desc, NULL, &count, &configs);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %x\n", hr);
+
+ hr = IDirectXVideoDecoderService_GetDecoderConfigurations(service, guid, &desc, NULL, &count, &configs);
+ ok(!hr, "Failed to get decoder configuration for: %s\n", convert_decoderguid_to_str(guid));
+ if (hr) return;
+
+ if (!count)
+ {
+ skip("Decoder for %s does not support a single decoder configuration? Skipping test\n",
+ convert_decoderguid_to_str(guid));
+ return;
+ }
+
+ memcpy(&config, &configs[0], sizeof(config));
+ CoTaskMemFree(configs);
+
+ surfaces = (void*)HeapAlloc(GetProcessHeap(), 0, surface_count * sizeof(IDirect3DSurface9));
+ if (!surfaces)
+ {
+ skip("Failed to allocate memory for surfaces\n");
+ return;
+ }
+
+ hr = IDirectXVideoDecoderService_CreateSurface(service, width, height, surface_count-1, format, D3DPOOL_DEFAULT, 0,
+ DXVA2_VideoDecoderRenderTarget, surfaces, NULL);
+ ok(!hr, "Failed to create surfaces: %x\n", hr);
+ if (hr)
+ {
+ HeapFree(GetProcessHeap(), 0, surfaces);
+ return;
+ }
+
+ hr = IDirectXVideoDecoderService_CreateVideoDecoder(service, guid, &desc, &configs[0], surfaces, surface_count, &decoder);
+ ok(!hr, "Failed to create decoder for %s: %x\n", convert_decoderguid_to_str(guid), hr);
+ if (!hr)
+ {
+ test_decoding(decoder, guid, surfaces);
+ IDirectXVideoDecoder_Release(decoder);
+ }
+
+ for (i = 0; i < surface_count; i++)
+ IDirect3DSurface9_Release(surfaces[i]);
+
+ HeapFree(GetProcessHeap(), 0, surfaces);
+}
+
+static void test_decoder(IDirectXVideoDecoderService *service, REFGUID const guid, UINT width, UINT height,
+ UINT surface_count)
+{
+ HRESULT hr;
+ D3DFORMAT *formats;
+ D3DFORMAT test_format;
+ UINT count;
+
+ if (0) /* crashes on windows */
+ {
+ hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, NULL, NULL);
+ ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr);
+
+ hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, &count, NULL);
+ ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr);
+
+ hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, NULL, &formats);
+ ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr);
+ }
+
+ hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, &GUID_NULL, &count, &formats);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %x\n", hr);
+
+ hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(service, guid, &count, &formats);
+ ok(!hr, "Failed to get formats for codec %s\n", convert_decoderguid_to_str(guid));
+ if (hr) return;
+
+ if (!count)
+ {
+ skip("Decoder for %s does not support a single output format? Skipping test\n",
+ convert_decoderguid_to_str(guid));
+ return;
+ }
+
+ test_format = formats[0];
+ CoTaskMemFree(formats);
+
+ test_decoder_resolution(service, guid, test_format, width, height, surface_count);
+}
+
+static void test_decoder_service(HWND focus_window)
+{
+ IDirectXVideoDecoderService *service;
+ unsigned int i, j;
+ HRESULT hr;
+ UINT count;
+ GUID *guids;
+
+ if (!create_video_service(focus_window, &IID_IDirectXVideoDecoderService, (void**)&service))
+ {
+ skip("Failed to create video decoder service, skipping decoder service tests\n");
+ return;
+ }
+
+ hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(service, &count, &guids);
+ if (hr)
+ {
+ skip("Failed to get decoder guids: %x\n", hr);
+ return;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ trace("supported codec: %s\n", convert_decoderguid_to_str(&guids[i]));
+
+ for (j = 0; j < sizeof(decoder_tests) / sizeof(decoder_tests[0]); j++)
+ {
+ if (IsEqualGUID(&guids[i], decoder_tests[j].guid))
+ decoder_tests[j].supported = TRUE;
+ }
+ }
+
+ CoTaskMemFree(guids);
+
+ for (i = 0; i < sizeof(decoder_tests) / sizeof(decoder_tests[0]); i++)
+ {
+ if (!decoder_tests[i].supported)
+ {
+ skip("Decoder %s not supported, skipping test\n", convert_decoderguid_to_str(decoder_tests[i].guid));
+ continue;
+ }
+
+ test_decoder(service, decoder_tests[i].guid, decoder_tests[i].width,
+ decoder_tests[i].height, decoder_tests[i].surface_count);
+ }
+
+ IDirectXVideoDecoderService_Release(service);
+}
+
+START_TEST(dxva2)
+{
+ HWND window;
+
+ if (!init_dxva2())
+ return;
+
+ window = CreateWindowA("static", "dxva2_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, NULL, NULL, NULL, NULL);
+
+ ok(window != NULL, "couldn't create window\n");
+ if (!window) return;
+
+ test_decoder_service(window);
+}
--
2.1.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
Fixes: Support for MPEG2 DXVA2 GPU video decoding through vaapi
Fixes: Support for H264 DXVA2 GPU video decoding through vaapi
Depends: winecfg-Staging

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
From 9741c7941627cf4a0aba5e6dcd02bc1d991cea7f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 21 Feb 2015 23:37:26 +0100
Subject: winecfg: Add checkbox to enable/disable vaapi GPU decoder.
---
programs/winecfg/resource.h | 1 +
programs/winecfg/staging.c | 20 ++++++++++++++++++++
programs/winecfg/winecfg.rc | 1 +
3 files changed, 22 insertions(+)
diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h
index 02d90fd..4b21d16 100644
--- a/programs/winecfg/resource.h
+++ b/programs/winecfg/resource.h
@@ -212,6 +212,7 @@
/* Staging tab */
#define IDC_ENABLE_CSMT 9001
+#define IDC_ENABLE_VAAPI 9002
/* About tab */
#define IDC_ABT_OWNER 8432
diff --git a/programs/winecfg/staging.c b/programs/winecfg/staging.c
index 09c0d3f..bda2e6e 100644
--- a/programs/winecfg/staging.c
+++ b/programs/winecfg/staging.c
@@ -49,10 +49,26 @@ static void csmt_set(BOOL status)
set_reg_key(config_key, keypath("DllRedirects"), "wined3d", status ? "wined3d-csmt.dll" : NULL);
}
+/*
+ * DXVA2
+ */
+static BOOL vaapi_get(void)
+{
+ BOOL ret;
+ char *value = get_reg_key(config_key, keypath("DXVA2"), "backend", NULL);
+ ret = (value && !strcmp(value, "va"));
+ HeapFree(GetProcessHeap(), 0, value);
+ return ret;
+}
+static void vaapi_set(BOOL status)
+{
+ set_reg_key(config_key, keypath("DXVA2"), "backend", status ? "va" : NULL);
+}
static void load_staging_settings(HWND dialog)
{
CheckDlgButton(dialog, IDC_ENABLE_CSMT, csmt_get() ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(dialog, IDC_ENABLE_VAAPI, vaapi_get() ? BST_CHECKED : BST_UNCHECKED);
}
INT_PTR CALLBACK StagingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -82,6 +98,10 @@ INT_PTR CALLBACK StagingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
csmt_set(IsDlgButtonChecked(hDlg, IDC_ENABLE_CSMT) == BST_CHECKED);
SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
return TRUE;
+ case IDC_ENABLE_VAAPI:
+ vaapi_set(IsDlgButtonChecked(hDlg, IDC_ENABLE_VAAPI) == BST_CHECKED);
+ SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
}
break;
}
diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc
index a723880..694bd73 100644
--- a/programs/winecfg/winecfg.rc
+++ b/programs/winecfg/winecfg.rc
@@ -314,6 +314,7 @@ BEGIN
GROUPBOX "Staging settings",IDC_STATIC,8,4,244,210
LTEXT "The following settings are experimental and may break stuff!\nMake sure to reset them again in case of a problem.",IDC_STATIC,16,16,230,16
CONTROL "Enable &CSMT for better graphic performance",IDC_ENABLE_CSMT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,40,230,8
+ CONTROL "Enable &VAAPI as backend for DXVA2 GPU decoding",IDC_ENABLE_VAAPI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,55,230,8
END
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
--
2.1.0