mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patch for MPEG2/H264 DXVA2 video decoding through vaapi.
This commit is contained in:
parent
8f19269b34
commit
44ea94f633
@ -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
1
debian/changelog
vendored
@ -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).
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,543 @@
|
||||
From 1b237c190789f62c00be35e5b3916b1bfb6283df Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Tue, 10 Feb 2015 16:54:21 +0100
|
||||
Subject: dxva2: Implement stubbed interfaces for
|
||||
IDirectXVideo{Acceleration,Decoder,Processor}Service.
|
||||
|
||||
---
|
||||
dlls/dxva2/Makefile.in | 1 +
|
||||
dlls/dxva2/devicemanager.c | 4 +-
|
||||
dlls/dxva2/dxva2_private.h | 1 +
|
||||
dlls/dxva2/main.c | 4 +-
|
||||
dlls/dxva2/videoservices.c | 467 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 473 insertions(+), 4 deletions(-)
|
||||
create mode 100644 dlls/dxva2/videoservices.c
|
||||
|
||||
diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in
|
||||
index ffa7fe8..02c9758 100644
|
||||
--- a/dlls/dxva2/Makefile.in
|
||||
+++ b/dlls/dxva2/Makefile.in
|
||||
@@ -3,4 +3,5 @@ IMPORTS = ole32
|
||||
|
||||
C_SRCS = \
|
||||
main.c \
|
||||
+ videoservices.c \
|
||||
devicemanager.c
|
||||
diff --git a/dlls/dxva2/devicemanager.c b/dlls/dxva2/devicemanager.c
|
||||
index 15d78aa..b9ed76c 100644
|
||||
--- a/dlls/dxva2/devicemanager.c
|
||||
+++ b/dlls/dxva2/devicemanager.c
|
||||
@@ -169,9 +169,9 @@ static HRESULT WINAPI Direct3DDeviceManager9_GetVideoService( IDirect3DDeviceMan
|
||||
{
|
||||
Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
|
||||
|
||||
- FIXME("(%p)->(%p, %p, %p): stub\n", This, hDevice, riid, ppService);
|
||||
+ FIXME("(%p)->(%p, %p, %p): semi-stub\n", This, hDevice, riid, ppService);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ return videoservice_create( (IDirect3DDevice9 *)hDevice, riid, ppService );
|
||||
}
|
||||
|
||||
static const IDirect3DDeviceManager9Vtbl Direct3DDeviceManager9_VTable =
|
||||
diff --git a/dlls/dxva2/dxva2_private.h b/dlls/dxva2/dxva2_private.h
|
||||
index d6e59fc..a88809c 100644
|
||||
--- a/dlls/dxva2/dxva2_private.h
|
||||
+++ b/dlls/dxva2/dxva2_private.h
|
||||
@@ -18,4 +18,5 @@
|
||||
|
||||
#include "dxva2api.h"
|
||||
|
||||
+extern HRESULT videoservice_create( IDirect3DDevice9 *device, REFIID riid, void **ppv ) DECLSPEC_HIDDEN;
|
||||
extern HRESULT devicemanager_create( UINT *resetToken, void **ppv ) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/dxva2/main.c b/dlls/dxva2/main.c
|
||||
index e9d43d3..355e11f 100644
|
||||
--- a/dlls/dxva2/main.c
|
||||
+++ b/dlls/dxva2/main.c
|
||||
@@ -49,9 +49,9 @@ HRESULT WINAPI DXVA2CreateDirect3DDeviceManager9( UINT *resetToken, IDirect3DDev
|
||||
|
||||
HRESULT WINAPI DXVA2CreateVideoService( IDirect3DDevice9 *device, REFIID riid, void **ppv )
|
||||
{
|
||||
- FIXME("(%p, %s, %p): stub\n", device, debugstr_guid(riid), ppv);
|
||||
+ TRACE("(%p, %s, %p)\n", device, debugstr_guid(riid), ppv);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ return videoservice_create( device, riid, ppv );
|
||||
}
|
||||
|
||||
BOOL WINAPI DegaussMonitor( HMONITOR monitor )
|
||||
diff --git a/dlls/dxva2/videoservices.c b/dlls/dxva2/videoservices.c
|
||||
new file mode 100644
|
||||
index 0000000..936aa37
|
||||
--- /dev/null
|
||||
+++ b/dlls/dxva2/videoservices.c
|
||||
@@ -0,0 +1,467 @@
|
||||
+/*
|
||||
+ * 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 <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
|
||||
+{
|
||||
+ IDirectXVideoAccelerationService IDirectXVideoAccelerationService_iface;
|
||||
+ IDirectXVideoDecoderService IDirectXVideoDecoderService_iface;
|
||||
+ IDirectXVideoProcessorService IDirectXVideoProcessorService_iface;
|
||||
+
|
||||
+ LONG refCount;
|
||||
+ IDirect3DDevice9 *device;
|
||||
+} DirectXVideoAccelerationServiceImpl;
|
||||
+
|
||||
+static BOOL is_h264_codec( REFGUID guid )
|
||||
+{
|
||||
+ return (IsEqualGUID(guid, &DXVA2_ModeH264_A) ||
|
||||
+ IsEqualGUID(guid, &DXVA2_ModeH264_B) ||
|
||||
+ IsEqualGUID(guid, &DXVA2_ModeH264_C) ||
|
||||
+ IsEqualGUID(guid, &DXVA2_ModeH264_D) ||
|
||||
+ IsEqualGUID(guid, &DXVA2_ModeH264_E) ||
|
||||
+ IsEqualGUID(guid, &DXVA2_ModeH264_F));
|
||||
+}
|
||||
+
|
||||
+static inline DirectXVideoAccelerationServiceImpl *impl_from_IDirectXVideoAccelerationService( IDirectXVideoAccelerationService *iface )
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, DirectXVideoAccelerationServiceImpl, IDirectXVideoAccelerationService_iface);
|
||||
+}
|
||||
+
|
||||
+static inline DirectXVideoAccelerationServiceImpl *impl_from_IDirectXVideoDecoderService( IDirectXVideoDecoderService *iface )
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, DirectXVideoAccelerationServiceImpl, IDirectXVideoDecoderService_iface);
|
||||
+}
|
||||
+
|
||||
+static inline DirectXVideoAccelerationServiceImpl *impl_from_IDirectXVideoProcessorService( IDirectXVideoProcessorService *iface )
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, DirectXVideoAccelerationServiceImpl, IDirectXVideoProcessorService_iface);
|
||||
+}
|
||||
+
|
||||
+/*****************************************************************************
|
||||
+ * IDirectXVideoAccelerationService interface
|
||||
+ */
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoAccelerationService_QueryInterface( IDirectXVideoAccelerationService *iface, REFIID riid, LPVOID *ppv )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoAccelerationService(iface);
|
||||
+ TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_guid(riid), ppv);
|
||||
+
|
||||
+ *ppv = NULL;
|
||||
+
|
||||
+ if (IsEqualIID(riid, &IID_IUnknown))
|
||||
+ *ppv = &This->IDirectXVideoAccelerationService_iface;
|
||||
+ else if (IsEqualIID(riid, &IID_IDirectXVideoAccelerationService))
|
||||
+ *ppv = &This->IDirectXVideoAccelerationService_iface;
|
||||
+ else if (IsEqualIID(riid, &IID_IDirectXVideoDecoderService))
|
||||
+ *ppv = &This->IDirectXVideoDecoderService_iface;
|
||||
+ else if (IsEqualIID(riid, &IID_IDirectXVideoProcessorService))
|
||||
+ *ppv = &This->IDirectXVideoProcessorService_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 DirectXVideoAccelerationService_AddRef( IDirectXVideoAccelerationService *iface )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoAccelerationService(iface);
|
||||
+ ULONG refCount = InterlockedIncrement(&This->refCount);
|
||||
+
|
||||
+ TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
|
||||
+
|
||||
+ return refCount;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI DirectXVideoAccelerationService_Release( IDirectXVideoAccelerationService *iface )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoAccelerationService(iface);
|
||||
+ ULONG refCount = InterlockedDecrement(&This->refCount);
|
||||
+
|
||||
+ TRACE("(%p)->() Release from %d\n", This, refCount + 1);
|
||||
+
|
||||
+ if (!refCount)
|
||||
+ {
|
||||
+ TRACE("Destroying\n");
|
||||
+ IDirect3DDevice9_Release(This->device);
|
||||
+ CoTaskMemFree(This);
|
||||
+ }
|
||||
+
|
||||
+ return refCount;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoAccelerationService_CreateSurface( IDirectXVideoAccelerationService *iface, UINT width, UINT height,
|
||||
+ UINT backBuffers, D3DFORMAT format, D3DPOOL pool, DWORD usage, DWORD dxvaType, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoAccelerationService(iface);
|
||||
+ HRESULT hr = S_OK;
|
||||
+ int i;
|
||||
+
|
||||
+ FIXME("(%p)->(%u, %u, %u, %#x, 0x%x, 0x%x, 0x%x, %p, %p): semi-stub\n",
|
||||
+ This, width, height, backBuffers, format, pool, usage, dxvaType, ppSurface, pSharedHandle);
|
||||
+
|
||||
+ /* We create only backbuffers as the front buffer usually does not support this format */
|
||||
+ for (i = 0; i < backBuffers + 1; i++)
|
||||
+ {
|
||||
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->device, width, height, format,
|
||||
+ pool, &ppSurface[i], pSharedHandle);
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ while (i-- > 0)
|
||||
+ IDirect3DSurface9_Release(ppSurface[i]);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static const IDirectXVideoAccelerationServiceVtbl DirectXVideoAccelerationService_VTable =
|
||||
+{
|
||||
+ DirectXVideoAccelerationService_QueryInterface,
|
||||
+ DirectXVideoAccelerationService_AddRef,
|
||||
+ DirectXVideoAccelerationService_Release,
|
||||
+ DirectXVideoAccelerationService_CreateSurface
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/*****************************************************************************
|
||||
+ * IDirectXVideoDecoderService interface
|
||||
+ */
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoDecoderService_QueryInterface( IDirectXVideoDecoderService *iface, REFIID riid, LPVOID *ppv )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+
|
||||
+ TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_guid(riid), ppv);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_QueryInterface(&This->IDirectXVideoAccelerationService_iface, riid, ppv);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI DirectXVideoDecoderService_AddRef( IDirectXVideoDecoderService *iface )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_AddRef(&This->IDirectXVideoAccelerationService_iface);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI DirectXVideoDecoderService_Release( IDirectXVideoDecoderService *iface )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_Release(&This->IDirectXVideoAccelerationService_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoDecoderService_CreateSurface( IDirectXVideoDecoderService *iface, UINT width, UINT height, UINT backBuffers,
|
||||
+ D3DFORMAT format, D3DPOOL pool, DWORD usage, DWORD dxvaType, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%u, %u, %u, %#x, 0x%x, 0x%x, 0x%x, %p, %p): stub\n",
|
||||
+ iface, This, width, height, backBuffers, format, pool, usage, dxvaType, ppSurface, pSharedHandle);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_CreateSurface(&This->IDirectXVideoAccelerationService_iface,
|
||||
+ width, height, backBuffers, format, pool, usage, dxvaType, ppSurface, pSharedHandle);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoDecoderService_CreateVideoDecoder( IDirectXVideoDecoderService *iface, REFGUID guid,
|
||||
+ const DXVA2_VideoDesc *pVideoDesc, DXVA2_ConfigPictureDecode *pConfig, IDirect3DSurface9 **ppDecoderRenderTargets, UINT NumSurfaces,
|
||||
+ IDirectXVideoDecoder **ppDecode )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %p, %p, %u, %p): stub\n",
|
||||
+ iface, This, debugstr_guid(guid), pVideoDesc, pConfig, ppDecoderRenderTargets, NumSurfaces, ppDecode);
|
||||
+
|
||||
+ if (!guid || !pVideoDesc || !pConfig || !ppDecoderRenderTargets || !NumSurfaces || !ppDecode)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoDecoderService_GetDecoderConfigurations( IDirectXVideoDecoderService *iface, REFGUID guid,
|
||||
+ const DXVA2_VideoDesc *pVideoDesc, IUnknown *pReserved, UINT *pCount, DXVA2_ConfigPictureDecode **ppConfigs )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+ DXVA2_ConfigPictureDecode *config;
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %p, %p, %p): semi-stub\n",
|
||||
+ iface, This, debugstr_guid(guid), pVideoDesc, pReserved, pCount, ppConfigs);
|
||||
+
|
||||
+ if (!guid || !pVideoDesc || !pCount || !ppConfigs)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ config = CoTaskMemAlloc(sizeof(*config));
|
||||
+ if (!config)
|
||||
+ return E_OUTOFMEMORY;
|
||||
+
|
||||
+ /* TODO: Query decoder instead of using hardcoded values */
|
||||
+
|
||||
+ memcpy(&config->guidConfigBitstreamEncryption, &DXVA_NoEncrypt, sizeof(GUID));
|
||||
+ memcpy(&config->guidConfigMBcontrolEncryption, &DXVA_NoEncrypt, sizeof(GUID));
|
||||
+ memcpy(&config->guidConfigResidDiffEncryption, &DXVA_NoEncrypt, sizeof(GUID));
|
||||
+
|
||||
+ config->ConfigBitstreamRaw = 1;
|
||||
+ config->ConfigMBcontrolRasterOrder = is_h264_codec(guid) ? 0 : 1;
|
||||
+ config->ConfigResidDiffHost = 0; /* FIXME */
|
||||
+ config->ConfigSpatialResid8 = 0; /* FIXME */
|
||||
+ config->ConfigResid8Subtraction = 0; /* FIXME */
|
||||
+ config->ConfigSpatialHost8or9Clipping = 0; /* FIXME */
|
||||
+ config->ConfigSpatialResidInterleaved = 0; /* FIXME */
|
||||
+ config->ConfigIntraResidUnsigned = 0; /* FIXME */
|
||||
+ config->ConfigResidDiffAccelerator = 0;
|
||||
+ config->ConfigHostInverseScan = 0;
|
||||
+ config->ConfigSpecificIDCT = 1;
|
||||
+ config->Config4GroupedCoefs = 0;
|
||||
+ config->ConfigMinRenderTargetBuffCount = 3;
|
||||
+ config->ConfigDecoderSpecific = 0;
|
||||
+
|
||||
+ *pCount = 1;
|
||||
+ *ppConfigs = config;
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoDecoderService_GetDecoderDeviceGuids( IDirectXVideoDecoderService *iface, UINT *count, GUID **pGuids )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%p, %p): stub\n", iface, This, count, pGuids);
|
||||
+
|
||||
+ if (!count || !pGuids)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoDecoderService_GetDecoderRenderTargets( IDirectXVideoDecoderService *iface, REFGUID guid,
|
||||
+ UINT *pCount, D3DFORMAT **pFormats )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoDecoderService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %p): stub\n", iface, This, debugstr_guid(guid), pCount, pFormats);
|
||||
+
|
||||
+ if (!guid || !pCount || !pFormats)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static const IDirectXVideoDecoderServiceVtbl DirectXVideoDecoderService_VTable =
|
||||
+{
|
||||
+ DirectXVideoDecoderService_QueryInterface,
|
||||
+ DirectXVideoDecoderService_AddRef,
|
||||
+ DirectXVideoDecoderService_Release,
|
||||
+ DirectXVideoDecoderService_CreateSurface,
|
||||
+ DirectXVideoDecoderService_GetDecoderDeviceGuids,
|
||||
+ DirectXVideoDecoderService_GetDecoderRenderTargets,
|
||||
+ DirectXVideoDecoderService_GetDecoderConfigurations,
|
||||
+ DirectXVideoDecoderService_CreateVideoDecoder
|
||||
+};
|
||||
+
|
||||
+/*****************************************************************************
|
||||
+ * IDirectXVideoProcessorService interface
|
||||
+ */
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_QueryInterface( IDirectXVideoProcessorService *iface, REFIID riid, LPVOID *ppv )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_guid(riid), ppv);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_QueryInterface(&This->IDirectXVideoAccelerationService_iface, riid, ppv);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI DirectXVideoProcessorService_AddRef( IDirectXVideoProcessorService *iface )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_AddRef(&This->IDirectXVideoAccelerationService_iface);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI DirectXVideoProcessorService_Release( IDirectXVideoProcessorService *iface )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_Release(&This->IDirectXVideoAccelerationService_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_CreateSurface( IDirectXVideoProcessorService *iface, UINT width, UINT height,
|
||||
+ UINT backBuffers, D3DFORMAT format, D3DPOOL pool, DWORD usage, DWORD dxvaType, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%u, %u, %u, %#x, 0x%x, 0x%x, 0x%x, %p, %p): stub\n",
|
||||
+ iface, This, width, height, backBuffers, format, pool, usage, dxvaType, ppSurface, pSharedHandle);
|
||||
+
|
||||
+ return DirectXVideoAccelerationService_CreateSurface(&This->IDirectXVideoAccelerationService_iface,
|
||||
+ width, height, backBuffers, format, pool, usage, dxvaType, ppSurface, pSharedHandle);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_RegisterVideoProcessorSoftwareDevice( IDirectXVideoProcessorService *iface, void *pCallbacks)
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%p): stub\n", iface, This, pCallbacks);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_GetVideoProcessorDeviceGuids( IDirectXVideoProcessorService *iface,
|
||||
+ const DXVA2_VideoDesc *pVideoDesc, UINT *pCount, GUID **pGuids )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%p, %p, %p): stub\n", iface, This, pVideoDesc, pCount, pGuids);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_GetVideoProcessorRenderTargets( IDirectXVideoProcessorService *iface,
|
||||
+ REFGUID VideoProcDeviceGuid, const DXVA2_VideoDesc *pVideoDesc, UINT *pCount, D3DFORMAT **pFormats )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %p, %p): stub\n",
|
||||
+ iface, This, debugstr_guid(VideoProcDeviceGuid), pVideoDesc, pCount, pFormats);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_GetVideoProcessorSubStreamFormats( IDirectXVideoProcessorService *iface,
|
||||
+ REFGUID VideoProcDeviceGuid, const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT RenderTargetFormat, UINT *pCount, D3DFORMAT **pFormats )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %#x, %p, %p): stub\n",
|
||||
+ iface, This, debugstr_guid(VideoProcDeviceGuid), pVideoDesc, RenderTargetFormat, pCount, pFormats);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_GetVideoProcessorCaps( IDirectXVideoProcessorService *iface, REFGUID VideoProcDeviceGuid,
|
||||
+ const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT RenderTargetFormat, DXVA2_VideoProcessorCaps *pCaps)
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %#x, %p): stub\n",
|
||||
+ iface, This, debugstr_guid(VideoProcDeviceGuid), pVideoDesc, RenderTargetFormat, pCaps);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_GetProcAmpRange( IDirectXVideoProcessorService *iface, REFGUID VideoProcDeviceGuid,
|
||||
+ const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT RenderTargetFormat, UINT ProcAmpCap, DXVA2_ValueRange *pRange )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %#x, %u, %p): stub\n",
|
||||
+ iface, This, debugstr_guid(VideoProcDeviceGuid), pVideoDesc, RenderTargetFormat, ProcAmpCap, pRange);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_GetFilterPropertyRange( IDirectXVideoProcessorService *iface, REFGUID VideoProcDeviceGuid,
|
||||
+ const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT RenderTargetFormat, UINT FilterSetting, DXVA2_ValueRange *pRange )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %p, %#x, %u, %p): stub\n",
|
||||
+ iface, This, debugstr_guid(VideoProcDeviceGuid), pVideoDesc, RenderTargetFormat, FilterSetting, pRange);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI DirectXVideoProcessorService_CreateVideoProcessor( IDirectXVideoProcessorService *iface, REFGUID VideoProcDeviceGuid,
|
||||
+ const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT RenderTargetFormat, UINT MaxNumSubStreams, IDirectXVideoProcessor **ppVidProcess )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *This = impl_from_IDirectXVideoProcessorService(iface);
|
||||
+
|
||||
+ FIXME("(%p/%p)->(%s, %#x, %u, %p): stub\n",
|
||||
+ iface, This, debugstr_guid(VideoProcDeviceGuid), RenderTargetFormat, MaxNumSubStreams, ppVidProcess);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static const IDirectXVideoProcessorServiceVtbl DirectXVideoProcessorService_VTable =
|
||||
+{
|
||||
+ DirectXVideoProcessorService_QueryInterface,
|
||||
+ DirectXVideoProcessorService_AddRef,
|
||||
+ DirectXVideoProcessorService_Release,
|
||||
+ DirectXVideoProcessorService_CreateSurface,
|
||||
+ DirectXVideoProcessorService_RegisterVideoProcessorSoftwareDevice,
|
||||
+ DirectXVideoProcessorService_GetVideoProcessorDeviceGuids,
|
||||
+ DirectXVideoProcessorService_GetVideoProcessorRenderTargets,
|
||||
+ DirectXVideoProcessorService_GetVideoProcessorSubStreamFormats,
|
||||
+ DirectXVideoProcessorService_GetVideoProcessorCaps,
|
||||
+ DirectXVideoProcessorService_GetProcAmpRange,
|
||||
+ DirectXVideoProcessorService_GetFilterPropertyRange,
|
||||
+ DirectXVideoProcessorService_CreateVideoProcessor
|
||||
+};
|
||||
+
|
||||
+HRESULT videoservice_create( IDirect3DDevice9 *device, REFIID riid, void **ppv )
|
||||
+{
|
||||
+ DirectXVideoAccelerationServiceImpl *videoservice;
|
||||
+
|
||||
+ if (!device || !riid || !ppv)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ *ppv = NULL;
|
||||
+
|
||||
+ videoservice = CoTaskMemAlloc(sizeof(DirectXVideoAccelerationServiceImpl));
|
||||
+ if (!videoservice)
|
||||
+ return E_OUTOFMEMORY;
|
||||
+
|
||||
+ videoservice->IDirectXVideoAccelerationService_iface.lpVtbl = &DirectXVideoAccelerationService_VTable;
|
||||
+ videoservice->IDirectXVideoDecoderService_iface.lpVtbl = &DirectXVideoDecoderService_VTable;
|
||||
+ videoservice->IDirectXVideoProcessorService_iface.lpVtbl = &DirectXVideoProcessorService_VTable;
|
||||
+ videoservice->refCount = 1;
|
||||
+ videoservice->device = device;
|
||||
+
|
||||
+ if (IsEqualIID(riid, &IID_IUnknown))
|
||||
+ *ppv = &videoservice->IDirectXVideoAccelerationService_iface;
|
||||
+ else if (IsEqualIID(riid, &IID_IDirectXVideoAccelerationService))
|
||||
+ *ppv = &videoservice->IDirectXVideoAccelerationService_iface;
|
||||
+ else if (IsEqualIID(riid, &IID_IDirectXVideoDecoderService))
|
||||
+ *ppv = &videoservice->IDirectXVideoDecoderService_iface;
|
||||
+ else if (IsEqualIID(riid, &IID_IDirectXVideoProcessorService))
|
||||
+ *ppv = &videoservice->IDirectXVideoProcessorService_iface;
|
||||
+ else
|
||||
+ {
|
||||
+ CoTaskMemFree(videoservice);
|
||||
+ return E_NOINTERFACE;
|
||||
+ }
|
||||
+
|
||||
+ IDirect3DDevice9_AddRef(device);
|
||||
+ return S_OK;
|
||||
+}
|
||||
--
|
||||
2.1.0
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -0,0 +1,949 @@
|
||||
From b4de3e81cdf0ba928d75455c871742d86920de13 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:43:36 +0100
|
||||
Subject: dxva2: Implement h264 decoder.
|
||||
|
||||
---
|
||||
dlls/dxva2/Makefile.in | 1 +
|
||||
dlls/dxva2/dxva2_private.h | 3 +
|
||||
dlls/dxva2/vaapi-h264.c | 890 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/dxva2/vaapi.c | 2 +
|
||||
4 files changed, 896 insertions(+)
|
||||
create mode 100644 dlls/dxva2/vaapi-h264.c
|
||||
|
||||
diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in
|
||||
index 808173c..69ce4c8 100644
|
||||
--- a/dlls/dxva2/Makefile.in
|
||||
+++ b/dlls/dxva2/Makefile.in
|
||||
@@ -10,5 +10,6 @@ C_SRCS = \
|
||||
main.c \
|
||||
softwareprocessor.c \
|
||||
vaapi.c \
|
||||
+ vaapi-h264.c \
|
||||
vaapi-mpeg2.c \
|
||||
videoservices.c \
|
||||
diff --git a/dlls/dxva2/dxva2_private.h b/dlls/dxva2/dxva2_private.h
|
||||
index f518637..5df59bd 100644
|
||||
--- a/dlls/dxva2/dxva2_private.h
|
||||
+++ b/dlls/dxva2/dxva2_private.h
|
||||
@@ -134,5 +134,8 @@ extern BOOL vaapi_create_surfaces( VADisplay va_display, const struct vaapi_form
|
||||
extern HRESULT vaapi_mpeg2decoder_create( IWineVideoService *backend, const DXVA2_VideoDesc *videoDesc,
|
||||
DXVA2_ConfigPictureDecode *config, UINT numSurfaces,
|
||||
IWineVideoDecoder **decoder ) DECLSPEC_HIDDEN;
|
||||
+extern HRESULT vaapi_h264decoder_create( IWineVideoService *service, const DXVA2_VideoDesc *videoDesc,
|
||||
+ DXVA2_ConfigPictureDecode *config, UINT numSurfaces,
|
||||
+ IWineVideoDecoder **decoder ) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* HAVE_VAAPI */
|
||||
diff --git a/dlls/dxva2/vaapi-h264.c b/dlls/dxva2/vaapi-h264.c
|
||||
new file mode 100644
|
||||
index 0000000..1a5817e
|
||||
--- /dev/null
|
||||
+++ b/dlls/dxva2/vaapi-h264.c
|
||||
@@ -0,0 +1,890 @@
|
||||
+/*
|
||||
+ * Copyright 2014-2015 Michael Müller for Pipelight
|
||||
+ * Copyright 2014-2015 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 "config.h"
|
||||
+#include <stdarg.h>
|
||||
+#include <assert.h>
|
||||
+#include "windef.h"
|
||||
+#include "winbase.h"
|
||||
+
|
||||
+#include "wine/debug.h"
|
||||
+
|
||||
+#define COBJMACROS
|
||||
+#include "d3d9.h"
|
||||
+#include "dxva2api.h"
|
||||
+#include "dxva.h"
|
||||
+#include "dxva2_private.h"
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(dxva2);
|
||||
+
|
||||
+#ifdef HAVE_VAAPI
|
||||
+
|
||||
+#define MAX_SLICES 4096
|
||||
+
|
||||
+#define SLICE_TYPE_P 0
|
||||
+#define SLICE_TYPE_B 1
|
||||
+#define SLICE_TYPE_I 2
|
||||
+#define SLICE_TYPE_SP 3
|
||||
+#define SLICE_TYPE_SI 4
|
||||
+
|
||||
+static inline UINT estimate_maximum_slice_size( UINT width, UINT height )
|
||||
+{
|
||||
+ return (2 * width * height * min(width, height)) / max(width, height);
|
||||
+}
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ IWineVideoDecoder IWineVideoDecoder_iface;
|
||||
+ LONG refCount;
|
||||
+ IWineVideoService *service;
|
||||
+
|
||||
+ /* video attributes */
|
||||
+ UINT width;
|
||||
+ UINT height;
|
||||
+ D3DFORMAT format;
|
||||
+ DWORD maxSliceSize;
|
||||
+ VAImage vaImage;
|
||||
+
|
||||
+ /* surfaces used by this decoder */
|
||||
+ UINT surfaceCount;
|
||||
+ VASurfaceID *surfaces;
|
||||
+ UINT currentSurface;
|
||||
+
|
||||
+ /* configuration and context of the decoder */
|
||||
+ VAConfigID config;
|
||||
+ VAContextID context;
|
||||
+
|
||||
+ /* slice buffer id */
|
||||
+ VABufferID vaBitstream;
|
||||
+ DXVA_PicParams_H264 d3dPictureParam;
|
||||
+ DXVA_Qmatrix_H264 d3dQMatrix;
|
||||
+ DXVA_Slice_H264_Long d3dSliceInfo[MAX_SLICES];
|
||||
+} WineVideoDecoderH264Impl;
|
||||
+
|
||||
+/* caller has to hold the vaapi_lock */
|
||||
+static HRESULT process_picture_parameters( WineVideoDecoderH264Impl *This, const DXVA2_DecodeBufferDesc *desc )
|
||||
+{
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAPictureParameterBufferH264 params;
|
||||
+ VABufferID vaPictureParam;
|
||||
+ VAStatus status;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (desc->DataSize != sizeof(This->d3dPictureParam))
|
||||
+ FIXME("unexpected picture parameter buffer size %u\n", desc->DataSize);
|
||||
+
|
||||
+ /* check for valid parameters */
|
||||
+ if (This->d3dPictureParam.CurrPic.Index7Bits > This->surfaceCount)
|
||||
+ {
|
||||
+ ERR("invalid picture reference index\n");
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ if (!This->d3dPictureParam.ContinuationFlag)
|
||||
+ FIXME("ContinuationFlag = 0 unsupported, decoding may fail\n");
|
||||
+
|
||||
+
|
||||
+ memset(¶ms, 0, sizeof(params));
|
||||
+
|
||||
+ params.CurrPic.picture_id = This->surfaces[This->d3dPictureParam.CurrPic.Index7Bits];
|
||||
+ params.CurrPic.frame_idx = This->d3dPictureParam.frame_num; /* FIXME - guessed */
|
||||
+
|
||||
+ if (This->d3dPictureParam.field_pic_flag)
|
||||
+ params.CurrPic.flags = This->d3dPictureParam.CurrPic.AssociatedFlag ? VA_PICTURE_H264_BOTTOM_FIELD : VA_PICTURE_H264_TOP_FIELD;
|
||||
+
|
||||
+ if (This->d3dPictureParam.RefPicFlag)
|
||||
+ params.CurrPic.flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
||||
+ /* FIXME: Distinguish between short term and longterm references */
|
||||
+
|
||||
+ params.CurrPic.TopFieldOrderCnt = This->d3dPictureParam.CurrFieldOrderCnt[0] & 0xffff;
|
||||
+ params.CurrPic.BottomFieldOrderCnt = This->d3dPictureParam.CurrFieldOrderCnt[1] & 0xffff;
|
||||
+
|
||||
+ for (i = 0; i < 16; i++)
|
||||
+ {
|
||||
+ unsigned int flags = 0;
|
||||
+
|
||||
+ if (This->d3dPictureParam.RefFrameList[i].Index7Bits == 127)
|
||||
+ {
|
||||
+ params.ReferenceFrames[i].picture_id = VA_INVALID_ID;
|
||||
+ params.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (This->d3dPictureParam.RefFrameList[i].Index7Bits >= This->surfaceCount)
|
||||
+ {
|
||||
+ FIXME("Out of range reference picture!\n");
|
||||
+ params.ReferenceFrames[i].picture_id = VA_INVALID_ID;
|
||||
+ params.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ params.ReferenceFrames[i].picture_id = This->surfaces[This->d3dPictureParam.RefFrameList[i].Index7Bits];
|
||||
+ params.ReferenceFrames[i].frame_idx = This->d3dPictureParam.FrameNumList[i];
|
||||
+
|
||||
+ /* TODO: check flag conversion again */
|
||||
+ if (This->d3dPictureParam.UsedForReferenceFlags & (1 << (2 * i + 0)))
|
||||
+ flags |= VA_PICTURE_H264_TOP_FIELD;
|
||||
+
|
||||
+ if (This->d3dPictureParam.UsedForReferenceFlags & (1 << (2 * i + 1)))
|
||||
+ flags |= VA_PICTURE_H264_BOTTOM_FIELD;
|
||||
+
|
||||
+ if (flags & VA_PICTURE_H264_TOP_FIELD || flags & VA_PICTURE_H264_BOTTOM_FIELD)
|
||||
+ {
|
||||
+ if (This->d3dPictureParam.RefFrameList[i].AssociatedFlag)
|
||||
+ flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
|
||||
+ else
|
||||
+ flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
||||
+ }
|
||||
+
|
||||
+ /* remove top and bottom field flag if we got a full frame */
|
||||
+ if ((flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) ==
|
||||
+ (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD))
|
||||
+ {
|
||||
+ flags &= ~(VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD);
|
||||
+ }
|
||||
+
|
||||
+ params.ReferenceFrames[i].flags = flags;
|
||||
+
|
||||
+ params.ReferenceFrames[i].TopFieldOrderCnt = This->d3dPictureParam.FieldOrderCntList[i][0] & 0xFFFF;
|
||||
+ params.ReferenceFrames[i].BottomFieldOrderCnt = This->d3dPictureParam.FieldOrderCntList[i][1] & 0xFFFF;
|
||||
+ }
|
||||
+
|
||||
+ params.picture_width_in_mbs_minus1 = This->d3dPictureParam.wFrameWidthInMbsMinus1;
|
||||
+ params.picture_height_in_mbs_minus1 = This->d3dPictureParam.wFrameHeightInMbsMinus1;
|
||||
+ params.bit_depth_luma_minus8 = This->d3dPictureParam.bit_depth_luma_minus8;
|
||||
+ params.bit_depth_chroma_minus8 = This->d3dPictureParam.bit_depth_chroma_minus8;
|
||||
+ params.num_ref_frames = This->d3dPictureParam.num_ref_frames;
|
||||
+
|
||||
+ params.seq_fields.bits.chroma_format_idc = This->d3dPictureParam.chroma_format_idc;
|
||||
+ params.seq_fields.bits.residual_colour_transform_flag = This->d3dPictureParam.residual_colour_transform_flag;
|
||||
+ params.seq_fields.bits.gaps_in_frame_num_value_allowed_flag = FALSE; /* FIXME */
|
||||
+ params.seq_fields.bits.frame_mbs_only_flag = This->d3dPictureParam.frame_mbs_only_flag;
|
||||
+ params.seq_fields.bits.mb_adaptive_frame_field_flag = This->d3dPictureParam.MbaffFrameFlag;
|
||||
+ params.seq_fields.bits.direct_8x8_inference_flag = This->d3dPictureParam.direct_8x8_inference_flag;
|
||||
+ params.seq_fields.bits.MinLumaBiPredSize8x8 = This->d3dPictureParam.MinLumaBipredSize8x8Flag;
|
||||
+ params.seq_fields.bits.log2_max_frame_num_minus4 = This->d3dPictureParam.log2_max_frame_num_minus4;
|
||||
+ params.seq_fields.bits.pic_order_cnt_type = This->d3dPictureParam.pic_order_cnt_type;
|
||||
+ params.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = This->d3dPictureParam.log2_max_pic_order_cnt_lsb_minus4;
|
||||
+ params.seq_fields.bits.delta_pic_order_always_zero_flag = This->d3dPictureParam.delta_pic_order_always_zero_flag;
|
||||
+
|
||||
+ params.num_slice_groups_minus1 = This->d3dPictureParam.num_slice_groups_minus1;
|
||||
+ params.slice_group_map_type = This->d3dPictureParam.slice_group_map_type;
|
||||
+ params.slice_group_change_rate_minus1 = This->d3dPictureParam.slice_group_change_rate_minus1;
|
||||
+ params.pic_init_qp_minus26 = This->d3dPictureParam.pic_init_qp_minus26;
|
||||
+ params.pic_init_qs_minus26 = This->d3dPictureParam.pic_init_qs_minus26;
|
||||
+ params.chroma_qp_index_offset = This->d3dPictureParam.chroma_qp_index_offset;
|
||||
+ params.second_chroma_qp_index_offset = This->d3dPictureParam.second_chroma_qp_index_offset;
|
||||
+ params.pic_fields.bits.entropy_coding_mode_flag = This->d3dPictureParam.entropy_coding_mode_flag;
|
||||
+
|
||||
+ params.pic_fields.bits.weighted_pred_flag = This->d3dPictureParam.weighted_pred_flag;
|
||||
+ params.pic_fields.bits.weighted_bipred_idc = This->d3dPictureParam.weighted_bipred_idc;
|
||||
+ params.pic_fields.bits.transform_8x8_mode_flag = This->d3dPictureParam.transform_8x8_mode_flag;
|
||||
+ params.pic_fields.bits.field_pic_flag = This->d3dPictureParam.field_pic_flag;
|
||||
+ params.pic_fields.bits.constrained_intra_pred_flag = This->d3dPictureParam.constrained_intra_pred_flag;
|
||||
+ params.pic_fields.bits.pic_order_present_flag = This->d3dPictureParam.pic_order_present_flag;
|
||||
+ params.pic_fields.bits.deblocking_filter_control_present_flag = This->d3dPictureParam.deblocking_filter_control_present_flag;
|
||||
+ params.pic_fields.bits.redundant_pic_cnt_present_flag = This->d3dPictureParam.redundant_pic_cnt_present_flag;
|
||||
+ params.pic_fields.bits.reference_pic_flag = This->d3dPictureParam.RefPicFlag;
|
||||
+
|
||||
+ params.frame_num = This->d3dPictureParam.frame_num;
|
||||
+
|
||||
+ status = pvaCreateBuffer(va_display, This->context, VAPictureParameterBufferType,
|
||||
+ sizeof(params), 1, ¶ms, &vaPictureParam);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to create picture parameter buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ /* vaRenderPicture is supposed to destroy the buffer */
|
||||
+ status = pvaRenderPicture(va_display, This->context, &vaPictureParam, 1);
|
||||
+ if (status == VA_STATUS_SUCCESS)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ ERR("failed to process picture parameter buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ pvaDestroyBuffer(va_display, vaPictureParam);
|
||||
+ return E_FAIL;
|
||||
+}
|
||||
+
|
||||
+/* caller has to hold the vaapi_lock */
|
||||
+static HRESULT process_quantization_matrix( WineVideoDecoderH264Impl *This, const DXVA2_DecodeBufferDesc *desc )
|
||||
+{
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAIQMatrixBufferH264 matrix;
|
||||
+ VABufferID vaIQMatrix;
|
||||
+ VAStatus status;
|
||||
+
|
||||
+ if (desc->DataSize != sizeof(This->d3dQMatrix))
|
||||
+ FIXME("unexpected quantization matrix buffer size %u\n", desc->DataSize);
|
||||
+
|
||||
+ memcpy(&matrix.ScalingList4x4, &This->d3dQMatrix.bScalingLists4x4, sizeof(matrix.ScalingList4x4));
|
||||
+ memcpy(&matrix.ScalingList8x8, &This->d3dQMatrix.bScalingLists8x8, sizeof(matrix.ScalingList8x8));
|
||||
+
|
||||
+ status = pvaCreateBuffer(va_display, This->context, VAIQMatrixBufferType,
|
||||
+ sizeof(matrix), 1, &matrix, &vaIQMatrix);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to create quantization matrix buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ /* vaRenderPicture is supposed to destroy the buffer */
|
||||
+ status = pvaRenderPicture(va_display, This->context, &vaIQMatrix, 1);
|
||||
+ if (status == VA_STATUS_SUCCESS)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ ERR("failed to process quantization matrix buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ pvaDestroyBuffer(va_display, vaIQMatrix);
|
||||
+ return E_FAIL;
|
||||
+}
|
||||
+
|
||||
+static void fill_reference_picture( WineVideoDecoderH264Impl *This, VAPictureH264 *pic, DXVA_PicEntry_H264 *dxva_pic )
|
||||
+{
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ pic->picture_id = dxva_pic->Index7Bits < This->surfaceCount ? This->surfaces[dxva_pic->Index7Bits] : VA_INVALID_ID;
|
||||
+ pic->frame_idx = 0;
|
||||
+
|
||||
+ if (This->d3dPictureParam.field_pic_flag)
|
||||
+ pic->flags = dxva_pic->AssociatedFlag ? VA_PICTURE_H264_BOTTOM_FIELD : VA_PICTURE_H264_TOP_FIELD;
|
||||
+ else
|
||||
+ pic->flags = 0;
|
||||
+
|
||||
+ pic->TopFieldOrderCnt = 0;
|
||||
+ pic->BottomFieldOrderCnt = 0;
|
||||
+
|
||||
+ for (i = 0; i < 16; i++)
|
||||
+ {
|
||||
+ if (This->d3dPictureParam.RefFrameList[i].Index7Bits != dxva_pic->Index7Bits)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((This->d3dPictureParam.UsedForReferenceFlags & (1 << (2 * i + 0))) ||
|
||||
+ (This->d3dPictureParam.UsedForReferenceFlags & (1 << (2 * i + 1))))
|
||||
+ {
|
||||
+ if (This->d3dPictureParam.RefFrameList[i].AssociatedFlag)
|
||||
+ pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
|
||||
+ else
|
||||
+ pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
||||
+ }
|
||||
+
|
||||
+ pic->frame_idx = This->d3dPictureParam.FrameNumList[i];
|
||||
+ pic->TopFieldOrderCnt = This->d3dPictureParam.FieldOrderCntList[i][0] & 0xFFFF;
|
||||
+ pic->BottomFieldOrderCnt = This->d3dPictureParam.FieldOrderCntList[i][1] & 0xFFFF;
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ WARN("Reference not found!\n");
|
||||
+}
|
||||
+
|
||||
+/* caller has to hold the vaapi_lock */
|
||||
+static HRESULT process_slice_control_buffer( WineVideoDecoderH264Impl *This, const DXVA2_DecodeBufferDesc *desc )
|
||||
+{
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VASliceParameterBufferH264 *slice = NULL;
|
||||
+ VABufferID vaSliceInfo;
|
||||
+ VAStatus status;
|
||||
+ unsigned int sliceCount, i, j;
|
||||
+
|
||||
+ /* check for valid parameters */
|
||||
+ if (!desc->DataSize || desc->DataSize % sizeof(DXVA_Slice_H264_Long) != 0)
|
||||
+ {
|
||||
+ ERR("slice control buffer size is invalid (got %u, expected multiple of %lu)\n",
|
||||
+ desc->DataSize, (SIZE_T)sizeof(DXVA_Slice_H264_Long));
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ sliceCount = desc->DataSize / sizeof(DXVA_Slice_H264_Long);
|
||||
+
|
||||
+ status = pvaCreateBuffer(va_display, This->context, VASliceParameterBufferType,
|
||||
+ sizeof(VASliceParameterBufferH264), sliceCount, NULL, &vaSliceInfo);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to create slice control buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ status = pvaMapBuffer(va_display, vaSliceInfo, (void **)&slice);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to map slice control buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < sliceCount; i++)
|
||||
+ {
|
||||
+ slice[i].slice_data_offset = This->d3dSliceInfo[i].BSNALunitDataLocation + 3;
|
||||
+ slice[i].slice_data_size = This->d3dSliceInfo[i].SliceBytesInBuffer - 3;
|
||||
+ slice[i].slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
|
||||
+ slice[i].slice_data_bit_offset = This->d3dSliceInfo[i].BitOffsetToSliceData + 8;
|
||||
+ slice[i].first_mb_in_slice = This->d3dSliceInfo[i].first_mb_in_slice;
|
||||
+ slice[i].slice_type = This->d3dSliceInfo[i].slice_type % 5;
|
||||
+ slice[i].direct_spatial_mv_pred_flag = This->d3dSliceInfo[i].direct_spatial_mv_pred_flag;
|
||||
+ if (slice[i].slice_type == SLICE_TYPE_I)
|
||||
+ {
|
||||
+ slice[i].num_ref_idx_l0_active_minus1 = 0;
|
||||
+ slice[i].num_ref_idx_l1_active_minus1 = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ slice[i].num_ref_idx_l0_active_minus1 = This->d3dSliceInfo[i].num_ref_idx_l0_active_minus1;
|
||||
+ slice[i].num_ref_idx_l1_active_minus1 = This->d3dSliceInfo[i].num_ref_idx_l1_active_minus1;
|
||||
+ }
|
||||
+ slice[i].cabac_init_idc = This->d3dSliceInfo[i].cabac_init_idc;
|
||||
+ slice[i].slice_qp_delta = This->d3dSliceInfo[i].slice_qp_delta;
|
||||
+ slice[i].disable_deblocking_filter_idc = This->d3dSliceInfo[i].disable_deblocking_filter_idc;
|
||||
+ slice[i].slice_alpha_c0_offset_div2 = This->d3dSliceInfo[i].slice_alpha_c0_offset_div2;
|
||||
+ slice[i].slice_beta_offset_div2 = This->d3dSliceInfo[i].slice_beta_offset_div2;
|
||||
+
|
||||
+ for (j = 0; j < 32; j++)
|
||||
+ {
|
||||
+ if (This->d3dSliceInfo[i].RefPicList[0][j].Index7Bits < This->surfaceCount)
|
||||
+ fill_reference_picture(This, &slice[i].RefPicList0[j], &This->d3dSliceInfo[i].RefPicList[0][j]);
|
||||
+ else
|
||||
+ {
|
||||
+ slice[i].RefPicList0[j].picture_id = VA_INVALID_ID;
|
||||
+ slice[i].RefPicList0[j].flags = VA_PICTURE_H264_INVALID;
|
||||
+ }
|
||||
+
|
||||
+ if (This->d3dSliceInfo[i].RefPicList[1][j].Index7Bits < This->surfaceCount)
|
||||
+ fill_reference_picture(This, &slice[i].RefPicList1[j], &This->d3dSliceInfo[i].RefPicList[1][j]);
|
||||
+ else
|
||||
+ {
|
||||
+ slice[i].RefPicList1[j].picture_id = VA_INVALID_ID;
|
||||
+ slice[i].RefPicList1[j].flags = VA_PICTURE_H264_INVALID;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ slice[i].luma_log2_weight_denom = This->d3dSliceInfo[i].luma_log2_weight_denom;
|
||||
+ slice[i].chroma_log2_weight_denom = This->d3dSliceInfo[i].chroma_log2_weight_denom;
|
||||
+
|
||||
+ slice[i].luma_weight_l0_flag = TRUE; /* FIXME */
|
||||
+ slice[i].chroma_weight_l0_flag = TRUE; /* FIXME */
|
||||
+ slice[i].luma_weight_l1_flag = TRUE; /* FIXME */
|
||||
+ slice[i].chroma_weight_l1_flag = TRUE; /* FIXME */
|
||||
+
|
||||
+ for (j = 0; j < 32; j++)
|
||||
+ {
|
||||
+ slice[i].luma_weight_l0[j] = This->d3dSliceInfo[i].Weights[0][j][0][0];
|
||||
+ slice[i].luma_offset_l0[j] = This->d3dSliceInfo[i].Weights[0][j][0][1];
|
||||
+
|
||||
+ slice[i].chroma_weight_l0[j][0] = This->d3dSliceInfo[i].Weights[0][j][1][0];
|
||||
+ slice[i].chroma_offset_l0[j][0] = This->d3dSliceInfo[i].Weights[0][j][1][1];
|
||||
+ slice[i].chroma_weight_l0[j][1] = This->d3dSliceInfo[i].Weights[0][j][2][0];
|
||||
+ slice[i].chroma_offset_l0[j][1] = This->d3dSliceInfo[i].Weights[0][j][2][1];
|
||||
+
|
||||
+ slice[i].luma_weight_l1[j] = This->d3dSliceInfo[i].Weights[1][j][0][0];
|
||||
+ slice[i].luma_offset_l1[j] = This->d3dSliceInfo[i].Weights[1][j][0][1];
|
||||
+
|
||||
+ slice[i].chroma_weight_l1[j][0] = This->d3dSliceInfo[i].Weights[1][j][1][0];
|
||||
+ slice[i].chroma_offset_l1[j][0] = This->d3dSliceInfo[i].Weights[1][j][1][1];
|
||||
+ slice[i].chroma_weight_l1[j][1] = This->d3dSliceInfo[i].Weights[1][j][2][0];
|
||||
+ slice[i].chroma_offset_l1[j][1] = This->d3dSliceInfo[i].Weights[1][j][2][1];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (pvaUnmapBuffer(va_display, vaSliceInfo) != VA_STATUS_SUCCESS)
|
||||
+ goto err;
|
||||
+
|
||||
+ /* vaRenderPicture is supposed to destroy the buffer */
|
||||
+ status = pvaRenderPicture(va_display, This->context, &vaSliceInfo, 1);
|
||||
+ if (status == VA_STATUS_SUCCESS)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ ERR("failed to process slice control buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+
|
||||
+err:
|
||||
+ pvaDestroyBuffer(va_display, vaSliceInfo);
|
||||
+ return E_FAIL;
|
||||
+}
|
||||
+
|
||||
+/* caller has to hold the vaapi_lock */
|
||||
+static HRESULT process_data_buffer( WineVideoDecoderH264Impl *This, const DXVA2_DecodeBufferDesc *desc )
|
||||
+{
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAStatus status;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ if (This->vaBitstream == VA_INVALID_ID)
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ /* vaRenderPicture is supposed to destroy the buffer */
|
||||
+ status = pvaRenderPicture(va_display, This->context, &This->vaBitstream, 1);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to process slice buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ pvaDestroyBuffer(va_display, This->vaBitstream);
|
||||
+ }
|
||||
+ else hr = S_OK;
|
||||
+
|
||||
+ This->vaBitstream = VA_INVALID_ID;
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static inline WineVideoDecoderH264Impl *impl_from_IWineVideoDecoder( IWineVideoDecoder *iface )
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, WineVideoDecoderH264Impl, IWineVideoDecoder_iface);
|
||||
+}
|
||||
+
|
||||
+/*****************************************************************************
|
||||
+ * IWineVideoDecoder interface
|
||||
+ */
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_QueryInterface( IWineVideoDecoder *iface, REFIID riid, void **ppv )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_guid(riid), ppv);
|
||||
+
|
||||
+ *ppv = NULL;
|
||||
+
|
||||
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IWineVideoDecoder))
|
||||
+ *ppv = &This->IWineVideoDecoder_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 WineVideoDecoderH264_AddRef( IWineVideoDecoder *iface )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ ULONG refCount = InterlockedIncrement(&This->refCount);
|
||||
+
|
||||
+ TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
|
||||
+
|
||||
+ return refCount;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI WineVideoDecoderH264_Release( IWineVideoDecoder *iface )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ ULONG refCount = InterlockedDecrement(&This->refCount);
|
||||
+
|
||||
+ TRACE("(%p)->() Release from %d\n", This, refCount + 1);
|
||||
+
|
||||
+ if (!refCount)
|
||||
+ {
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ TRACE("Destroying\n");
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ if (This->vaBitstream != VA_INVALID_ID)
|
||||
+ pvaDestroyBuffer(va_display, This->vaBitstream);
|
||||
+
|
||||
+ pvaDestroySurfaces(va_display, This->surfaces, This->surfaceCount);
|
||||
+ HeapFree(GetProcessHeap(), 0, This->surfaces);
|
||||
+
|
||||
+ pvaDestroyImage(va_display, This->vaImage.image_id);
|
||||
+
|
||||
+ pvaDestroyContext(va_display, This->context);
|
||||
+ pvaDestroyConfig(va_display, This->config);
|
||||
+
|
||||
+ vaapi_unlock();
|
||||
+
|
||||
+ IWineVideoService_Release(This->service);
|
||||
+ CoTaskMemFree(This);
|
||||
+ }
|
||||
+
|
||||
+ return refCount;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_LockBuffer( IWineVideoDecoder *iface, UINT type, void **buffer,
|
||||
+ UINT *size )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAStatus status;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+ void *buf;
|
||||
+
|
||||
+ TRACE("(%p, %u, %p, %p)\n", This, type, buffer, size);
|
||||
+
|
||||
+ if (type == DXVA2_PictureParametersBufferType)
|
||||
+ {
|
||||
+ *buffer = &This->d3dPictureParam;
|
||||
+ *size = sizeof(This->d3dPictureParam);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ else if(type == DXVA2_InverseQuantizationMatrixBufferType)
|
||||
+ {
|
||||
+ *buffer = &This->d3dQMatrix;
|
||||
+ *size = sizeof(This->d3dQMatrix);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ else if (type == DXVA2_SliceControlBufferType)
|
||||
+ {
|
||||
+ *buffer = &This->d3dSliceInfo;
|
||||
+ *size = sizeof(This->d3dSliceInfo);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ else if (type != DXVA2_BitStreamDateBufferType)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ /* reuse existing vaSlice buffer if any */
|
||||
+ if (This->vaBitstream == VA_INVALID_ID)
|
||||
+ {
|
||||
+ status = pvaCreateBuffer(va_display, This->context, VASliceDataBufferType,
|
||||
+ This->maxSliceSize, 1, NULL, &This->vaBitstream);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to create slice buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ status = pvaMapBuffer(va_display, This->vaBitstream, &buf);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to map slice buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ memset(buf, 0, This->maxSliceSize);
|
||||
+ *buffer = buf;
|
||||
+ *size = This->maxSliceSize;
|
||||
+ hr = S_OK;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ vaapi_unlock();
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_UnlockBuffer( IWineVideoDecoder *iface, UINT type )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAStatus status;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ TRACE("(%p, %u,)\n", This, type);
|
||||
+
|
||||
+ if (type == DXVA2_PictureParametersBufferType ||
|
||||
+ type == DXVA2_InverseQuantizationMatrixBufferType ||
|
||||
+ type == DXVA2_SliceControlBufferType)
|
||||
+ {
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ else if (type != DXVA2_BitStreamDateBufferType)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ if (This->vaBitstream == VA_INVALID_ID)
|
||||
+ {
|
||||
+ ERR("no slice buffer allocated\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ status = pvaUnmapBuffer(va_display, This->vaBitstream);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to unmap slice buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ }
|
||||
+ else hr = S_OK;
|
||||
+
|
||||
+out:
|
||||
+ vaapi_unlock();
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_ExecuteBuffer( IWineVideoDecoder *iface, DXVA2_DecodeBufferDesc *pictureParam,
|
||||
+ DXVA2_DecodeBufferDesc *qMatrix, DXVA2_DecodeBufferDesc *sliceInfo, DXVA2_DecodeBufferDesc *bitStream )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ TRACE("(%p, %p, %p, %p, %p)\n", This, pictureParam, qMatrix, sliceInfo, bitStream);
|
||||
+
|
||||
+ if (!pictureParam || !qMatrix || !sliceInfo || !bitStream)
|
||||
+ {
|
||||
+ FIXME("not enough buffers to decode picture\n");
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ hr = process_picture_parameters(This, pictureParam);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = process_quantization_matrix(This, qMatrix);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = process_slice_control_buffer(This, sliceInfo);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = process_data_buffer(This, bitStream);
|
||||
+
|
||||
+ vaapi_unlock();
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_BeginFrame( IWineVideoDecoder *iface, UINT surfaceIndex )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAStatus status;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ TRACE("(%p, %d)\n", This, surfaceIndex);
|
||||
+
|
||||
+ if (surfaceIndex >= This->surfaceCount)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ status = pvaBeginPicture(va_display, This->context, This->surfaces[surfaceIndex]);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to begin picture: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ This->currentSurface = surfaceIndex;
|
||||
+ hr = S_OK;
|
||||
+ }
|
||||
+
|
||||
+ vaapi_unlock();
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_EndFrame( IWineVideoDecoder *iface )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAStatus status;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ TRACE("(%p)\n", This);
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ status = pvaEndPicture(va_display, This->context);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("ending picture failed: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ }
|
||||
+ else hr = S_OK;
|
||||
+
|
||||
+ vaapi_unlock();
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_LockImage( IWineVideoDecoder *iface, WineVideoImage *image )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAStatus status;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ TRACE("(%p, %p)\n", This, image);
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ pvaSyncSurface(va_display, This->surfaces[This->currentSurface]);
|
||||
+
|
||||
+ status = pvaGetImage(va_display, This->surfaces[This->currentSurface], 0, 0,
|
||||
+ This->width, This->height, This->vaImage.image_id);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to get image: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ status = pvaMapBuffer(va_display, This->vaImage.buf, &image->buffer);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to map image buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ image->format = This->format;
|
||||
+ image->width = This->vaImage.width;
|
||||
+ image->height = This->vaImage.height;
|
||||
+ image->planeCount = This->vaImage.num_planes;
|
||||
+ image->offsets = This->vaImage.offsets;
|
||||
+ image->pitches = This->vaImage.pitches;
|
||||
+ hr = S_OK;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ vaapi_unlock();
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI WineVideoDecoderH264_UnlockImage( IWineVideoDecoder *iface )
|
||||
+{
|
||||
+ WineVideoDecoderH264Impl *This = impl_from_IWineVideoDecoder(iface);
|
||||
+ VADisplay va_display = IWineVideoService_VADisplay(This->service);
|
||||
+ VAStatus status;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ TRACE("(%p)\n", This);
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ status = pvaUnmapBuffer(va_display, This->vaImage.buf);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to unmap image buffer: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ }
|
||||
+ else hr = S_OK;
|
||||
+
|
||||
+ vaapi_unlock();
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static const IWineVideoDecoderVtbl WineVideoDecoderH264_VTable =
|
||||
+{
|
||||
+ WineVideoDecoderH264_QueryInterface,
|
||||
+ WineVideoDecoderH264_AddRef,
|
||||
+ WineVideoDecoderH264_Release,
|
||||
+ WineVideoDecoderH264_LockBuffer,
|
||||
+ WineVideoDecoderH264_UnlockBuffer,
|
||||
+ WineVideoDecoderH264_ExecuteBuffer,
|
||||
+ WineVideoDecoderH264_BeginFrame,
|
||||
+ WineVideoDecoderH264_EndFrame,
|
||||
+ WineVideoDecoderH264_LockImage,
|
||||
+ WineVideoDecoderH264_UnlockImage
|
||||
+};
|
||||
+
|
||||
+HRESULT vaapi_h264decoder_create( IWineVideoService *service, const DXVA2_VideoDesc *videoDesc,
|
||||
+ DXVA2_ConfigPictureDecode *config, UINT numSurfaces, IWineVideoDecoder **decoder )
|
||||
+{
|
||||
+ struct vaapi_format *format;
|
||||
+ struct vaapi_profile *profile;
|
||||
+ WineVideoDecoderH264Impl *h264decoder;
|
||||
+ VAConfigAttrib codecAttrib;
|
||||
+ VADisplay va_display;
|
||||
+ VAStatus status;
|
||||
+
|
||||
+ if (!service || !videoDesc || !config || !decoder)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ va_display = IWineVideoService_VADisplay(service);
|
||||
+ *decoder = NULL;
|
||||
+
|
||||
+ /* H264 requires at least 17 frames - 16 reference frames + 1 target */
|
||||
+ if (numSurfaces < 17)
|
||||
+ WARN("decoder initialized with less than 16 + 1 frames\n");
|
||||
+
|
||||
+ format = vaapi_lookup_d3dformat(videoDesc->Format);
|
||||
+ profile = vaapi_lookup_guid(&DXVA2_ModeH264_E);
|
||||
+ if (!format || !profile)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ if (!vaapi_is_format_supported(va_display, profile, format))
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ if (videoDesc->InputSampleFreq.Numerator * videoDesc->OutputFrameFreq.Denominator !=
|
||||
+ videoDesc->OutputFrameFreq.Numerator * videoDesc->InputSampleFreq.Denominator)
|
||||
+ {
|
||||
+ FIXME("Changing the framerate is not supported.\n");
|
||||
+ return E_INVALIDARG;
|
||||
+ }
|
||||
+
|
||||
+ h264decoder = CoTaskMemAlloc(sizeof(*h264decoder));
|
||||
+ if (!h264decoder)
|
||||
+ return E_OUTOFMEMORY;
|
||||
+
|
||||
+ memset(h264decoder, 0, sizeof(*h264decoder));
|
||||
+
|
||||
+ h264decoder->IWineVideoDecoder_iface.lpVtbl = &WineVideoDecoderH264_VTable;
|
||||
+ h264decoder->refCount = 1;
|
||||
+ h264decoder->service = service;
|
||||
+
|
||||
+ h264decoder->width = videoDesc->SampleWidth;
|
||||
+ h264decoder->height = videoDesc->SampleHeight;
|
||||
+ h264decoder->format = videoDesc->Format;
|
||||
+ h264decoder->maxSliceSize = estimate_maximum_slice_size(videoDesc->SampleWidth, videoDesc->SampleHeight);
|
||||
+ memset(&h264decoder->vaImage, 0, sizeof(h264decoder->vaImage));
|
||||
+ h264decoder->vaImage.image_id = VA_INVALID_ID;
|
||||
+
|
||||
+ h264decoder->surfaceCount = numSurfaces;
|
||||
+ h264decoder->surfaces = NULL;
|
||||
+ h264decoder->currentSurface = 0;
|
||||
+
|
||||
+ h264decoder->config = 0;
|
||||
+ h264decoder->context = 0;
|
||||
+
|
||||
+ h264decoder->vaBitstream = VA_INVALID_ID;
|
||||
+
|
||||
+ vaapi_lock();
|
||||
+
|
||||
+ codecAttrib.type = VAConfigAttribRTFormat;
|
||||
+ codecAttrib.value = format->vaformat;
|
||||
+
|
||||
+ status = pvaCreateConfig(va_display, profile->profile, profile->entryPoint,
|
||||
+ &codecAttrib, 1, &h264decoder->config);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to create decoder config: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (!vaapi_create_surfaces(va_display, format, h264decoder->width, h264decoder->height,
|
||||
+ &h264decoder->vaImage, numSurfaces, &h264decoder->surfaces))
|
||||
+ {
|
||||
+ ERR("Failed to create image or surfaces\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ status = pvaCreateContext(va_display, h264decoder->config, h264decoder->width, h264decoder->height,
|
||||
+ VA_PROGRESSIVE, h264decoder->surfaces, numSurfaces, &h264decoder->context);
|
||||
+ if (status != VA_STATUS_SUCCESS)
|
||||
+ {
|
||||
+ ERR("failed to create context: %s (0x%x)\n", pvaErrorStr(status), status);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ vaapi_unlock();
|
||||
+
|
||||
+ IWineVideoService_AddRef(service);
|
||||
+
|
||||
+ *decoder = &h264decoder->IWineVideoDecoder_iface;
|
||||
+ return S_OK;
|
||||
+
|
||||
+err:
|
||||
+ if (h264decoder->surfaces)
|
||||
+ {
|
||||
+ pvaDestroySurfaces(va_display, h264decoder->surfaces, h264decoder->surfaceCount);
|
||||
+ HeapFree(GetProcessHeap(), 0, h264decoder->surfaces);
|
||||
+ }
|
||||
+
|
||||
+ if (h264decoder->vaImage.image_id != VA_INVALID_ID)
|
||||
+ pvaDestroyImage(va_display, h264decoder->vaImage.image_id);
|
||||
+
|
||||
+ if (h264decoder->config)
|
||||
+ pvaDestroyConfig(va_display, h264decoder->config);
|
||||
+
|
||||
+ vaapi_unlock();
|
||||
+ CoTaskMemFree(h264decoder);
|
||||
+ return E_FAIL;
|
||||
+}
|
||||
+
|
||||
+#endif /* HAVE_VAAPI */
|
||||
diff --git a/dlls/dxva2/vaapi.c b/dlls/dxva2/vaapi.c
|
||||
index 3369a03..404f1ab 100644
|
||||
--- a/dlls/dxva2/vaapi.c
|
||||
+++ b/dlls/dxva2/vaapi.c
|
||||
@@ -655,6 +655,8 @@ static HRESULT WINAPI WineVideoService_CreateVideoDecoder( IWineVideoService *if
|
||||
|
||||
if (IsEqualGUID(guid, &DXVA2_ModeMPEG2_VLD))
|
||||
return vaapi_mpeg2decoder_create(iface, videoDesc, config, numSurfaces, decoder);
|
||||
+ if (IsEqualGUID(guid, &DXVA2_ModeH264_E))
|
||||
+ return vaapi_h264decoder_create(iface, videoDesc, config, numSurfaces, decoder);
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
--
|
||||
2.1.0
|
||||
|
4
patches/dxva2-Video_Decoder/definition
Normal file
4
patches/dxva2-Video_Decoder/definition
Normal 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
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user