• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   guint major_version;
48   guint minor_version;
49 
50     CUresult (CUDAAPI * CuvidCtxLockCreate) (CUvideoctxlock * pLock,
51       CUcontext ctx);
52     CUresult (CUDAAPI * CuvidCtxLockDestroy) (CUvideoctxlock lck);
53     CUresult (CUDAAPI * CuvidCtxLock) (CUvideoctxlock lck,
54       unsigned int reserved_flags);
55     CUresult (CUDAAPI * CuvidCtxUnlock) (CUvideoctxlock lck,
56       unsigned int reserved_flags);
57     CUresult (CUDAAPI * CuvidCreateDecoder) (CUvideodecoder * phDecoder,
58       CUVIDDECODECREATEINFO * pdci);
59     CUresult (CUDAAPI * CuvidDestroyDecoder) (CUvideodecoder hDecoder);
60     CUresult (CUDAAPI * CuvidDecodePicture) (CUvideodecoder hDecoder,
61       CUVIDPICPARAMS * pPicParams);
62     CUresult (CUDAAPI * CuvidCreateVideoParser) (CUvideoparser * pObj,
63       CUVIDPARSERPARAMS * pParams);
64     CUresult (CUDAAPI * CuvidParseVideoData) (CUvideoparser obj,
65       CUVIDSOURCEDATAPACKET * pPacket);
66     CUresult (CUDAAPI * CuvidDestroyVideoParser) (CUvideoparser obj);
67     CUresult (CUDAAPI * CuvidMapVideoFrame) (CUvideodecoder hDecoder,
68       int nPicIdx, guintptr * pDevPtr, unsigned int *pPitch,
69       CUVIDPROCPARAMS * pVPP);
70     CUresult (CUDAAPI * CuvidUnmapVideoFrame) (CUvideodecoder hDecoder,
71       guintptr DevPtr);
72     CUresult (CUDAAPI * CuvidGetDecoderCaps) (CUVIDDECODECAPS * pdc);
73 } GstnvdecCuvidVTable;
74 
75 static GstnvdecCuvidVTable gst_cuvid_vtable = { 0, };
76 
77 gboolean
gst_cuvid_load_library(guint api_major_ver,guint api_minor_ver)78 gst_cuvid_load_library (guint api_major_ver, guint api_minor_ver)
79 {
80   GModule *module;
81   const gchar *filename = NVCUVID_LIBNAME;
82   GstnvdecCuvidVTable *vtable;
83 
84   if (gst_cuvid_vtable.loaded)
85     return TRUE;
86 
87   module = g_module_open (filename, G_MODULE_BIND_LAZY);
88   if (module == NULL) {
89     GST_WARNING ("Could not open library %s, %s", filename, g_module_error ());
90     return FALSE;
91   }
92 
93   vtable = &gst_cuvid_vtable;
94 
95   LOAD_SYMBOL (cuvidCtxLockCreate, CuvidCtxLockCreate, TRUE);
96   LOAD_SYMBOL (cuvidCtxLockDestroy, CuvidCtxLockDestroy, TRUE);
97   LOAD_SYMBOL (cuvidCtxLock, CuvidCtxLock, TRUE);
98   LOAD_SYMBOL (cuvidCtxUnlock, CuvidCtxUnlock, TRUE);
99   LOAD_SYMBOL (cuvidCreateDecoder, CuvidCreateDecoder, TRUE);
100   LOAD_SYMBOL (cuvidDestroyDecoder, CuvidDestroyDecoder, TRUE);
101   LOAD_SYMBOL (cuvidDecodePicture, CuvidDecodePicture, TRUE);
102   LOAD_SYMBOL (cuvidCreateVideoParser, CuvidCreateVideoParser, TRUE);
103   LOAD_SYMBOL (cuvidParseVideoData, CuvidParseVideoData, TRUE);
104   LOAD_SYMBOL (cuvidDestroyVideoParser, CuvidDestroyVideoParser, TRUE);
105   LOAD_SYMBOL (cuvidMapVideoFrame, CuvidMapVideoFrame, TRUE);
106   LOAD_SYMBOL (cuvidUnmapVideoFrame, CuvidUnmapVideoFrame, TRUE);
107   LOAD_SYMBOL (cuvidGetDecoderCaps, CuvidGetDecoderCaps, FALSE);
108 
109   vtable->loaded = TRUE;
110   vtable->major_version = api_major_ver;
111   vtable->minor_version = api_minor_ver;
112 
113   return TRUE;
114 
115 error:
116   g_module_close (module);
117 
118   return FALSE;
119 }
120 
121 gboolean
gst_cuvid_get_api_version(guint * api_major_ver,guint * api_minor_ver)122 gst_cuvid_get_api_version (guint * api_major_ver, guint * api_minor_ver)
123 {
124   if (!gst_cuvid_vtable.loaded)
125     return FALSE;
126 
127   if (api_major_ver)
128     *api_major_ver = gst_cuvid_vtable.major_version;
129 
130   if (api_minor_ver)
131     *api_minor_ver = gst_cuvid_vtable.minor_version;
132 
133   return TRUE;
134 }
135 
136 gboolean
gst_cuvid_can_get_decoder_caps(void)137 gst_cuvid_can_get_decoder_caps (void)
138 {
139   return ! !gst_cuvid_vtable.CuvidGetDecoderCaps;
140 }
141 
142 CUresult CUDAAPI
CuvidCtxLockCreate(CUvideoctxlock * pLock,CUcontext ctx)143 CuvidCtxLockCreate (CUvideoctxlock * pLock, CUcontext ctx)
144 {
145   g_assert (gst_cuvid_vtable.CuvidCtxLockCreate != NULL);
146 
147   return gst_cuvid_vtable.CuvidCtxLockCreate (pLock, ctx);
148 }
149 
150 CUresult CUDAAPI
CuvidCtxLockDestroy(CUvideoctxlock lck)151 CuvidCtxLockDestroy (CUvideoctxlock lck)
152 {
153   g_assert (gst_cuvid_vtable.CuvidCtxLockDestroy != NULL);
154 
155   return gst_cuvid_vtable.CuvidCtxLockDestroy (lck);
156 }
157 
158 CUresult CUDAAPI
CuvidCtxLock(CUvideoctxlock lck,unsigned int reserved_flags)159 CuvidCtxLock (CUvideoctxlock lck, unsigned int reserved_flags)
160 {
161   g_assert (gst_cuvid_vtable.CuvidCtxLock != NULL);
162 
163   return gst_cuvid_vtable.CuvidCtxLock (lck, reserved_flags);
164 }
165 
166 CUresult CUDAAPI
CuvidCtxUnlock(CUvideoctxlock lck,unsigned int reserved_flags)167 CuvidCtxUnlock (CUvideoctxlock lck, unsigned int reserved_flags)
168 {
169   g_assert (gst_cuvid_vtable.CuvidCtxLockDestroy != NULL);
170 
171   return gst_cuvid_vtable.CuvidCtxUnlock (lck, reserved_flags);
172 }
173 
174 CUresult CUDAAPI
CuvidCreateDecoder(CUvideodecoder * phDecoder,CUVIDDECODECREATEINFO * pdci)175 CuvidCreateDecoder (CUvideodecoder * phDecoder, CUVIDDECODECREATEINFO * pdci)
176 {
177   g_assert (gst_cuvid_vtable.CuvidCreateDecoder != NULL);
178 
179   return gst_cuvid_vtable.CuvidCreateDecoder (phDecoder, pdci);
180 }
181 
182 CUresult CUDAAPI
CuvidDestroyDecoder(CUvideodecoder hDecoder)183 CuvidDestroyDecoder (CUvideodecoder hDecoder)
184 {
185   g_assert (gst_cuvid_vtable.CuvidDestroyDecoder != NULL);
186 
187   return gst_cuvid_vtable.CuvidDestroyDecoder (hDecoder);
188 }
189 
190 CUresult CUDAAPI
CuvidDecodePicture(CUvideodecoder hDecoder,CUVIDPICPARAMS * pPicParams)191 CuvidDecodePicture (CUvideodecoder hDecoder, CUVIDPICPARAMS * pPicParams)
192 {
193   g_assert (gst_cuvid_vtable.CuvidDecodePicture != NULL);
194 
195   return gst_cuvid_vtable.CuvidDecodePicture (hDecoder, pPicParams);
196 }
197 
198 CUresult CUDAAPI
CuvidCreateVideoParser(CUvideoparser * pObj,CUVIDPARSERPARAMS * pParams)199 CuvidCreateVideoParser (CUvideoparser * pObj, CUVIDPARSERPARAMS * pParams)
200 {
201   g_assert (gst_cuvid_vtable.CuvidCreateVideoParser != NULL);
202 
203   return gst_cuvid_vtable.CuvidCreateVideoParser (pObj, pParams);
204 }
205 
206 CUresult CUDAAPI
CuvidParseVideoData(CUvideoparser obj,CUVIDSOURCEDATAPACKET * pPacket)207 CuvidParseVideoData (CUvideoparser obj, CUVIDSOURCEDATAPACKET * pPacket)
208 {
209   g_assert (gst_cuvid_vtable.CuvidParseVideoData != NULL);
210 
211   return gst_cuvid_vtable.CuvidParseVideoData (obj, pPacket);
212 }
213 
214 CUresult CUDAAPI
CuvidDestroyVideoParser(CUvideoparser obj)215 CuvidDestroyVideoParser (CUvideoparser obj)
216 {
217   g_assert (gst_cuvid_vtable.CuvidDestroyVideoParser != NULL);
218 
219   return gst_cuvid_vtable.CuvidDestroyVideoParser (obj);
220 }
221 
222 CUresult CUDAAPI
CuvidMapVideoFrame(CUvideodecoder hDecoder,int nPicIdx,guintptr * pDevPtr,unsigned int * pPitch,CUVIDPROCPARAMS * pVPP)223 CuvidMapVideoFrame (CUvideodecoder hDecoder, int nPicIdx,
224     guintptr * pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS * pVPP)
225 {
226   g_assert (gst_cuvid_vtable.CuvidMapVideoFrame != NULL);
227 
228   return gst_cuvid_vtable.CuvidMapVideoFrame (hDecoder, nPicIdx, pDevPtr,
229       pPitch, pVPP);
230 }
231 
232 CUresult CUDAAPI
CuvidUnmapVideoFrame(CUvideodecoder hDecoder,guintptr DevPtr)233 CuvidUnmapVideoFrame (CUvideodecoder hDecoder, guintptr DevPtr)
234 {
235   g_assert (gst_cuvid_vtable.CuvidUnmapVideoFrame != NULL);
236 
237   return gst_cuvid_vtable.CuvidUnmapVideoFrame (hDecoder, DevPtr);
238 }
239 
240 CUresult CUDAAPI
CuvidGetDecoderCaps(CUVIDDECODECAPS * pdc)241 CuvidGetDecoderCaps (CUVIDDECODECAPS * pdc)
242 {
243   g_assert (gst_cuvid_vtable.CuvidGetDecoderCaps != NULL);
244 
245   return gst_cuvid_vtable.CuvidGetDecoderCaps (pdc);
246 }
247