nvcodec: Fix various typos
[platform/upstream/gstreamer.git] / sys / nvcodec / gstnvenc.c
1 /* GStreamer NVENC plugin
2  * Copyright (C) 2015 Centricular Ltd
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 "gstnvenc.h"
25 #include "gstnvh264enc.h"
26 #include "gstnvh265enc.h"
27 #include "gstcudabufferpool.h"
28
29 #include <gmodule.h>
30
31 #if HAVE_NVCODEC_GST_GL
32 #include <gst/gl/gl.h>
33 #endif
34
35 #ifdef _WIN32
36 #ifdef _WIN64
37 #define NVENC_LIBRARY_NAME "nvEncodeAPI64.dll"
38 #else
39 #define NVENC_LIBRARY_NAME "nvEncodeAPI.dll"
40 #endif
41 #else
42 #define NVENC_LIBRARY_NAME "libnvidia-encode.so.1"
43 #endif
44
45 /* For backward compatibility */
46 #define GST_NVENC_MIN_API_MAJOR_VERSION 8
47 #define GST_NVENC_MIN_API_MINOR_VERSION 1
48
49 #define GST_NVENCAPI_VERSION(major,minor) ((major) | ((minor) << 24))
50 #define GST_NVENCAPI_STRUCT_VERSION(ver,api_ver) ((uint32_t)(api_ver) | ((ver)<<16) | (0x7 << 28))
51
52 static guint32 gst_nvenc_api_version = NVENCAPI_VERSION;
53
54 typedef NVENCSTATUS NVENCAPI
55 tNvEncodeAPICreateInstance (NV_ENCODE_API_FUNCTION_LIST * functionList);
56 tNvEncodeAPICreateInstance *nvEncodeAPICreateInstance;
57
58 typedef NVENCSTATUS NVENCAPI
59 tNvEncodeAPIGetMaxSupportedVersion (uint32_t * version);
60 tNvEncodeAPIGetMaxSupportedVersion *nvEncodeAPIGetMaxSupportedVersion;
61
62 GST_DEBUG_CATEGORY_EXTERN (gst_nvenc_debug);
63 #define GST_CAT_DEFAULT gst_nvenc_debug
64
65 static NV_ENCODE_API_FUNCTION_LIST nvenc_api;
66
67 NVENCSTATUS NVENCAPI
68 NvEncOpenEncodeSessionEx (NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS * params,
69     void **encoder)
70 {
71   g_assert (nvenc_api.nvEncOpenEncodeSessionEx != NULL);
72   return nvenc_api.nvEncOpenEncodeSessionEx (params, encoder);
73 }
74
75 NVENCSTATUS NVENCAPI
76 NvEncDestroyEncoder (void *encoder)
77 {
78   g_assert (nvenc_api.nvEncDestroyEncoder != NULL);
79   return nvenc_api.nvEncDestroyEncoder (encoder);
80 }
81
82 NVENCSTATUS NVENCAPI
83 NvEncGetEncodeGUIDs (void *encoder, GUID * array, uint32_t array_size,
84     uint32_t * count)
85 {
86   g_assert (nvenc_api.nvEncGetEncodeGUIDs != NULL);
87   return nvenc_api.nvEncGetEncodeGUIDs (encoder, array, array_size, count);
88 }
89
90 NVENCSTATUS NVENCAPI
91 NvEncGetEncodeProfileGUIDCount (void *encoder, GUID encodeGUID,
92     uint32_t * encodeProfileGUIDCount)
93 {
94   g_assert (nvenc_api.nvEncGetEncodeProfileGUIDCount != NULL);
95   return nvenc_api.nvEncGetEncodeProfileGUIDCount (encoder, encodeGUID,
96       encodeProfileGUIDCount);
97 }
98
99 NVENCSTATUS NVENCAPI
100 NvEncGetEncodeProfileGUIDs (void *encoder, GUID encodeGUID,
101     GUID * profileGUIDs, uint32_t guidArraySize, uint32_t * GUIDCount)
102 {
103   g_assert (nvenc_api.nvEncGetEncodeProfileGUIDs != NULL);
104   return nvenc_api.nvEncGetEncodeProfileGUIDs (encoder, encodeGUID,
105       profileGUIDs, guidArraySize, GUIDCount);
106 }
107
108 NVENCSTATUS NVENCAPI
109 NvEncGetInputFormats (void *encoder, GUID enc_guid,
110     NV_ENC_BUFFER_FORMAT * array, uint32_t size, uint32_t * num)
111 {
112   g_assert (nvenc_api.nvEncGetInputFormats != NULL);
113   return nvenc_api.nvEncGetInputFormats (encoder, enc_guid, array, size, num);
114 }
115
116 NVENCSTATUS NVENCAPI
117 NvEncGetEncodePresetCount (void *encoder, GUID encodeGUID,
118     uint32_t * encodePresetGUIDCount)
119 {
120   g_assert (nvenc_api.nvEncGetEncodeProfileGUIDCount != NULL);
121   return nvenc_api.nvEncGetEncodePresetCount (encoder, encodeGUID,
122       encodePresetGUIDCount);
123 }
124
125 NVENCSTATUS NVENCAPI
126 NvEncGetEncodePresetGUIDs (void *encoder, GUID encodeGUID,
127     GUID * presetGUIDs, uint32_t guidArraySize, uint32_t * GUIDCount)
128 {
129   g_assert (nvenc_api.nvEncGetEncodeProfileGUIDs != NULL);
130   return nvenc_api.nvEncGetEncodePresetGUIDs (encoder, encodeGUID,
131       presetGUIDs, guidArraySize, GUIDCount);
132 }
133
134 NVENCSTATUS NVENCAPI
135 NvEncGetEncodePresetConfig (void *encoder, GUID encodeGUID,
136     GUID presetGUID, NV_ENC_PRESET_CONFIG * presetConfig)
137 {
138   g_assert (nvenc_api.nvEncGetEncodePresetConfig != NULL);
139   return nvenc_api.nvEncGetEncodePresetConfig (encoder, encodeGUID, presetGUID,
140       presetConfig);
141 }
142
143 NVENCSTATUS NVENCAPI
144 NvEncGetEncodeCaps (void *encoder, GUID encodeGUID,
145     NV_ENC_CAPS_PARAM * capsParam, int *capsVal)
146 {
147   g_assert (nvenc_api.nvEncGetEncodeCaps != NULL);
148   return nvenc_api.nvEncGetEncodeCaps (encoder, encodeGUID, capsParam, capsVal);
149 }
150
151 NVENCSTATUS NVENCAPI
152 NvEncGetSequenceParams (void *encoder,
153     NV_ENC_SEQUENCE_PARAM_PAYLOAD * sequenceParamPayload)
154 {
155   g_assert (nvenc_api.nvEncGetSequenceParams != NULL);
156   return nvenc_api.nvEncGetSequenceParams (encoder, sequenceParamPayload);
157 }
158
159 NVENCSTATUS NVENCAPI
160 NvEncInitializeEncoder (void *encoder, NV_ENC_INITIALIZE_PARAMS * params)
161 {
162   g_assert (nvenc_api.nvEncInitializeEncoder != NULL);
163   return nvenc_api.nvEncInitializeEncoder (encoder, params);
164 }
165
166 NVENCSTATUS NVENCAPI
167 NvEncReconfigureEncoder (void *encoder, NV_ENC_RECONFIGURE_PARAMS * params)
168 {
169   g_assert (nvenc_api.nvEncReconfigureEncoder != NULL);
170   return nvenc_api.nvEncReconfigureEncoder (encoder, params);
171 }
172
173 NVENCSTATUS NVENCAPI
174 NvEncRegisterResource (void *encoder, NV_ENC_REGISTER_RESOURCE * params)
175 {
176   g_assert (nvenc_api.nvEncRegisterResource != NULL);
177   return nvenc_api.nvEncRegisterResource (encoder, params);
178 }
179
180 NVENCSTATUS NVENCAPI
181 NvEncUnregisterResource (void *encoder, NV_ENC_REGISTERED_PTR resource)
182 {
183   g_assert (nvenc_api.nvEncUnregisterResource != NULL);
184   return nvenc_api.nvEncUnregisterResource (encoder, resource);
185 }
186
187 NVENCSTATUS NVENCAPI
188 NvEncMapInputResource (void *encoder, NV_ENC_MAP_INPUT_RESOURCE * params)
189 {
190   g_assert (nvenc_api.nvEncMapInputResource != NULL);
191   return nvenc_api.nvEncMapInputResource (encoder, params);
192 }
193
194 NVENCSTATUS NVENCAPI
195 NvEncUnmapInputResource (void *encoder, NV_ENC_INPUT_PTR input_buffer)
196 {
197   g_assert (nvenc_api.nvEncUnmapInputResource != NULL);
198   return nvenc_api.nvEncUnmapInputResource (encoder, input_buffer);
199 }
200
201 NVENCSTATUS NVENCAPI
202 NvEncCreateInputBuffer (void *encoder, NV_ENC_CREATE_INPUT_BUFFER * input_buf)
203 {
204   g_assert (nvenc_api.nvEncCreateInputBuffer != NULL);
205   return nvenc_api.nvEncCreateInputBuffer (encoder, input_buf);
206 }
207
208 NVENCSTATUS NVENCAPI
209 NvEncLockInputBuffer (void *encoder, NV_ENC_LOCK_INPUT_BUFFER * input_buf)
210 {
211   g_assert (nvenc_api.nvEncLockInputBuffer != NULL);
212   return nvenc_api.nvEncLockInputBuffer (encoder, input_buf);
213 }
214
215 NVENCSTATUS NVENCAPI
216 NvEncUnlockInputBuffer (void *encoder, NV_ENC_INPUT_PTR input_buf)
217 {
218   g_assert (nvenc_api.nvEncUnlockInputBuffer != NULL);
219   return nvenc_api.nvEncUnlockInputBuffer (encoder, input_buf);
220 }
221
222 NVENCSTATUS NVENCAPI
223 NvEncDestroyInputBuffer (void *encoder, NV_ENC_INPUT_PTR input_buf)
224 {
225   g_assert (nvenc_api.nvEncDestroyInputBuffer != NULL);
226   return nvenc_api.nvEncDestroyInputBuffer (encoder, input_buf);
227 }
228
229 NVENCSTATUS NVENCAPI
230 NvEncCreateBitstreamBuffer (void *encoder, NV_ENC_CREATE_BITSTREAM_BUFFER * bb)
231 {
232   g_assert (nvenc_api.nvEncCreateBitstreamBuffer != NULL);
233   return nvenc_api.nvEncCreateBitstreamBuffer (encoder, bb);
234 }
235
236 NVENCSTATUS NVENCAPI
237 NvEncLockBitstream (void *encoder, NV_ENC_LOCK_BITSTREAM * lock_bs)
238 {
239   g_assert (nvenc_api.nvEncLockBitstream != NULL);
240   return nvenc_api.nvEncLockBitstream (encoder, lock_bs);
241 }
242
243 NVENCSTATUS NVENCAPI
244 NvEncUnlockBitstream (void *encoder, NV_ENC_OUTPUT_PTR bb)
245 {
246   g_assert (nvenc_api.nvEncUnlockBitstream != NULL);
247   return nvenc_api.nvEncUnlockBitstream (encoder, bb);
248 }
249
250 NVENCSTATUS NVENCAPI
251 NvEncDestroyBitstreamBuffer (void *encoder, NV_ENC_OUTPUT_PTR bit_buf)
252 {
253   g_assert (nvenc_api.nvEncDestroyBitstreamBuffer != NULL);
254   return nvenc_api.nvEncDestroyBitstreamBuffer (encoder, bit_buf);
255 }
256
257 NVENCSTATUS NVENCAPI
258 NvEncEncodePicture (void *encoder, NV_ENC_PIC_PARAMS * pic_params)
259 {
260   g_assert (nvenc_api.nvEncEncodePicture != NULL);
261   return nvenc_api.nvEncEncodePicture (encoder, pic_params);
262 }
263
264 gboolean
265 gst_nvenc_cmp_guid (GUID g1, GUID g2)
266 {
267   return (g1.Data1 == g2.Data1 && g1.Data2 == g2.Data2 && g1.Data3 == g2.Data3
268       && g1.Data4[0] == g2.Data4[0] && g1.Data4[1] == g2.Data4[1]
269       && g1.Data4[2] == g2.Data4[2] && g1.Data4[3] == g2.Data4[3]
270       && g1.Data4[4] == g2.Data4[4] && g1.Data4[5] == g2.Data4[5]
271       && g1.Data4[6] == g2.Data4[6] && g1.Data4[7] == g2.Data4[7]);
272 }
273
274 NV_ENC_BUFFER_FORMAT
275 gst_nvenc_get_nv_buffer_format (GstVideoFormat fmt)
276 {
277   switch (fmt) {
278     case GST_VIDEO_FORMAT_NV12:
279       return NV_ENC_BUFFER_FORMAT_NV12_PL;
280     case GST_VIDEO_FORMAT_YV12:
281       return NV_ENC_BUFFER_FORMAT_YV12_PL;
282     case GST_VIDEO_FORMAT_I420:
283       return NV_ENC_BUFFER_FORMAT_IYUV_PL;
284     case GST_VIDEO_FORMAT_Y444:
285       return NV_ENC_BUFFER_FORMAT_YUV444_PL;
286     case GST_VIDEO_FORMAT_P010_10LE:
287     case GST_VIDEO_FORMAT_P010_10BE:
288       return NV_ENC_BUFFER_FORMAT_YUV420_10BIT;
289     case GST_VIDEO_FORMAT_BGRA:
290       return NV_ENC_BUFFER_FORMAT_ARGB;
291     case GST_VIDEO_FORMAT_RGBA:
292       return NV_ENC_BUFFER_FORMAT_ABGR;
293     case GST_VIDEO_FORMAT_BGR10A2_LE:
294       return NV_ENC_BUFFER_FORMAT_ARGB10;
295     case GST_VIDEO_FORMAT_RGB10A2_LE:
296       return NV_ENC_BUFFER_FORMAT_ABGR10;
297     case GST_VIDEO_FORMAT_Y444_16LE:
298     case GST_VIDEO_FORMAT_Y444_16BE:
299       return NV_ENC_BUFFER_FORMAT_YUV444_10BIT;
300     case GST_VIDEO_FORMAT_VUYA:
301       return NV_ENC_BUFFER_FORMAT_AYUV;
302     default:
303       break;
304   }
305   return NV_ENC_BUFFER_FORMAT_UNDEFINED;
306 }
307
308 typedef struct
309 {
310   GstVideoFormat gst_format;
311   NV_ENC_BUFFER_FORMAT nv_format;
312   gboolean is_10bit;
313
314   gboolean supported;
315 } GstNvEncFormat;
316
317 gboolean
318 gst_nvenc_get_supported_input_formats (gpointer encoder, GUID codec_id,
319     GValue ** formats)
320 {
321   guint32 i, count = 0;
322   NV_ENC_BUFFER_FORMAT format_list[64];
323   GValue val = G_VALUE_INIT;
324   GValue *ret = NULL;
325   NV_ENC_CAPS_PARAM param = { 0, };
326   gint support_yuv444 = 0;
327   gint support_10bit = 0;
328   guint num_format = 0;
329   GstNvEncFormat format_map[] = {
330     {GST_VIDEO_FORMAT_NV12, NV_ENC_BUFFER_FORMAT_NV12, FALSE, FALSE},
331     {GST_VIDEO_FORMAT_YV12, NV_ENC_BUFFER_FORMAT_YV12, FALSE, FALSE},
332     {GST_VIDEO_FORMAT_I420, NV_ENC_BUFFER_FORMAT_IYUV, FALSE, FALSE},
333     {GST_VIDEO_FORMAT_BGRA, NV_ENC_BUFFER_FORMAT_ARGB, FALSE, FALSE},
334     {GST_VIDEO_FORMAT_RGBA, NV_ENC_BUFFER_FORMAT_ABGR, FALSE, FALSE},
335     {GST_VIDEO_FORMAT_Y444, NV_ENC_BUFFER_FORMAT_YUV444, FALSE, FALSE},
336     {GST_VIDEO_FORMAT_VUYA, NV_ENC_BUFFER_FORMAT_AYUV, FALSE, FALSE},
337 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
338     {GST_VIDEO_FORMAT_P010_10LE, NV_ENC_BUFFER_FORMAT_YUV420_10BIT, TRUE,
339         FALSE},
340     {GST_VIDEO_FORMAT_BGR10A2_LE, NV_ENC_BUFFER_FORMAT_ARGB10, TRUE,
341         FALSE},
342     {GST_VIDEO_FORMAT_RGB10A2_LE, NV_ENC_BUFFER_FORMAT_ABGR10, TRUE,
343         FALSE},
344     {GST_VIDEO_FORMAT_Y444_16LE, NV_ENC_BUFFER_FORMAT_YUV444_10BIT, TRUE,
345         FALSE},
346 #else
347     {GST_VIDEO_FORMAT_P010_10BE, NV_ENC_BUFFER_FORMAT_YUV420_10BIT, TRUE,
348         FALSE},
349     {GST_VIDEO_FORMAT_Y444_16BE, NV_ENC_BUFFER_FORMAT_YUV444_10BIT, TRUE,
350         FALSE},
351     /* FIXME: No 10bits big-endian ARGB10 format is defined */
352 #endif
353   };
354
355   param.version = gst_nvenc_get_caps_param_version ();
356   param.capsToQuery = NV_ENC_CAPS_SUPPORT_YUV444_ENCODE;
357   if (NvEncGetEncodeCaps (encoder,
358           codec_id, &param, &support_yuv444) != NV_ENC_SUCCESS) {
359     support_yuv444 = 0;
360   }
361
362   param.capsToQuery = NV_ENC_CAPS_SUPPORT_10BIT_ENCODE;
363   if (NvEncGetEncodeCaps (encoder,
364           codec_id, &param, &support_10bit) != NV_ENC_SUCCESS) {
365     support_10bit = 0;
366   }
367
368   if (NvEncGetInputFormats (encoder,
369           codec_id, format_list, G_N_ELEMENTS (format_list),
370           &count) != NV_ENC_SUCCESS || count == 0) {
371     return FALSE;
372   }
373
374   for (i = 0; i < count; i++) {
375     GST_INFO ("input format: 0x%08x", format_list[i]);
376     switch (format_list[i]) {
377       case NV_ENC_BUFFER_FORMAT_NV12:
378       case NV_ENC_BUFFER_FORMAT_YV12:
379       case NV_ENC_BUFFER_FORMAT_IYUV:
380       case NV_ENC_BUFFER_FORMAT_ARGB:
381       case NV_ENC_BUFFER_FORMAT_ABGR:
382         if (!format_map[i].supported) {
383           format_map[i].supported = TRUE;
384           num_format++;
385         }
386         break;
387       case NV_ENC_BUFFER_FORMAT_YUV444:
388       case NV_ENC_BUFFER_FORMAT_AYUV:
389         if (support_yuv444 && !format_map[i].supported) {
390           format_map[i].supported = TRUE;
391           num_format++;
392         }
393         break;
394       case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
395         if (support_10bit && !format_map[i].supported) {
396           format_map[i].supported = TRUE;
397           num_format++;
398         }
399         break;
400       case NV_ENC_BUFFER_FORMAT_YUV444_10BIT:
401         if (support_yuv444 && support_10bit && !format_map[i].supported) {
402           format_map[i].supported = TRUE;
403           num_format++;
404         }
405         break;
406 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
407       case NV_ENC_BUFFER_FORMAT_ARGB10:
408       case NV_ENC_BUFFER_FORMAT_ABGR10:
409         if (support_10bit && !format_map[i].supported) {
410           format_map[i].supported = TRUE;
411           num_format++;
412         }
413         break;
414 #endif
415       default:
416         GST_FIXME ("unmapped input format: 0x%08x", format_list[i]);
417         break;
418     }
419   }
420
421   if (num_format == 0)
422     return FALSE;
423
424   /* process a second time so we can add formats in the order we want */
425   g_value_init (&val, G_TYPE_STRING);
426   ret = g_new0 (GValue, 1);
427   g_value_init (ret, GST_TYPE_LIST);
428
429   for (i = 0; i < G_N_ELEMENTS (format_map); i++) {
430     if (!format_map[i].supported)
431       continue;
432
433     g_value_set_static_string (&val,
434         gst_video_format_to_string (format_map[i].gst_format));
435
436     gst_value_list_append_value (ret, &val);
437   }
438
439   g_value_unset (&val);
440
441   *formats = ret;
442
443   return TRUE;
444 }
445
446 GValue *
447 gst_nvenc_get_interlace_modes (gpointer enc, GUID codec_id)
448 {
449   NV_ENC_CAPS_PARAM caps_param = { 0, };
450   GValue *list;
451   GValue val = G_VALUE_INIT;
452   gint interlace_modes = 0;
453
454   caps_param.version = gst_nvenc_get_caps_param_version ();
455   caps_param.capsToQuery = NV_ENC_CAPS_SUPPORT_FIELD_ENCODING;
456
457   if (NvEncGetEncodeCaps (enc, codec_id, &caps_param,
458           &interlace_modes) != NV_ENC_SUCCESS)
459     interlace_modes = 0;
460
461   list = g_new0 (GValue, 1);
462
463   g_value_init (list, GST_TYPE_LIST);
464   g_value_init (&val, G_TYPE_STRING);
465
466   g_value_set_static_string (&val, "progressive");
467   gst_value_list_append_value (list, &val);
468
469   if (interlace_modes == 0)
470     return list;
471
472   if (interlace_modes >= 1) {
473     g_value_set_static_string (&val, "interleaved");
474     gst_value_list_append_value (list, &val);
475     g_value_set_static_string (&val, "mixed");
476     gst_value_list_append_value (list, &val);
477     g_value_unset (&val);
478   }
479   /* TODO: figure out what nvenc frame based interlacing means in gst terms */
480
481   return list;
482 }
483
484 typedef struct
485 {
486   const gchar *gst_profile;
487   const GUID nv_profile;
488   const GUID codec_id;
489   const gboolean need_yuv444;
490   const gboolean need_10bit;
491
492   gboolean supported;
493 } GstNvEncCodecProfile;
494
495 GValue *
496 gst_nvenc_get_supported_codec_profiles (gpointer enc, GUID codec_id)
497 {
498   NVENCSTATUS nv_ret;
499   GUID profile_guids[64];
500   GValue *ret;
501   GValue val = G_VALUE_INIT;
502   guint i, j, n, n_profiles;
503   NV_ENC_CAPS_PARAM param = { 0, };
504   gint support_yuv444 = 0;
505   gint support_10bit = 0;
506   GstNvEncCodecProfile profiles[] = {
507     /* avc profiles */
508     {"main", NV_ENC_H264_PROFILE_MAIN_GUID, NV_ENC_CODEC_H264_GUID, FALSE,
509         FALSE, FALSE},
510     {"high", NV_ENC_H264_PROFILE_HIGH_GUID, NV_ENC_CODEC_H264_GUID, FALSE,
511         FALSE, FALSE},
512     {"high-4:4:4", NV_ENC_H264_PROFILE_HIGH_444_GUID, NV_ENC_CODEC_H264_GUID,
513         TRUE, FALSE, FALSE},
514     /* put baseline to last since it does not support bframe */
515     {"baseline", NV_ENC_H264_PROFILE_BASELINE_GUID, NV_ENC_CODEC_H264_GUID,
516         FALSE, FALSE, FALSE},
517     /* hevc profiles */
518     {"main", NV_ENC_HEVC_PROFILE_MAIN_GUID, NV_ENC_CODEC_HEVC_GUID, FALSE,
519         FALSE, FALSE},
520     {"main-10", NV_ENC_HEVC_PROFILE_MAIN10_GUID, NV_ENC_CODEC_HEVC_GUID, FALSE,
521         TRUE, FALSE},
522     {"main-444", NV_ENC_HEVC_PROFILE_FREXT_GUID, NV_ENC_CODEC_HEVC_GUID, TRUE,
523         FALSE, FALSE},
524 #if 0
525     /* FIXME: seems to unsupported format */
526     {"main-444-10", NV_ENC_HEVC_PROFILE_FREXT_GUID, FALSE}
527 #endif
528   };
529
530   param.version = gst_nvenc_get_caps_param_version ();
531   param.capsToQuery = NV_ENC_CAPS_SUPPORT_YUV444_ENCODE;
532   if (NvEncGetEncodeCaps (enc,
533           codec_id, &param, &support_yuv444) != NV_ENC_SUCCESS) {
534     support_yuv444 = 0;
535   }
536
537   param.capsToQuery = NV_ENC_CAPS_SUPPORT_10BIT_ENCODE;
538   if (NvEncGetEncodeCaps (enc,
539           codec_id, &param, &support_10bit) != NV_ENC_SUCCESS) {
540     support_10bit = 0;
541   }
542
543   nv_ret = NvEncGetEncodeProfileGUIDCount (enc, codec_id, &n);
544
545   if (nv_ret != NV_ENC_SUCCESS)
546     return NULL;
547
548   nv_ret = NvEncGetEncodeProfileGUIDs (enc,
549       codec_id, profile_guids, G_N_ELEMENTS (profile_guids), &n);
550
551   if (nv_ret != NV_ENC_SUCCESS)
552     return NULL;
553
554   n_profiles = 0;
555
556   for (i = 0; i < n; i++) {
557     for (j = 0; j < G_N_ELEMENTS (profiles); j++) {
558       if (profiles[j].supported == FALSE &&
559           gst_nvenc_cmp_guid (profile_guids[i], profiles[j].nv_profile) &&
560           gst_nvenc_cmp_guid (codec_id, profiles[j].codec_id)) {
561         if (profiles[j].need_yuv444 && !support_yuv444)
562           continue;
563
564         if (profiles[j].need_10bit && !support_10bit)
565           continue;
566
567         profiles[j].supported = TRUE;
568         n_profiles++;
569       }
570     }
571   }
572
573   if (n_profiles == 0)
574     return NULL;
575
576   ret = g_new0 (GValue, 1);
577
578   g_value_init (ret, GST_TYPE_LIST);
579   g_value_init (&val, G_TYPE_STRING);
580
581   for (i = 0; i < G_N_ELEMENTS (profiles); i++) {
582     if (!profiles[i].supported)
583       continue;
584
585     g_value_set_static_string (&val, profiles[i].gst_profile);
586     gst_value_list_append_value (ret, &val);
587   }
588
589   g_value_unset (&val);
590
591   return ret;
592 }
593
594 #define DEBUG_DEVICE_CAPS(d,c,caps,s) \
595   GST_DEBUG ("[device-%d %s] %s: %s", \
596       d, c, caps, s ? "supported" : "not supported");
597
598 #define ERROR_DETAILS "codec %s, device %i, error code %i"
599
600 static void
601 gst_nv_enc_register (GstPlugin * plugin, GUID codec_id, const gchar * codec,
602     guint rank, gint device_index, CUcontext cuda_ctx)
603 {
604   {
605     GValue *formats = NULL;
606     GValue *profiles;
607     GValue *interlace_modes;
608     gpointer enc;
609     NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = { 0, };
610     NV_ENC_CAPS_PARAM caps_param = { 0, };
611     GUID guids[16];
612     guint32 count;
613     gint max_width = 0;
614     gint max_height = 0;
615     gint min_width = 16;
616     gint min_height = 16;
617     GstCaps *sink_templ = NULL;
618     GstCaps *src_templ = NULL;
619     gchar *name;
620     gint j;
621     GstNvEncDeviceCaps device_caps = { 0, };
622     NVENCSTATUS status;
623     CUresult cu_res;
624
625     params.version = gst_nvenc_get_open_encode_session_ex_params_version ();
626     params.apiVersion = gst_nvenc_get_api_version ();
627     params.device = cuda_ctx;
628     params.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
629
630     if ((cu_res = CuCtxPushCurrent (cuda_ctx)) != CUDA_SUCCESS) {
631       GST_ERROR ("CuCtxPushCurrent failed: " ERROR_DETAILS, codec,
632           device_index, cu_res);
633       goto done;
634     }
635
636     if ((status = NvEncOpenEncodeSessionEx (&params, &enc)) != NV_ENC_SUCCESS) {
637       CuCtxPopCurrent (NULL);
638       GST_ERROR ("NvEncOpenEncodeSessionEx failed: " ERROR_DETAILS, codec,
639           device_index, status);
640       goto done;
641     }
642
643     if ((status = NvEncGetEncodeGUIDs (enc, guids, G_N_ELEMENTS (guids),
644                 &count)) != NV_ENC_SUCCESS) {
645       GST_ERROR ("NvEncGetEncodeGUIDs failed: " ERROR_DETAILS, codec,
646           device_index, status);
647       goto enc_free;
648     }
649
650     for (j = 0; j < count; j++) {
651       if (gst_nvenc_cmp_guid (guids[j], codec_id))
652         break;
653     }
654
655     if (j == count)
656       goto enc_free;
657
658     if (!gst_nvenc_get_supported_input_formats (enc, codec_id, &formats))
659       goto enc_free;
660
661     profiles = gst_nvenc_get_supported_codec_profiles (enc, codec_id);
662     if (!profiles)
663       goto free_format;
664
665     caps_param.version = gst_nvenc_get_caps_param_version ();
666     caps_param.capsToQuery = NV_ENC_CAPS_WIDTH_MAX;
667     if ((status = NvEncGetEncodeCaps (enc,
668                 codec_id, &caps_param, &max_width)) != NV_ENC_SUCCESS) {
669       max_width = 4096;
670       GST_WARNING ("could not query max width, setting as %i: "
671           ERROR_DETAILS, max_width, codec, device_index, status);
672     } else if (max_width < 4096) {
673       GST_WARNING ("max width %d is less than expected value", max_width);
674       max_width = 4096;
675     }
676
677     caps_param.capsToQuery = NV_ENC_CAPS_HEIGHT_MAX;
678     if ((status = NvEncGetEncodeCaps (enc,
679                 codec_id, &caps_param, &max_height)) != NV_ENC_SUCCESS) {
680       GST_WARNING ("could not query max height, setting as %i: "
681           ERROR_DETAILS, max_height, codec, device_index, status);
682       max_height = 4096;
683     } else if (max_height < 4096) {
684       GST_WARNING ("max height %d is less than expected value", max_height);
685       max_height = 4096;
686     }
687
688     caps_param.capsToQuery = NV_ENC_CAPS_WIDTH_MIN;
689     if ((status = NvEncGetEncodeCaps (enc,
690                 codec_id, &caps_param, &min_width)) != NV_ENC_SUCCESS) {
691       GST_WARNING ("could not query min width, setting as %i: "
692           ERROR_DETAILS, min_width, codec, device_index, status);
693       min_width = 16;
694     }
695
696     caps_param.capsToQuery = NV_ENC_CAPS_HEIGHT_MIN;
697     if ((status = NvEncGetEncodeCaps (enc,
698                 codec_id, &caps_param, &min_height)) != NV_ENC_SUCCESS) {
699       GST_WARNING ("could not query min height, setting as %i: "
700           ERROR_DETAILS, min_height, codec, device_index, status);
701       min_height = 16;
702     }
703
704     caps_param.capsToQuery = NV_ENC_CAPS_SUPPORTED_RATECONTROL_MODES;
705     if (NvEncGetEncodeCaps (enc, codec_id, &caps_param,
706             &device_caps.rc_modes) != NV_ENC_SUCCESS) {
707       device_caps.rc_modes = 0;
708     } else {
709       GST_DEBUG ("[device-%d %s] rate control modes: 0x%x",
710           device_index, codec, device_caps.rc_modes);
711 #define IS_SUPPORTED_RC(rc_modes,mode) \
712       ((((rc_modes) & (mode)) == mode) ? "supported" : "not supported")
713
714       GST_DEBUG ("\tconst-qp:         %s",
715           IS_SUPPORTED_RC (device_caps.rc_modes, NV_ENC_PARAMS_RC_CONSTQP));
716       GST_DEBUG ("\tvbr:              %s",
717           IS_SUPPORTED_RC (device_caps.rc_modes, NV_ENC_PARAMS_RC_VBR));
718       GST_DEBUG ("\tcbr:              %s",
719           IS_SUPPORTED_RC (device_caps.rc_modes, NV_ENC_PARAMS_RC_CBR));
720       GST_DEBUG ("\tcbr-lowdelay-hq:  %s",
721           IS_SUPPORTED_RC (device_caps.rc_modes,
722               NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ));
723       GST_DEBUG ("\tcbr-hq:           %s",
724           IS_SUPPORTED_RC (device_caps.rc_modes, NV_ENC_PARAMS_RC_CBR_HQ));
725       GST_DEBUG ("\tvbr-hq:           %s",
726           IS_SUPPORTED_RC (device_caps.rc_modes, NV_ENC_PARAMS_RC_VBR_HQ));
727       GST_DEBUG ("\tvbr-minqp:        %s (deprecated)",
728           IS_SUPPORTED_RC (device_caps.rc_modes, NV_ENC_PARAMS_RC_VBR_MINQP));
729 #undef IS_SUPPORTED_RC
730     }
731
732     caps_param.capsToQuery = NV_ENC_CAPS_SUPPORT_WEIGHTED_PREDICTION;
733     if (NvEncGetEncodeCaps (enc, codec_id, &caps_param,
734             &device_caps.weighted_prediction) != NV_ENC_SUCCESS) {
735       device_caps.weighted_prediction = FALSE;
736     }
737
738     caps_param.capsToQuery = NV_ENC_CAPS_SUPPORT_CUSTOM_VBV_BUF_SIZE;
739     if (NvEncGetEncodeCaps (enc, codec_id, &caps_param,
740             &device_caps.custom_vbv_bufsize) != NV_ENC_SUCCESS) {
741       device_caps.custom_vbv_bufsize = FALSE;
742     }
743
744     caps_param.capsToQuery = NV_ENC_CAPS_SUPPORT_LOOKAHEAD;
745     if (NvEncGetEncodeCaps (enc,
746             codec_id, &caps_param, &device_caps.lookahead) != NV_ENC_SUCCESS) {
747       device_caps.lookahead = FALSE;
748     }
749
750     caps_param.capsToQuery = NV_ENC_CAPS_SUPPORT_TEMPORAL_AQ;
751     if (NvEncGetEncodeCaps (enc, codec_id, &caps_param,
752             &device_caps.temporal_aq) != NV_ENC_SUCCESS) {
753       device_caps.temporal_aq = FALSE;
754     }
755
756     caps_param.capsToQuery = NV_ENC_CAPS_NUM_MAX_BFRAMES;
757     if (NvEncGetEncodeCaps (enc, codec_id, &caps_param,
758             &device_caps.bframes) != NV_ENC_SUCCESS) {
759       device_caps.bframes = 0;
760     }
761
762     DEBUG_DEVICE_CAPS (device_index,
763         codec, "weighted prediction", device_caps.weighted_prediction);
764
765     DEBUG_DEVICE_CAPS (device_index, codec, "custom vbv-buffer-size",
766         device_caps.custom_vbv_bufsize);
767
768     DEBUG_DEVICE_CAPS (device_index, codec, "rc-loockahead",
769         device_caps.lookahead);
770
771     DEBUG_DEVICE_CAPS (device_index, codec, "temporal adaptive quantization",
772         device_caps.temporal_aq);
773
774     GST_DEBUG ("[device-%d %s] max bframes: %d", device_index, codec,
775         device_caps.bframes);
776
777     interlace_modes = gst_nvenc_get_interlace_modes (enc, codec_id);
778
779     sink_templ = gst_caps_new_empty_simple ("video/x-raw");
780     gst_caps_set_value (sink_templ, "format", formats);
781
782     gst_caps_set_simple (sink_templ,
783         "width", GST_TYPE_INT_RANGE, min_width, max_width,
784         "height", GST_TYPE_INT_RANGE, min_height, max_height,
785         "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
786
787     if (interlace_modes) {
788       gst_caps_set_value (sink_templ, "interlace-mode", interlace_modes);
789       g_value_unset (interlace_modes);
790       g_free (interlace_modes);
791     }
792
793     {
794       GstCaps *cuda_caps = gst_caps_copy (sink_templ);
795 #if HAVE_NVCODEC_GST_GL
796       GstCaps *gl_caps = gst_caps_copy (sink_templ);
797       gst_caps_set_features_simple (gl_caps,
798           gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));
799       gst_caps_append (sink_templ, gl_caps);
800 #endif
801
802       gst_caps_set_features_simple (cuda_caps,
803           gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_CUDA_MEMORY));
804       gst_caps_append (sink_templ, cuda_caps);
805     }
806
807     name = g_strdup_printf ("video/x-%s", codec);
808     src_templ = gst_caps_new_simple (name,
809         "width", GST_TYPE_INT_RANGE, min_width, max_width,
810         "height", GST_TYPE_INT_RANGE, min_height, max_height,
811         "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
812         "stream-format", G_TYPE_STRING, "byte-stream",
813         "alignment", G_TYPE_STRING, "au", NULL);
814     gst_caps_set_value (src_templ, "profile", profiles);
815     g_free (name);
816
817     GST_DEBUG ("sink template caps %" GST_PTR_FORMAT, sink_templ);
818     GST_DEBUG ("src template caps %" GST_PTR_FORMAT, src_templ);
819
820     g_value_unset (profiles);
821     g_free (profiles);
822
823   free_format:
824     if (formats) {
825       g_value_unset (formats);
826       g_free (formats);
827     }
828     /* fall-through */
829
830   enc_free:
831     NvEncDestroyEncoder (enc);
832     CuCtxPopCurrent (NULL);
833     /* fall-through */
834
835   done:
836     if (sink_templ && src_templ) {
837       if (gst_nvenc_cmp_guid (codec_id, NV_ENC_CODEC_H264_GUID)) {
838         gst_nv_h264_enc_register (plugin, device_index, rank, sink_templ,
839             src_templ, &device_caps);
840       } else if (gst_nvenc_cmp_guid (codec_id, NV_ENC_CODEC_HEVC_GUID)) {
841         gst_nv_h265_enc_register (plugin, device_index, rank, sink_templ,
842             src_templ, &device_caps);
843       } else {
844         g_assert_not_reached ();
845       }
846     }
847
848     gst_clear_caps (&sink_templ);
849     gst_clear_caps (&src_templ);
850   }
851 }
852
853 typedef struct
854 {
855   gint major;
856   gint minor;
857 } GstNvEncVersion;
858
859 gboolean
860 gst_nvenc_load_library (guint * api_major_ver, guint * api_minor_ver)
861 {
862   GModule *module;
863   NVENCSTATUS ret = NV_ENC_SUCCESS;
864   uint32_t max_supported_version;
865   gint major_ver, minor_ver;
866   gint i;
867   static const GstNvEncVersion version_list[] = {
868     {NVENCAPI_MAJOR_VERSION, NVENCAPI_MINOR_VERSION},
869     {9, 0},
870     {GST_NVENC_MIN_API_MAJOR_VERSION, GST_NVENC_MIN_API_MINOR_VERSION}
871   };
872
873   module = g_module_open (NVENC_LIBRARY_NAME, G_MODULE_BIND_LAZY);
874   if (module == NULL) {
875     GST_WARNING ("Could not open library %s, %s",
876         NVENC_LIBRARY_NAME, g_module_error ());
877     return FALSE;
878   }
879
880   if (!g_module_symbol (module, "NvEncodeAPICreateInstance",
881           (gpointer *) & nvEncodeAPICreateInstance)) {
882     GST_ERROR ("%s", g_module_error ());
883     return FALSE;
884   }
885
886   if (!g_module_symbol (module, "NvEncodeAPIGetMaxSupportedVersion",
887           (gpointer *) & nvEncodeAPIGetMaxSupportedVersion)) {
888     GST_ERROR ("NvEncodeAPIGetMaxSupportedVersion unavailable");
889     return FALSE;
890   }
891
892   /* WARNING: Any developers who want to bump SDK version must ensure that
893    * following macro values were not changed and also need to check ABI compatibility.
894    * Otherwise, gst_nvenc_get_ helpers also should be updated.
895    * Currently SDK 8.1 and 9.0 compatible
896    *
897    * NVENCAPI_VERSION (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24))
898    *
899    * NVENCAPI_STRUCT_VERSION(ver) ((uint32_t)NVENCAPI_VERSION | ((ver)<<16) | (0x7 << 28))
900    *
901    * NV_ENC_CAPS_PARAM_VER                NVENCAPI_STRUCT_VERSION(1)
902    * NV_ENC_ENCODE_OUT_PARAMS_VER         NVENCAPI_STRUCT_VERSION(1)
903    * NV_ENC_CREATE_INPUT_BUFFER_VER       NVENCAPI_STRUCT_VERSION(1)
904    * NV_ENC_CREATE_BITSTREAM_BUFFER_VER   NVENCAPI_STRUCT_VERSION(1)
905    * NV_ENC_CREATE_MV_BUFFER_VER          NVENCAPI_STRUCT_VERSION(1)
906    * NV_ENC_RC_PARAMS_VER                 NVENCAPI_STRUCT_VERSION(1)
907    * NV_ENC_CONFIG_VER                   (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 ))
908    * NV_ENC_INITIALIZE_PARAMS_VER        (NVENCAPI_STRUCT_VERSION(5) | ( 1<<31 ))
909    * NV_ENC_RECONFIGURE_PARAMS_VER       (NVENCAPI_STRUCT_VERSION(1) | ( 1<<31 ))
910    * NV_ENC_PRESET_CONFIG_VER            (NVENCAPI_STRUCT_VERSION(4) | ( 1<<31 ))
911    * NV_ENC_PIC_PARAMS_VER               (NVENCAPI_STRUCT_VERSION(4) | ( 1<<31 ))
912    * NV_ENC_MEONLY_PARAMS_VER             NVENCAPI_STRUCT_VERSION(3)
913    * NV_ENC_LOCK_BITSTREAM_VER            NVENCAPI_STRUCT_VERSION(1)
914    * NV_ENC_LOCK_INPUT_BUFFER_VER         NVENCAPI_STRUCT_VERSION(1)
915    * NV_ENC_MAP_INPUT_RESOURCE_VER        NVENCAPI_STRUCT_VERSION(4)
916    * NV_ENC_REGISTER_RESOURCE_VER         NVENCAPI_STRUCT_VERSION(3)
917    * NV_ENC_STAT_VER                      NVENCAPI_STRUCT_VERSION(1)
918    * NV_ENC_SEQUENCE_PARAM_PAYLOAD_VER    NVENCAPI_STRUCT_VERSION(1)
919    * NV_ENC_EVENT_PARAMS_VER              NVENCAPI_STRUCT_VERSION(1)
920    * NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER NVENCAPI_STRUCT_VERSION(1)
921    * NV_ENCODE_API_FUNCTION_LIST_VER      NVENCAPI_STRUCT_VERSION(2)
922    */
923
924   ret = nvEncodeAPIGetMaxSupportedVersion (&max_supported_version);
925
926   if (ret != NV_ENC_SUCCESS) {
927     GST_ERROR ("Could not query max supported api version, ret %d", ret);
928     return FALSE;
929   }
930
931   /* 4 LSB: minor version
932    * the rest: major version */
933   major_ver = max_supported_version >> 4;
934   minor_ver = max_supported_version & 0xf;
935
936   GST_INFO ("Maximum supported API version by driver: %d.%d",
937       major_ver, minor_ver);
938
939   ret = NV_ENC_ERR_INVALID_VERSION;
940   for (i = 0; i < G_N_ELEMENTS (version_list); i++) {
941     if (version_list[i].major > major_ver ||
942         (version_list[i].major == major_ver
943             && version_list[i].minor > minor_ver)) {
944       continue;
945     }
946
947     gst_nvenc_api_version =
948         GST_NVENCAPI_VERSION (version_list[i].major, version_list[i].minor);
949
950     nvenc_api.version = GST_NVENCAPI_STRUCT_VERSION (2, gst_nvenc_api_version);
951     ret = nvEncodeAPICreateInstance (&nvenc_api);
952
953     if (ret == NV_ENC_SUCCESS) {
954       GST_INFO ("API version %d.%d load done",
955           version_list[i].major, version_list[i].minor);
956
957       *api_major_ver = version_list[i].major;
958       *api_minor_ver = version_list[i].minor;
959       break;
960     }
961   }
962
963   return ret == NV_ENC_SUCCESS;
964 }
965
966 void
967 gst_nvenc_plugin_init (GstPlugin * plugin, guint device_index,
968     CUcontext cuda_ctx)
969 {
970   gst_nv_enc_register (plugin, NV_ENC_CODEC_H264_GUID,
971       "h264", GST_RANK_PRIMARY * 2, device_index, cuda_ctx);
972   gst_nv_enc_register (plugin, NV_ENC_CODEC_HEVC_GUID,
973       "h265", GST_RANK_PRIMARY * 2, device_index, cuda_ctx);
974 }
975
976 guint32
977 gst_nvenc_get_api_version (void)
978 {
979   /* NVENCAPI_VERSION == (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24)) */
980   return gst_nvenc_api_version;
981 }
982
983 guint32
984 gst_nvenc_get_caps_param_version (void)
985 {
986   /* NV_ENC_CAPS_PARAM_VER == NVENCAPI_STRUCT_VERSION(1) */
987   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
988 }
989
990 guint32
991 gst_nvenc_get_encode_out_params_version (void)
992 {
993   /* NV_ENC_ENCODE_OUT_PARAMS_VER == NVENCAPI_STRUCT_VERSION(1) */
994   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
995 }
996
997 guint32
998 gst_nvenc_get_create_input_buffer_version (void)
999 {
1000   /* NV_ENC_CREATE_INPUT_BUFFER_VER == NVENCAPI_STRUCT_VERSION(1) */
1001   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1002 }
1003
1004 guint32
1005 gst_nvenc_get_create_bitstream_buffer_version (void)
1006 {
1007   /* NV_ENC_CREATE_BITSTREAM_BUFFER_VER == NVENCAPI_STRUCT_VERSION(1) */
1008   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1009 }
1010
1011 guint32
1012 gst_nvenc_get_create_mv_buffer_version (void)
1013 {
1014   /* NV_ENC_CREATE_MV_BUFFER_VER == NVENCAPI_STRUCT_VERSION(1) */
1015   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1016 }
1017
1018 guint32
1019 gst_nvenc_get_rc_params_version (void)
1020 {
1021   /* NV_ENC_RC_PARAMS_VER == NVENCAPI_STRUCT_VERSION(1) */
1022   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1023 }
1024
1025 guint32
1026 gst_nvenc_get_config_version (void)
1027 {
1028   /* NV_ENC_CONFIG_VER ==
1029    *   (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 )) */
1030   return GST_NVENCAPI_STRUCT_VERSION (7, gst_nvenc_api_version) | (1 << 31);
1031 }
1032
1033 guint32
1034 gst_nvenc_get_initialize_params_version (void)
1035 {
1036   /* NV_ENC_INITIALIZE_PARAMS_VER ==
1037    *   (NVENCAPI_STRUCT_VERSION(5) | ( 1<<31 )) */
1038   return GST_NVENCAPI_STRUCT_VERSION (5, gst_nvenc_api_version) | (1 << 31);
1039 }
1040
1041 guint32
1042 gst_nvenc_get_reconfigure_params_version (void)
1043 {
1044   /* NV_ENC_RECONFIGURE_PARAMS_VER ==
1045    *   (NVENCAPI_STRUCT_VERSION(1) | ( 1<<31 )) */
1046   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version) | (1 << 31);
1047 }
1048
1049 guint32
1050 gst_nvenc_get_preset_config_version (void)
1051 {
1052   /* NV_ENC_PRESET_CONFIG_VER ==
1053    *   (NVENCAPI_STRUCT_VERSION(4) | ( 1<<31 )) */
1054   return GST_NVENCAPI_STRUCT_VERSION (4, gst_nvenc_api_version) | (1 << 31);
1055 }
1056
1057 guint32
1058 gst_nvenc_get_pic_params_version (void)
1059 {
1060   /* NV_ENC_PIC_PARAMS_VER ==
1061    *  (NVENCAPI_STRUCT_VERSION(4) | ( 1<<31 )) */
1062   return GST_NVENCAPI_STRUCT_VERSION (4, gst_nvenc_api_version) | (1 << 31);
1063 }
1064
1065 guint32
1066 gst_nvenc_get_meonly_params_version (void)
1067 {
1068   /* NV_ENC_MEONLY_PARAMS_VER == NVENCAPI_STRUCT_VERSION(3) */
1069   return GST_NVENCAPI_STRUCT_VERSION (3, gst_nvenc_api_version);
1070 }
1071
1072 guint32
1073 gst_nvenc_get_lock_bitstream_version (void)
1074 {
1075   /* NV_ENC_LOCK_BITSTREAM_VER == NVENCAPI_STRUCT_VERSION(1) */
1076   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1077 }
1078
1079 guint32
1080 gst_nvenc_get_lock_input_buffer_version (void)
1081 {
1082   /* NV_ENC_LOCK_INPUT_BUFFER_VER == NVENCAPI_STRUCT_VERSION(1) */
1083   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1084 }
1085
1086 guint32
1087 gst_nvenc_get_map_input_resource_version (void)
1088 {
1089   /* NV_ENC_MAP_INPUT_RESOURCE_VER == NVENCAPI_STRUCT_VERSION(4) */
1090   return GST_NVENCAPI_STRUCT_VERSION (4, gst_nvenc_api_version);
1091 }
1092
1093 guint32
1094 gst_nvenc_get_register_resource_version (void)
1095 {
1096   /* NV_ENC_REGISTER_RESOURCE_VER == NVENCAPI_STRUCT_VERSION(3) */
1097   return GST_NVENCAPI_STRUCT_VERSION (3, gst_nvenc_api_version);
1098 }
1099
1100 guint32
1101 gst_nvenc_get_stat_version (void)
1102 {
1103   /* NV_ENC_STAT_VER == NVENCAPI_STRUCT_VERSION(1) */
1104   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1105 }
1106
1107 guint32
1108 gst_nvenc_get_sequence_param_payload_version (void)
1109 {
1110   /* NV_ENC_SEQUENCE_PARAM_PAYLOAD_VER == NVENCAPI_STRUCT_VERSION(1) */
1111   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1112 }
1113
1114 guint32
1115 gst_nvenc_get_event_params_version (void)
1116 {
1117   /* NV_ENC_EVENT_PARAMS_VER == NVENCAPI_STRUCT_VERSION(1) */
1118   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1119 }
1120
1121 guint32
1122 gst_nvenc_get_open_encode_session_ex_params_version (void)
1123 {
1124   /* NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER == NVENCAPI_STRUCT_VERSION(1) */
1125   return GST_NVENCAPI_STRUCT_VERSION (1, gst_nvenc_api_version);
1126 }