nvcodec: Fix crash on 32-bit Windows
[platform/upstream/gstreamer.git] / sys / nvcodec / gstcuvidloader.c
1 /* GStreamer
2  * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "gstcuvidloader.h"
25 #include <gmodule.h>
26
27 #ifdef G_OS_WIN32
28 #define NVCUVID_LIBNAME "nvcuvid.dll"
29 #else
30 #define NVCUVID_LIBNAME "libnvcuvid.so.1"
31 #endif
32
33 #define LOAD_SYMBOL(name,func,mandatory) G_STMT_START { \
34   if (!g_module_symbol (module, G_STRINGIFY (name), (gpointer *) &vtable->func)) { \
35     if (mandatory) { \
36       GST_ERROR ("Failed to load '%s' from %s, %s", G_STRINGIFY (name), filename, g_module_error()); \
37       goto error; \
38     } \
39     GST_WARNING ("Failed to load '%s' from %s, %s", G_STRINGIFY (name), filename, g_module_error()); \
40   } \
41 } G_STMT_END;
42
43 typedef struct _GstnvdecCuvidVTable
44 {
45   gboolean loaded;
46
47     CUresult (CUDAAPI * CuvidCtxLockCreate) (CUvideoctxlock * pLock,
48       CUcontext ctx);
49     CUresult (CUDAAPI * CuvidCtxLockDestroy) (CUvideoctxlock lck);
50     CUresult (CUDAAPI * CuvidCtxLock) (CUvideoctxlock lck,
51       unsigned int reserved_flags);
52     CUresult (CUDAAPI * CuvidCtxUnlock) (CUvideoctxlock lck,
53       unsigned int reserved_flags);
54     CUresult (CUDAAPI * CuvidCreateDecoder) (CUvideodecoder * phDecoder,
55       CUVIDDECODECREATEINFO * pdci);
56     CUresult (CUDAAPI * CuvidDestroyDecoder) (CUvideodecoder hDecoder);
57     CUresult (CUDAAPI * CuvidDecodePicture) (CUvideodecoder hDecoder,
58       CUVIDPICPARAMS * pPicParams);
59     CUresult (CUDAAPI * CuvidCreateVideoParser) (CUvideoparser * pObj,
60       CUVIDPARSERPARAMS * pParams);
61     CUresult (CUDAAPI * CuvidParseVideoData) (CUvideoparser obj,
62       CUVIDSOURCEDATAPACKET * pPacket);
63     CUresult (CUDAAPI * CuvidDestroyVideoParser) (CUvideoparser obj);
64     CUresult (CUDAAPI * CuvidMapVideoFrame) (CUvideodecoder hDecoder,
65       int nPicIdx, guintptr * pDevPtr, unsigned int *pPitch,
66       CUVIDPROCPARAMS * pVPP);
67     CUresult (CUDAAPI * CuvidUnmapVideoFrame) (CUvideodecoder hDecoder,
68       guintptr DevPtr);
69     CUresult (CUDAAPI * CuvidGetDecoderCaps) (CUVIDDECODECAPS * pdc);
70 } GstnvdecCuvidVTable;
71
72 static GstnvdecCuvidVTable gst_cuvid_vtable = { 0, };
73
74 gboolean
75 gst_cuvid_load_library (void)
76 {
77   GModule *module;
78   const gchar *filename = NVCUVID_LIBNAME;
79   GstnvdecCuvidVTable *vtable;
80
81   if (gst_cuvid_vtable.loaded)
82     return TRUE;
83
84   module = g_module_open (filename, G_MODULE_BIND_LAZY);
85   if (module == NULL) {
86     GST_WARNING ("Could not open library %s, %s", filename, g_module_error ());
87     return FALSE;
88   }
89
90   vtable = &gst_cuvid_vtable;
91
92   LOAD_SYMBOL (cuvidCtxLockCreate, CuvidCtxLockCreate, TRUE);
93   LOAD_SYMBOL (cuvidCtxLockDestroy, CuvidCtxLockDestroy, TRUE);
94   LOAD_SYMBOL (cuvidCtxLock, CuvidCtxLock, TRUE);
95   LOAD_SYMBOL (cuvidCtxUnlock, CuvidCtxUnlock, TRUE);
96   LOAD_SYMBOL (cuvidCreateDecoder, CuvidCreateDecoder, TRUE);
97   LOAD_SYMBOL (cuvidDestroyDecoder, CuvidDestroyDecoder, TRUE);
98   LOAD_SYMBOL (cuvidDecodePicture, CuvidDecodePicture, TRUE);
99   LOAD_SYMBOL (cuvidCreateVideoParser, CuvidCreateVideoParser, TRUE);
100   LOAD_SYMBOL (cuvidParseVideoData, CuvidParseVideoData, TRUE);
101   LOAD_SYMBOL (cuvidDestroyVideoParser, CuvidDestroyVideoParser, TRUE);
102   LOAD_SYMBOL (cuvidMapVideoFrame, CuvidMapVideoFrame, TRUE);
103   LOAD_SYMBOL (cuvidUnmapVideoFrame, CuvidUnmapVideoFrame, TRUE);
104   LOAD_SYMBOL (cuvidGetDecoderCaps, CuvidGetDecoderCaps, FALSE);
105
106   vtable->loaded = TRUE;
107
108   return TRUE;
109
110 error:
111   g_module_close (module);
112
113   return FALSE;
114 }
115
116 gboolean
117 gst_cuvid_can_get_decoder_caps (void)
118 {
119   return ! !gst_cuvid_vtable.CuvidGetDecoderCaps;
120 }
121
122 CUresult CUDAAPI
123 CuvidCtxLockCreate (CUvideoctxlock * pLock, CUcontext ctx)
124 {
125   g_assert (gst_cuvid_vtable.CuvidCtxLockCreate != NULL);
126
127   return gst_cuvid_vtable.CuvidCtxLockCreate (pLock, ctx);
128 }
129
130 CUresult CUDAAPI
131 CuvidCtxLockDestroy (CUvideoctxlock lck)
132 {
133   g_assert (gst_cuvid_vtable.CuvidCtxLockDestroy != NULL);
134
135   return gst_cuvid_vtable.CuvidCtxLockDestroy (lck);
136 }
137
138 CUresult CUDAAPI
139 CuvidCtxLock (CUvideoctxlock lck, unsigned int reserved_flags)
140 {
141   g_assert (gst_cuvid_vtable.CuvidCtxLock != NULL);
142
143   return gst_cuvid_vtable.CuvidCtxLock (lck, reserved_flags);
144 }
145
146 CUresult CUDAAPI
147 CuvidCtxUnlock (CUvideoctxlock lck, unsigned int reserved_flags)
148 {
149   g_assert (gst_cuvid_vtable.CuvidCtxLockDestroy != NULL);
150
151   return gst_cuvid_vtable.CuvidCtxUnlock (lck, reserved_flags);
152 }
153
154 CUresult CUDAAPI
155 CuvidCreateDecoder (CUvideodecoder * phDecoder, CUVIDDECODECREATEINFO * pdci)
156 {
157   g_assert (gst_cuvid_vtable.CuvidCreateDecoder != NULL);
158
159   return gst_cuvid_vtable.CuvidCreateDecoder (phDecoder, pdci);
160 }
161
162 CUresult CUDAAPI
163 CuvidDestroyDecoder (CUvideodecoder hDecoder)
164 {
165   g_assert (gst_cuvid_vtable.CuvidDestroyDecoder != NULL);
166
167   return gst_cuvid_vtable.CuvidDestroyDecoder (hDecoder);
168 }
169
170 CUresult CUDAAPI
171 CuvidDecodePicture (CUvideodecoder hDecoder, CUVIDPICPARAMS * pPicParams)
172 {
173   g_assert (gst_cuvid_vtable.CuvidDecodePicture != NULL);
174
175   return gst_cuvid_vtable.CuvidDecodePicture (hDecoder, pPicParams);
176 }
177
178 CUresult CUDAAPI
179 CuvidCreateVideoParser (CUvideoparser * pObj, CUVIDPARSERPARAMS * pParams)
180 {
181   g_assert (gst_cuvid_vtable.CuvidCreateVideoParser != NULL);
182
183   return gst_cuvid_vtable.CuvidCreateVideoParser (pObj, pParams);
184 }
185
186 CUresult CUDAAPI
187 CuvidParseVideoData (CUvideoparser obj, CUVIDSOURCEDATAPACKET * pPacket)
188 {
189   g_assert (gst_cuvid_vtable.CuvidParseVideoData != NULL);
190
191   return gst_cuvid_vtable.CuvidParseVideoData (obj, pPacket);
192 }
193
194 CUresult CUDAAPI
195 CuvidDestroyVideoParser (CUvideoparser obj)
196 {
197   g_assert (gst_cuvid_vtable.CuvidDestroyVideoParser != NULL);
198
199   return gst_cuvid_vtable.CuvidDestroyVideoParser (obj);
200 }
201
202 CUresult CUDAAPI
203 CuvidMapVideoFrame (CUvideodecoder hDecoder, int nPicIdx,
204     guintptr * pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS * pVPP)
205 {
206   g_assert (gst_cuvid_vtable.CuvidMapVideoFrame != NULL);
207
208   return gst_cuvid_vtable.CuvidMapVideoFrame (hDecoder, nPicIdx, pDevPtr,
209       pPitch, pVPP);
210 }
211
212 CUresult CUDAAPI
213 CuvidUnmapVideoFrame (CUvideodecoder hDecoder, guintptr DevPtr)
214 {
215   g_assert (gst_cuvid_vtable.CuvidUnmapVideoFrame != NULL);
216
217   return gst_cuvid_vtable.CuvidUnmapVideoFrame (hDecoder, DevPtr);
218 }
219
220 CUresult CUDAAPI
221 CuvidGetDecoderCaps (CUVIDDECODECAPS * pdc)
222 {
223   g_assert (gst_cuvid_vtable.CuvidGetDecoderCaps != NULL);
224
225   return gst_cuvid_vtable.CuvidGetDecoderCaps (pdc);
226 }