FFmpeg
nvenc.c
Go to the documentation of this file.
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 
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 
51  AV_PIX_FMT_P016, // Truncated to 10bits
52  AV_PIX_FMT_YUV444P16, // Truncated to 10bits
56  AV_PIX_FMT_GBRP16, // Truncated to 10bits
58 #if CONFIG_D3D11VA
60 #endif
62 };
63 
65  HW_CONFIG_ENCODER_FRAMES(CUDA, CUDA),
67 #if CONFIG_D3D11VA
68  HW_CONFIG_ENCODER_FRAMES(D3D11, 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 
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),
179  // Compat aliases
184  PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
187  PRESET_ALIAS(LOSSLESS_DEFAULT, P4, 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)
213 #endif
214 }
215 
216 #undef PRESET
217 #undef PRESET_ALIAS
218 
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 
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) {
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);
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 
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 
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 
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 
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 
416 {
417  NvencContext *ctx = avctx->priv_data;
418  int ret;
419 
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 
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 
624 
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 
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 
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 
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 
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) {
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 
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) {
1096  cc->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
1098  break;
1100  cc->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
1101  avctx->profile = FF_PROFILE_H264_MAIN;
1102  break;
1104  cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
1105  avctx->profile = FF_PROFILE_H264_HIGH;
1106  break;
1108  cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
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;
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 
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) {
1183  cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
1184  avctx->profile = FF_PROFILE_HEVC_MAIN;
1185  break;
1187  cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID;
1189  break;
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;
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 
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 
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 
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 
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;
1556 
1557  if (!avctx->extradata) {
1558  return AVERROR(ENOMEM);
1559  }
1560 
1561  memcpy(avctx->extradata, tmpHeader, outSize);
1562 
1563  return 0;
1564 }
1565 
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  if (ctx->nvencoder) {
1614  p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
1615 
1616  res = nvenc_pop_context(avctx);
1617  if (res < 0)
1618  return res;
1619  }
1620  ctx->nvencoder = NULL;
1621 
1622  if (ctx->cu_context_internal)
1623  CHECK_CU(dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal));
1624  ctx->cu_context = ctx->cu_context_internal = NULL;
1625 
1626 #if CONFIG_D3D11VA
1627  if (ctx->d3d11_device) {
1628  ID3D11Device_Release(ctx->d3d11_device);
1629  ctx->d3d11_device = NULL;
1630  }
1631 #endif
1632 
1633  nvenc_free_functions(&dl_fn->nvenc_dl);
1634  cuda_free_functions(&dl_fn->cuda_dl);
1635 
1636  dl_fn->nvenc_device_count = 0;
1637 
1638  av_log(avctx, AV_LOG_VERBOSE, "Nvenc unloaded\n");
1639 
1640  return 0;
1641 }
1642 
1644 {
1645  NvencContext *ctx = avctx->priv_data;
1646  int ret;
1647 
1648  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1649  AVHWFramesContext *frames_ctx;
1650  if (!avctx->hw_frames_ctx) {
1651  av_log(avctx, AV_LOG_ERROR,
1652  "hw_frames_ctx must be set when using GPU frames as input\n");
1653  return AVERROR(EINVAL);
1654  }
1655  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1656  if (frames_ctx->format != avctx->pix_fmt) {
1657  av_log(avctx, AV_LOG_ERROR,
1658  "hw_frames_ctx must match the GPU frame type\n");
1659  return AVERROR(EINVAL);
1660  }
1661  ctx->data_pix_fmt = frames_ctx->sw_format;
1662  } else {
1663  ctx->data_pix_fmt = avctx->pix_fmt;
1664  }
1665 
1666  ctx->frame = av_frame_alloc();
1667  if (!ctx->frame)
1668  return AVERROR(ENOMEM);
1669 
1670  if ((ret = nvenc_load_libraries(avctx)) < 0)
1671  return ret;
1672 
1673  if ((ret = nvenc_setup_device(avctx)) < 0)
1674  return ret;
1675 
1676  if ((ret = nvenc_setup_encoder(avctx)) < 0)
1677  return ret;
1678 
1679  if ((ret = nvenc_setup_surfaces(avctx)) < 0)
1680  return ret;
1681 
1682  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1683  if ((ret = nvenc_setup_extradata(avctx)) < 0)
1684  return ret;
1685  }
1686 
1687  return 0;
1688 }
1689 
1691 {
1692  NvencSurface *tmp_surf;
1693 
1694  if (!(av_fifo_size(ctx->unused_surface_queue) > 0))
1695  // queue empty
1696  return NULL;
1697 
1698  av_fifo_generic_read(ctx->unused_surface_queue, &tmp_surf, sizeof(tmp_surf), NULL);
1699  return tmp_surf;
1700 }
1701 
1702 static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *nv_surface,
1703  NV_ENC_LOCK_INPUT_BUFFER *lock_buffer_params, const AVFrame *frame)
1704 {
1705  int dst_linesize[4] = {
1706  lock_buffer_params->pitch,
1707  lock_buffer_params->pitch,
1708  lock_buffer_params->pitch,
1709  lock_buffer_params->pitch
1710  };
1711  uint8_t *dst_data[4];
1712  int ret;
1713 
1714  if (frame->format == AV_PIX_FMT_YUV420P)
1715  dst_linesize[1] = dst_linesize[2] >>= 1;
1716 
1717  ret = av_image_fill_pointers(dst_data, frame->format, nv_surface->height,
1718  lock_buffer_params->bufferDataPtr, dst_linesize);
1719  if (ret < 0)
1720  return ret;
1721 
1722  if (frame->format == AV_PIX_FMT_YUV420P)
1723  FFSWAP(uint8_t*, dst_data[1], dst_data[2]);
1724 
1725  av_image_copy(dst_data, dst_linesize,
1726  (const uint8_t**)frame->data, frame->linesize, frame->format,
1727  avctx->width, avctx->height);
1728 
1729  return 0;
1730 }
1731 
1733 {
1734  NvencContext *ctx = avctx->priv_data;
1735  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1736  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1737  NVENCSTATUS nv_status;
1738 
1739  int i, first_round;
1740 
1741  if (ctx->nb_registered_frames == FF_ARRAY_ELEMS(ctx->registered_frames)) {
1742  for (first_round = 1; first_round >= 0; first_round--) {
1743  for (i = 0; i < ctx->nb_registered_frames; i++) {
1744  if (!ctx->registered_frames[i].mapped) {
1745  if (ctx->registered_frames[i].regptr) {
1746  if (first_round)
1747  continue;
1748  nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr);
1749  if (nv_status != NV_ENC_SUCCESS)
1750  return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource");
1751  ctx->registered_frames[i].ptr = NULL;
1752  ctx->registered_frames[i].regptr = NULL;
1753  }
1754  return i;
1755  }
1756  }
1757  }
1758  } else {
1759  return ctx->nb_registered_frames++;
1760  }
1761 
1762  av_log(avctx, AV_LOG_ERROR, "Too many registered CUDA frames\n");
1763  return AVERROR(ENOMEM);
1764 }
1765 
1767 {
1768  NvencContext *ctx = avctx->priv_data;
1769  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1770  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1771 
1772  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
1773  NV_ENC_REGISTER_RESOURCE reg;
1774  int i, idx, ret;
1775 
1776  for (i = 0; i < ctx->nb_registered_frames; i++) {
1777  if (avctx->pix_fmt == AV_PIX_FMT_CUDA && ctx->registered_frames[i].ptr == frame->data[0])
1778  return i;
1779  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])
1780  return i;
1781  }
1782 
1783  idx = nvenc_find_free_reg_resource(avctx);
1784  if (idx < 0)
1785  return idx;
1786 
1787  reg.version = NV_ENC_REGISTER_RESOURCE_VER;
1788  reg.width = frames_ctx->width;
1789  reg.height = frames_ctx->height;
1790  reg.pitch = frame->linesize[0];
1791  reg.resourceToRegister = frame->data[0];
1792 
1793  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
1794  reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR;
1795  }
1796  else if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1797  reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
1798  reg.subResourceIndex = (intptr_t)frame->data[1];
1799  }
1800 
1801  reg.bufferFormat = nvenc_map_buffer_format(frames_ctx->sw_format);
1802  if (reg.bufferFormat == NV_ENC_BUFFER_FORMAT_UNDEFINED) {
1803  av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n",
1804  av_get_pix_fmt_name(frames_ctx->sw_format));
1805  return AVERROR(EINVAL);
1806  }
1807 
1808  ret = p_nvenc->nvEncRegisterResource(ctx->nvencoder, &reg);
1809  if (ret != NV_ENC_SUCCESS) {
1810  nvenc_print_error(avctx, ret, "Error registering an input resource");
1811  return AVERROR_UNKNOWN;
1812  }
1813 
1814  ctx->registered_frames[idx].ptr = frame->data[0];
1815  ctx->registered_frames[idx].ptr_index = reg.subResourceIndex;
1816  ctx->registered_frames[idx].regptr = reg.registeredResource;
1817  return idx;
1818 }
1819 
1821  NvencSurface *nvenc_frame)
1822 {
1823  NvencContext *ctx = avctx->priv_data;
1824  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1825  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1826 
1827  int res;
1828  NVENCSTATUS nv_status;
1829 
1830  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1831  int reg_idx = nvenc_register_frame(avctx, frame);
1832  if (reg_idx < 0) {
1833  av_log(avctx, AV_LOG_ERROR, "Could not register an input HW frame\n");
1834  return reg_idx;
1835  }
1836 
1837  res = av_frame_ref(nvenc_frame->in_ref, frame);
1838  if (res < 0)
1839  return res;
1840 
1841  if (!ctx->registered_frames[reg_idx].mapped) {
1842  ctx->registered_frames[reg_idx].in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER;
1843  ctx->registered_frames[reg_idx].in_map.registeredResource = ctx->registered_frames[reg_idx].regptr;
1844  nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, &ctx->registered_frames[reg_idx].in_map);
1845  if (nv_status != NV_ENC_SUCCESS) {
1846  av_frame_unref(nvenc_frame->in_ref);
1847  return nvenc_print_error(avctx, nv_status, "Error mapping an input resource");
1848  }
1849  }
1850 
1851  ctx->registered_frames[reg_idx].mapped += 1;
1852 
1853  nvenc_frame->reg_idx = reg_idx;
1854  nvenc_frame->input_surface = ctx->registered_frames[reg_idx].in_map.mappedResource;
1855  nvenc_frame->format = ctx->registered_frames[reg_idx].in_map.mappedBufferFmt;
1856  nvenc_frame->pitch = frame->linesize[0];
1857 
1858  return 0;
1859  } else {
1860  NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };
1861 
1862  lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;
1863  lockBufferParams.inputBuffer = nvenc_frame->input_surface;
1864 
1865  nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);
1866  if (nv_status != NV_ENC_SUCCESS) {
1867  return nvenc_print_error(avctx, nv_status, "Failed locking nvenc input buffer");
1868  }
1869 
1870  nvenc_frame->pitch = lockBufferParams.pitch;
1871  res = nvenc_copy_frame(avctx, nvenc_frame, &lockBufferParams, frame);
1872 
1873  nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, nvenc_frame->input_surface);
1874  if (nv_status != NV_ENC_SUCCESS) {
1875  return nvenc_print_error(avctx, nv_status, "Failed unlocking input buffer!");
1876  }
1877 
1878  return res;
1879  }
1880 }
1881 
1883  NV_ENC_PIC_PARAMS *params,
1884  NV_ENC_SEI_PAYLOAD *sei_data,
1885  int sei_count)
1886 {
1887  NvencContext *ctx = avctx->priv_data;
1888 
1889  switch (avctx->codec->id) {
1890  case AV_CODEC_ID_H264:
1891  params->codecPicParams.h264PicParams.sliceMode =
1892  ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
1893  params->codecPicParams.h264PicParams.sliceModeData =
1894  ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
1895  if (sei_count > 0) {
1896  params->codecPicParams.h264PicParams.seiPayloadArray = sei_data;
1897  params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count;
1898  }
1899 
1900  break;
1901  case AV_CODEC_ID_HEVC:
1902  params->codecPicParams.hevcPicParams.sliceMode =
1903  ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
1904  params->codecPicParams.hevcPicParams.sliceModeData =
1905  ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
1906  if (sei_count > 0) {
1907  params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data;
1908  params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = sei_count;
1909  }
1910 
1911  break;
1912  }
1913 }
1914 
1915 static inline void timestamp_queue_enqueue(AVFifoBuffer* queue, int64_t timestamp)
1916 {
1917  av_fifo_generic_write(queue, &timestamp, sizeof(timestamp), NULL);
1918 }
1919 
1920 static inline int64_t timestamp_queue_dequeue(AVFifoBuffer* queue)
1921 {
1922  int64_t timestamp = AV_NOPTS_VALUE;
1923  if (av_fifo_size(queue) > 0)
1924  av_fifo_generic_read(queue, &timestamp, sizeof(timestamp), NULL);
1925 
1926  return timestamp;
1927 }
1928 
1930  NV_ENC_LOCK_BITSTREAM *params,
1931  AVPacket *pkt)
1932 {
1933  NvencContext *ctx = avctx->priv_data;
1934 
1935  pkt->pts = params->outputTimeStamp;
1936  pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
1937 
1938  pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1);
1939 
1940  return 0;
1941 }
1942 
1944 {
1945  NvencContext *ctx = avctx->priv_data;
1946  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1947  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1948 
1949  uint32_t slice_mode_data;
1950  uint32_t *slice_offsets = NULL;
1951  NV_ENC_LOCK_BITSTREAM lock_params = { 0 };
1952  NVENCSTATUS nv_status;
1953  int res = 0;
1954 
1955  enum AVPictureType pict_type;
1956 
1957  switch (avctx->codec->id) {
1958  case AV_CODEC_ID_H264:
1959  slice_mode_data = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
1960  break;
1961  case AV_CODEC_ID_H265:
1962  slice_mode_data = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
1963  break;
1964  default:
1965  av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");
1966  res = AVERROR(EINVAL);
1967  goto error;
1968  }
1969  slice_offsets = av_mallocz(slice_mode_data * sizeof(*slice_offsets));
1970 
1971  if (!slice_offsets) {
1972  res = AVERROR(ENOMEM);
1973  goto error;
1974  }
1975 
1976  lock_params.version = NV_ENC_LOCK_BITSTREAM_VER;
1977 
1978  lock_params.doNotWait = 0;
1979  lock_params.outputBitstream = tmpoutsurf->output_surface;
1980  lock_params.sliceOffsets = slice_offsets;
1981 
1982  nv_status = p_nvenc->nvEncLockBitstream(ctx->nvencoder, &lock_params);
1983  if (nv_status != NV_ENC_SUCCESS) {
1984  res = nvenc_print_error(avctx, nv_status, "Failed locking bitstream buffer");
1985  goto error;
1986  }
1987 
1988  res = ff_get_encode_buffer(avctx, pkt, lock_params.bitstreamSizeInBytes, 0);
1989 
1990  if (res < 0) {
1991  p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
1992  goto error;
1993  }
1994 
1995  memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes);
1996 
1997  nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
1998  if (nv_status != NV_ENC_SUCCESS) {
1999  res = nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open");
2000  goto error;
2001  }
2002 
2003 
2004  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
2005  ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1;
2006  if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) {
2007  nv_status = p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource);
2008  if (nv_status != NV_ENC_SUCCESS) {
2009  res = nvenc_print_error(avctx, nv_status, "Failed unmapping input resource");
2010  goto error;
2011  }
2012  } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) {
2013  res = AVERROR_BUG;
2014  goto error;
2015  }
2016 
2017  av_frame_unref(tmpoutsurf->in_ref);
2018 
2019  tmpoutsurf->input_surface = NULL;
2020  }
2021 
2022  switch (lock_params.pictureType) {
2023  case NV_ENC_PIC_TYPE_IDR:
2025  case NV_ENC_PIC_TYPE_I:
2026  pict_type = AV_PICTURE_TYPE_I;
2027  break;
2028  case NV_ENC_PIC_TYPE_P:
2029  pict_type = AV_PICTURE_TYPE_P;
2030  break;
2031  case NV_ENC_PIC_TYPE_B:
2032  pict_type = AV_PICTURE_TYPE_B;
2033  break;
2034  case NV_ENC_PIC_TYPE_BI:
2035  pict_type = AV_PICTURE_TYPE_BI;
2036  break;
2037  default:
2038  av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered, expect the output to be broken.\n");
2039  av_log(avctx, AV_LOG_ERROR, "Please report this error and include as much information on how to reproduce it as possible.\n");
2040  res = AVERROR_EXTERNAL;
2041  goto error;
2042  }
2043 
2044 #if FF_API_CODED_FRAME
2046  avctx->coded_frame->pict_type = pict_type;
2048 #endif
2049 
2051  (lock_params.frameAvgQP - 1) * FF_QP2LAMBDA, NULL, 0, pict_type);
2052 
2053  res = nvenc_set_timestamp(avctx, &lock_params, pkt);
2054  if (res < 0)
2055  goto error2;
2056 
2057  av_free(slice_offsets);
2058 
2059  return 0;
2060 
2061 error:
2062  timestamp_queue_dequeue(ctx->timestamp_list);
2063 
2064 error2:
2065  av_free(slice_offsets);
2066 
2067  return res;
2068 }
2069 
2070 static int output_ready(AVCodecContext *avctx, int flush)
2071 {
2072  NvencContext *ctx = avctx->priv_data;
2073  int nb_ready, nb_pending;
2074 
2075  nb_ready = av_fifo_size(ctx->output_surface_ready_queue) / sizeof(NvencSurface*);
2076  nb_pending = av_fifo_size(ctx->output_surface_queue) / sizeof(NvencSurface*);
2077  if (flush)
2078  return nb_ready > 0;
2079  return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth);
2080 }
2081 
2082 static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
2083 {
2084  NvencContext *ctx = avctx->priv_data;
2085  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
2086  NVENCSTATUS ret;
2087 
2088  NV_ENC_RECONFIGURE_PARAMS params = { 0 };
2089  int needs_reconfig = 0;
2090  int needs_encode_config = 0;
2091  int reconfig_bitrate = 0, reconfig_dar = 0;
2092  int dw, dh;
2093 
2094  params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
2095  params.reInitEncodeParams = ctx->init_encode_params;
2096 
2097  compute_dar(avctx, &dw, &dh);
2098  if (dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight) {
2099  av_log(avctx, AV_LOG_VERBOSE,
2100  "aspect ratio change (DAR): %d:%d -> %d:%d\n",
2101  ctx->init_encode_params.darWidth,
2102  ctx->init_encode_params.darHeight, dw, dh);
2103 
2104  params.reInitEncodeParams.darHeight = dh;
2105  params.reInitEncodeParams.darWidth = dw;
2106 
2107  needs_reconfig = 1;
2108  reconfig_dar = 1;
2109  }
2110 
2111  if (ctx->rc != NV_ENC_PARAMS_RC_CONSTQP && ctx->support_dyn_bitrate) {
2112  if (avctx->bit_rate > 0 && params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate != avctx->bit_rate) {
2113  av_log(avctx, AV_LOG_VERBOSE,
2114  "avg bitrate change: %d -> %d\n",
2115  params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate,
2116  (uint32_t)avctx->bit_rate);
2117 
2118  params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate = avctx->bit_rate;
2119  reconfig_bitrate = 1;
2120  }
2121 
2122  if (avctx->rc_max_rate > 0 && ctx->encode_config.rcParams.maxBitRate != avctx->rc_max_rate) {
2123  av_log(avctx, AV_LOG_VERBOSE,
2124  "max bitrate change: %d -> %d\n",
2125  params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate,
2126  (uint32_t)avctx->rc_max_rate);
2127 
2128  params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate = avctx->rc_max_rate;
2129  reconfig_bitrate = 1;
2130  }
2131 
2132  if (avctx->rc_buffer_size > 0 && ctx->encode_config.rcParams.vbvBufferSize != avctx->rc_buffer_size) {
2133  av_log(avctx, AV_LOG_VERBOSE,
2134  "vbv buffer size change: %d -> %d\n",
2135  params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize,
2136  avctx->rc_buffer_size);
2137 
2138  params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize = avctx->rc_buffer_size;
2139  reconfig_bitrate = 1;
2140  }
2141 
2142  if (reconfig_bitrate) {
2143  params.resetEncoder = 1;
2144  params.forceIDR = 1;
2145 
2146  needs_encode_config = 1;
2147  needs_reconfig = 1;
2148  }
2149  }
2150 
2151  if (!needs_encode_config)
2152  params.reInitEncodeParams.encodeConfig = NULL;
2153 
2154  if (needs_reconfig) {
2155  ret = p_nvenc->nvEncReconfigureEncoder(ctx->nvencoder, &params);
2156  if (ret != NV_ENC_SUCCESS) {
2157  nvenc_print_error(avctx, ret, "failed to reconfigure nvenc");
2158  } else {
2159  if (reconfig_dar) {
2160  ctx->init_encode_params.darHeight = dh;
2161  ctx->init_encode_params.darWidth = dw;
2162  }
2163 
2164  if (reconfig_bitrate) {
2165  ctx->encode_config.rcParams.averageBitRate = params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate;
2166  ctx->encode_config.rcParams.maxBitRate = params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate;
2167  ctx->encode_config.rcParams.vbvBufferSize = params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize;
2168  }
2169 
2170  }
2171  }
2172 }
2173 
2174 static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
2175 {
2176  NVENCSTATUS nv_status;
2177  NvencSurface *tmp_out_surf, *in_surf;
2178  int res, res2;
2179  NV_ENC_SEI_PAYLOAD sei_data[8];
2180  int sei_count = 0;
2181  int i;
2182 
2183  NvencContext *ctx = avctx->priv_data;
2184  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2185  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2186 
2187  NV_ENC_PIC_PARAMS pic_params = { 0 };
2188  pic_params.version = NV_ENC_PIC_PARAMS_VER;
2189 
2190  if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2191  return AVERROR(EINVAL);
2192 
2193  if (frame && frame->buf[0]) {
2194  in_surf = get_free_frame(ctx);
2195  if (!in_surf)
2196  return AVERROR(EAGAIN);
2197 
2198  res = nvenc_push_context(avctx);
2199  if (res < 0)
2200  return res;
2201 
2202  reconfig_encoder(avctx, frame);
2203 
2204  res = nvenc_upload_frame(avctx, frame, in_surf);
2205 
2206  res2 = nvenc_pop_context(avctx);
2207  if (res2 < 0)
2208  return res2;
2209 
2210  if (res)
2211  return res;
2212 
2213  pic_params.inputBuffer = in_surf->input_surface;
2214  pic_params.bufferFmt = in_surf->format;
2215  pic_params.inputWidth = in_surf->width;
2216  pic_params.inputHeight = in_surf->height;
2217  pic_params.inputPitch = in_surf->pitch;
2218  pic_params.outputBitstream = in_surf->output_surface;
2219 
2220  if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
2221  if (frame->top_field_first)
2222  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;
2223  else
2224  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;
2225  } else {
2226  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
2227  }
2228 
2229  if (ctx->forced_idr >= 0 && frame->pict_type == AV_PICTURE_TYPE_I) {
2230  pic_params.encodePicFlags =
2231  ctx->forced_idr ? NV_ENC_PIC_FLAG_FORCEIDR : NV_ENC_PIC_FLAG_FORCEINTRA;
2232  } else {
2233  pic_params.encodePicFlags = 0;
2234  }
2235 
2236  pic_params.inputTimeStamp = frame->pts;
2237 
2239  void *a53_data = NULL;
2240  size_t a53_size = 0;
2241 
2242  if (ff_alloc_a53_sei(frame, 0, (void**)&a53_data, &a53_size) < 0) {
2243  av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2244  }
2245 
2246  if (a53_data) {
2247  sei_data[sei_count].payloadSize = (uint32_t)a53_size;
2248  sei_data[sei_count].payloadType = 4;
2249  sei_data[sei_count].payload = (uint8_t*)a53_data;
2250  sei_count ++;
2251  }
2252  }
2253 
2255  void *tc_data = NULL;
2256  size_t tc_size = 0;
2257 
2258  if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, (void**)&tc_data, &tc_size) < 0) {
2259  av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n");
2260  }
2261 
2262  if (tc_data) {
2263  sei_data[sei_count].payloadSize = (uint32_t)tc_size;
2264  sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
2265  sei_data[sei_count].payload = (uint8_t*)tc_data;
2266  sei_count ++;
2267  }
2268  }
2269 
2270  nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data, sei_count);
2271  } else {
2272  pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
2273  }
2274 
2275  res = nvenc_push_context(avctx);
2276  if (res < 0)
2277  return res;
2278 
2279  nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
2280 
2281  for ( i = 0; i < sei_count; i++)
2282  av_freep(&sei_data[i].payload);
2283 
2284  res = nvenc_pop_context(avctx);
2285  if (res < 0)
2286  return res;
2287 
2288  if (nv_status != NV_ENC_SUCCESS &&
2289  nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
2290  return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
2291 
2292  if (frame && frame->buf[0]) {
2293  av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL);
2294  timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);
2295  }
2296 
2297  /* all the pending buffers are now ready for output */
2298  if (nv_status == NV_ENC_SUCCESS) {
2299  while (av_fifo_size(ctx->output_surface_queue) > 0) {
2300  av_fifo_generic_read(ctx->output_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2301  av_fifo_generic_write(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2302  }
2303  }
2304 
2305  return 0;
2306 }
2307 
2309 {
2310  NvencSurface *tmp_out_surf;
2311  int res, res2;
2312 
2313  NvencContext *ctx = avctx->priv_data;
2314 
2315  AVFrame *frame = ctx->frame;
2316 
2317  if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2318  return AVERROR(EINVAL);
2319 
2320  if (!frame->buf[0]) {
2321  res = ff_encode_get_frame(avctx, frame);
2322  if (res < 0 && res != AVERROR_EOF)
2323  return res;
2324  }
2325 
2326  res = nvenc_send_frame(avctx, frame);
2327  if (res < 0) {
2328  if (res != AVERROR(EAGAIN))
2329  return res;
2330  } else
2332 
2333  if (output_ready(avctx, avctx->internal->draining)) {
2334  av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2335 
2336  res = nvenc_push_context(avctx);
2337  if (res < 0)
2338  return res;
2339 
2340  res = process_output_surface(avctx, pkt, tmp_out_surf);
2341 
2342  res2 = nvenc_pop_context(avctx);
2343  if (res2 < 0)
2344  return res2;
2345 
2346  if (res)
2347  return res;
2348 
2349  av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2350  } else if (avctx->internal->draining) {
2351  return AVERROR_EOF;
2352  } else {
2353  return AVERROR(EAGAIN);
2354  }
2355 
2356  return 0;
2357 }
2358 
2360 {
2361  NvencContext *ctx = avctx->priv_data;
2362 
2363  nvenc_send_frame(avctx, NULL);
2364  av_fifo_reset(ctx->timestamp_list);
2365 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:30
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
FF_PROFILE_HEVC_REXT
#define FF_PROFILE_HEVC_REXT
Definition: avcodec.h:1949
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
ff_alloc_a53_sei
int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size)
Check AVFrame for A53 side data and allocate and fill SEI message with A53 info.
Definition: atsc_a53.c:25
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
PRESET_ALIAS
#define PRESET_ALIAS(alias, name,...)
Definition: nvenc.c:160
AV_PIX_FMT_CUDA
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition: pixfmt.h:235
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
GUIDTuple::guid
const GUID guid
Definition: nvenc.c:156
level
uint8_t level
Definition: svq3.c:204
av_clip
#define av_clip
Definition: common.h:122
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1164
P3
#define P3
Definition: hevcdsp_template.c:1497
av_fifo_generic_write
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Definition: fifo.c:122
NV_ENC_H264_PROFILE_HIGH
@ NV_ENC_H264_PROFILE_HIGH
Definition: nvenc.h:122
FFSWAP
#define FFSWAP(type, a, b)
Definition: common.h:108
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:739
GUIDTuple
Definition: nvenc.c:155
NONE
@ NONE
Definition: af_afade.c:54
GUIDTuple::flags
int flags
Definition: nvenc.c:157
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
ff_side_data_set_encoder_stats
int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type)
Definition: avpacket.c:820
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:92
FF_PROFILE_H264_BASELINE
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:1897
AV_FRAME_DATA_A53_CC
@ AV_FRAME_DATA_A53_CC
ATSC A53 Part 4 Closed Captions.
Definition: frame.h:58
nvenc_push_context
static int nvenc_push_context(AVCodecContext *avctx)
Definition: nvenc.c:313
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:209
AVPictureType
AVPictureType
Definition: avutil.h:272
output_ready
static int output_ready(AVCodecContext *avctx, int flush)
Definition: nvenc.c:2070
NvencContext
Definition: nvenc.h:146
NV_ENC_H264_PROFILE_HIGH_444P
@ NV_ENC_H264_PROFILE_HIGH_444P
Definition: nvenc.h:123
AV_FRAME_DATA_S12M_TIMECODE
@ AV_FRAME_DATA_S12M_TIMECODE
Timecode which conforms to SMPTE ST 12-1.
Definition: frame.h:168
NvencSurface::in_ref
AVFrame * in_ref
Definition: nvenc.h:76
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:204
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:324
pixdesc.h
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:1157
nvenc_set_timestamp
static int nvenc_set_timestamp(AVCodecContext *avctx, NV_ENC_LOCK_BITSTREAM *params, AVPacket *pkt)
Definition: nvenc.c:1929
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:586
P1
#define P1
Definition: cavsdsp.c:39
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:369
encode.h
AVCodecContext::b_quant_offset
float b_quant_offset
qscale offset between IP and B-frames
Definition: avcodec.h:818
FF_PROFILE_H264_HIGH_444_PREDICTIVE
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: avcodec.h:1909
reconfig_encoder
static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2082
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:190
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
Definition: pixfmt.h:513
ff_nvenc_pix_fmts
enum AVPixelFormat ff_nvenc_pix_fmts[]
Definition: nvenc.c:46
set_constqp
static av_cold void set_constqp(AVCodecContext *avctx)
Definition: nvenc.c:718
NvencSurface
Definition: nvenc.h:73
nvenc_print_error
static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err, const char *error_string)
Definition: nvenc.c:135
BD
#define BD
av_fifo_generic_read
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
Definition: fifo.c:213
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
ff_add_cpb_side_data
AVCPBProperties * ff_add_cpb_side_data(AVCodecContext *avctx)
Add a CPB properties side data to an encoding context.
Definition: utils.c:1031
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:229
AVCodecContext::qmax
int qmax
maximum quantizer
Definition: avcodec.h:1387
nverr
NVENCSTATUS nverr
Definition: nvenc.c:88
set_lossless
static av_cold void set_lossless(AVCodecContext *avctx)
Definition: nvenc.c:813
PRESET
#define PRESET(name,...)
Definition: nvenc.c:163
av_fifo_reset
void av_fifo_reset(AVFifoBuffer *f)
Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
Definition: fifo.c:71
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:410
ff_nvenc_encode_flush
av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
Definition: nvenc.c:2359
NV_ENC_H264_PROFILE_BASELINE
@ NV_ENC_H264_PROFILE_BASELINE
Definition: nvenc.h:120
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:329
nvenc.h
AV_HWDEVICE_TYPE_CUDA
@ AV_HWDEVICE_TYPE_CUDA
Definition: hwcontext.h:30
AVFifoBuffer
Definition: fifo.h:31
compute_dar
static void compute_dar(AVCodecContext *avctx, int *dw, int *dh)
Definition: nvenc.c:1241
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:2071
nvenc_upload_frame
static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, NvencSurface *nvenc_frame)
Definition: nvenc.c:1820
NvencDynLoadFunctions::nvenc_device_count
int nvenc_device_count
Definition: nvenc.h:92
AVCodecContext::i_quant_factor
float i_quant_factor
qscale factor between P- and I-frames If > 0 then the last P-frame quantizer will be used (q = lastp_...
Definition: avcodec.h:841
set_vbr
static av_cold void set_vbr(AVCodecContext *avctx)
Definition: nvenc.c:751
nvenc_map_error
static int nvenc_map_error(NVENCSTATUS err, const char **desc)
Definition: nvenc.c:120
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:545
nvenc_check_cap
static int nvenc_check_cap(AVCodecContext *avctx, NV_ENC_CAPS cap)
Definition: nvenc.c:398
presets
static const Preset presets[]
Definition: vf_pseudocolor.c:150
fail
#define fail()
Definition: checkasm.h:133
NvencSurface::format
NV_ENC_BUFFER_FORMAT format
Definition: nvenc.h:83
AVCodecContext::refs
int refs
number of reference frames
Definition: avcodec.h:1124
AV_HWDEVICE_TYPE_D3D11VA
@ AV_HWDEVICE_TYPE_D3D11VA
Definition: hwcontext.h:35
nvenc_map_preset
static void nvenc_map_preset(NvencContext *ctx)
Definition: nvenc.c:165
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:616
FF_PROFILE_H264_HIGH
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1901
val
static double val(void *priv, double ch)
Definition: aeval.c:76
nvenc_copy_frame
static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *nv_surface, NV_ENC_LOCK_INPUT_BUFFER *lock_buffer_params, const AVFrame *frame)
Definition: nvenc.c:1702
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:51
hwcontext_cuda.h
av_image_fill_pointers
int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, uint8_t *ptr, const int linesizes[4])
Fill plane data pointers for an image with pixel format pix_fmt and height height.
Definition: imgutils.c:146
ANY_DEVICE
@ ANY_DEVICE
Definition: nvenc.h:143
IS_GBRP
#define IS_GBRP(pix_fmt)
Definition: nvenc.c:84
AVCUDADeviceContext::cuda_ctx
CUcontext cuda_ctx
Definition: hwcontext_cuda.h:43
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
nvenc_print_driver_requirement
static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level)
Definition: nvenc.c:219
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_CODEC_FLAG_INTERLACED_DCT
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition: avcodec.h:321
nvenc_check_capabilities
static int nvenc_check_capabilities(AVCodecContext *avctx)
Definition: nvenc.c:415
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:191
avassert.h
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:1150
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
FF_PROFILE_HEVC_MAIN
#define FF_PROFILE_HEVC_MAIN
Definition: avcodec.h:1946
AVHWFramesContext::height
int height
Definition: hwcontext.h:229
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:638
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:826
ff_nvenc_encode_init
av_cold int ff_nvenc_encode_init(AVCodecContext *avctx)
Definition: nvenc.c:1643
width
#define width
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:602
AVD3D11VADeviceContext::device
ID3D11Device * device
Device used for texture creation and access.
Definition: hwcontext_d3d11va.h:56
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1362
AV_PIX_FMT_0BGR32
#define AV_PIX_FMT_0BGR32
Definition: pixfmt.h:377
AVCodecContext::ticks_per_frame
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:668
NvencDynLoadFunctions
Definition: nvenc.h:86
NVENC_DEPRECATED_PRESET
@ NVENC_DEPRECATED_PRESET
Definition: nvenc.h:138
NV_ENC_HEVC_PROFILE_MAIN
@ NV_ENC_HEVC_PROFILE_MAIN
Definition: nvenc.h:127
ctx
AVFormatContext * ctx
Definition: movenc.c:48
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:40
nvenc_setup_extradata
static av_cold int nvenc_setup_extradata(AVCodecContext *avctx)
Definition: nvenc.c:1533
timestamp_queue_enqueue
static void timestamp_queue_enqueue(AVFifoBuffer *queue, int64_t timestamp)
Definition: nvenc.c:1915
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1416
NvencDynLoadFunctions::nvenc_dl
NvencFunctions * nvenc_dl
Definition: nvenc.h:89
AVCPBProperties
This structure describes the bitrate properties of an encoded bitstream.
Definition: avcodec.h:453
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
NvencSurface::pitch
int pitch
Definition: nvenc.h:80
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
NV_ENC_HEVC_PROFILE_MAIN_10
@ NV_ENC_HEVC_PROFILE_MAIN_10
Definition: nvenc.h:128
NvencSurface::input_surface
NV_ENC_INPUT_PTR input_surface
Definition: nvenc.h:75
if
if(ret)
Definition: filter_design.txt:179
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1401
NVENC_CAP
#define NVENC_CAP
Definition: nvenc.c:41
AVCPBProperties::avg_bitrate
int avg_bitrate
Average bitrate of the stream, in bits per second.
Definition: avcodec.h:477
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:418
IS_10BIT
#define IS_10BIT(pix_fmt)
Definition: nvenc.c:74
nvenc_setup_rate_control
static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
Definition: nvenc.c:897
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
flush
static void flush(AVCodecContext *avctx)
Definition: aacdec_template.c:592
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:222
NvencSurface::reg_idx
int reg_idx
Definition: nvenc.h:77
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:1171
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:571
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:586
ff_nvenc_encode_close
av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
Definition: nvenc.c:1566
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
FF_PROFILE_HEVC_MAIN_10
#define FF_PROFILE_HEVC_MAIN_10
Definition: avcodec.h:1947
NvencDynLoadFunctions::cuda_dl
CudaFunctions * cuda_dl
Definition: nvenc.h:88
nvenc_setup_h264_config
static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
Definition: nvenc.c:1042
convert_header.major
int major
Definition: convert_header.py:23
SEI_TYPE_TIME_CODE
@ SEI_TYPE_TIME_CODE
Definition: sei.h:95
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:659
AVCUDADeviceContext::stream
CUstream stream
Definition: hwcontext_cuda.h:44
desc
const char * desc
Definition: nvenc.c:90
nvenc_pop_context
static int nvenc_pop_context(AVCodecContext *avctx)
Definition: nvenc.c:324
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:407
HW_CONFIG_ENCODER_DEVICE
#define HW_CONFIG_ENCODER_DEVICE(format, device_type_)
Definition: hwconfig.h:96
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:731
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:444
nvenc_check_codec_support
static int nvenc_check_codec_support(AVCodecContext *avctx)
Definition: nvenc.c:362
ff_nvenc_hw_configs
const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[]
Definition: nvenc.c:64
MAX_REGISTERED_FRAMES
#define MAX_REGISTERED_FRAMES
Definition: nvenc.h:40
ff_alloc_timecode_sei
int ff_alloc_timecode_sei(const AVFrame *frame, AVRational rate, size_t prefix_len, void **data, size_t *sei_size)
Check AVFrame for S12M timecode side data and allocate and fill TC SEI message with timecode info.
Definition: utils.c:1071
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
nvenc_alloc_surface
static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx)
Definition: nvenc.c:1436
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
nvenc_check_device
static av_cold int nvenc_check_device(AVCodecContext *avctx, int idx)
Definition: nvenc.c:532
nvenc_register_frame
static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:1766
AVCodecHWConfigInternal
Definition: hwconfig.h:29
ff_nvenc_receive_packet
int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: nvenc.c:2308
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:368
height
#define height
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
nvenc_override_rate_control
static void nvenc_override_rate_control(AVCodecContext *avctx)
Definition: nvenc.c:827
AVCPBProperties::max_bitrate
int max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition: avcodec.h:459
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:375
AV_PIX_FMT_D3D11
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:313
get_free_frame
static NvencSurface * get_free_frame(NvencContext *ctx)
Definition: nvenc.c:1690
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
AVCodecContext::b_quant_factor
float b_quant_factor
qscale factor between IP and B-frames If > 0 then the last P-frame quantizer will be used (q= lastp_q...
Definition: avcodec.h:805
AVCodec::id
enum AVCodecID id
Definition: codec.h:211
nvenc_open_session
static av_cold int nvenc_open_session(AVCodecContext *avctx)
Definition: nvenc.c:336
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:99
convert_header.minor
int minor
Definition: convert_header.py:26
i
int i
Definition: input.c:407
LIST_DEVICES
@ LIST_DEVICES
Definition: nvenc.h:142
NVENC_LOWLATENCY
@ NVENC_LOWLATENCY
Definition: nvenc.h:133
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:362
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:637
process_output_surface
static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSurface *tmpoutsurf)
Definition: nvenc.c:1943
nvenc_load_libraries
static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
Definition: nvenc.c:269
nvenc_recalc_surfaces
static av_cold int nvenc_recalc_surfaces(AVCodecContext *avctx)
Definition: nvenc.c:858
AVD3D11VADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_d3d11va.h:45
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:664
uint8_t
uint8_t
Definition: audio_convert.c:194
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:554
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
AVCodecContext::hw_device_ctx
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition: avcodec.h:2270
IS_YUV444
#define IS_YUV444(pix_fmt)
Definition: nvenc.c:79
P2
#define P2
Definition: cavsdsp.c:38
IS_CBR
#define IS_CBR(rc)
Definition: nvenc.c:42
AVCodecContext::height
int height
Definition: avcodec.h:709
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
CHECK_CU
#define CHECK_CU(x)
Definition: nvenc.c:39
nvenc_map_buffer_format
static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt)
Definition: nvenc.c:1411
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:449
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:2218
NvencSurface::width
int width
Definition: nvenc.h:78
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
AVCUDADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_cuda.h:42
ret
ret
Definition: filter_design.txt:187
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:188
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:79
nvenc_setup_encoder
static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
Definition: nvenc.c:1255
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
averr
int averr
Definition: nvenc.c:89
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:376
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:149
cuda_check.h
atsc_a53.h
AVCPBProperties::buffer_size
int buffer_size
The size of the buffer to which the ratecontrol is applied, in bits.
Definition: avcodec.h:486
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: avcodec.h:215
nvenc_codec_specific_pic_params
static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, NV_ENC_PIC_PARAMS *params, NV_ENC_SEI_PAYLOAD *sei_data, int sei_count)
Definition: nvenc.c:1882
AVCodecContext::coded_frame
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:1764
AVCodecContext
main external API structure.
Definition: avcodec.h:536
av_image_copy
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:422
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:276
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:82
NvencSurface::height
int height
Definition: nvenc.h:79
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1380
AVRational::den
int den
Denominator.
Definition: rational.h:60
timestamp_queue_dequeue
static int64_t timestamp_queue_dequeue(AVFifoBuffer *queue)
Definition: nvenc.c:1920
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
dummy
int dummy
Definition: motion.c:64
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1858
nvenc_setup_surfaces
static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx)
Definition: nvenc.c:1492
NVENC_ONE_PASS
@ NVENC_ONE_PASS
Definition: nvenc.h:135
AVCodecContext::i_quant_offset
float i_quant_offset
qscale offset between P and I-frames
Definition: avcodec.h:848
NVENC_TWO_PASSES
@ NVENC_TWO_PASSES
Definition: nvenc.h:136
AV_CODEC_ID_H265
#define AV_CODEC_ID_H265
Definition: codec_id.h:224
NvencSurface::output_surface
NV_ENC_OUTPUT_PTR output_surface
Definition: nvenc.h:82
nvenc_find_free_reg_resource
static int nvenc_find_free_reg_resource(AVCodecContext *avctx)
Definition: nvenc.c:1732
FF_PROFILE_H264_MAIN
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1899
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
nvenc_errors
static const struct @102 nvenc_errors[]
NV_ENC_HEVC_PROFILE_REXT
@ NV_ENC_HEVC_PROFILE_REXT
Definition: nvenc.h:129
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:448
AVCodecInternal::draining
int draining
checks API usage: after codec draining, flush is required to resume operation
Definition: internal.h:180
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:83
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
NvencDynLoadFunctions::nvenc_funcs
NV_ENCODE_API_FUNCTION_LIST nvenc_funcs
Definition: nvenc.h:91
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
mem.h
AVCodecContext::max_b_frames
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:796
ff_encode_get_frame
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition: encode.c:160
packet_internal.h
av_fifo_size
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
Definition: fifo.c:77
av_fifo_freep
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
Definition: fifo.c:63
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
DEFAULT
#define DEFAULT
Definition: avdct.c:28
AVPacket
This structure stores compressed data.
Definition: packet.h:346
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:563
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_PICTURE_TYPE_BI
@ AV_PICTURE_TYPE_BI
BI type.
Definition: avutil.h:280
nvenc_setup_device
static av_cold int nvenc_setup_device(AVCodecContext *avctx)
Definition: nvenc.c:607
NV_ENC_H264_PROFILE_MAIN
@ NV_ENC_H264_PROFILE_MAIN
Definition: nvenc.h:121
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:709
av_fifo_alloc
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
hwcontext.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
nvenc_setup_codec_config
static av_cold int nvenc_setup_codec_config(AVCodecContext *avctx)
Definition: nvenc.c:1228
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:227
int
int
Definition: ffmpeg_filter.c:158
hevc_sei.h
AVCodecContext::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition: avcodec.h:915
nvenc_setup_hevc_config
static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
Definition: nvenc.c:1139
RC_MODE_DEPRECATED
#define RC_MODE_DEPRECATED
Definition: nvenc.h:41
nvenc_send_frame
static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2174
NVENC_LOSSLESS
@ NVENC_LOSSLESS
Definition: nvenc.h:134
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2489