avcodec/nvenc: extract sei data prep into own function
[ffmpeg.git] / libavcodec / nvenc.c
1 /*
2  * H.264/HEVC hardware encoding using nvidia nvenc
3  * Copyright (c) 2016 Timo Rothenpieler <timo@rothenpieler.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "config.h"
23
24 #include "nvenc.h"
25 #include "hevc_sei.h"
26
27 #include "libavutil/hwcontext_cuda.h"
28 #include "libavutil/hwcontext.h"
29 #include "libavutil/cuda_check.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/avassert.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/pixdesc.h"
34 #include "atsc_a53.h"
35 #include "encode.h"
36 #include "internal.h"
37 #include "packet_internal.h"
38
39 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, dl_fn->cuda_dl, x)
40
41 #define NVENC_CAP 0x30
42 #define IS_CBR(rc) (rc == NV_ENC_PARAMS_RC_CBR ||             \
43                     rc == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ || \
44                     rc == NV_ENC_PARAMS_RC_CBR_HQ)
45
46 const enum AVPixelFormat ff_nvenc_pix_fmts[] = {
47     AV_PIX_FMT_YUV420P,
48     AV_PIX_FMT_NV12,
49     AV_PIX_FMT_P010,
50     AV_PIX_FMT_YUV444P,
51     AV_PIX_FMT_P016,      // Truncated to 10bits
52     AV_PIX_FMT_YUV444P16, // Truncated to 10bits
53     AV_PIX_FMT_0RGB32,
54     AV_PIX_FMT_0BGR32,
55     AV_PIX_FMT_GBRP,
56     AV_PIX_FMT_GBRP16,    // Truncated to 10bits
57     AV_PIX_FMT_CUDA,
58 #if CONFIG_D3D11VA
59     AV_PIX_FMT_D3D11,
60 #endif
61     AV_PIX_FMT_NONE
62 };
63
64 const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[] = {
65     HW_CONFIG_ENCODER_FRAMES(CUDA,  CUDA),
66     HW_CONFIG_ENCODER_DEVICE(NONE,  CUDA),
67 #if CONFIG_D3D11VA
68     HW_CONFIG_ENCODER_FRAMES(D3D11, D3D11VA),
69     HW_CONFIG_ENCODER_DEVICE(NONE,  D3D11VA),
70 #endif
71     NULL,
72 };
73
74 #define IS_10BIT(pix_fmt)  (pix_fmt == AV_PIX_FMT_P010      || \
75                             pix_fmt == AV_PIX_FMT_P016      || \
76                             pix_fmt == AV_PIX_FMT_YUV444P16 || \
77                             pix_fmt == AV_PIX_FMT_GBRP16)
78
79 #define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P   || \
80                             pix_fmt == AV_PIX_FMT_YUV444P16 || \
81                             pix_fmt == AV_PIX_FMT_GBRP      || \
82                             pix_fmt == AV_PIX_FMT_GBRP16)
83
84 #define IS_GBRP(pix_fmt) (pix_fmt == AV_PIX_FMT_GBRP || \
85                           pix_fmt == AV_PIX_FMT_GBRP16)
86
87 static const struct {
88     NVENCSTATUS nverr;
89     int         averr;
90     const char *desc;
91 } nvenc_errors[] = {
92     { NV_ENC_SUCCESS,                      0,                "success"                  },
93     { NV_ENC_ERR_NO_ENCODE_DEVICE,         AVERROR(ENOENT),  "no encode device"         },
94     { NV_ENC_ERR_UNSUPPORTED_DEVICE,       AVERROR(ENOSYS),  "unsupported device"       },
95     { NV_ENC_ERR_INVALID_ENCODERDEVICE,    AVERROR(EINVAL),  "invalid encoder device"   },
96     { NV_ENC_ERR_INVALID_DEVICE,           AVERROR(EINVAL),  "invalid device"           },
97     { NV_ENC_ERR_DEVICE_NOT_EXIST,         AVERROR(EIO),     "device does not exist"    },
98     { NV_ENC_ERR_INVALID_PTR,              AVERROR(EFAULT),  "invalid ptr"              },
99     { NV_ENC_ERR_INVALID_EVENT,            AVERROR(EINVAL),  "invalid event"            },
100     { NV_ENC_ERR_INVALID_PARAM,            AVERROR(EINVAL),  "invalid param"            },
101     { NV_ENC_ERR_INVALID_CALL,             AVERROR(EINVAL),  "invalid call"             },
102     { NV_ENC_ERR_OUT_OF_MEMORY,            AVERROR(ENOMEM),  "out of memory"            },
103     { NV_ENC_ERR_ENCODER_NOT_INITIALIZED,  AVERROR(EINVAL),  "encoder not initialized"  },
104     { NV_ENC_ERR_UNSUPPORTED_PARAM,        AVERROR(ENOSYS),  "unsupported param"        },
105     { NV_ENC_ERR_LOCK_BUSY,                AVERROR(EAGAIN),  "lock busy"                },
106     { NV_ENC_ERR_NOT_ENOUGH_BUFFER,        AVERROR_BUFFER_TOO_SMALL, "not enough buffer"},
107     { NV_ENC_ERR_INVALID_VERSION,          AVERROR(EINVAL),  "invalid version"          },
108     { NV_ENC_ERR_MAP_FAILED,               AVERROR(EIO),     "map failed"               },
109     { NV_ENC_ERR_NEED_MORE_INPUT,          AVERROR(EAGAIN),  "need more input"          },
110     { NV_ENC_ERR_ENCODER_BUSY,             AVERROR(EAGAIN),  "encoder busy"             },
111     { NV_ENC_ERR_EVENT_NOT_REGISTERD,      AVERROR(EBADF),   "event not registered"     },
112     { NV_ENC_ERR_GENERIC,                  AVERROR_UNKNOWN,  "generic error"            },
113     { NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY,  AVERROR(EINVAL),  "incompatible client key"  },
114     { NV_ENC_ERR_UNIMPLEMENTED,            AVERROR(ENOSYS),  "unimplemented"            },
115     { NV_ENC_ERR_RESOURCE_REGISTER_FAILED, AVERROR(EIO),     "resource register failed" },
116     { NV_ENC_ERR_RESOURCE_NOT_REGISTERED,  AVERROR(EBADF),   "resource not registered"  },
117     { NV_ENC_ERR_RESOURCE_NOT_MAPPED,      AVERROR(EBADF),   "resource not mapped"      },
118 };
119
120 static int nvenc_map_error(NVENCSTATUS err, const char **desc)
121 {
122     int i;
123     for (i = 0; i < FF_ARRAY_ELEMS(nvenc_errors); i++) {
124         if (nvenc_errors[i].nverr == err) {
125             if (desc)
126                 *desc = nvenc_errors[i].desc;
127             return nvenc_errors[i].averr;
128         }
129     }
130     if (desc)
131         *desc = "unknown error";
132     return AVERROR_UNKNOWN;
133 }
134
135 static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err,
136                              const char *error_string)
137 {
138     const char *desc;
139     const char *details = "(no details)";
140     int ret = nvenc_map_error(err, &desc);
141
142 #ifdef NVENC_HAVE_GETLASTERRORSTRING
143     NvencContext *ctx = avctx->priv_data;
144     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
145
146     if (p_nvenc && ctx->nvencoder)
147         details = p_nvenc->nvEncGetLastErrorString(ctx->nvencoder);
148 #endif
149
150     av_log(avctx, AV_LOG_ERROR, "%s: %s (%d): %s\n", error_string, desc, err, details);
151
152     return ret;
153 }
154
155 typedef struct GUIDTuple {
156     const GUID guid;
157     int flags;
158 } GUIDTuple;
159
160 #define PRESET_ALIAS(alias, name, ...) \
161     [PRESET_ ## alias] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ }
162
163 #define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__)
164
165 static void nvenc_map_preset(NvencContext *ctx)
166 {
167     GUIDTuple presets[] = {
168 #ifdef NVENC_HAVE_NEW_PRESETS
169         PRESET(P1),
170         PRESET(P2),
171         PRESET(P3),
172         PRESET(P4),
173         PRESET(P5),
174         PRESET(P6),
175         PRESET(P7),
176         PRESET_ALIAS(SLOW,   P7, NVENC_TWO_PASSES),
177         PRESET_ALIAS(MEDIUM, P4, NVENC_ONE_PASS),
178         PRESET_ALIAS(FAST,   P1, NVENC_ONE_PASS),
179         // Compat aliases
180         PRESET_ALIAS(DEFAULT,             P4, NVENC_DEPRECATED_PRESET),
181         PRESET_ALIAS(HP,                  P1, NVENC_DEPRECATED_PRESET),
182         PRESET_ALIAS(HQ,                  P7, NVENC_DEPRECATED_PRESET),
183         PRESET_ALIAS(BD,                  P5, NVENC_DEPRECATED_PRESET),
184         PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
185         PRESET_ALIAS(LOW_LATENCY_HP,      P1, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
186         PRESET_ALIAS(LOW_LATENCY_HQ,      P7, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
187         PRESET_ALIAS(LOSSLESS_DEFAULT,    P4, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS),
188         PRESET_ALIAS(LOSSLESS_HP,         P1, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS),
189 #else
190         PRESET(DEFAULT),
191         PRESET(HP),
192         PRESET(HQ),
193         PRESET(BD),
194         PRESET_ALIAS(SLOW,   HQ,    NVENC_TWO_PASSES),
195         PRESET_ALIAS(MEDIUM, HQ,    NVENC_ONE_PASS),
196         PRESET_ALIAS(FAST,   HP,    NVENC_ONE_PASS),
197         PRESET(LOW_LATENCY_DEFAULT, NVENC_LOWLATENCY),
198         PRESET(LOW_LATENCY_HP,      NVENC_LOWLATENCY),
199         PRESET(LOW_LATENCY_HQ,      NVENC_LOWLATENCY),
200         PRESET(LOSSLESS_DEFAULT,    NVENC_LOSSLESS),
201         PRESET(LOSSLESS_HP,         NVENC_LOSSLESS),
202 #endif
203     };
204
205     GUIDTuple *t = &presets[ctx->preset];
206
207     ctx->init_encode_params.presetGUID = t->guid;
208     ctx->flags = t->flags;
209
210 #ifdef NVENC_HAVE_NEW_PRESETS
211     if (ctx->tuning_info == NV_ENC_TUNING_INFO_LOSSLESS)
212         ctx->flags |= NVENC_LOSSLESS;
213 #endif
214 }
215
216 #undef PRESET
217 #undef PRESET_ALIAS
218
219 static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level)
220 {
221 #if NVENCAPI_CHECK_VERSION(11, 1)
222     const char *minver = "(unknown)";
223 #elif NVENCAPI_CHECK_VERSION(11, 0)
224 # if defined(_WIN32) || defined(__CYGWIN__)
225     const char *minver = "456.71";
226 # else
227     const char *minver = "455.28";
228 # endif
229 #elif NVENCAPI_CHECK_VERSION(10, 0)
230 # if defined(_WIN32) || defined(__CYGWIN__)
231     const char *minver = "450.51";
232 # else
233     const char *minver = "445.87";
234 # endif
235 #elif NVENCAPI_CHECK_VERSION(9, 1)
236 # if defined(_WIN32) || defined(__CYGWIN__)
237     const char *minver = "436.15";
238 # else
239     const char *minver = "435.21";
240 # endif
241 #elif NVENCAPI_CHECK_VERSION(9, 0)
242 # if defined(_WIN32) || defined(__CYGWIN__)
243     const char *minver = "418.81";
244 # else
245     const char *minver = "418.30";
246 # endif
247 #elif NVENCAPI_CHECK_VERSION(8, 2)
248 # if defined(_WIN32) || defined(__CYGWIN__)
249     const char *minver = "397.93";
250 # else
251     const char *minver = "396.24";
252 #endif
253 #elif NVENCAPI_CHECK_VERSION(8, 1)
254 # if defined(_WIN32) || defined(__CYGWIN__)
255     const char *minver = "390.77";
256 # else
257     const char *minver = "390.25";
258 # endif
259 #else
260 # if defined(_WIN32) || defined(__CYGWIN__)
261     const char *minver = "378.66";
262 # else
263     const char *minver = "378.13";
264 # endif
265 #endif
266     av_log(avctx, level, "The minimum required Nvidia driver for nvenc is %s or newer\n", minver);
267 }
268
269 static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
270 {
271     NvencContext *ctx            = avctx->priv_data;
272     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
273     NVENCSTATUS err;
274     uint32_t nvenc_max_ver;
275     int ret;
276
277     ret = cuda_load_functions(&dl_fn->cuda_dl, avctx);
278     if (ret < 0)
279         return ret;
280
281     ret = nvenc_load_functions(&dl_fn->nvenc_dl, avctx);
282     if (ret < 0) {
283         nvenc_print_driver_requirement(avctx, AV_LOG_ERROR);
284         return ret;
285     }
286
287     err = dl_fn->nvenc_dl->NvEncodeAPIGetMaxSupportedVersion(&nvenc_max_ver);
288     if (err != NV_ENC_SUCCESS)
289         return nvenc_print_error(avctx, err, "Failed to query nvenc max version");
290
291     av_log(avctx, AV_LOG_VERBOSE, "Loaded Nvenc version %d.%d\n", nvenc_max_ver >> 4, nvenc_max_ver & 0xf);
292
293     if ((NVENCAPI_MAJOR_VERSION << 4 | NVENCAPI_MINOR_VERSION) > nvenc_max_ver) {
294         av_log(avctx, AV_LOG_ERROR, "Driver does not support the required nvenc API version. "
295                "Required: %d.%d Found: %d.%d\n",
296                NVENCAPI_MAJOR_VERSION, NVENCAPI_MINOR_VERSION,
297                nvenc_max_ver >> 4, nvenc_max_ver & 0xf);
298         nvenc_print_driver_requirement(avctx, AV_LOG_ERROR);
299         return AVERROR(ENOSYS);
300     }
301
302     dl_fn->nvenc_funcs.version = NV_ENCODE_API_FUNCTION_LIST_VER;
303
304     err = dl_fn->nvenc_dl->NvEncodeAPICreateInstance(&dl_fn->nvenc_funcs);
305     if (err != NV_ENC_SUCCESS)
306         return nvenc_print_error(avctx, err, "Failed to create nvenc instance");
307
308     av_log(avctx, AV_LOG_VERBOSE, "Nvenc initialized successfully\n");
309
310     return 0;
311 }
312
313 static int nvenc_push_context(AVCodecContext *avctx)
314 {
315     NvencContext *ctx            = avctx->priv_data;
316     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
317
318     if (ctx->d3d11_device)
319         return 0;
320
321     return CHECK_CU(dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context));
322 }
323
324 static int nvenc_pop_context(AVCodecContext *avctx)
325 {
326     NvencContext *ctx            = avctx->priv_data;
327     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
328     CUcontext dummy;
329
330     if (ctx->d3d11_device)
331         return 0;
332
333     return CHECK_CU(dl_fn->cuda_dl->cuCtxPopCurrent(&dummy));
334 }
335
336 static av_cold int nvenc_open_session(AVCodecContext *avctx)
337 {
338     NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = { 0 };
339     NvencContext *ctx = avctx->priv_data;
340     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
341     NVENCSTATUS ret;
342
343     params.version    = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
344     params.apiVersion = NVENCAPI_VERSION;
345     if (ctx->d3d11_device) {
346         params.device     = ctx->d3d11_device;
347         params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
348     } else {
349         params.device     = ctx->cu_context;
350         params.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
351     }
352
353     ret = p_nvenc->nvEncOpenEncodeSessionEx(&params, &ctx->nvencoder);
354     if (ret != NV_ENC_SUCCESS) {
355         ctx->nvencoder = NULL;
356         return nvenc_print_error(avctx, ret, "OpenEncodeSessionEx failed");
357     }
358
359     return 0;
360 }
361
362 static int nvenc_check_codec_support(AVCodecContext *avctx)
363 {
364     NvencContext *ctx                    = avctx->priv_data;
365     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
366     int i, ret, count = 0;
367     GUID *guids = NULL;
368
369     ret = p_nvenc->nvEncGetEncodeGUIDCount(ctx->nvencoder, &count);
370
371     if (ret != NV_ENC_SUCCESS || !count)
372         return AVERROR(ENOSYS);
373
374     guids = av_malloc(count * sizeof(GUID));
375     if (!guids)
376         return AVERROR(ENOMEM);
377
378     ret = p_nvenc->nvEncGetEncodeGUIDs(ctx->nvencoder, guids, count, &count);
379     if (ret != NV_ENC_SUCCESS) {
380         ret = AVERROR(ENOSYS);
381         goto fail;
382     }
383
384     ret = AVERROR(ENOSYS);
385     for (i = 0; i < count; i++) {
386         if (!memcmp(&guids[i], &ctx->init_encode_params.encodeGUID, sizeof(*guids))) {
387             ret = 0;
388             break;
389         }
390     }
391
392 fail:
393     av_free(guids);
394
395     return ret;
396 }
397
398 static int nvenc_check_cap(AVCodecContext *avctx, NV_ENC_CAPS cap)
399 {
400     NvencContext *ctx = avctx->priv_data;
401     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
402     NV_ENC_CAPS_PARAM params        = { 0 };
403     int ret, val = 0;
404
405     params.version     = NV_ENC_CAPS_PARAM_VER;
406     params.capsToQuery = cap;
407
408     ret = p_nvenc->nvEncGetEncodeCaps(ctx->nvencoder, ctx->init_encode_params.encodeGUID, &params, &val);
409
410     if (ret == NV_ENC_SUCCESS)
411         return val;
412     return 0;
413 }
414
415 static int nvenc_check_capabilities(AVCodecContext *avctx)
416 {
417     NvencContext *ctx = avctx->priv_data;
418     int ret;
419
420     ret = nvenc_check_codec_support(avctx);
421     if (ret < 0) {
422         av_log(avctx, AV_LOG_WARNING, "Codec not supported\n");
423         return ret;
424     }
425
426     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_YUV444_ENCODE);
427     if (IS_YUV444(ctx->data_pix_fmt) && ret <= 0) {
428         av_log(avctx, AV_LOG_WARNING, "YUV444P not supported\n");
429         return AVERROR(ENOSYS);
430     }
431
432     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE);
433     if (ctx->flags & NVENC_LOSSLESS && ret <= 0) {
434         av_log(avctx, AV_LOG_WARNING, "Lossless encoding not supported\n");
435         return AVERROR(ENOSYS);
436     }
437
438     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_WIDTH_MAX);
439     if (ret < avctx->width) {
440         av_log(avctx, AV_LOG_WARNING, "Width %d exceeds %d\n",
441                avctx->width, ret);
442         return AVERROR(ENOSYS);
443     }
444
445     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_HEIGHT_MAX);
446     if (ret < avctx->height) {
447         av_log(avctx, AV_LOG_WARNING, "Height %d exceeds %d\n",
448                avctx->height, ret);
449         return AVERROR(ENOSYS);
450     }
451
452     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_NUM_MAX_BFRAMES);
453     if (ret < avctx->max_b_frames) {
454         av_log(avctx, AV_LOG_WARNING, "Max B-frames %d exceed %d\n",
455                avctx->max_b_frames, ret);
456
457         return AVERROR(ENOSYS);
458     }
459
460     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_FIELD_ENCODING);
461     if (ret < 1 && avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
462         av_log(avctx, AV_LOG_WARNING,
463                "Interlaced encoding is not supported. Supported level: %d\n",
464                ret);
465         return AVERROR(ENOSYS);
466     }
467
468     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_10BIT_ENCODE);
469     if (IS_10BIT(ctx->data_pix_fmt) && ret <= 0) {
470         av_log(avctx, AV_LOG_WARNING, "10 bit encode not supported\n");
471         return AVERROR(ENOSYS);
472     }
473
474     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_LOOKAHEAD);
475     if (ctx->rc_lookahead > 0 && ret <= 0) {
476         av_log(avctx, AV_LOG_WARNING, "RC lookahead not supported\n");
477         return AVERROR(ENOSYS);
478     }
479
480     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_TEMPORAL_AQ);
481     if (ctx->temporal_aq > 0 && ret <= 0) {
482         av_log(avctx, AV_LOG_WARNING, "Temporal AQ not supported\n");
483         return AVERROR(ENOSYS);
484     }
485
486     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_WEIGHTED_PREDICTION);
487     if (ctx->weighted_pred > 0 && ret <= 0) {
488         av_log (avctx, AV_LOG_WARNING, "Weighted Prediction not supported\n");
489         return AVERROR(ENOSYS);
490     }
491
492     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_CABAC);
493     if (ctx->coder == NV_ENC_H264_ENTROPY_CODING_MODE_CABAC && ret <= 0) {
494         av_log(avctx, AV_LOG_WARNING, "CABAC entropy coding not supported\n");
495         return AVERROR(ENOSYS);
496     }
497
498 #ifdef NVENC_HAVE_BFRAME_REF_MODE
499     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE);
500     if (ctx->b_ref_mode == NV_ENC_BFRAME_REF_MODE_EACH && ret != 1 && ret != 3) {
501         av_log(avctx, AV_LOG_WARNING, "Each B frame as reference is not supported\n");
502         return AVERROR(ENOSYS);
503     } else if (ctx->b_ref_mode != NV_ENC_BFRAME_REF_MODE_DISABLED && ret == 0) {
504         av_log(avctx, AV_LOG_WARNING, "B frames as references are not supported\n");
505         return AVERROR(ENOSYS);
506     }
507 #else
508     if (ctx->b_ref_mode != 0) {
509         av_log(avctx, AV_LOG_WARNING, "B frames as references need SDK 8.1 at build time\n");
510         return AVERROR(ENOSYS);
511     }
512 #endif
513
514 #ifdef NVENC_HAVE_MULTIPLE_REF_FRAMES
515     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES);
516     if(avctx->refs != NV_ENC_NUM_REF_FRAMES_AUTOSELECT && ret <= 0) {
517         av_log(avctx, AV_LOG_WARNING, "Multiple reference frames are not supported by the device\n");
518         return AVERROR(ENOSYS);
519     }
520 #else
521     if(avctx->refs != 0) {
522         av_log(avctx, AV_LOG_WARNING, "Multiple reference frames need SDK 9.1 at build time\n");
523         return AVERROR(ENOSYS);
524     }
525 #endif
526
527     ctx->support_dyn_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
528
529     return 0;
530 }
531
532 static av_cold int nvenc_check_device(AVCodecContext *avctx, int idx)
533 {
534     NvencContext *ctx = avctx->priv_data;
535     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
536     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
537     char name[128] = { 0};
538     int major, minor, ret;
539     CUdevice cu_device;
540     int loglevel = AV_LOG_VERBOSE;
541
542     if (ctx->device == LIST_DEVICES)
543         loglevel = AV_LOG_INFO;
544
545     ret = CHECK_CU(dl_fn->cuda_dl->cuDeviceGet(&cu_device, idx));
546     if (ret < 0)
547         return ret;
548
549     ret = CHECK_CU(dl_fn->cuda_dl->cuDeviceGetName(name, sizeof(name), cu_device));
550     if (ret < 0)
551         return ret;
552
553     ret = CHECK_CU(dl_fn->cuda_dl->cuDeviceComputeCapability(&major, &minor, cu_device));
554     if (ret < 0)
555         return ret;
556
557     av_log(avctx, loglevel, "[ GPU #%d - < %s > has Compute SM %d.%d ]\n", idx, name, major, minor);
558     if (((major << 4) | minor) < NVENC_CAP) {
559         av_log(avctx, loglevel, "does not support NVENC\n");
560         goto fail;
561     }
562
563     if (ctx->device != idx && ctx->device != ANY_DEVICE)
564         return -1;
565
566     ret = CHECK_CU(dl_fn->cuda_dl->cuCtxCreate(&ctx->cu_context_internal, 0, cu_device));
567     if (ret < 0)
568         goto fail;
569
570     ctx->cu_context = ctx->cu_context_internal;
571     ctx->cu_stream = NULL;
572
573     if ((ret = nvenc_pop_context(avctx)) < 0)
574         goto fail2;
575
576     if ((ret = nvenc_open_session(avctx)) < 0)
577         goto fail2;
578
579     if ((ret = nvenc_check_capabilities(avctx)) < 0)
580         goto fail3;
581
582     av_log(avctx, loglevel, "supports NVENC\n");
583
584     dl_fn->nvenc_device_count++;
585
586     if (ctx->device == idx || ctx->device == ANY_DEVICE)
587         return 0;
588
589 fail3:
590     if ((ret = nvenc_push_context(avctx)) < 0)
591         return ret;
592
593     p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
594     ctx->nvencoder = NULL;
595
596     if ((ret = nvenc_pop_context(avctx)) < 0)
597         return ret;
598
599 fail2:
600     CHECK_CU(dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal));
601     ctx->cu_context_internal = NULL;
602
603 fail:
604     return AVERROR(ENOSYS);
605 }
606
607 static av_cold int nvenc_setup_device(AVCodecContext *avctx)
608 {
609     NvencContext *ctx            = avctx->priv_data;
610     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
611
612     switch (avctx->codec->id) {
613     case AV_CODEC_ID_H264:
614         ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_H264_GUID;
615         break;
616     case AV_CODEC_ID_HEVC:
617         ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_HEVC_GUID;
618         break;
619     default:
620         return AVERROR_BUG;
621     }
622
623     nvenc_map_preset(ctx);
624
625     if (ctx->flags & NVENC_DEPRECATED_PRESET)
626         av_log(avctx, AV_LOG_WARNING, "The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.\n");
627
628     if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11 || avctx->hw_frames_ctx || avctx->hw_device_ctx) {
629         AVHWFramesContext   *frames_ctx;
630         AVHWDeviceContext   *hwdev_ctx;
631         AVCUDADeviceContext *cuda_device_hwctx = NULL;
632 #if CONFIG_D3D11VA
633         AVD3D11VADeviceContext *d3d11_device_hwctx = NULL;
634 #endif
635         int ret;
636
637         if (avctx->hw_frames_ctx) {
638             frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
639             if (frames_ctx->format == AV_PIX_FMT_CUDA)
640                 cuda_device_hwctx = frames_ctx->device_ctx->hwctx;
641 #if CONFIG_D3D11VA
642             else if (frames_ctx->format == AV_PIX_FMT_D3D11)
643                 d3d11_device_hwctx = frames_ctx->device_ctx->hwctx;
644 #endif
645             else
646                 return AVERROR(EINVAL);
647         } else if (avctx->hw_device_ctx) {
648             hwdev_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data;
649             if (hwdev_ctx->type == AV_HWDEVICE_TYPE_CUDA)
650                 cuda_device_hwctx = hwdev_ctx->hwctx;
651 #if CONFIG_D3D11VA
652             else if (hwdev_ctx->type == AV_HWDEVICE_TYPE_D3D11VA)
653                 d3d11_device_hwctx = hwdev_ctx->hwctx;
654 #endif
655             else
656                 return AVERROR(EINVAL);
657         } else {
658             return AVERROR(EINVAL);
659         }
660
661         if (cuda_device_hwctx) {
662             ctx->cu_context = cuda_device_hwctx->cuda_ctx;
663             ctx->cu_stream = cuda_device_hwctx->stream;
664         }
665 #if CONFIG_D3D11VA
666         else if (d3d11_device_hwctx) {
667             ctx->d3d11_device = d3d11_device_hwctx->device;
668             ID3D11Device_AddRef(ctx->d3d11_device);
669         }
670 #endif
671
672         ret = nvenc_open_session(avctx);
673         if (ret < 0)
674             return ret;
675
676         ret = nvenc_check_capabilities(avctx);
677         if (ret < 0) {
678             av_log(avctx, AV_LOG_FATAL, "Provided device doesn't support required NVENC features\n");
679             return ret;
680         }
681     } else {
682         int i, nb_devices = 0;
683
684         if (CHECK_CU(dl_fn->cuda_dl->cuInit(0)) < 0)
685             return AVERROR_UNKNOWN;
686
687         if (CHECK_CU(dl_fn->cuda_dl->cuDeviceGetCount(&nb_devices)) < 0)
688             return AVERROR_UNKNOWN;
689
690         if (!nb_devices) {
691             av_log(avctx, AV_LOG_FATAL, "No CUDA capable devices found\n");
692                 return AVERROR_EXTERNAL;
693         }
694
695         av_log(avctx, AV_LOG_VERBOSE, "%d CUDA capable devices found\n", nb_devices);
696
697         dl_fn->nvenc_device_count = 0;
698         for (i = 0; i < nb_devices; ++i) {
699             if ((nvenc_check_device(avctx, i)) >= 0 && ctx->device != LIST_DEVICES)
700                 return 0;
701         }
702
703         if (ctx->device == LIST_DEVICES)
704             return AVERROR_EXIT;
705
706         if (!dl_fn->nvenc_device_count) {
707             av_log(avctx, AV_LOG_FATAL, "No capable devices found\n");
708             return AVERROR_EXTERNAL;
709         }
710
711         av_log(avctx, AV_LOG_FATAL, "Requested GPU %d, but only %d GPUs are available!\n", ctx->device, nb_devices);
712         return AVERROR(EINVAL);
713     }
714
715     return 0;
716 }
717
718 static av_cold void set_constqp(AVCodecContext *avctx)
719 {
720     NvencContext *ctx = avctx->priv_data;
721     NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
722
723     rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
724
725     if (ctx->init_qp_p >= 0) {
726         rc->constQP.qpInterP = ctx->init_qp_p;
727         if (ctx->init_qp_i >= 0 && ctx->init_qp_b >= 0) {
728             rc->constQP.qpIntra = ctx->init_qp_i;
729             rc->constQP.qpInterB = ctx->init_qp_b;
730         } else if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
731             rc->constQP.qpIntra = av_clip(
732                 rc->constQP.qpInterP * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, 51);
733             rc->constQP.qpInterB = av_clip(
734                 rc->constQP.qpInterP * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, 51);
735         } else {
736             rc->constQP.qpIntra = rc->constQP.qpInterP;
737             rc->constQP.qpInterB = rc->constQP.qpInterP;
738         }
739     } else if (ctx->cqp >= 0) {
740         rc->constQP.qpInterP = rc->constQP.qpInterB = rc->constQP.qpIntra = ctx->cqp;
741         if (avctx->b_quant_factor != 0.0)
742             rc->constQP.qpInterB = av_clip(ctx->cqp * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, 51);
743         if (avctx->i_quant_factor != 0.0)
744             rc->constQP.qpIntra = av_clip(ctx->cqp * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, 51);
745     }
746
747     avctx->qmin = -1;
748     avctx->qmax = -1;
749 }
750
751 static av_cold void set_vbr(AVCodecContext *avctx)
752 {
753     NvencContext *ctx = avctx->priv_data;
754     NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
755     int qp_inter_p;
756
757     if (avctx->qmin >= 0 && avctx->qmax >= 0) {
758         rc->enableMinQP = 1;
759         rc->enableMaxQP = 1;
760
761         rc->minQP.qpInterB = avctx->qmin;
762         rc->minQP.qpInterP = avctx->qmin;
763         rc->minQP.qpIntra  = avctx->qmin;
764
765         rc->maxQP.qpInterB = avctx->qmax;
766         rc->maxQP.qpInterP = avctx->qmax;
767         rc->maxQP.qpIntra = avctx->qmax;
768
769         qp_inter_p = (avctx->qmax + 3 * avctx->qmin) / 4; // biased towards Qmin
770     } else if (avctx->qmin >= 0) {
771         rc->enableMinQP = 1;
772
773         rc->minQP.qpInterB = avctx->qmin;
774         rc->minQP.qpInterP = avctx->qmin;
775         rc->minQP.qpIntra = avctx->qmin;
776
777         qp_inter_p = avctx->qmin;
778     } else {
779         qp_inter_p = 26; // default to 26
780     }
781
782     rc->enableInitialRCQP = 1;
783
784     if (ctx->init_qp_p < 0) {
785         rc->initialRCQP.qpInterP  = qp_inter_p;
786     } else {
787         rc->initialRCQP.qpInterP = ctx->init_qp_p;
788     }
789
790     if (ctx->init_qp_i < 0) {
791         if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
792             rc->initialRCQP.qpIntra = av_clip(
793                 rc->initialRCQP.qpInterP * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, 51);
794         } else {
795             rc->initialRCQP.qpIntra = rc->initialRCQP.qpInterP;
796         }
797     } else {
798         rc->initialRCQP.qpIntra = ctx->init_qp_i;
799     }
800
801     if (ctx->init_qp_b < 0) {
802         if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
803             rc->initialRCQP.qpInterB = av_clip(
804                 rc->initialRCQP.qpInterP * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, 51);
805         } else {
806             rc->initialRCQP.qpInterB = rc->initialRCQP.qpInterP;
807         }
808     } else {
809         rc->initialRCQP.qpInterB = ctx->init_qp_b;
810     }
811 }
812
813 static av_cold void set_lossless(AVCodecContext *avctx)
814 {
815     NvencContext *ctx = avctx->priv_data;
816     NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
817
818     rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
819     rc->constQP.qpInterB = 0;
820     rc->constQP.qpInterP = 0;
821     rc->constQP.qpIntra  = 0;
822
823     avctx->qmin = -1;
824     avctx->qmax = -1;
825 }
826
827 static void nvenc_override_rate_control(AVCodecContext *avctx)
828 {
829     NvencContext *ctx    = avctx->priv_data;
830     NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
831
832     switch (ctx->rc) {
833     case NV_ENC_PARAMS_RC_CONSTQP:
834         set_constqp(avctx);
835         return;
836     case NV_ENC_PARAMS_RC_VBR_MINQP:
837         if (avctx->qmin < 0) {
838             av_log(avctx, AV_LOG_WARNING,
839                    "The variable bitrate rate-control requires "
840                    "the 'qmin' option set.\n");
841             set_vbr(avctx);
842             return;
843         }
844         /* fall through */
845     case NV_ENC_PARAMS_RC_VBR_HQ:
846     case NV_ENC_PARAMS_RC_VBR:
847         set_vbr(avctx);
848         break;
849     case NV_ENC_PARAMS_RC_CBR:
850     case NV_ENC_PARAMS_RC_CBR_HQ:
851     case NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ:
852         break;
853     }
854
855     rc->rateControlMode = ctx->rc;
856 }
857
858 static av_cold int nvenc_recalc_surfaces(AVCodecContext *avctx)
859 {
860     NvencContext *ctx = avctx->priv_data;
861     // default minimum of 4 surfaces
862     // multiply by 2 for number of NVENCs on gpu (hardcode to 2)
863     // another multiply by 2 to avoid blocking next PBB group
864     int nb_surfaces = FFMAX(4, ctx->encode_config.frameIntervalP * 2 * 2);
865
866     // lookahead enabled
867     if (ctx->rc_lookahead > 0) {
868         // +1 is to account for lkd_bound calculation later
869         // +4 is to allow sufficient pipelining with lookahead
870         nb_surfaces = FFMAX(1, FFMAX(nb_surfaces, ctx->rc_lookahead + ctx->encode_config.frameIntervalP + 1 + 4));
871         if (nb_surfaces > ctx->nb_surfaces && ctx->nb_surfaces > 0)
872         {
873             av_log(avctx, AV_LOG_WARNING,
874                    "Defined rc_lookahead requires more surfaces, "
875                    "increasing used surfaces %d -> %d\n", ctx->nb_surfaces, nb_surfaces);
876         }
877         ctx->nb_surfaces = FFMAX(nb_surfaces, ctx->nb_surfaces);
878     } else {
879         if (ctx->encode_config.frameIntervalP > 1 && ctx->nb_surfaces < nb_surfaces && ctx->nb_surfaces > 0)
880         {
881             av_log(avctx, AV_LOG_WARNING,
882                    "Defined b-frame requires more surfaces, "
883                    "increasing used surfaces %d -> %d\n", ctx->nb_surfaces, nb_surfaces);
884             ctx->nb_surfaces = FFMAX(ctx->nb_surfaces, nb_surfaces);
885         }
886         else if (ctx->nb_surfaces <= 0)
887             ctx->nb_surfaces = nb_surfaces;
888         // otherwise use user specified value
889     }
890
891     ctx->nb_surfaces = FFMAX(1, FFMIN(MAX_REGISTERED_FRAMES, ctx->nb_surfaces));
892     ctx->async_depth = FFMIN(ctx->async_depth, ctx->nb_surfaces - 1);
893
894     return 0;
895 }
896
897 static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
898 {
899     NvencContext *ctx = avctx->priv_data;
900
901     if (avctx->global_quality > 0)
902         av_log(avctx, AV_LOG_WARNING, "Using global_quality with nvenc is deprecated. Use qp instead.\n");
903
904     if (ctx->cqp < 0 && avctx->global_quality > 0)
905         ctx->cqp = avctx->global_quality;
906
907     if (avctx->bit_rate > 0) {
908         ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate;
909     } else if (ctx->encode_config.rcParams.averageBitRate > 0) {
910         ctx->encode_config.rcParams.maxBitRate = ctx->encode_config.rcParams.averageBitRate;
911     }
912
913     if (avctx->rc_max_rate > 0)
914         ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;
915
916 #ifdef NVENC_HAVE_MULTIPASS
917     ctx->encode_config.rcParams.multiPass = ctx->multipass;
918
919     if (ctx->flags & NVENC_ONE_PASS)
920         ctx->encode_config.rcParams.multiPass = NV_ENC_MULTI_PASS_DISABLED;
921     if (ctx->flags & NVENC_TWO_PASSES || ctx->twopass > 0)
922         ctx->encode_config.rcParams.multiPass = NV_ENC_TWO_PASS_FULL_RESOLUTION;
923
924     if (ctx->rc < 0) {
925         if (ctx->cbr) {
926             ctx->rc = NV_ENC_PARAMS_RC_CBR;
927         } else if (ctx->cqp >= 0) {
928             ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
929         } else if (ctx->quality >= 0.0f) {
930             ctx->rc = NV_ENC_PARAMS_RC_VBR;
931         }
932     }
933 #else
934     if (ctx->rc < 0) {
935         if (ctx->flags & NVENC_ONE_PASS)
936             ctx->twopass = 0;
937         if (ctx->flags & NVENC_TWO_PASSES)
938             ctx->twopass = 1;
939
940         if (ctx->twopass < 0)
941             ctx->twopass = (ctx->flags & NVENC_LOWLATENCY) != 0;
942
943         if (ctx->cbr) {
944             if (ctx->twopass) {
945                 ctx->rc = NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ;
946             } else {
947                 ctx->rc = NV_ENC_PARAMS_RC_CBR;
948             }
949         } else if (ctx->cqp >= 0) {
950             ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
951         } else if (ctx->twopass) {
952             ctx->rc = NV_ENC_PARAMS_RC_VBR_HQ;
953         } else if (avctx->qmin >= 0 && avctx->qmax >= 0) {
954             ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP;
955         }
956     }
957 #endif
958
959     if (ctx->rc >= 0 && ctx->rc & RC_MODE_DEPRECATED) {
960         av_log(avctx, AV_LOG_WARNING, "Specified rc mode is deprecated.\n");
961         av_log(avctx, AV_LOG_WARNING, "Use -rc constqp/cbr/vbr, -tune and -multipass instead.\n");
962
963         ctx->rc &= ~RC_MODE_DEPRECATED;
964     }
965
966 #ifdef NVENC_HAVE_LDKFS
967     if (ctx->ldkfs)
968          ctx->encode_config.rcParams.lowDelayKeyFrameScale = ctx->ldkfs;
969 #endif
970
971     if (ctx->flags & NVENC_LOSSLESS) {
972         set_lossless(avctx);
973     } else if (ctx->rc >= 0) {
974         nvenc_override_rate_control(avctx);
975     } else {
976         ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_VBR;
977         set_vbr(avctx);
978     }
979
980     if (avctx->rc_buffer_size > 0) {
981         ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size;
982     } else if (ctx->encode_config.rcParams.averageBitRate > 0) {
983         avctx->rc_buffer_size = ctx->encode_config.rcParams.vbvBufferSize = 2 * ctx->encode_config.rcParams.averageBitRate;
984     }
985
986     if (ctx->aq) {
987         ctx->encode_config.rcParams.enableAQ   = 1;
988         ctx->encode_config.rcParams.aqStrength = ctx->aq_strength;
989         av_log(avctx, AV_LOG_VERBOSE, "AQ enabled.\n");
990     }
991
992     if (ctx->temporal_aq) {
993         ctx->encode_config.rcParams.enableTemporalAQ = 1;
994         av_log(avctx, AV_LOG_VERBOSE, "Temporal AQ enabled.\n");
995     }
996
997     if (ctx->rc_lookahead > 0) {
998         int lkd_bound = FFMIN(ctx->nb_surfaces, ctx->async_depth) -
999                         ctx->encode_config.frameIntervalP - 4;
1000
1001         if (lkd_bound < 0) {
1002             av_log(avctx, AV_LOG_WARNING,
1003                    "Lookahead not enabled. Increase buffer delay (-delay).\n");
1004         } else {
1005             ctx->encode_config.rcParams.enableLookahead = 1;
1006             ctx->encode_config.rcParams.lookaheadDepth  = av_clip(ctx->rc_lookahead, 0, lkd_bound);
1007             ctx->encode_config.rcParams.disableIadapt   = ctx->no_scenecut;
1008             ctx->encode_config.rcParams.disableBadapt   = !ctx->b_adapt;
1009             av_log(avctx, AV_LOG_VERBOSE,
1010                    "Lookahead enabled: depth %d, scenecut %s, B-adapt %s.\n",
1011                    ctx->encode_config.rcParams.lookaheadDepth,
1012                    ctx->encode_config.rcParams.disableIadapt ? "disabled" : "enabled",
1013                    ctx->encode_config.rcParams.disableBadapt ? "disabled" : "enabled");
1014         }
1015     }
1016
1017     if (ctx->strict_gop) {
1018         ctx->encode_config.rcParams.strictGOPTarget = 1;
1019         av_log(avctx, AV_LOG_VERBOSE, "Strict GOP target enabled.\n");
1020     }
1021
1022     if (ctx->nonref_p)
1023         ctx->encode_config.rcParams.enableNonRefP = 1;
1024
1025     if (ctx->zerolatency)
1026         ctx->encode_config.rcParams.zeroReorderDelay = 1;
1027
1028     if (ctx->quality) {
1029         //convert from float to fixed point 8.8
1030         int tmp_quality = (int)(ctx->quality * 256.0f);
1031         ctx->encode_config.rcParams.targetQuality = (uint8_t)(tmp_quality >> 8);
1032         ctx->encode_config.rcParams.targetQualityLSB = (uint8_t)(tmp_quality & 0xff);
1033
1034         av_log(avctx, AV_LOG_VERBOSE, "CQ(%d) mode enabled.\n", tmp_quality);
1035
1036         //CQ mode shall discard avg bitrate & honor max bitrate;
1037         ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate = 0;
1038         ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;
1039     }
1040 }
1041
1042 static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
1043 {
1044     NvencContext *ctx                      = avctx->priv_data;
1045     NV_ENC_CONFIG *cc                      = &ctx->encode_config;
1046     NV_ENC_CONFIG_H264 *h264               = &cc->encodeCodecConfig.h264Config;
1047     NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui = &h264->h264VUIParameters;
1048
1049     vui->colourMatrix = IS_GBRP(ctx->data_pix_fmt) ? AVCOL_SPC_RGB : avctx->colorspace;
1050     vui->colourPrimaries = avctx->color_primaries;
1051     vui->transferCharacteristics = avctx->color_trc;
1052     vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
1053         || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);
1054
1055     vui->colourDescriptionPresentFlag =
1056         (vui->colourMatrix != 2 || vui->colourPrimaries != 2 || vui->transferCharacteristics != 2);
1057
1058     vui->videoSignalTypePresentFlag =
1059         (vui->colourDescriptionPresentFlag
1060         || vui->videoFormat != 5
1061         || vui->videoFullRangeFlag != 0);
1062
1063     h264->sliceMode = 3;
1064     h264->sliceModeData = 1;
1065
1066     h264->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
1067     h264->repeatSPSPPS  = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
1068     h264->outputAUD     = ctx->aud;
1069
1070     if (ctx->dpb_size >= 0) {
1071         /* 0 means "let the hardware decide" */
1072         h264->maxNumRefFrames = ctx->dpb_size;
1073     }
1074     if (avctx->gop_size >= 0) {
1075         h264->idrPeriod = cc->gopLength;
1076     }
1077
1078     if (IS_CBR(cc->rcParams.rateControlMode)) {
1079         h264->outputBufferingPeriodSEI = 1;
1080     }
1081
1082     h264->outputPictureTimingSEI = 1;
1083
1084     if (cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ ||
1085         cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CBR_HQ ||
1086         cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_VBR_HQ) {
1087         h264->adaptiveTransformMode = NV_ENC_H264_ADAPTIVE_TRANSFORM_ENABLE;
1088         h264->fmoMode = NV_ENC_H264_FMO_DISABLE;
1089     }
1090
1091     if (ctx->flags & NVENC_LOSSLESS) {
1092         h264->qpPrimeYZeroTransformBypassFlag = 1;
1093     } else {
1094         switch(ctx->profile) {
1095         case NV_ENC_H264_PROFILE_BASELINE:
1096             cc->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
1097             avctx->profile = FF_PROFILE_H264_BASELINE;
1098             break;
1099         case NV_ENC_H264_PROFILE_MAIN:
1100             cc->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
1101             avctx->profile = FF_PROFILE_H264_MAIN;
1102             break;
1103         case NV_ENC_H264_PROFILE_HIGH:
1104             cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
1105             avctx->profile = FF_PROFILE_H264_HIGH;
1106             break;
1107         case NV_ENC_H264_PROFILE_HIGH_444P:
1108             cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
1109             avctx->profile = FF_PROFILE_H264_HIGH_444_PREDICTIVE;
1110             break;
1111         }
1112     }
1113
1114     // force setting profile as high444p if input is AV_PIX_FMT_YUV444P
1115     if (IS_YUV444(ctx->data_pix_fmt)) {
1116         cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
1117         avctx->profile = FF_PROFILE_H264_HIGH_444_PREDICTIVE;
1118     }
1119
1120     h264->chromaFormatIDC = avctx->profile == FF_PROFILE_H264_HIGH_444_PREDICTIVE ? 3 : 1;
1121
1122     h264->level = ctx->level;
1123
1124     if (ctx->coder >= 0)
1125         h264->entropyCodingMode = ctx->coder;
1126
1127 #ifdef NVENC_HAVE_BFRAME_REF_MODE
1128     h264->useBFramesAsRef = ctx->b_ref_mode;
1129 #endif
1130
1131 #ifdef NVENC_HAVE_MULTIPLE_REF_FRAMES
1132     h264->numRefL0 = avctx->refs;
1133     h264->numRefL1 = avctx->refs;
1134 #endif
1135
1136     return 0;
1137 }
1138
1139 static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
1140 {
1141     NvencContext *ctx                      = avctx->priv_data;
1142     NV_ENC_CONFIG *cc                      = &ctx->encode_config;
1143     NV_ENC_CONFIG_HEVC *hevc               = &cc->encodeCodecConfig.hevcConfig;
1144     NV_ENC_CONFIG_HEVC_VUI_PARAMETERS *vui = &hevc->hevcVUIParameters;
1145
1146     vui->colourMatrix = IS_GBRP(ctx->data_pix_fmt) ? AVCOL_SPC_RGB : avctx->colorspace;
1147     vui->colourPrimaries = avctx->color_primaries;
1148     vui->transferCharacteristics = avctx->color_trc;
1149     vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
1150         || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);
1151
1152     vui->colourDescriptionPresentFlag =
1153         (vui->colourMatrix != 2 || vui->colourPrimaries != 2 || vui->transferCharacteristics != 2);
1154
1155     vui->videoSignalTypePresentFlag =
1156         (vui->colourDescriptionPresentFlag
1157         || vui->videoFormat != 5
1158         || vui->videoFullRangeFlag != 0);
1159
1160     hevc->sliceMode = 3;
1161     hevc->sliceModeData = 1;
1162
1163     hevc->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
1164     hevc->repeatSPSPPS  = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
1165     hevc->outputAUD     = ctx->aud;
1166
1167     if (ctx->dpb_size >= 0) {
1168         /* 0 means "let the hardware decide" */
1169         hevc->maxNumRefFramesInDPB = ctx->dpb_size;
1170     }
1171     if (avctx->gop_size >= 0) {
1172         hevc->idrPeriod = cc->gopLength;
1173     }
1174
1175     if (IS_CBR(cc->rcParams.rateControlMode)) {
1176         hevc->outputBufferingPeriodSEI = 1;
1177     }
1178
1179     hevc->outputPictureTimingSEI = 1;
1180
1181     switch (ctx->profile) {
1182     case NV_ENC_HEVC_PROFILE_MAIN:
1183         cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
1184         avctx->profile  = FF_PROFILE_HEVC_MAIN;
1185         break;
1186     case NV_ENC_HEVC_PROFILE_MAIN_10:
1187         cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID;
1188         avctx->profile  = FF_PROFILE_HEVC_MAIN_10;
1189         break;
1190     case NV_ENC_HEVC_PROFILE_REXT:
1191         cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
1192         avctx->profile  = FF_PROFILE_HEVC_REXT;
1193         break;
1194     }
1195
1196     // force setting profile as main10 if input is 10 bit
1197     if (IS_10BIT(ctx->data_pix_fmt)) {
1198         cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID;
1199         avctx->profile = FF_PROFILE_HEVC_MAIN_10;
1200     }
1201
1202     // force setting profile as rext if input is yuv444
1203     if (IS_YUV444(ctx->data_pix_fmt)) {
1204         cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
1205         avctx->profile = FF_PROFILE_HEVC_REXT;
1206     }
1207
1208     hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : 1;
1209
1210     hevc->pixelBitDepthMinus8 = IS_10BIT(ctx->data_pix_fmt) ? 2 : 0;
1211
1212     hevc->level = ctx->level;
1213
1214     hevc->tier = ctx->tier;
1215
1216 #ifdef NVENC_HAVE_HEVC_BFRAME_REF_MODE
1217     hevc->useBFramesAsRef = ctx->b_ref_mode;
1218 #endif
1219
1220 #ifdef NVENC_HAVE_MULTIPLE_REF_FRAMES
1221     hevc->numRefL0 = avctx->refs;
1222     hevc->numRefL1 = avctx->refs;
1223 #endif
1224
1225     return 0;
1226 }
1227
1228 static av_cold int nvenc_setup_codec_config(AVCodecContext *avctx)
1229 {
1230     switch (avctx->codec->id) {
1231     case AV_CODEC_ID_H264:
1232         return nvenc_setup_h264_config(avctx);
1233     case AV_CODEC_ID_HEVC:
1234         return nvenc_setup_hevc_config(avctx);
1235     /* Earlier switch/case will return if unknown codec is passed. */
1236     }
1237
1238     return 0;
1239 }
1240
1241 static void compute_dar(AVCodecContext *avctx, int *dw, int *dh) {
1242     int sw, sh;
1243
1244     sw = avctx->width;
1245     sh = avctx->height;
1246
1247     if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {
1248         sw *= avctx->sample_aspect_ratio.num;
1249         sh *= avctx->sample_aspect_ratio.den;
1250     }
1251
1252     av_reduce(dw, dh, sw, sh, 1024 * 1024);
1253 }
1254
1255 static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
1256 {
1257     NvencContext *ctx = avctx->priv_data;
1258     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1259     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1260
1261     NV_ENC_PRESET_CONFIG preset_config = { 0 };
1262     NVENCSTATUS nv_status = NV_ENC_SUCCESS;
1263     AVCPBProperties *cpb_props;
1264     int res = 0;
1265     int dw, dh;
1266
1267     ctx->encode_config.version = NV_ENC_CONFIG_VER;
1268     ctx->init_encode_params.version = NV_ENC_INITIALIZE_PARAMS_VER;
1269
1270     ctx->init_encode_params.encodeHeight = avctx->height;
1271     ctx->init_encode_params.encodeWidth = avctx->width;
1272
1273     ctx->init_encode_params.encodeConfig = &ctx->encode_config;
1274
1275     preset_config.version = NV_ENC_PRESET_CONFIG_VER;
1276     preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
1277
1278 #ifdef NVENC_HAVE_NEW_PRESETS
1279     ctx->init_encode_params.tuningInfo = ctx->tuning_info;
1280
1281     if (ctx->flags & NVENC_LOSSLESS)
1282         ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOSSLESS;
1283     else if (ctx->flags & NVENC_LOWLATENCY)
1284         ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOW_LATENCY;
1285
1286     nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder,
1287         ctx->init_encode_params.encodeGUID,
1288         ctx->init_encode_params.presetGUID,
1289         ctx->init_encode_params.tuningInfo,
1290         &preset_config);
1291 #else
1292     nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder,
1293         ctx->init_encode_params.encodeGUID,
1294         ctx->init_encode_params.presetGUID,
1295         &preset_config);
1296 #endif
1297     if (nv_status != NV_ENC_SUCCESS)
1298         return nvenc_print_error(avctx, nv_status, "Cannot get the preset configuration");
1299
1300     memcpy(&ctx->encode_config, &preset_config.presetCfg, sizeof(ctx->encode_config));
1301
1302     ctx->encode_config.version = NV_ENC_CONFIG_VER;
1303
1304     compute_dar(avctx, &dw, &dh);
1305     ctx->init_encode_params.darHeight = dh;
1306     ctx->init_encode_params.darWidth = dw;
1307
1308     if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
1309         ctx->init_encode_params.frameRateNum = avctx->framerate.num;
1310         ctx->init_encode_params.frameRateDen = avctx->framerate.den;
1311     } else {
1312         ctx->init_encode_params.frameRateNum = avctx->time_base.den;
1313         ctx->init_encode_params.frameRateDen = avctx->time_base.num * avctx->ticks_per_frame;
1314     }
1315
1316     ctx->init_encode_params.enableEncodeAsync = 0;
1317     ctx->init_encode_params.enablePTD = 1;
1318
1319 #ifdef NVENC_HAVE_NEW_PRESETS
1320     /* If lookahead isn't set from CLI, use value from preset.
1321      * P6 & P7 presets may enable lookahead for better quality.
1322      * */
1323     if (ctx->rc_lookahead == 0 && ctx->encode_config.rcParams.enableLookahead)
1324         ctx->rc_lookahead = ctx->encode_config.rcParams.lookaheadDepth;
1325 #endif
1326
1327     if (ctx->weighted_pred == 1)
1328         ctx->init_encode_params.enableWeightedPrediction = 1;
1329
1330     if (ctx->bluray_compat) {
1331         ctx->aud = 1;
1332         ctx->dpb_size = FFMIN(FFMAX(avctx->refs, 0), 6);
1333         avctx->max_b_frames = FFMIN(avctx->max_b_frames, 3);
1334         switch (avctx->codec->id) {
1335         case AV_CODEC_ID_H264:
1336             /* maximum level depends on used resolution */
1337             break;
1338         case AV_CODEC_ID_HEVC:
1339             ctx->level = NV_ENC_LEVEL_HEVC_51;
1340             ctx->tier = NV_ENC_TIER_HEVC_HIGH;
1341             break;
1342         }
1343     }
1344
1345     if (avctx->gop_size > 0) {
1346         if (avctx->max_b_frames >= 0) {
1347             /* 0 is intra-only, 1 is I/P only, 2 is one B-Frame, 3 two B-frames, and so on. */
1348             ctx->encode_config.frameIntervalP = avctx->max_b_frames + 1;
1349         }
1350
1351         ctx->encode_config.gopLength = avctx->gop_size;
1352     } else if (avctx->gop_size == 0) {
1353         ctx->encode_config.frameIntervalP = 0;
1354         ctx->encode_config.gopLength = 1;
1355     }
1356
1357     nvenc_recalc_surfaces(avctx);
1358
1359     nvenc_setup_rate_control(avctx);
1360
1361     if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
1362         ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD;
1363     } else {
1364         ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME;
1365     }
1366
1367     res = nvenc_setup_codec_config(avctx);
1368     if (res)
1369         return res;
1370
1371     res = nvenc_push_context(avctx);
1372     if (res < 0)
1373         return res;
1374
1375     nv_status = p_nvenc->nvEncInitializeEncoder(ctx->nvencoder, &ctx->init_encode_params);
1376     if (nv_status != NV_ENC_SUCCESS) {
1377         nvenc_pop_context(avctx);
1378         return nvenc_print_error(avctx, nv_status, "InitializeEncoder failed");
1379     }
1380
1381 #ifdef NVENC_HAVE_CUSTREAM_PTR
1382     if (ctx->cu_context) {
1383         nv_status = p_nvenc->nvEncSetIOCudaStreams(ctx->nvencoder, &ctx->cu_stream, &ctx->cu_stream);
1384         if (nv_status != NV_ENC_SUCCESS) {
1385             nvenc_pop_context(avctx);
1386             return nvenc_print_error(avctx, nv_status, "SetIOCudaStreams failed");
1387         }
1388     }
1389 #endif
1390
1391     res = nvenc_pop_context(avctx);
1392     if (res < 0)
1393         return res;
1394
1395     if (ctx->encode_config.frameIntervalP > 1)
1396         avctx->has_b_frames = 2;
1397
1398     if (ctx->encode_config.rcParams.averageBitRate > 0)
1399         avctx->bit_rate = ctx->encode_config.rcParams.averageBitRate;
1400
1401     cpb_props = ff_add_cpb_side_data(avctx);
1402     if (!cpb_props)
1403         return AVERROR(ENOMEM);
1404     cpb_props->max_bitrate = ctx->encode_config.rcParams.maxBitRate;
1405     cpb_props->avg_bitrate = avctx->bit_rate;
1406     cpb_props->buffer_size = ctx->encode_config.rcParams.vbvBufferSize;
1407
1408     return 0;
1409 }
1410
1411 static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt)
1412 {
1413     switch (pix_fmt) {
1414     case AV_PIX_FMT_YUV420P:
1415         return NV_ENC_BUFFER_FORMAT_YV12_PL;
1416     case AV_PIX_FMT_NV12:
1417         return NV_ENC_BUFFER_FORMAT_NV12_PL;
1418     case AV_PIX_FMT_P010:
1419     case AV_PIX_FMT_P016:
1420         return NV_ENC_BUFFER_FORMAT_YUV420_10BIT;
1421     case AV_PIX_FMT_GBRP:
1422     case AV_PIX_FMT_YUV444P:
1423         return NV_ENC_BUFFER_FORMAT_YUV444_PL;
1424     case AV_PIX_FMT_GBRP16:
1425     case AV_PIX_FMT_YUV444P16:
1426         return NV_ENC_BUFFER_FORMAT_YUV444_10BIT;
1427     case AV_PIX_FMT_0RGB32:
1428         return NV_ENC_BUFFER_FORMAT_ARGB;
1429     case AV_PIX_FMT_0BGR32:
1430         return NV_ENC_BUFFER_FORMAT_ABGR;
1431     default:
1432         return NV_ENC_BUFFER_FORMAT_UNDEFINED;
1433     }
1434 }
1435
1436 static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx)
1437 {
1438     NvencContext *ctx = avctx->priv_data;
1439     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1440     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1441     NvencSurface* tmp_surface = &ctx->surfaces[idx];
1442
1443     NVENCSTATUS nv_status;
1444     NV_ENC_CREATE_BITSTREAM_BUFFER allocOut = { 0 };
1445     allocOut.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER;
1446
1447     if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1448         ctx->surfaces[idx].in_ref = av_frame_alloc();
1449         if (!ctx->surfaces[idx].in_ref)
1450             return AVERROR(ENOMEM);
1451     } else {
1452         NV_ENC_CREATE_INPUT_BUFFER allocSurf = { 0 };
1453
1454         ctx->surfaces[idx].format = nvenc_map_buffer_format(ctx->data_pix_fmt);
1455         if (ctx->surfaces[idx].format == NV_ENC_BUFFER_FORMAT_UNDEFINED) {
1456             av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n",
1457                    av_get_pix_fmt_name(ctx->data_pix_fmt));
1458             return AVERROR(EINVAL);
1459         }
1460
1461         allocSurf.version = NV_ENC_CREATE_INPUT_BUFFER_VER;
1462         allocSurf.width = avctx->width;
1463         allocSurf.height = avctx->height;
1464         allocSurf.bufferFmt = ctx->surfaces[idx].format;
1465
1466         nv_status = p_nvenc->nvEncCreateInputBuffer(ctx->nvencoder, &allocSurf);
1467         if (nv_status != NV_ENC_SUCCESS) {
1468             return nvenc_print_error(avctx, nv_status, "CreateInputBuffer failed");
1469         }
1470
1471         ctx->surfaces[idx].input_surface = allocSurf.inputBuffer;
1472         ctx->surfaces[idx].width = allocSurf.width;
1473         ctx->surfaces[idx].height = allocSurf.height;
1474     }
1475
1476     nv_status = p_nvenc->nvEncCreateBitstreamBuffer(ctx->nvencoder, &allocOut);
1477     if (nv_status != NV_ENC_SUCCESS) {
1478         int err = nvenc_print_error(avctx, nv_status, "CreateBitstreamBuffer failed");
1479         if (avctx->pix_fmt != AV_PIX_FMT_CUDA && avctx->pix_fmt != AV_PIX_FMT_D3D11)
1480             p_nvenc->nvEncDestroyInputBuffer(ctx->nvencoder, ctx->surfaces[idx].input_surface);
1481         av_frame_free(&ctx->surfaces[idx].in_ref);
1482         return err;
1483     }
1484
1485     ctx->surfaces[idx].output_surface = allocOut.bitstreamBuffer;
1486
1487     av_fifo_generic_write(ctx->unused_surface_queue, &tmp_surface, sizeof(tmp_surface), NULL);
1488
1489     return 0;
1490 }
1491
1492 static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx)
1493 {
1494     NvencContext *ctx = avctx->priv_data;
1495     int i, res = 0, res2;
1496
1497     ctx->surfaces = av_mallocz_array(ctx->nb_surfaces, sizeof(*ctx->surfaces));
1498     if (!ctx->surfaces)
1499         return AVERROR(ENOMEM);
1500
1501     ctx->timestamp_list = av_fifo_alloc(ctx->nb_surfaces * sizeof(int64_t));
1502     if (!ctx->timestamp_list)
1503         return AVERROR(ENOMEM);
1504
1505     ctx->unused_surface_queue = av_fifo_alloc(ctx->nb_surfaces * sizeof(NvencSurface*));
1506     if (!ctx->unused_surface_queue)
1507         return AVERROR(ENOMEM);
1508
1509     ctx->output_surface_queue = av_fifo_alloc(ctx->nb_surfaces * sizeof(NvencSurface*));
1510     if (!ctx->output_surface_queue)
1511         return AVERROR(ENOMEM);
1512     ctx->output_surface_ready_queue = av_fifo_alloc(ctx->nb_surfaces * sizeof(NvencSurface*));
1513     if (!ctx->output_surface_ready_queue)
1514         return AVERROR(ENOMEM);
1515
1516     res = nvenc_push_context(avctx);
1517     if (res < 0)
1518         return res;
1519
1520     for (i = 0; i < ctx->nb_surfaces; i++) {
1521         if ((res = nvenc_alloc_surface(avctx, i)) < 0)
1522             goto fail;
1523     }
1524
1525 fail:
1526     res2 = nvenc_pop_context(avctx);
1527     if (res2 < 0)
1528         return res2;
1529
1530     return res;
1531 }
1532
1533 static av_cold int nvenc_setup_extradata(AVCodecContext *avctx)
1534 {
1535     NvencContext *ctx = avctx->priv_data;
1536     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1537     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1538
1539     NVENCSTATUS nv_status;
1540     uint32_t outSize = 0;
1541     char tmpHeader[256];
1542     NV_ENC_SEQUENCE_PARAM_PAYLOAD payload = { 0 };
1543     payload.version = NV_ENC_SEQUENCE_PARAM_PAYLOAD_VER;
1544
1545     payload.spsppsBuffer = tmpHeader;
1546     payload.inBufferSize = sizeof(tmpHeader);
1547     payload.outSPSPPSPayloadSize = &outSize;
1548
1549     nv_status = p_nvenc->nvEncGetSequenceParams(ctx->nvencoder, &payload);
1550     if (nv_status != NV_ENC_SUCCESS) {
1551         return nvenc_print_error(avctx, nv_status, "GetSequenceParams failed");
1552     }
1553
1554     avctx->extradata_size = outSize;
1555     avctx->extradata = av_mallocz(outSize + AV_INPUT_BUFFER_PADDING_SIZE);
1556
1557     if (!avctx->extradata) {
1558         return AVERROR(ENOMEM);
1559     }
1560
1561     memcpy(avctx->extradata, tmpHeader, outSize);
1562
1563     return 0;
1564 }
1565
1566 av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
1567 {
1568     NvencContext *ctx               = avctx->priv_data;
1569     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1570     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1571     int i, res;
1572
1573     /* the encoder has to be flushed before it can be closed */
1574     if (ctx->nvencoder) {
1575         NV_ENC_PIC_PARAMS params        = { .version        = NV_ENC_PIC_PARAMS_VER,
1576                                             .encodePicFlags = NV_ENC_PIC_FLAG_EOS };
1577
1578         res = nvenc_push_context(avctx);
1579         if (res < 0)
1580             return res;
1581
1582         p_nvenc->nvEncEncodePicture(ctx->nvencoder, &params);
1583     }
1584
1585     av_fifo_freep(&ctx->timestamp_list);
1586     av_fifo_freep(&ctx->output_surface_ready_queue);
1587     av_fifo_freep(&ctx->output_surface_queue);
1588     av_fifo_freep(&ctx->unused_surface_queue);
1589
1590     if (ctx->surfaces && (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11)) {
1591         for (i = 0; i < ctx->nb_registered_frames; i++) {
1592             if (ctx->registered_frames[i].mapped)
1593                 p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[i].in_map.mappedResource);
1594             if (ctx->registered_frames[i].regptr)
1595                 p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr);
1596         }
1597         ctx->nb_registered_frames = 0;
1598     }
1599
1600     if (ctx->surfaces) {
1601         for (i = 0; i < ctx->nb_surfaces; ++i) {
1602             if (avctx->pix_fmt != AV_PIX_FMT_CUDA && avctx->pix_fmt != AV_PIX_FMT_D3D11)
1603                 p_nvenc->nvEncDestroyInputBuffer(ctx->nvencoder, ctx->surfaces[i].input_surface);
1604             av_frame_free(&ctx->surfaces[i].in_ref);
1605             p_nvenc->nvEncDestroyBitstreamBuffer(ctx->nvencoder, ctx->surfaces[i].output_surface);
1606         }
1607     }
1608     av_freep(&ctx->surfaces);
1609     ctx->nb_surfaces = 0;
1610
1611     av_frame_free(&ctx->frame);
1612
1613     av_freep(&ctx->sei_data);
1614
1615     if (ctx->nvencoder) {
1616         p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
1617
1618         res = nvenc_pop_context(avctx);
1619         if (res < 0)
1620             return res;
1621     }
1622     ctx->nvencoder = NULL;
1623
1624     if (ctx->cu_context_internal)
1625         CHECK_CU(dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal));
1626     ctx->cu_context = ctx->cu_context_internal = NULL;
1627
1628 #if CONFIG_D3D11VA
1629     if (ctx->d3d11_device) {
1630         ID3D11Device_Release(ctx->d3d11_device);
1631         ctx->d3d11_device = NULL;
1632     }
1633 #endif
1634
1635     nvenc_free_functions(&dl_fn->nvenc_dl);
1636     cuda_free_functions(&dl_fn->cuda_dl);
1637
1638     dl_fn->nvenc_device_count = 0;
1639
1640     av_log(avctx, AV_LOG_VERBOSE, "Nvenc unloaded\n");
1641
1642     return 0;
1643 }
1644
1645 av_cold int ff_nvenc_encode_init(AVCodecContext *avctx)
1646 {
1647     NvencContext *ctx = avctx->priv_data;
1648     int ret;
1649
1650     if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1651         AVHWFramesContext *frames_ctx;
1652         if (!avctx->hw_frames_ctx) {
1653             av_log(avctx, AV_LOG_ERROR,
1654                    "hw_frames_ctx must be set when using GPU frames as input\n");
1655             return AVERROR(EINVAL);
1656         }
1657         frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1658         if (frames_ctx->format != avctx->pix_fmt) {
1659             av_log(avctx, AV_LOG_ERROR,
1660                    "hw_frames_ctx must match the GPU frame type\n");
1661             return AVERROR(EINVAL);
1662         }
1663         ctx->data_pix_fmt = frames_ctx->sw_format;
1664     } else {
1665         ctx->data_pix_fmt = avctx->pix_fmt;
1666     }
1667
1668     ctx->frame = av_frame_alloc();
1669     if (!ctx->frame)
1670         return AVERROR(ENOMEM);
1671
1672     if ((ret = nvenc_load_libraries(avctx)) < 0)
1673         return ret;
1674
1675     if ((ret = nvenc_setup_device(avctx)) < 0)
1676         return ret;
1677
1678     if ((ret = nvenc_setup_encoder(avctx)) < 0)
1679         return ret;
1680
1681     if ((ret = nvenc_setup_surfaces(avctx)) < 0)
1682         return ret;
1683
1684     if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1685         if ((ret = nvenc_setup_extradata(avctx)) < 0)
1686             return ret;
1687     }
1688
1689     return 0;
1690 }
1691
1692 static NvencSurface *get_free_frame(NvencContext *ctx)
1693 {
1694     NvencSurface *tmp_surf;
1695
1696     if (!(av_fifo_size(ctx->unused_surface_queue) > 0))
1697         // queue empty
1698         return NULL;
1699
1700     av_fifo_generic_read(ctx->unused_surface_queue, &tmp_surf, sizeof(tmp_surf), NULL);
1701     return tmp_surf;
1702 }
1703
1704 static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *nv_surface,
1705             NV_ENC_LOCK_INPUT_BUFFER *lock_buffer_params, const AVFrame *frame)
1706 {
1707     int dst_linesize[4] = {
1708         lock_buffer_params->pitch,
1709         lock_buffer_params->pitch,
1710         lock_buffer_params->pitch,
1711         lock_buffer_params->pitch
1712     };
1713     uint8_t *dst_data[4];
1714     int ret;
1715
1716     if (frame->format == AV_PIX_FMT_YUV420P)
1717         dst_linesize[1] = dst_linesize[2] >>= 1;
1718
1719     ret = av_image_fill_pointers(dst_data, frame->format, nv_surface->height,
1720                                  lock_buffer_params->bufferDataPtr, dst_linesize);
1721     if (ret < 0)
1722         return ret;
1723
1724     if (frame->format == AV_PIX_FMT_YUV420P)
1725         FFSWAP(uint8_t*, dst_data[1], dst_data[2]);
1726
1727     av_image_copy(dst_data, dst_linesize,
1728                   (const uint8_t**)frame->data, frame->linesize, frame->format,
1729                   avctx->width, avctx->height);
1730
1731     return 0;
1732 }
1733
1734 static int nvenc_find_free_reg_resource(AVCodecContext *avctx)
1735 {
1736     NvencContext *ctx = avctx->priv_data;
1737     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1738     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1739     NVENCSTATUS nv_status;
1740
1741     int i, first_round;
1742
1743     if (ctx->nb_registered_frames == FF_ARRAY_ELEMS(ctx->registered_frames)) {
1744         for (first_round = 1; first_round >= 0; first_round--) {
1745             for (i = 0; i < ctx->nb_registered_frames; i++) {
1746                 if (!ctx->registered_frames[i].mapped) {
1747                     if (ctx->registered_frames[i].regptr) {
1748                         if (first_round)
1749                             continue;
1750                         nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr);
1751                         if (nv_status != NV_ENC_SUCCESS)
1752                             return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource");
1753                         ctx->registered_frames[i].ptr = NULL;
1754                         ctx->registered_frames[i].regptr = NULL;
1755                     }
1756                     return i;
1757                 }
1758             }
1759         }
1760     } else {
1761         return ctx->nb_registered_frames++;
1762     }
1763
1764     av_log(avctx, AV_LOG_ERROR, "Too many registered CUDA frames\n");
1765     return AVERROR(ENOMEM);
1766 }
1767
1768 static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame)
1769 {
1770     NvencContext *ctx = avctx->priv_data;
1771     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1772     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1773
1774     AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
1775     NV_ENC_REGISTER_RESOURCE reg;
1776     int i, idx, ret;
1777
1778     for (i = 0; i < ctx->nb_registered_frames; i++) {
1779         if (avctx->pix_fmt == AV_PIX_FMT_CUDA && ctx->registered_frames[i].ptr == frame->data[0])
1780             return i;
1781         else if (avctx->pix_fmt == AV_PIX_FMT_D3D11 && ctx->registered_frames[i].ptr == frame->data[0] && ctx->registered_frames[i].ptr_index == (intptr_t)frame->data[1])
1782             return i;
1783     }
1784
1785     idx = nvenc_find_free_reg_resource(avctx);
1786     if (idx < 0)
1787         return idx;
1788
1789     reg.version            = NV_ENC_REGISTER_RESOURCE_VER;
1790     reg.width              = frames_ctx->width;
1791     reg.height             = frames_ctx->height;
1792     reg.pitch              = frame->linesize[0];
1793     reg.resourceToRegister = frame->data[0];
1794
1795     if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
1796         reg.resourceType   = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR;
1797     }
1798     else if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1799         reg.resourceType     = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
1800         reg.subResourceIndex = (intptr_t)frame->data[1];
1801     }
1802
1803     reg.bufferFormat       = nvenc_map_buffer_format(frames_ctx->sw_format);
1804     if (reg.bufferFormat == NV_ENC_BUFFER_FORMAT_UNDEFINED) {
1805         av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n",
1806                av_get_pix_fmt_name(frames_ctx->sw_format));
1807         return AVERROR(EINVAL);
1808     }
1809
1810     ret = p_nvenc->nvEncRegisterResource(ctx->nvencoder, &reg);
1811     if (ret != NV_ENC_SUCCESS) {
1812         nvenc_print_error(avctx, ret, "Error registering an input resource");
1813         return AVERROR_UNKNOWN;
1814     }
1815
1816     ctx->registered_frames[idx].ptr       = frame->data[0];
1817     ctx->registered_frames[idx].ptr_index = reg.subResourceIndex;
1818     ctx->registered_frames[idx].regptr    = reg.registeredResource;
1819     return idx;
1820 }
1821
1822 static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame,
1823                                       NvencSurface *nvenc_frame)
1824 {
1825     NvencContext *ctx = avctx->priv_data;
1826     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1827     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1828
1829     int res;
1830     NVENCSTATUS nv_status;
1831
1832     if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1833         int reg_idx = nvenc_register_frame(avctx, frame);
1834         if (reg_idx < 0) {
1835             av_log(avctx, AV_LOG_ERROR, "Could not register an input HW frame\n");
1836             return reg_idx;
1837         }
1838
1839         res = av_frame_ref(nvenc_frame->in_ref, frame);
1840         if (res < 0)
1841             return res;
1842
1843         if (!ctx->registered_frames[reg_idx].mapped) {
1844             ctx->registered_frames[reg_idx].in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER;
1845             ctx->registered_frames[reg_idx].in_map.registeredResource = ctx->registered_frames[reg_idx].regptr;
1846             nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, &ctx->registered_frames[reg_idx].in_map);
1847             if (nv_status != NV_ENC_SUCCESS) {
1848                 av_frame_unref(nvenc_frame->in_ref);
1849                 return nvenc_print_error(avctx, nv_status, "Error mapping an input resource");
1850             }
1851         }
1852
1853         ctx->registered_frames[reg_idx].mapped += 1;
1854
1855         nvenc_frame->reg_idx                   = reg_idx;
1856         nvenc_frame->input_surface             = ctx->registered_frames[reg_idx].in_map.mappedResource;
1857         nvenc_frame->format                    = ctx->registered_frames[reg_idx].in_map.mappedBufferFmt;
1858         nvenc_frame->pitch                     = frame->linesize[0];
1859
1860         return 0;
1861     } else {
1862         NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };
1863
1864         lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;
1865         lockBufferParams.inputBuffer = nvenc_frame->input_surface;
1866
1867         nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);
1868         if (nv_status != NV_ENC_SUCCESS) {
1869             return nvenc_print_error(avctx, nv_status, "Failed locking nvenc input buffer");
1870         }
1871
1872         nvenc_frame->pitch = lockBufferParams.pitch;
1873         res = nvenc_copy_frame(avctx, nvenc_frame, &lockBufferParams, frame);
1874
1875         nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, nvenc_frame->input_surface);
1876         if (nv_status != NV_ENC_SUCCESS) {
1877             return nvenc_print_error(avctx, nv_status, "Failed unlocking input buffer!");
1878         }
1879
1880         return res;
1881     }
1882 }
1883
1884 static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
1885                                             NV_ENC_PIC_PARAMS *params,
1886                                             NV_ENC_SEI_PAYLOAD *sei_data,
1887                                             int sei_count)
1888 {
1889     NvencContext *ctx = avctx->priv_data;
1890
1891     switch (avctx->codec->id) {
1892     case AV_CODEC_ID_H264:
1893         params->codecPicParams.h264PicParams.sliceMode =
1894             ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
1895         params->codecPicParams.h264PicParams.sliceModeData =
1896             ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
1897         if (sei_count > 0) {
1898             params->codecPicParams.h264PicParams.seiPayloadArray = sei_data;
1899             params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count;
1900         }
1901
1902       break;
1903     case AV_CODEC_ID_HEVC:
1904         params->codecPicParams.hevcPicParams.sliceMode =
1905             ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
1906         params->codecPicParams.hevcPicParams.sliceModeData =
1907             ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
1908         if (sei_count > 0) {
1909             params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data;
1910             params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = sei_count;
1911         }
1912
1913         break;
1914     }
1915 }
1916
1917 static inline void timestamp_queue_enqueue(AVFifoBuffer* queue, int64_t timestamp)
1918 {
1919     av_fifo_generic_write(queue, &timestamp, sizeof(timestamp), NULL);
1920 }
1921
1922 static inline int64_t timestamp_queue_dequeue(AVFifoBuffer* queue)
1923 {
1924     int64_t timestamp = AV_NOPTS_VALUE;
1925     if (av_fifo_size(queue) > 0)
1926         av_fifo_generic_read(queue, &timestamp, sizeof(timestamp), NULL);
1927
1928     return timestamp;
1929 }
1930
1931 static int nvenc_set_timestamp(AVCodecContext *avctx,
1932                                NV_ENC_LOCK_BITSTREAM *params,
1933                                AVPacket *pkt)
1934 {
1935     NvencContext *ctx = avctx->priv_data;
1936
1937     pkt->pts = params->outputTimeStamp;
1938     pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
1939
1940     pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1);
1941
1942     return 0;
1943 }
1944
1945 static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSurface *tmpoutsurf)
1946 {
1947     NvencContext *ctx = avctx->priv_data;
1948     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1949     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1950
1951     uint32_t slice_mode_data;
1952     uint32_t *slice_offsets = NULL;
1953     NV_ENC_LOCK_BITSTREAM lock_params = { 0 };
1954     NVENCSTATUS nv_status;
1955     int res = 0;
1956
1957     enum AVPictureType pict_type;
1958
1959     switch (avctx->codec->id) {
1960     case AV_CODEC_ID_H264:
1961       slice_mode_data = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
1962       break;
1963     case AV_CODEC_ID_H265:
1964       slice_mode_data = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
1965       break;
1966     default:
1967       av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");
1968       res = AVERROR(EINVAL);
1969       goto error;
1970     }
1971     slice_offsets = av_mallocz(slice_mode_data * sizeof(*slice_offsets));
1972
1973     if (!slice_offsets) {
1974         res = AVERROR(ENOMEM);
1975         goto error;
1976     }
1977
1978     lock_params.version = NV_ENC_LOCK_BITSTREAM_VER;
1979
1980     lock_params.doNotWait = 0;
1981     lock_params.outputBitstream = tmpoutsurf->output_surface;
1982     lock_params.sliceOffsets = slice_offsets;
1983
1984     nv_status = p_nvenc->nvEncLockBitstream(ctx->nvencoder, &lock_params);
1985     if (nv_status != NV_ENC_SUCCESS) {
1986         res = nvenc_print_error(avctx, nv_status, "Failed locking bitstream buffer");
1987         goto error;
1988     }
1989
1990     res = ff_get_encode_buffer(avctx, pkt, lock_params.bitstreamSizeInBytes, 0);
1991
1992     if (res < 0) {
1993         p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
1994         goto error;
1995     }
1996
1997     memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes);
1998
1999     nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
2000     if (nv_status != NV_ENC_SUCCESS) {
2001         res = nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open");
2002         goto error;
2003     }
2004
2005
2006     if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
2007         ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1;
2008         if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) {
2009             nv_status = p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource);
2010             if (nv_status != NV_ENC_SUCCESS) {
2011                 res = nvenc_print_error(avctx, nv_status, "Failed unmapping input resource");
2012                 goto error;
2013             }
2014         } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) {
2015             res = AVERROR_BUG;
2016             goto error;
2017         }
2018
2019         av_frame_unref(tmpoutsurf->in_ref);
2020
2021         tmpoutsurf->input_surface = NULL;
2022     }
2023
2024     switch (lock_params.pictureType) {
2025     case NV_ENC_PIC_TYPE_IDR:
2026         pkt->flags |= AV_PKT_FLAG_KEY;
2027     case NV_ENC_PIC_TYPE_I:
2028         pict_type = AV_PICTURE_TYPE_I;
2029         break;
2030     case NV_ENC_PIC_TYPE_P:
2031         pict_type = AV_PICTURE_TYPE_P;
2032         break;
2033     case NV_ENC_PIC_TYPE_B:
2034         pict_type = AV_PICTURE_TYPE_B;
2035         break;
2036     case NV_ENC_PIC_TYPE_BI:
2037         pict_type = AV_PICTURE_TYPE_BI;
2038         break;
2039     default:
2040         av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered, expect the output to be broken.\n");
2041         av_log(avctx, AV_LOG_ERROR, "Please report this error and include as much information on how to reproduce it as possible.\n");
2042         res = AVERROR_EXTERNAL;
2043         goto error;
2044     }
2045
2046     ff_side_data_set_encoder_stats(pkt,
2047         (lock_params.frameAvgQP - 1) * FF_QP2LAMBDA, NULL, 0, pict_type);
2048
2049     res = nvenc_set_timestamp(avctx, &lock_params, pkt);
2050     if (res < 0)
2051         goto error2;
2052
2053     av_free(slice_offsets);
2054
2055     return 0;
2056
2057 error:
2058     timestamp_queue_dequeue(ctx->timestamp_list);
2059
2060 error2:
2061     av_free(slice_offsets);
2062
2063     return res;
2064 }
2065
2066 static int output_ready(AVCodecContext *avctx, int flush)
2067 {
2068     NvencContext *ctx = avctx->priv_data;
2069     int nb_ready, nb_pending;
2070
2071     nb_ready   = av_fifo_size(ctx->output_surface_ready_queue)   / sizeof(NvencSurface*);
2072     nb_pending = av_fifo_size(ctx->output_surface_queue)         / sizeof(NvencSurface*);
2073     if (flush)
2074         return nb_ready > 0;
2075     return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth);
2076 }
2077
2078 static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame)
2079 {
2080     NvencContext *ctx = avctx->priv_data;
2081     int sei_count = 0;
2082     int i, res;
2083
2084     if (ctx->a53_cc && av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC)) {
2085         void *a53_data = NULL;
2086         size_t a53_size = 0;
2087
2088         if (ff_alloc_a53_sei(frame, 0, &a53_data, &a53_size) < 0) {
2089             av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2090         }
2091
2092         if (a53_data) {
2093             void *tmp = av_fast_realloc(ctx->sei_data,
2094                                         &ctx->sei_data_size,
2095                                         (sei_count + 1) * sizeof(*ctx->sei_data));
2096             if (!tmp) {
2097                 av_free(a53_data);
2098                 res = AVERROR(ENOMEM);
2099                 goto error;
2100             } else {
2101                 ctx->sei_data = tmp;
2102                 ctx->sei_data[sei_count].payloadSize = (uint32_t)a53_size;
2103                 ctx->sei_data[sei_count].payloadType = 4;
2104                 ctx->sei_data[sei_count].payload = (uint8_t*)a53_data;
2105                 sei_count++;
2106             }
2107         }
2108     }
2109
2110     if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) {
2111         void *tc_data = NULL;
2112         size_t tc_size = 0;
2113
2114         if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, &tc_data, &tc_size) < 0) {
2115             av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n");
2116         }
2117
2118         if (tc_data) {
2119             void *tmp = av_fast_realloc(ctx->sei_data,
2120                                         &ctx->sei_data_size,
2121                                         (sei_count + 1) * sizeof(*ctx->sei_data));
2122             if (!tmp) {
2123                 av_free(tc_data);
2124                 res = AVERROR(ENOMEM);
2125                 goto error;
2126             } else {
2127                 ctx->sei_data = tmp;
2128                 ctx->sei_data[sei_count].payloadSize = (uint32_t)tc_size;
2129                 ctx->sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
2130                 ctx->sei_data[sei_count].payload = (uint8_t*)tc_data;
2131                 sei_count++;
2132             }
2133         }
2134     }
2135
2136     for (i = 0; i < frame->nb_side_data; i++) {
2137         AVFrameSideData *side_data = frame->side_data[i];
2138         void *tmp;
2139
2140         if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
2141             continue;
2142
2143         tmp = av_fast_realloc(ctx->sei_data,
2144                               &ctx->sei_data_size,
2145                               (sei_count + 1) * sizeof(*ctx->sei_data));
2146         if (!tmp) {
2147             res = AVERROR(ENOMEM);
2148             goto error;
2149         } else {
2150             ctx->sei_data = tmp;
2151             ctx->sei_data[sei_count].payloadSize = side_data->size;
2152             ctx->sei_data[sei_count].payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
2153             ctx->sei_data[sei_count].payload = av_memdup(side_data->data, side_data->size);
2154
2155             if (!ctx->sei_data[sei_count].payload) {
2156                 res = AVERROR(ENOMEM);
2157                 goto error;
2158             }
2159
2160             sei_count++;
2161         }
2162     }
2163
2164     return sei_count;
2165
2166 error:
2167     for (i = 0; i < sei_count; i++)
2168         av_freep(&(ctx->sei_data[i].payload));
2169
2170     return res;
2171 }
2172
2173 static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
2174 {
2175     NvencContext *ctx = avctx->priv_data;
2176     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
2177     NVENCSTATUS ret;
2178
2179     NV_ENC_RECONFIGURE_PARAMS params = { 0 };
2180     int needs_reconfig = 0;
2181     int needs_encode_config = 0;
2182     int reconfig_bitrate = 0, reconfig_dar = 0;
2183     int dw, dh;
2184
2185     params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
2186     params.reInitEncodeParams = ctx->init_encode_params;
2187
2188     compute_dar(avctx, &dw, &dh);
2189     if (dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight) {
2190         av_log(avctx, AV_LOG_VERBOSE,
2191                "aspect ratio change (DAR): %d:%d -> %d:%d\n",
2192                ctx->init_encode_params.darWidth,
2193                ctx->init_encode_params.darHeight, dw, dh);
2194
2195         params.reInitEncodeParams.darHeight = dh;
2196         params.reInitEncodeParams.darWidth = dw;
2197
2198         needs_reconfig = 1;
2199         reconfig_dar = 1;
2200     }
2201
2202     if (ctx->rc != NV_ENC_PARAMS_RC_CONSTQP && ctx->support_dyn_bitrate) {
2203         if (avctx->bit_rate > 0 && params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate != avctx->bit_rate) {
2204             av_log(avctx, AV_LOG_VERBOSE,
2205                    "avg bitrate change: %d -> %d\n",
2206                    params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate,
2207                    (uint32_t)avctx->bit_rate);
2208
2209             params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate = avctx->bit_rate;
2210             reconfig_bitrate = 1;
2211         }
2212
2213         if (avctx->rc_max_rate > 0 && ctx->encode_config.rcParams.maxBitRate != avctx->rc_max_rate) {
2214             av_log(avctx, AV_LOG_VERBOSE,
2215                    "max bitrate change: %d -> %d\n",
2216                    params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate,
2217                    (uint32_t)avctx->rc_max_rate);
2218
2219             params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate = avctx->rc_max_rate;
2220             reconfig_bitrate = 1;
2221         }
2222
2223         if (avctx->rc_buffer_size > 0 && ctx->encode_config.rcParams.vbvBufferSize != avctx->rc_buffer_size) {
2224             av_log(avctx, AV_LOG_VERBOSE,
2225                    "vbv buffer size change: %d -> %d\n",
2226                    params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize,
2227                    avctx->rc_buffer_size);
2228
2229             params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize = avctx->rc_buffer_size;
2230             reconfig_bitrate = 1;
2231         }
2232
2233         if (reconfig_bitrate) {
2234             params.resetEncoder = 1;
2235             params.forceIDR = 1;
2236
2237             needs_encode_config = 1;
2238             needs_reconfig = 1;
2239         }
2240     }
2241
2242     if (!needs_encode_config)
2243         params.reInitEncodeParams.encodeConfig = NULL;
2244
2245     if (needs_reconfig) {
2246         ret = p_nvenc->nvEncReconfigureEncoder(ctx->nvencoder, &params);
2247         if (ret != NV_ENC_SUCCESS) {
2248             nvenc_print_error(avctx, ret, "failed to reconfigure nvenc");
2249         } else {
2250             if (reconfig_dar) {
2251                 ctx->init_encode_params.darHeight = dh;
2252                 ctx->init_encode_params.darWidth = dw;
2253             }
2254
2255             if (reconfig_bitrate) {
2256                 ctx->encode_config.rcParams.averageBitRate = params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate;
2257                 ctx->encode_config.rcParams.maxBitRate = params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate;
2258                 ctx->encode_config.rcParams.vbvBufferSize = params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize;
2259             }
2260
2261         }
2262     }
2263 }
2264
2265 static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
2266 {
2267     NVENCSTATUS nv_status;
2268     NvencSurface *tmp_out_surf, *in_surf;
2269     int res, res2;
2270     int sei_count = 0;
2271     int i;
2272
2273     NvencContext *ctx = avctx->priv_data;
2274     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2275     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2276
2277     NV_ENC_PIC_PARAMS pic_params = { 0 };
2278     pic_params.version = NV_ENC_PIC_PARAMS_VER;
2279
2280     if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2281         return AVERROR(EINVAL);
2282
2283     if (frame && frame->buf[0]) {
2284         in_surf = get_free_frame(ctx);
2285         if (!in_surf)
2286             return AVERROR(EAGAIN);
2287
2288         res = nvenc_push_context(avctx);
2289         if (res < 0)
2290             return res;
2291
2292         reconfig_encoder(avctx, frame);
2293
2294         res = nvenc_upload_frame(avctx, frame, in_surf);
2295
2296         res2 = nvenc_pop_context(avctx);
2297         if (res2 < 0)
2298             return res2;
2299
2300         if (res)
2301             return res;
2302
2303         pic_params.inputBuffer = in_surf->input_surface;
2304         pic_params.bufferFmt = in_surf->format;
2305         pic_params.inputWidth = in_surf->width;
2306         pic_params.inputHeight = in_surf->height;
2307         pic_params.inputPitch = in_surf->pitch;
2308         pic_params.outputBitstream = in_surf->output_surface;
2309
2310         if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
2311             if (frame->top_field_first)
2312                 pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;
2313             else
2314                 pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;
2315         } else {
2316             pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
2317         }
2318
2319         if (ctx->forced_idr >= 0 && frame->pict_type == AV_PICTURE_TYPE_I) {
2320             pic_params.encodePicFlags =
2321                 ctx->forced_idr ? NV_ENC_PIC_FLAG_FORCEIDR : NV_ENC_PIC_FLAG_FORCEINTRA;
2322         } else {
2323             pic_params.encodePicFlags = 0;
2324         }
2325
2326         pic_params.inputTimeStamp = frame->pts;
2327
2328         res = prepare_sei_data_array(avctx, frame);
2329         if (res < 0)
2330             return res;
2331         sei_count = res;
2332
2333         nvenc_codec_specific_pic_params(avctx, &pic_params, ctx->sei_data, sei_count);
2334     } else {
2335         pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
2336     }
2337
2338     res = nvenc_push_context(avctx);
2339     if (res < 0)
2340         return res;
2341
2342     nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
2343
2344     for (i = 0; i < sei_count; i++)
2345         av_freep(&(ctx->sei_data[i].payload));
2346
2347     res = nvenc_pop_context(avctx);
2348     if (res < 0)
2349         return res;
2350
2351     if (nv_status != NV_ENC_SUCCESS &&
2352         nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
2353         return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
2354
2355     if (frame && frame->buf[0]) {
2356         av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL);
2357         timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);
2358     }
2359
2360     /* all the pending buffers are now ready for output */
2361     if (nv_status == NV_ENC_SUCCESS) {
2362         while (av_fifo_size(ctx->output_surface_queue) > 0) {
2363             av_fifo_generic_read(ctx->output_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2364             av_fifo_generic_write(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2365         }
2366     }
2367
2368     return 0;
2369 }
2370
2371 int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
2372 {
2373     NvencSurface *tmp_out_surf;
2374     int res, res2;
2375
2376     NvencContext *ctx = avctx->priv_data;
2377
2378     AVFrame *frame = ctx->frame;
2379
2380     if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2381         return AVERROR(EINVAL);
2382
2383     if (!frame->buf[0]) {
2384         res = ff_encode_get_frame(avctx, frame);
2385         if (res < 0 && res != AVERROR_EOF)
2386             return res;
2387     }
2388
2389     res = nvenc_send_frame(avctx, frame);
2390     if (res < 0) {
2391         if (res != AVERROR(EAGAIN))
2392             return res;
2393     } else
2394         av_frame_unref(frame);
2395
2396     if (output_ready(avctx, avctx->internal->draining)) {
2397         av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2398
2399         res = nvenc_push_context(avctx);
2400         if (res < 0)
2401             return res;
2402
2403         res = process_output_surface(avctx, pkt, tmp_out_surf);
2404
2405         res2 = nvenc_pop_context(avctx);
2406         if (res2 < 0)
2407             return res2;
2408
2409         if (res)
2410             return res;
2411
2412         av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2413     } else if (avctx->internal->draining) {
2414         return AVERROR_EOF;
2415     } else {
2416         return AVERROR(EAGAIN);
2417     }
2418
2419     return 0;
2420 }
2421
2422 av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
2423 {
2424     NvencContext *ctx = avctx->priv_data;
2425
2426     nvenc_send_frame(avctx, NULL);
2427     av_fifo_reset(ctx->timestamp_list);
2428 }