nvcodec: Fix crash on 32-bit Windows
[platform/upstream/gstreamer.git] / sys / nvcodec / gstcudaloader.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 "gstcudaloader.h"
25 #include <gmodule.h>
26
27 GST_DEBUG_CATEGORY_EXTERN (gst_nvcodec_debug);
28 #define GST_CAT_DEFAULT gst_nvcodec_debug
29
30 #ifndef G_OS_WIN32
31 #define CUDA_LIBNAME "libcuda.so.1"
32 #else
33 #define CUDA_LIBNAME "nvcuda.dll"
34 #endif
35
36 #define LOAD_SYMBOL(name,func) G_STMT_START { \
37   if (!g_module_symbol (module, G_STRINGIFY (name), (gpointer *) &vtable->func)) { \
38     GST_ERROR ("Failed to load '%s' from %s, %s", G_STRINGIFY (name), filename, g_module_error()); \
39     goto error; \
40   } \
41 } G_STMT_END;
42
43 typedef struct _GstNvCodecCudaVTable
44 {
45   gboolean loaded;
46
47     CUresult (CUDAAPI * CuInit) (unsigned int Flags);
48     CUresult (CUDAAPI * CuGetErrorName) (CUresult error, const char **pStr);
49     CUresult (CUDAAPI * CuGetErrorString) (CUresult error, const char **pStr);
50
51     CUresult (CUDAAPI * CuCtxCreate) (CUcontext * pctx, unsigned int flags,
52       CUdevice dev);
53     CUresult (CUDAAPI * CuCtxDestroy) (CUcontext ctx);
54     CUresult (CUDAAPI * CuCtxPopCurrent) (CUcontext * pctx);
55     CUresult (CUDAAPI * CuCtxPushCurrent) (CUcontext ctx);
56
57     CUresult (CUDAAPI * CuGraphicsMapResources) (unsigned int count,
58       CUgraphicsResource * resources, CUstream hStream);
59     CUresult (CUDAAPI * CuGraphicsUnmapResources) (unsigned int count,
60       CUgraphicsResource * resources, CUstream hStream);
61     CUresult (CUDAAPI * CuGraphicsSubResourceGetMappedArray) (CUarray * pArray,
62       CUgraphicsResource resource, unsigned int arrayIndex,
63       unsigned int mipLevel);
64     CUresult (CUDAAPI * CuGraphicsResourceGetMappedPointer) (CUdeviceptr *
65       pDevPtr, size_t * pSize, CUgraphicsResource resource);
66     CUresult (CUDAAPI *
67       CuGraphicsUnregisterResource) (CUgraphicsResource resource);
68
69     CUresult (CUDAAPI * CuMemAlloc) (CUdeviceptr * dptr, unsigned int bytesize);
70     CUresult (CUDAAPI * CuMemAllocPitch) (CUdeviceptr * dptr, size_t * pPitch,
71       size_t WidthInBytes, size_t Height, unsigned int ElementSizeBytes);
72     CUresult (CUDAAPI * CuMemcpy2D) (const CUDA_MEMCPY2D * pCopy);
73     CUresult (CUDAAPI * CuMemcpy2DAsync) (const CUDA_MEMCPY2D * pCopy,
74       CUstream hStream);
75     CUresult (CUDAAPI * CuMemFree) (CUdeviceptr dptr);
76     CUresult (CUDAAPI * CuStreamCreate) (CUstream * phStream,
77       unsigned int Flags);
78     CUresult (CUDAAPI * CuStreamDestroy) (CUstream hStream);
79     CUresult (CUDAAPI * CuStreamSynchronize) (CUstream hStream);
80
81     CUresult (CUDAAPI * CuDeviceGet) (CUdevice * device, int ordinal);
82     CUresult (CUDAAPI * CuDeviceGetCount) (int *count);
83     CUresult (CUDAAPI * CuDeviceGetName) (char *name, int len, CUdevice dev);
84     CUresult (CUDAAPI * CuDeviceGetAttribute) (int *pi,
85       CUdevice_attribute attrib, CUdevice dev);
86
87     CUresult (CUDAAPI * CuGraphicsGLRegisterImage) (CUgraphicsResource *
88       pCudaResource, unsigned int image, unsigned int target,
89       unsigned int Flags);
90     CUresult (CUDAAPI * CuGraphicsGLRegisterBuffer) (CUgraphicsResource *
91       pCudaResource, unsigned int buffer, unsigned int Flags);
92     CUresult (CUDAAPI *
93       CuGraphicsResourceSetMapFlags) (CUgraphicsResource resource,
94       unsigned int flags);
95 } GstNvCodecCudaVTable;
96
97 static GstNvCodecCudaVTable gst_cuda_vtable = { 0, };
98
99 gboolean
100 gst_cuda_load_library (void)
101 {
102   GModule *module;
103   const gchar *filename = CUDA_LIBNAME;
104   GstNvCodecCudaVTable *vtable;
105
106   if (gst_cuda_vtable.loaded)
107     return TRUE;
108
109   module = g_module_open (filename, G_MODULE_BIND_LAZY);
110   if (module == NULL) {
111     GST_WARNING ("Could not open library %s, %s", filename, g_module_error ());
112     return FALSE;
113   }
114
115   vtable = &gst_cuda_vtable;
116
117   /* cuda.h */
118   LOAD_SYMBOL (cuInit, CuInit);
119   LOAD_SYMBOL (cuGetErrorName, CuGetErrorName);
120   LOAD_SYMBOL (cuGetErrorString, CuGetErrorString);
121   LOAD_SYMBOL (cuCtxCreate, CuCtxCreate);
122   LOAD_SYMBOL (cuCtxDestroy, CuCtxDestroy);
123   LOAD_SYMBOL (cuCtxPopCurrent, CuCtxPopCurrent);
124   LOAD_SYMBOL (cuCtxPushCurrent, CuCtxPushCurrent);
125
126   LOAD_SYMBOL (cuGraphicsMapResources, CuGraphicsMapResources);
127   LOAD_SYMBOL (cuGraphicsUnmapResources, CuGraphicsUnmapResources);
128   LOAD_SYMBOL (cuGraphicsSubResourceGetMappedArray,
129       CuGraphicsSubResourceGetMappedArray);
130   LOAD_SYMBOL (cuGraphicsResourceGetMappedPointer,
131       CuGraphicsResourceGetMappedPointer);
132   LOAD_SYMBOL (cuGraphicsUnregisterResource, CuGraphicsUnregisterResource);
133
134   LOAD_SYMBOL (cuMemAlloc, CuMemAlloc);
135   LOAD_SYMBOL (cuMemAllocPitch, CuMemAllocPitch);
136   LOAD_SYMBOL (cuMemcpy2D, CuMemcpy2D);
137   LOAD_SYMBOL (cuMemcpy2DAsync, CuMemcpy2DAsync);
138   LOAD_SYMBOL (cuMemFree, CuMemFree);
139
140   LOAD_SYMBOL (cuStreamCreate, CuStreamCreate);
141   LOAD_SYMBOL (cuStreamDestroy, CuStreamDestroy);
142   LOAD_SYMBOL (cuStreamSynchronize, CuStreamSynchronize);
143
144   LOAD_SYMBOL (cuDeviceGet, CuDeviceGet);
145   LOAD_SYMBOL (cuDeviceGetCount, CuDeviceGetCount);
146   LOAD_SYMBOL (cuDeviceGetName, CuDeviceGetName);
147   LOAD_SYMBOL (cuDeviceGetAttribute, CuDeviceGetAttribute);
148
149   /* cudaGL.h */
150   LOAD_SYMBOL (cuGraphicsGLRegisterImage, CuGraphicsGLRegisterImage);
151   LOAD_SYMBOL (cuGraphicsGLRegisterBuffer, CuGraphicsGLRegisterBuffer);
152   LOAD_SYMBOL (cuGraphicsResourceSetMapFlags, CuGraphicsResourceSetMapFlags);
153
154   vtable->loaded = TRUE;
155
156   return TRUE;
157
158 error:
159   g_module_close (module);
160
161   return FALSE;
162 }
163
164 CUresult CUDAAPI
165 CuInit (unsigned int Flags)
166 {
167   g_assert (gst_cuda_vtable.CuInit != NULL);
168
169   return gst_cuda_vtable.CuInit (Flags);
170 }
171
172 CUresult CUDAAPI
173 CuGetErrorName (CUresult error, const char **pStr)
174 {
175   g_assert (gst_cuda_vtable.CuGetErrorName != NULL);
176
177   return gst_cuda_vtable.CuGetErrorName (error, pStr);
178 }
179
180 CUresult CUDAAPI
181 CuGetErrorString (CUresult error, const char **pStr)
182 {
183   g_assert (gst_cuda_vtable.CuGetErrorString != NULL);
184
185   return gst_cuda_vtable.CuGetErrorString (error, pStr);
186 }
187
188 CUresult CUDAAPI
189 CuCtxCreate (CUcontext * pctx, unsigned int flags, CUdevice dev)
190 {
191   g_assert (gst_cuda_vtable.CuCtxCreate != NULL);
192
193   return gst_cuda_vtable.CuCtxCreate (pctx, flags, dev);
194 }
195
196 CUresult CUDAAPI
197 CuCtxDestroy (CUcontext ctx)
198 {
199   g_assert (gst_cuda_vtable.CuCtxDestroy != NULL);
200
201   return gst_cuda_vtable.CuCtxDestroy (ctx);
202 }
203
204 CUresult CUDAAPI
205 CuCtxPopCurrent (CUcontext * pctx)
206 {
207   g_assert (gst_cuda_vtable.CuCtxPopCurrent != NULL);
208
209   return gst_cuda_vtable.CuCtxPopCurrent (pctx);
210 }
211
212 CUresult CUDAAPI
213 CuCtxPushCurrent (CUcontext ctx)
214 {
215   g_assert (gst_cuda_vtable.CuCtxPushCurrent != NULL);
216
217   return gst_cuda_vtable.CuCtxPushCurrent (ctx);
218 }
219
220 CUresult CUDAAPI
221 CuGraphicsMapResources (unsigned int count, CUgraphicsResource * resources,
222     CUstream hStream)
223 {
224   g_assert (gst_cuda_vtable.CuGraphicsMapResources != NULL);
225
226   return gst_cuda_vtable.CuGraphicsMapResources (count, resources, hStream);
227 }
228
229 CUresult CUDAAPI
230 CuGraphicsUnmapResources (unsigned int count, CUgraphicsResource * resources,
231     CUstream hStream)
232 {
233   g_assert (gst_cuda_vtable.CuGraphicsUnmapResources != NULL);
234
235   return gst_cuda_vtable.CuGraphicsUnmapResources (count, resources, hStream);
236 }
237
238 CUresult CUDAAPI
239 CuGraphicsSubResourceGetMappedArray (CUarray * pArray,
240     CUgraphicsResource resource, unsigned int arrayIndex, unsigned int mipLevel)
241 {
242   g_assert (gst_cuda_vtable.CuGraphicsSubResourceGetMappedArray != NULL);
243
244   return gst_cuda_vtable.CuGraphicsSubResourceGetMappedArray (pArray, resource,
245       arrayIndex, mipLevel);
246 }
247
248 CUresult CUDAAPI
249 CuGraphicsResourceGetMappedPointer (CUdeviceptr * pDevPtr, size_t * pSize,
250     CUgraphicsResource resource)
251 {
252   g_assert (gst_cuda_vtable.CuGraphicsResourceGetMappedPointer != NULL);
253
254   return gst_cuda_vtable.CuGraphicsResourceGetMappedPointer (pDevPtr, pSize,
255       resource);
256 }
257
258 CUresult CUDAAPI
259 CuGraphicsUnregisterResource (CUgraphicsResource resource)
260 {
261   g_assert (gst_cuda_vtable.CuGraphicsUnregisterResource != NULL);
262
263   return gst_cuda_vtable.CuGraphicsUnregisterResource (resource);
264 }
265
266 CUresult CUDAAPI
267 CuMemAlloc (CUdeviceptr * dptr, unsigned int bytesize)
268 {
269   g_assert (gst_cuda_vtable.CuMemAlloc != NULL);
270
271   return gst_cuda_vtable.CuMemAlloc (dptr, bytesize);
272 }
273
274 CUresult CUDAAPI
275 CuMemAllocPitch (CUdeviceptr * dptr, size_t * pPitch, size_t WidthInBytes,
276     size_t Height, unsigned int ElementSizeBytes)
277 {
278   g_assert (gst_cuda_vtable.CuMemAllocPitch != NULL);
279
280   return gst_cuda_vtable.CuMemAllocPitch (dptr, pPitch, WidthInBytes, Height,
281       ElementSizeBytes);
282 }
283
284 CUresult CUDAAPI
285 CuMemcpy2D (const CUDA_MEMCPY2D * pCopy)
286 {
287   g_assert (gst_cuda_vtable.CuMemcpy2D != NULL);
288
289   return gst_cuda_vtable.CuMemcpy2D (pCopy);
290 }
291
292 CUresult CUDAAPI
293 CuMemcpy2DAsync (const CUDA_MEMCPY2D * pCopy, CUstream hStream)
294 {
295   g_assert (gst_cuda_vtable.CuMemcpy2DAsync != NULL);
296
297   return gst_cuda_vtable.CuMemcpy2DAsync (pCopy, hStream);
298 }
299
300 CUresult CUDAAPI
301 CuMemFree (CUdeviceptr dptr)
302 {
303   g_assert (gst_cuda_vtable.CuMemFree != NULL);
304
305   return gst_cuda_vtable.CuMemFree (dptr);
306 }
307
308 CUresult CUDAAPI
309 CuStreamCreate (CUstream * phStream, unsigned int Flags)
310 {
311   g_assert (gst_cuda_vtable.CuStreamCreate != NULL);
312
313   return gst_cuda_vtable.CuStreamCreate (phStream, Flags);
314 }
315
316 CUresult CUDAAPI
317 CuStreamDestroy (CUstream hStream)
318 {
319   g_assert (gst_cuda_vtable.CuStreamDestroy != NULL);
320
321   return gst_cuda_vtable.CuStreamDestroy (hStream);
322 }
323
324 CUresult CUDAAPI
325 CuStreamSynchronize (CUstream hStream)
326 {
327   g_assert (gst_cuda_vtable.CuStreamSynchronize != NULL);
328
329   return gst_cuda_vtable.CuStreamSynchronize (hStream);
330 }
331
332 CUresult CUDAAPI
333 CuDeviceGet (CUdevice * device, int ordinal)
334 {
335   g_assert (gst_cuda_vtable.CuDeviceGet != NULL);
336
337   return gst_cuda_vtable.CuDeviceGet (device, ordinal);
338 }
339
340 CUresult CUDAAPI
341 CuDeviceGetCount (int *count)
342 {
343   g_assert (gst_cuda_vtable.CuDeviceGetCount != NULL);
344
345   return gst_cuda_vtable.CuDeviceGetCount (count);
346 }
347
348 CUresult CUDAAPI
349 CuDeviceGetName (char *name, int len, CUdevice dev)
350 {
351   g_assert (gst_cuda_vtable.CuDeviceGetName != NULL);
352
353   return gst_cuda_vtable.CuDeviceGetName (name, len, dev);
354 }
355
356 CUresult CUDAAPI
357 CuDeviceGetAttribute (int *pi, CUdevice_attribute attrib, CUdevice dev)
358 {
359   g_assert (gst_cuda_vtable.CuDeviceGetAttribute != NULL);
360
361   return gst_cuda_vtable.CuDeviceGetAttribute (pi, attrib, dev);
362 }
363
364 /* cudaGL.h */
365 CUresult CUDAAPI
366 CuGraphicsGLRegisterImage (CUgraphicsResource * pCudaResource,
367     unsigned int image, unsigned int target, unsigned int Flags)
368 {
369   g_assert (gst_cuda_vtable.CuGraphicsGLRegisterImage != NULL);
370
371   return gst_cuda_vtable.CuGraphicsGLRegisterImage (pCudaResource, image,
372       target, Flags);
373 }
374
375 CUresult CUDAAPI
376 CuGraphicsGLRegisterBuffer (CUgraphicsResource * pCudaResource,
377     unsigned int buffer, unsigned int Flags)
378 {
379   g_assert (gst_cuda_vtable.CuGraphicsGLRegisterBuffer != NULL);
380
381   return gst_cuda_vtable.CuGraphicsGLRegisterBuffer (pCudaResource, buffer,
382       Flags);
383 }
384
385 CUresult CUDAAPI
386 CuGraphicsResourceSetMapFlags (CUgraphicsResource resource, unsigned int flags)
387 {
388   g_assert (gst_cuda_vtable.CuGraphicsResourceSetMapFlags != NULL);
389
390   return gst_cuda_vtable.CuGraphicsResourceSetMapFlags (resource, flags);
391 }