diff --git a/README.md b/README.md index 9445e119..bac72101 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Wine. All those differences are also documented on the Included bug fixes and improvements =================================== -**Bugfixes and features included in the next upcoming release [25]:** +**Bugfixes and features included in the next upcoming release [26]:** * Add nvapi stubs required for GPU PhysX support * Add stub for D3DXComputeNormalMap @@ -56,6 +56,7 @@ Included bug fixes and improvements * IOCTL_DVD_READ_STRUCTURE expects the wrong size of output buffer for some requests ([Wine Bug #37767](https://bugs.winehq.org/show_bug.cgi?id=37767)) * Implement ID3DXEffect::FindNextValidTechnique ([Wine Bug #34101](https://bugs.winehq.org/show_bug.cgi?id=34101)) * Implement IDXGIOutput::GetDesc +* Support for CUDA GPU video decoding * Support for D3DXComputeNormals ([Wine Bug #26379](https://bugs.winehq.org/show_bug.cgi?id=26379)) * Support for ID3DXFont::DrawTextA/W ([Wine Bug #24754](https://bugs.winehq.org/show_bug.cgi?id=24754)) * Support for SLGetWindowsInformationDWORD ([Wine Bug #36709](https://bugs.winehq.org/show_bug.cgi?id=36709)) diff --git a/debian/changelog b/debian/changelog index f8ac2c5f..5bc319a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -33,6 +33,7 @@ wine-staging (1.7.34) UNRELEASED; urgency=low * Added patches for D3DXComputeNormals and D3DXComputeNormalMap. * Added patch for nvapi stubs (required for GPU PhysX support). * Added patch to fix NULL dereference in ICSeqCompressFrameStart. + * Added patch to implement support for CUDA GPU video decoding. * Removed patch to emulate write to CR4 register (accepted upstream). * Removed patch with stub for KeSetSystemAffinityThread (accepted upstream). * Removed patch to implement combase HSTRING objects (accepted upstream). diff --git a/patches/nvcuvid-CUDA_Video_Support/0001-nvcuvid-First-implementation.patch b/patches/nvcuvid-CUDA_Video_Support/0001-nvcuvid-First-implementation.patch new file mode 100644 index 00000000..223af3c2 --- /dev/null +++ b/patches/nvcuvid-CUDA_Video_Support/0001-nvcuvid-First-implementation.patch @@ -0,0 +1,634 @@ +From 701f3aa88ae330949f2e6618050b6923728ff782 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Tue, 6 Jan 2015 05:16:36 +0100 +Subject: nvcuvid: First implementation. + +--- + configure.ac | 1 + + dlls/nvcuvid/Makefile.in | 4 + + dlls/nvcuvid/nvcuvid.c | 422 ++++++++++++++++++++++++++++++++++++++++++++++ + dlls/nvcuvid/nvcuvid.spec | 24 +++ + include/Makefile.in | 2 + + include/cuviddec.h | 32 ++++ + include/nvcuvid.h | 67 ++++++++ + 7 files changed, 552 insertions(+) + create mode 100644 dlls/nvcuvid/Makefile.in + create mode 100644 dlls/nvcuvid/nvcuvid.c + create mode 100644 dlls/nvcuvid/nvcuvid.spec + create mode 100644 include/cuviddec.h + create mode 100644 include/nvcuvid.h + +diff --git a/configure.ac b/configure.ac +index efc143a..25e853d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3130,6 +3130,7 @@ WINE_CONFIG_TEST(dlls/nvapi/tests) + WINE_CONFIG_DLL(nvapi64,enable_win64) + WINE_CONFIG_DLL(nvcuda) + WINE_CONFIG_TEST(dlls/nvcuda/tests) ++WINE_CONFIG_DLL(nvcuvid) + WINE_CONFIG_DLL(objsel,,[clean]) + WINE_CONFIG_DLL(odbc32,,[implib]) + WINE_CONFIG_DLL(odbccp32,,[implib]) +diff --git a/dlls/nvcuvid/Makefile.in b/dlls/nvcuvid/Makefile.in +new file mode 100644 +index 0000000..2c2dc8c +--- /dev/null ++++ b/dlls/nvcuvid/Makefile.in +@@ -0,0 +1,4 @@ ++MODULE = nvcuvid.dll ++ ++C_SRCS = \ ++ nvcuvid.c +diff --git a/dlls/nvcuvid/nvcuvid.c b/dlls/nvcuvid/nvcuvid.c +new file mode 100644 +index 0000000..cf6a3a4 +--- /dev/null ++++ b/dlls/nvcuvid/nvcuvid.c +@@ -0,0 +1,422 @@ ++/* ++ * Copyright (C) 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 "config.h" ++#include "wine/port.h" ++ ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "winternl.h" ++#include "wine/library.h" ++#include "wine/debug.h" ++#include "nvcuvid.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(nvcuvid); ++ ++static CUresult (*pcuvidCreateDecoder)(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci); ++static CUresult (*pcuvidCreateVideoParser)(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams); ++static CUresult (*pcuvidCreateVideoSource)(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams); ++static CUresult (*pcuvidCtxLock)(CUvideoctxlock lck, unsigned int reserved_flags); ++static CUresult (*pcuvidCtxLockCreate)(CUvideoctxlock *pLock, CUcontext ctx); ++static CUresult (*pcuvidCtxLockDestroy)(CUvideoctxlock lck); ++static CUresult (*pcuvidCtxUnlock)(CUvideoctxlock lck, unsigned int reserved_flags); ++static CUresult (*pcuvidDecodePicture)(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams); ++static CUresult (*pcuvidDestroyDecoder)(CUvideodecoder hDecoder); ++static CUresult (*pcuvidDestroyVideoParser)(CUvideoparser obj); ++static CUresult (*pcuvidDestroyVideoSource)(CUvideosource obj); ++static CUresult (*pcuvidGetSourceAudioFormat)(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags); ++static CUresult (*pcuvidGetSourceVideoFormat)(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags); ++/* static CUresult (*pcuvidGetVideoFrameSurface)(CUvideodecoder hDecoder, int nPicIdx, void **pSrcSurface); */ ++static cudaVideoState (*pcuvidGetVideoSourceState)(CUvideosource obj); ++static CUresult (*pcuvidMapVideoFrame)(CUvideodecoder hDecoder, int nPicIdx, unsigned int *pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS *pVPP); ++static CUresult (*pcuvidParseVideoData)(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket); ++static CUresult (*pcuvidSetVideoSourceState)(CUvideosource obj, cudaVideoState state); ++static CUresult (*pcuvidUnmapVideoFrame)(CUvideodecoder hDecoder, unsigned int DevPtr); ++ ++static void *cuvid_handle = NULL; ++ ++static BOOL load_functions(void) ++{ ++ cuvid_handle = wine_dlopen("libnvcuvid.so", RTLD_NOW, NULL, 0); ++ ++ if (!cuvid_handle) ++ { ++ FIXME("Wine cannot find the libnvcuvid.so library, CUDA gpu decoding support disabled.\n"); ++ return FALSE; ++ } ++ ++ #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(cuvid_handle, #f, NULL, 0)) == NULL){FIXME("Can't find symbol %s\n", #f); return FALSE;} ++ ++ LOAD_FUNCPTR(cuvidCreateDecoder); ++ LOAD_FUNCPTR(cuvidCreateVideoParser); ++ LOAD_FUNCPTR(cuvidCtxLock); ++ LOAD_FUNCPTR(cuvidCtxLockCreate); ++ LOAD_FUNCPTR(cuvidCtxLockDestroy); ++ LOAD_FUNCPTR(cuvidCtxUnlock); ++ LOAD_FUNCPTR(cuvidDecodePicture); ++ LOAD_FUNCPTR(cuvidDestroyDecoder); ++ LOAD_FUNCPTR(cuvidDestroyVideoParser); ++ LOAD_FUNCPTR(cuvidDestroyVideoSource); ++ LOAD_FUNCPTR(cuvidGetSourceAudioFormat); ++ LOAD_FUNCPTR(cuvidGetSourceVideoFormat); ++ /* LOAD_FUNCPTR(cuvidGetVideoFrameSurface); */ ++ LOAD_FUNCPTR(cuvidGetVideoSourceState) ++ LOAD_FUNCPTR(cuvidMapVideoFrame); ++ LOAD_FUNCPTR(cuvidParseVideoData); ++ LOAD_FUNCPTR(cuvidSetVideoSourceState); ++ LOAD_FUNCPTR(cuvidUnmapVideoFrame); ++ LOAD_FUNCPTR(cuvidCreateVideoSource); ++ ++ #undef LOAD_FUNCPTR ++ ++ return TRUE; ++} ++ ++struct fake_parser ++{ ++ CUvideoparser *orig_parser; ++ int (WINAPI *orig_SequenceCallback)(void *, CUVIDEOFORMAT *); ++ int (WINAPI *orig_DecodePicture)(void *, CUVIDPICPARAMS *); ++ int (WINAPI *orig_DisplayPicture)(void *, CUVIDPARSERDISPINFO *); ++ void *orig_data; ++}; ++ ++struct fake_source ++{ ++ CUvideoparser *orig_source; ++ int (WINAPI *orig_VideoDataHandler)(void *, CUVIDSOURCEDATAPACKET *); ++ int (WINAPI *orig_AudioDataHandler)(void *, CUVIDSOURCEDATAPACKET *); ++ void *orig_data; ++}; ++ ++static int relay_SequenceCallback(void *data, CUVIDEOFORMAT *fmt) ++{ ++ struct fake_parser *parser = data; ++ TRACE("(%p, %p)\n", data, fmt); ++ return parser->orig_SequenceCallback(parser->orig_data, fmt); ++} ++ ++static int relay_DecodePicture(void *data, CUVIDPICPARAMS *params) ++{ ++ struct fake_parser *parser = data; ++ TRACE("(%p, %p)\n", data, params); ++ return parser->orig_DecodePicture(parser->orig_data, params); ++} ++ ++static int relay_DisplayPicture(void *data, CUVIDPARSERDISPINFO *info) ++{ ++ struct fake_parser *parser = data; ++ TRACE("(%p, %p)\n", data, info); ++ return parser->orig_DisplayPicture(parser->orig_data, info); ++} ++ ++static int relay_VideoDataHandler(void *data, CUVIDSOURCEDATAPACKET *pkt) ++{ ++ struct fake_source *source = data; ++ TRACE("(%p, %p)\n", data, pkt); ++ return source->orig_VideoDataHandler(source->orig_data, pkt); ++} ++ ++static int relay_AudioDataHandler(void *data, CUVIDSOURCEDATAPACKET *pkt) ++{ ++ struct fake_source *source = data; ++ TRACE("(%p, %p)\n", data, pkt); ++ return source->orig_AudioDataHandler(source->orig_data, pkt); ++} ++ ++CUresult WINAPI wine_cuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci) ++{ ++ TRACE("(%p, %p)\n", phDecoder, pdci); ++ return pcuvidCreateDecoder(phDecoder, pdci); ++} ++ ++CUresult WINAPI wine_cuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams) ++{ ++ struct fake_parser *parser; ++ CUVIDPARSERPARAMS fake_params; ++ CUresult ret; ++ ++ TRACE("(%p, %p)\n", pObj, pParams); ++ ++ /* FIXME: check error codes */ ++ if (!pObj || !pParams) ++ return CUDA_ERROR_INVALID_VALUE; ++ ++ parser = HeapAlloc(GetProcessHeap(), 0, sizeof(*parser)); ++ if (!parser) ++ return CUDA_ERROR_OUT_OF_MEMORY; ++ ++ memcpy(&fake_params, pParams, sizeof(fake_params)); ++ ++ if (pParams->pfnSequenceCallback) ++ { ++ parser->orig_SequenceCallback = pParams->pfnSequenceCallback; ++ fake_params.pfnSequenceCallback = &relay_SequenceCallback; ++ } ++ ++ if (pParams->pfnDecodePicture) ++ { ++ parser->orig_DecodePicture = pParams->pfnDecodePicture; ++ fake_params.pfnDecodePicture = &relay_DecodePicture; ++ } ++ ++ if (pParams->pfnDisplayPicture) ++ { ++ parser->orig_DisplayPicture = pParams->pfnDisplayPicture; ++ fake_params.pfnDisplayPicture = &relay_DisplayPicture; ++ } ++ ++ parser->orig_data = pParams->pUserData; ++ fake_params.pUserData = parser; ++ ++ ret = pcuvidCreateVideoParser((void *)&parser->orig_parser, &fake_params); ++ if (ret) ++ { ++ HeapFree(GetProcessHeap(), 0, parser); ++ return ret; ++ } ++ ++ *pObj = (void *)parser; ++ return CUDA_SUCCESS; ++} ++ ++/* FIXME: Should we pay attention to AreFileApisANSI() ? */ ++static BOOL get_unix_path(ANSI_STRING *unix_name, const char *filename) ++{ ++ UNICODE_STRING dospathW, ntpathW; ++ ANSI_STRING dospath; ++ NTSTATUS status; ++ ++ RtlInitAnsiString(&dospath, filename); ++ ++ if (RtlAnsiStringToUnicodeString(&dospathW, &dospath, TRUE)) ++ return FALSE; ++ ++ if (!RtlDosPathNameToNtPathName_U(dospathW.Buffer, &ntpathW, NULL, NULL)) ++ { ++ RtlFreeUnicodeString(&dospathW); ++ return FALSE; ++ } ++ ++ status = wine_nt_to_unix_file_name(&ntpathW, unix_name, FILE_OPEN, FALSE); ++ ++ RtlFreeUnicodeString(&ntpathW); ++ RtlFreeUnicodeString(&dospathW); ++ return !status; ++} ++ ++CUresult WINAPI wine_cuvidCreateVideoSource(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams) ++{ ++ struct fake_source *source; ++ CUVIDSOURCEPARAMS fake_params; ++ ANSI_STRING unix_name; ++ CUresult ret; ++ ++ TRACE("(%p, %s, %p)\n", pObj, pszFileName, pParams); ++ ++ /* FIXME: check error codes */ ++ if (!pObj || !pParams) ++ return CUDA_ERROR_INVALID_VALUE; ++ ++ if (!pszFileName) ++ return CUDA_ERROR_UNKNOWN; ++ ++ if (!get_unix_path(&unix_name, pszFileName)) ++ return CUDA_ERROR_UNKNOWN; ++ ++ source = HeapAlloc(GetProcessHeap(), 0, sizeof(*source)); ++ if (!source) ++ { ++ RtlFreeAnsiString(&unix_name); ++ return CUDA_ERROR_OUT_OF_MEMORY; ++ } ++ ++ memcpy(&fake_params, pParams, sizeof(fake_params)); ++ ++ if (pParams->pfnVideoDataHandler) ++ { ++ source->orig_VideoDataHandler = pParams->pfnVideoDataHandler; ++ fake_params.pfnVideoDataHandler = &relay_VideoDataHandler; ++ } ++ ++ if (pParams->pfnAudioDataHandler) ++ { ++ source->orig_AudioDataHandler = pParams->pfnAudioDataHandler; ++ fake_params.pfnAudioDataHandler = &relay_AudioDataHandler; ++ } ++ ++ source->orig_data = pParams->pUserData; ++ fake_params.pUserData = source; ++ ++ ret = pcuvidCreateVideoSource((void *)&source->orig_source, unix_name.Buffer, &fake_params); ++ RtlFreeAnsiString(&unix_name); ++ ++ if (ret) ++ { ++ HeapFree( GetProcessHeap(), 0, source ); ++ return ret; ++ } ++ ++ *pObj = (void *)source; ++ return ret; ++} ++ ++CUresult WINAPI wine_cuvidCtxLock(CUvideoctxlock lck, unsigned int reserved_flags) ++{ ++ TRACE("(%p, %u)\n", lck, reserved_flags); ++ return pcuvidCtxLock(lck, reserved_flags); ++} ++ ++CUresult WINAPI wine_cuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx) ++{ ++ TRACE("(%p, %p)\n", pLock, ctx); ++ return pcuvidCtxLockCreate(pLock, ctx); ++} ++ ++CUresult WINAPI wine_cuvidCtxLockDestroy(CUvideoctxlock lck) ++{ ++ TRACE("(%p)\n", lck); ++ return pcuvidCtxLockDestroy(lck); ++} ++ ++CUresult WINAPI wine_cuvidCtxUnlock(CUvideoctxlock lck, unsigned int reserved_flags) ++{ ++ TRACE("(%p, %u)\n", lck, reserved_flags); ++ return pcuvidCtxUnlock(lck, reserved_flags); ++} ++ ++CUresult WINAPI wine_cuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams) ++{ ++ TRACE("(%p, %p)\n", hDecoder, pPicParams); ++ return pcuvidDecodePicture(hDecoder, pPicParams); ++} ++ ++CUresult WINAPI wine_cuvidDestroyDecoder(CUvideodecoder hDecoder) ++{ ++ TRACE("(%p)\n", hDecoder); ++ return pcuvidDestroyDecoder(hDecoder); ++} ++ ++CUresult WINAPI wine_cuvidDestroyVideoParser(CUvideoparser obj) ++{ ++ struct fake_parser *parser = (void *)obj; ++ CUresult ret; ++ ++ TRACE("(%p)\n", obj); ++ ++ if (!parser) return CUDA_ERROR_INVALID_VALUE; /* FIXME */ ++ ret = pcuvidDestroyVideoParser(parser->orig_parser); ++ ++ HeapFree(GetProcessHeap(), 0, parser); ++ return ret; ++} ++ ++CUresult WINAPI wine_cuvidDestroyVideoSource(CUvideosource obj) ++{ ++ struct fake_source *source = (void *)obj; ++ CUresult ret; ++ ++ TRACE("(%p)\n", obj); ++ ++ if (!source) return CUDA_ERROR_INVALID_VALUE; /* FIXME */ ++ ret = pcuvidDestroyVideoSource(source->orig_source); ++ ++ HeapFree(GetProcessHeap(), 0, source); ++ return ret; ++} ++ ++CUresult WINAPI wine_cuvidGetSourceAudioFormat(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags) ++{ ++ struct fake_source *source = (void *)obj; ++ TRACE("(%p, %p, %u)\n", obj, paudfmt, flags); ++ if (!source) return CUDA_ERROR_INVALID_VALUE; /* FIXME */ ++ return pcuvidGetSourceAudioFormat(source->orig_source, paudfmt, flags); ++} ++ ++CUresult WINAPI wine_cuvidGetSourceVideoFormat(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags) ++{ ++ struct fake_source *source = (void *)obj; ++ TRACE("(%p, %p, %u)\n", obj, pvidfmt, flags); ++ if (!source) return CUDA_ERROR_INVALID_VALUE; /* FIXME */ ++ return pcuvidGetSourceVideoFormat(source->orig_source, pvidfmt, flags); ++} ++ ++/* ++CUresult WINAPI wine_cuvidGetVideoFrameSurface(CUvideodecoder hDecoder, int nPicIdx, void **pSrcSurface) ++{ ++ TRACE("(%p, %d, %p)\n", hDecoder, nPicIdx, pSrcSurface); ++ return pcuvidGetVideoFrameSurface(hDecoder, nPicIdx, pSrcSurface); ++} ++*/ ++ ++cudaVideoState WINAPI wine_cuvidGetVideoSourceState(CUvideosource obj) ++{ ++ struct fake_source *source = (void *)obj; ++ TRACE("(%p)\n", obj); ++ if (!source) return CUDA_ERROR_INVALID_VALUE; /* FIXME */ ++ return pcuvidGetVideoSourceState(source->orig_source); ++} ++ ++CUresult WINAPI wine_cuvidMapVideoFrame(CUvideodecoder hDecoder, int nPicIdx, unsigned int *pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS *pVPP) ++{ ++ TRACE("(%p, %d, %p, %p, %p)\n", hDecoder, nPicIdx, pDevPtr, pPitch, pVPP); ++ return pcuvidMapVideoFrame(hDecoder, nPicIdx, pDevPtr, pPitch, pVPP); ++} ++ ++CUresult WINAPI wine_cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket) ++{ ++ struct fake_parser *parser = (void *)obj; ++ TRACE("(%p, %p)\n", obj, pPacket); ++ if (!parser) return CUDA_ERROR_INVALID_VALUE; /* FIXME */ ++ return pcuvidParseVideoData(parser->orig_parser, pPacket); ++} ++ ++CUresult WINAPI wine_cuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state) ++{ ++ struct fake_source *source = (void *)obj; ++ TRACE("(%p, %d)\n", obj, state); ++ if (!source) return CUDA_ERROR_INVALID_VALUE; ++ return pcuvidSetVideoSourceState(source->orig_source, state); ++} ++ ++CUresult WINAPI wine_cuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned int DevPtr) ++{ ++ TRACE("(%p, %u)\n", hDecoder, DevPtr); ++ return pcuvidUnmapVideoFrame(hDecoder, DevPtr); ++} ++ ++BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) ++{ ++ TRACE("(%p, %u, %p)\n", instance, reason, reserved); ++ ++ switch (reason) ++ { ++ case DLL_PROCESS_ATTACH: ++ DisableThreadLibraryCalls(instance); ++ if (!load_functions()) return FALSE; ++ break; ++ case DLL_PROCESS_DETACH: ++ if (reserved) break; ++ if (cuvid_handle) wine_dlclose(cuvid_handle, NULL, 0); ++ break; ++ } ++ ++ return TRUE; ++} +diff --git a/dlls/nvcuvid/nvcuvid.spec b/dlls/nvcuvid/nvcuvid.spec +new file mode 100644 +index 0000000..73e49f1 +--- /dev/null ++++ b/dlls/nvcuvid/nvcuvid.spec +@@ -0,0 +1,24 @@ ++@ stub CreateEncoderInterface ++@ stub cuvidMapVideoFrame64 ++@ stub cuvidUnmapVideoFrame64 ++@ stdcall cuvidCreateDecoder(ptr ptr) wine_cuvidCreateDecoder ++@ stdcall cuvidCreateVideoParser(ptr ptr) wine_cuvidCreateVideoParser ++@ stdcall cuvidCreateVideoSource(ptr str ptr) wine_cuvidCreateVideoSource ++@ stub cuvidCreateVideoSourceW ++@ stdcall cuvidCtxLock(ptr long) wine_cuvidCtxLock ++@ stdcall cuvidCtxLockCreate(ptr ptr) wine_cuvidCtxLockCreate ++@ stdcall cuvidCtxLockDestroy(ptr) wine_cuvidCtxLockDestroy ++@ stdcall cuvidCtxUnlock(ptr long) wine_cuvidCtxUnlock ++@ stdcall cuvidDecodePicture(ptr ptr) wine_cuvidDecodePicture ++@ stdcall cuvidDestroyDecoder(ptr) wine_cuvidDestroyDecoder ++@ stdcall cuvidDestroyVideoParser(ptr) wine_cuvidDestroyVideoParser ++@ stdcall cuvidDestroyVideoSource(ptr) wine_cuvidDestroyVideoSource ++@ stdcall cuvidGetSourceAudioFormat(ptr ptr long) wine_cuvidGetSourceAudioFormat ++@ stdcall cuvidGetSourceVideoFormat(ptr ptr long) wine_cuvidGetSourceVideoFormat ++@ stub cuvidGetVideoFrameSurface ++#@ stdcall cuvidGetVideoFrameSurface(ptr long ptr) wine_cuvidGetVideoFrameSurface ++@ stdcall cuvidGetVideoSourceState(ptr) wine_cuvidGetVideoSourceState ++@ stdcall cuvidMapVideoFrame(ptr long ptr ptr ptr) wine_cuvidMapVideoFrame ++@ stdcall cuvidParseVideoData(ptr ptr) wine_cuvidParseVideoData ++@ stdcall cuvidSetVideoSourceState(ptr long) wine_cuvidSetVideoSourceState ++@ stdcall cuvidUnmapVideoFrame(ptr long) wine_cuvidUnmapVideoFrame +diff --git a/include/Makefile.in b/include/Makefile.in +index f9eaf44..e29f3e5 100644 +--- a/include/Makefile.in ++++ b/include/Makefile.in +@@ -199,6 +199,7 @@ SRCDIR_INCLUDES = \ + cryptuiapi.h \ + cuda.h \ + custcntl.h \ ++ cuviddec.h \ + cvconst.h \ + d2dbasetypes.h \ + d2derr.h \ +@@ -478,6 +479,7 @@ SRCDIR_INCLUDES = \ + ntsecpkg.h \ + ntstatus.h \ + nvapi.h \ ++ nvcuvid.h \ + objbase.h \ + objsel.h \ + odbcinst.h \ +diff --git a/include/cuviddec.h b/include/cuviddec.h +new file mode 100644 +index 0000000..7fba042 +--- /dev/null ++++ b/include/cuviddec.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (C) 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 ++ */ ++ ++#ifndef __WINE_CUVIDDEC_H ++#define __WINE_CUVIDDEC_H ++ ++#include "cuda.h" ++ ++typedef void *CUvideodecoder; ++typedef void *CUvideoctxlock; ++ ++/* the following structures are documented but we don't need to know the content */ ++typedef struct _CUVIDDECODECREATEINFO CUVIDDECODECREATEINFO; ++typedef struct _CUVIDPICPARAMS CUVIDPICPARAMS; ++typedef struct _CUVIDPROCPARAMS CUVIDPROCPARAMS; ++ ++#endif /* __WINE_CUVIDDEC_H */ +diff --git a/include/nvcuvid.h b/include/nvcuvid.h +new file mode 100644 +index 0000000..2de8e3f +--- /dev/null ++++ b/include/nvcuvid.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 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 ++ */ ++ ++#ifndef __WINE_NVCUVID_H ++#define __WINE_NVCUVID_H ++ ++#include "cuviddec.h" ++ ++typedef void *CUvideosource; ++typedef void *CUvideoparser; ++typedef long long CUvideotimestamp; ++ ++typedef int cudaVideoCodec; ++typedef int cudaVideoState; ++ ++/* the following structures are documented but we don't need to know the details */ ++typedef struct _CUAUDIOFORMAT CUAUDIOFORMAT; ++typedef struct _CUVIDDECODECREATEINFO CUVIDDECODECREATEINFO; ++typedef struct _CUVIDEOFORMAT CUVIDEOFORMAT; ++typedef struct _CUVIDEOFORMATEX CUVIDEOFORMATEX; ++typedef struct _CUVIDPARSERDISPINFO CUVIDPARSERDISPINFO; ++typedef struct _CUVIDPARSERPARAMS CUVIDPARSERPARAMS; ++typedef struct _CUVIDPICPARAMS CUVIDPICPARAMS; ++typedef struct _CUVIDSOURCEDATAPACKET CUVIDSOURCEDATAPACKET; ++ ++typedef struct _CUVIDPARSERPARAMS ++{ ++ cudaVideoCodec CodecType; ++ unsigned int ulMaxNumDecodeSurfaces; ++ unsigned int ulClockRate; ++ unsigned int ulErrorThreshold; ++ unsigned int ulMaxDisplayDelay; ++ unsigned int uReserved1[5]; ++ void *pUserData; ++ void *pfnSequenceCallback; ++ void *pfnDecodePicture; ++ void *pfnDisplayPicture; ++ void *pvReserved2[7]; ++ CUVIDEOFORMATEX *pExtVideoInfo; ++} CUVIDPARSERPARAMS; ++ ++typedef struct _CUVIDSOURCEPARAMS ++{ ++ unsigned int ulClockRate; ++ unsigned int uReserved1[7]; ++ void *pUserData; ++ void *pfnVideoDataHandler; ++ void *pfnAudioDataHandler; ++ void *pvReserved2[8]; ++} CUVIDSOURCEPARAMS; ++ ++#endif /* __WINE_NVCUVID_H */ +-- +2.2.1 + diff --git a/patches/nvcuvid-CUDA_Video_Support/definition b/patches/nvcuvid-CUDA_Video_Support/definition new file mode 100644 index 00000000..1c54645c --- /dev/null +++ b/patches/nvcuvid-CUDA_Video_Support/definition @@ -0,0 +1,2 @@ +Fixes: Support for CUDA GPU video decoding +Depends: nvapi-Stub_DLL diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index ce5cd7f0..1165a944 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -127,6 +127,7 @@ patch_enable_all () enable_ntoskrnl_Stub_FileObject="$1" enable_nvcuda_CUDA_Support="$1" enable_nvapi_Stub_DLL="$1" + enable_nvcuvid_CUDA_Video_Support="$1" enable_ole32_CoWaitForMultipleHandles="$1" enable_quartz_MediaSeeking_Positions="$1" enable_riched20_IText_Interface="$1" @@ -413,6 +414,9 @@ patch_enable () nvapi-Stub_DLL) enable_nvapi_Stub_DLL="$2" ;; + nvcuvid-CUDA_Video_Support) + enable_nvcuvid_CUDA_Video_Support="$2" + ;; ole32-CoWaitForMultipleHandles) enable_ole32_CoWaitForMultipleHandles="$2" ;; @@ -694,10 +698,10 @@ if [ "$enable_wined3d_CSMT_Main" -eq 1 ]; then fi if [ "$enable_wined3d_CSMT_Helper" -eq 1 ]; then - [ "$enable_makedep_PARENTSPEC" -gt 1 ] && abort "ERROR: Patchset makedep-PARENTSPEC disabled, but wined3d-CSMT_Helper depends on that." >&2 [ "$enable_wined3d_DXTn" -gt 1 ] && abort "ERROR: Patchset wined3d-DXTn disabled, but wined3d-CSMT_Helper depends on that." >&2 - enable_makedep_PARENTSPEC=1 + [ "$enable_makedep_PARENTSPEC" -gt 1 ] && abort "ERROR: Patchset makedep-PARENTSPEC disabled, but wined3d-CSMT_Helper depends on that." >&2 enable_wined3d_DXTn=1 + enable_makedep_PARENTSPEC=1 fi if [ "$enable_server_ACL_Compat" -eq 1 ]; then @@ -715,6 +719,11 @@ if [ "$enable_server_Stored_ACLs" -eq 1 ]; then enable_ntdll_DOS_Attributes=1 fi +if [ "$enable_nvcuvid_CUDA_Video_Support" -eq 1 ]; then + [ "$enable_nvapi_Stub_DLL" -gt 1 ] && abort "ERROR: Patchset nvapi-Stub_DLL disabled, but nvcuvid-CUDA_Video_Support depends on that." >&2 + enable_nvapi_Stub_DLL=1 +fi + if [ "$enable_nvapi_Stub_DLL" -eq 1 ]; then [ "$enable_nvcuda_CUDA_Support" -gt 1 ] && abort "ERROR: Patchset nvcuda-CUDA_Support disabled, but nvapi-Stub_DLL depends on that." >&2 enable_nvcuda_CUDA_Support=1 @@ -2046,6 +2055,19 @@ if [ "$enable_nvapi_Stub_DLL" -eq 1 ]; then ) >> "$patchlist" fi +# Patchset nvcuvid-CUDA_Video_Support +# | +# | Modified files: +# | * configure.ac, dlls/nvcuvid/Makefile.in, dlls/nvcuvid/nvcuvid.c, dlls/nvcuvid/nvcuvid.spec, include/Makefile.in, +# | include/cuviddec.h, include/nvcuvid.h +# | +if [ "$enable_nvcuvid_CUDA_Video_Support" -eq 1 ]; then + patch_apply nvcuvid-CUDA_Video_Support/0001-nvcuvid-First-implementation.patch + ( + echo '+ { "Michael Müller", "nvcuvid: First implementation.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ole32-CoWaitForMultipleHandles # | # | Modified files: