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),
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  av_freep(&ctx->sei_data);
1614 
1615  if (ctx->nvencoder) {
1616  p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
1617 
1618  res = nvenc_pop_context(avctx);
1619  if (res < 0)
1620  return res;
1621  }
1622  ctx->nvencoder = NULL;
1623 
1624  if (ctx->cu_context_internal)
1625  CHECK_CU(dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal));
1626  ctx->cu_context = ctx->cu_context_internal = NULL;
1627 
1628 #if CONFIG_D3D11VA
1629  if (ctx->d3d11_device) {
1630  ID3D11Device_Release(ctx->d3d11_device);
1631  ctx->d3d11_device = NULL;
1632  }
1633 #endif
1634 
1635  nvenc_free_functions(&dl_fn->nvenc_dl);
1636  cuda_free_functions(&dl_fn->cuda_dl);
1637 
1638  dl_fn->nvenc_device_count = 0;
1639 
1640  av_log(avctx, AV_LOG_VERBOSE, "Nvenc unloaded\n");
1641 
1642  return 0;
1643 }
1644 
1646 {
1647  NvencContext *ctx = avctx->priv_data;
1648  int ret;
1649 
1650  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1651  AVHWFramesContext *frames_ctx;
1652  if (!avctx->hw_frames_ctx) {
1653  av_log(avctx, AV_LOG_ERROR,
1654  "hw_frames_ctx must be set when using GPU frames as input\n");
1655  return AVERROR(EINVAL);
1656  }
1657  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1658  if (frames_ctx->format != avctx->pix_fmt) {
1659  av_log(avctx, AV_LOG_ERROR,
1660  "hw_frames_ctx must match the GPU frame type\n");
1661  return AVERROR(EINVAL);
1662  }
1663  ctx->data_pix_fmt = frames_ctx->sw_format;
1664  } else {
1665  ctx->data_pix_fmt = avctx->pix_fmt;
1666  }
1667 
1668  ctx->frame = av_frame_alloc();
1669  if (!ctx->frame)
1670  return AVERROR(ENOMEM);
1671 
1672  if ((ret = nvenc_load_libraries(avctx)) < 0)
1673  return ret;
1674 
1675  if ((ret = nvenc_setup_device(avctx)) < 0)
1676  return ret;
1677 
1678  if ((ret = nvenc_setup_encoder(avctx)) < 0)
1679  return ret;
1680 
1681  if ((ret = nvenc_setup_surfaces(avctx)) < 0)
1682  return ret;
1683 
1684  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1685  if ((ret = nvenc_setup_extradata(avctx)) < 0)
1686  return ret;
1687  }
1688 
1689  return 0;
1690 }
1691 
1693 {
1694  NvencSurface *tmp_surf;
1695 
1696  if (!(av_fifo_size(ctx->unused_surface_queue) > 0))
1697  // queue empty
1698  return NULL;
1699 
1700  av_fifo_generic_read(ctx->unused_surface_queue, &tmp_surf, sizeof(tmp_surf), NULL);
1701  return tmp_surf;
1702 }
1703 
1704 static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *nv_surface,
1705  NV_ENC_LOCK_INPUT_BUFFER *lock_buffer_params, const AVFrame *frame)
1706 {
1707  int dst_linesize[4] = {
1708  lock_buffer_params->pitch,
1709  lock_buffer_params->pitch,
1710  lock_buffer_params->pitch,
1711  lock_buffer_params->pitch
1712  };
1713  uint8_t *dst_data[4];
1714  int ret;
1715 
1716  if (frame->format == AV_PIX_FMT_YUV420P)
1717  dst_linesize[1] = dst_linesize[2] >>= 1;
1718 
1719  ret = av_image_fill_pointers(dst_data, frame->format, nv_surface->height,
1720  lock_buffer_params->bufferDataPtr, dst_linesize);
1721  if (ret < 0)
1722  return ret;
1723 
1724  if (frame->format == AV_PIX_FMT_YUV420P)
1725  FFSWAP(uint8_t*, dst_data[1], dst_data[2]);
1726 
1727  av_image_copy(dst_data, dst_linesize,
1728  (const uint8_t**)frame->data, frame->linesize, frame->format,
1729  avctx->width, avctx->height);
1730 
1731  return 0;
1732 }
1733 
1735 {
1736  NvencContext *ctx = avctx->priv_data;
1737  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1738  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1739  NVENCSTATUS nv_status;
1740 
1741  int i, first_round;
1742 
1743  if (ctx->nb_registered_frames == FF_ARRAY_ELEMS(ctx->registered_frames)) {
1744  for (first_round = 1; first_round >= 0; first_round--) {
1745  for (i = 0; i < ctx->nb_registered_frames; i++) {
1746  if (!ctx->registered_frames[i].mapped) {
1747  if (ctx->registered_frames[i].regptr) {
1748  if (first_round)
1749  continue;
1750  nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr);
1751  if (nv_status != NV_ENC_SUCCESS)
1752  return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource");
1753  ctx->registered_frames[i].ptr = NULL;
1754  ctx->registered_frames[i].regptr = NULL;
1755  }
1756  return i;
1757  }
1758  }
1759  }
1760  } else {
1761  return ctx->nb_registered_frames++;
1762  }
1763 
1764  av_log(avctx, AV_LOG_ERROR, "Too many registered CUDA frames\n");
1765  return AVERROR(ENOMEM);
1766 }
1767 
1769 {
1770  NvencContext *ctx = avctx->priv_data;
1771  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1772  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1773 
1774  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
1775  NV_ENC_REGISTER_RESOURCE reg;
1776  int i, idx, ret;
1777 
1778  for (i = 0; i < ctx->nb_registered_frames; i++) {
1779  if (avctx->pix_fmt == AV_PIX_FMT_CUDA && ctx->registered_frames[i].ptr == frame->data[0])
1780  return i;
1781  else if (avctx->pix_fmt == AV_PIX_FMT_D3D11 && ctx->registered_frames[i].ptr == frame->data[0] && ctx->registered_frames[i].ptr_index == (intptr_t)frame->data[1])
1782  return i;
1783  }
1784 
1785  idx = nvenc_find_free_reg_resource(avctx);
1786  if (idx < 0)
1787  return idx;
1788 
1789  reg.version = NV_ENC_REGISTER_RESOURCE_VER;
1790  reg.width = frames_ctx->width;
1791  reg.height = frames_ctx->height;
1792  reg.pitch = frame->linesize[0];
1793  reg.resourceToRegister = frame->data[0];
1794 
1795  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
1796  reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR;
1797  }
1798  else if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1799  reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
1800  reg.subResourceIndex = (intptr_t)frame->data[1];
1801  }
1802 
1803  reg.bufferFormat = nvenc_map_buffer_format(frames_ctx->sw_format);
1804  if (reg.bufferFormat == NV_ENC_BUFFER_FORMAT_UNDEFINED) {
1805  av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n",
1806  av_get_pix_fmt_name(frames_ctx->sw_format));
1807  return AVERROR(EINVAL);
1808  }
1809 
1810  ret = p_nvenc->nvEncRegisterResource(ctx->nvencoder, &reg);
1811  if (ret != NV_ENC_SUCCESS) {
1812  nvenc_print_error(avctx, ret, "Error registering an input resource");
1813  return AVERROR_UNKNOWN;
1814  }
1815 
1816  ctx->registered_frames[idx].ptr = frame->data[0];
1817  ctx->registered_frames[idx].ptr_index = reg.subResourceIndex;
1818  ctx->registered_frames[idx].regptr = reg.registeredResource;
1819  return idx;
1820 }
1821 
1823  NvencSurface *nvenc_frame)
1824 {
1825  NvencContext *ctx = avctx->priv_data;
1826  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1827  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1828 
1829  int res;
1830  NVENCSTATUS nv_status;
1831 
1832  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1833  int reg_idx = nvenc_register_frame(avctx, frame);
1834  if (reg_idx < 0) {
1835  av_log(avctx, AV_LOG_ERROR, "Could not register an input HW frame\n");
1836  return reg_idx;
1837  }
1838 
1839  res = av_frame_ref(nvenc_frame->in_ref, frame);
1840  if (res < 0)
1841  return res;
1842 
1843  if (!ctx->registered_frames[reg_idx].mapped) {
1844  ctx->registered_frames[reg_idx].in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER;
1845  ctx->registered_frames[reg_idx].in_map.registeredResource = ctx->registered_frames[reg_idx].regptr;
1846  nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, &ctx->registered_frames[reg_idx].in_map);
1847  if (nv_status != NV_ENC_SUCCESS) {
1848  av_frame_unref(nvenc_frame->in_ref);
1849  return nvenc_print_error(avctx, nv_status, "Error mapping an input resource");
1850  }
1851  }
1852 
1853  ctx->registered_frames[reg_idx].mapped += 1;
1854 
1855  nvenc_frame->reg_idx = reg_idx;
1856  nvenc_frame->input_surface = ctx->registered_frames[reg_idx].in_map.mappedResource;
1857  nvenc_frame->format = ctx->registered_frames[reg_idx].in_map.mappedBufferFmt;
1858  nvenc_frame->pitch = frame->linesize[0];
1859 
1860  return 0;
1861  } else {
1862  NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };
1863 
1864  lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;
1865  lockBufferParams.inputBuffer = nvenc_frame->input_surface;
1866 
1867  nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);
1868  if (nv_status != NV_ENC_SUCCESS) {
1869  return nvenc_print_error(avctx, nv_status, "Failed locking nvenc input buffer");
1870  }
1871 
1872  nvenc_frame->pitch = lockBufferParams.pitch;
1873  res = nvenc_copy_frame(avctx, nvenc_frame, &lockBufferParams, frame);
1874 
1875  nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, nvenc_frame->input_surface);
1876  if (nv_status != NV_ENC_SUCCESS) {
1877  return nvenc_print_error(avctx, nv_status, "Failed unlocking input buffer!");
1878  }
1879 
1880  return res;
1881  }
1882 }
1883 
1885  NV_ENC_PIC_PARAMS *params,
1886  NV_ENC_SEI_PAYLOAD *sei_data,
1887  int sei_count)
1888 {
1889  NvencContext *ctx = avctx->priv_data;
1890 
1891  switch (avctx->codec->id) {
1892  case AV_CODEC_ID_H264:
1893  params->codecPicParams.h264PicParams.sliceMode =
1894  ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
1895  params->codecPicParams.h264PicParams.sliceModeData =
1896  ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
1897  if (sei_count > 0) {
1898  params->codecPicParams.h264PicParams.seiPayloadArray = sei_data;
1899  params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count;
1900  }
1901 
1902  break;
1903  case AV_CODEC_ID_HEVC:
1904  params->codecPicParams.hevcPicParams.sliceMode =
1905  ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
1906  params->codecPicParams.hevcPicParams.sliceModeData =
1907  ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
1908  if (sei_count > 0) {
1909  params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data;
1910  params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = sei_count;
1911  }
1912 
1913  break;
1914  }
1915 }
1916 
1917 static inline void timestamp_queue_enqueue(AVFifoBuffer* queue, int64_t timestamp)
1918 {
1919  av_fifo_generic_write(queue, &timestamp, sizeof(timestamp), NULL);
1920 }
1921 
1922 static inline int64_t timestamp_queue_dequeue(AVFifoBuffer* queue)
1923 {
1924  int64_t timestamp = AV_NOPTS_VALUE;
1925  if (av_fifo_size(queue) > 0)
1926  av_fifo_generic_read(queue, &timestamp, sizeof(timestamp), NULL);
1927 
1928  return timestamp;
1929 }
1930 
1932  NV_ENC_LOCK_BITSTREAM *params,
1933  AVPacket *pkt)
1934 {
1935  NvencContext *ctx = avctx->priv_data;
1936 
1937  pkt->pts = params->outputTimeStamp;
1938  pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
1939 
1940  pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1);
1941 
1942  return 0;
1943 }
1944 
1946 {
1947  NvencContext *ctx = avctx->priv_data;
1948  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1949  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1950 
1951  uint32_t slice_mode_data;
1952  uint32_t *slice_offsets = NULL;
1953  NV_ENC_LOCK_BITSTREAM lock_params = { 0 };
1954  NVENCSTATUS nv_status;
1955  int res = 0;
1956 
1957  enum AVPictureType pict_type;
1958 
1959  switch (avctx->codec->id) {
1960  case AV_CODEC_ID_H264:
1961  slice_mode_data = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
1962  break;
1963  case AV_CODEC_ID_H265:
1964  slice_mode_data = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
1965  break;
1966  default:
1967  av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");
1968  res = AVERROR(EINVAL);
1969  goto error;
1970  }
1971  slice_offsets = av_mallocz(slice_mode_data * sizeof(*slice_offsets));
1972 
1973  if (!slice_offsets) {
1974  res = AVERROR(ENOMEM);
1975  goto error;
1976  }
1977 
1978  lock_params.version = NV_ENC_LOCK_BITSTREAM_VER;
1979 
1980  lock_params.doNotWait = 0;
1981  lock_params.outputBitstream = tmpoutsurf->output_surface;
1982  lock_params.sliceOffsets = slice_offsets;
1983 
1984  nv_status = p_nvenc->nvEncLockBitstream(ctx->nvencoder, &lock_params);
1985  if (nv_status != NV_ENC_SUCCESS) {
1986  res = nvenc_print_error(avctx, nv_status, "Failed locking bitstream buffer");
1987  goto error;
1988  }
1989 
1990  res = ff_get_encode_buffer(avctx, pkt, lock_params.bitstreamSizeInBytes, 0);
1991 
1992  if (res < 0) {
1993  p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
1994  goto error;
1995  }
1996 
1997  memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes);
1998 
1999  nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
2000  if (nv_status != NV_ENC_SUCCESS) {
2001  res = nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open");
2002  goto error;
2003  }
2004 
2005 
2006  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
2007  ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1;
2008  if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) {
2009  nv_status = p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource);
2010  if (nv_status != NV_ENC_SUCCESS) {
2011  res = nvenc_print_error(avctx, nv_status, "Failed unmapping input resource");
2012  goto error;
2013  }
2014  } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) {
2015  res = AVERROR_BUG;
2016  goto error;
2017  }
2018 
2019  av_frame_unref(tmpoutsurf->in_ref);
2020 
2021  tmpoutsurf->input_surface = NULL;
2022  }
2023 
2024  switch (lock_params.pictureType) {
2025  case NV_ENC_PIC_TYPE_IDR:
2027  case NV_ENC_PIC_TYPE_I:
2028  pict_type = AV_PICTURE_TYPE_I;
2029  break;
2030  case NV_ENC_PIC_TYPE_P:
2031  pict_type = AV_PICTURE_TYPE_P;
2032  break;
2033  case NV_ENC_PIC_TYPE_B:
2034  pict_type = AV_PICTURE_TYPE_B;
2035  break;
2036  case NV_ENC_PIC_TYPE_BI:
2037  pict_type = AV_PICTURE_TYPE_BI;
2038  break;
2039  default:
2040  av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered, expect the output to be broken.\n");
2041  av_log(avctx, AV_LOG_ERROR, "Please report this error and include as much information on how to reproduce it as possible.\n");
2042  res = AVERROR_EXTERNAL;
2043  goto error;
2044  }
2045 
2047  (lock_params.frameAvgQP - 1) * FF_QP2LAMBDA, NULL, 0, pict_type);
2048 
2049  res = nvenc_set_timestamp(avctx, &lock_params, pkt);
2050  if (res < 0)
2051  goto error2;
2052 
2053  av_free(slice_offsets);
2054 
2055  return 0;
2056 
2057 error:
2058  timestamp_queue_dequeue(ctx->timestamp_list);
2059 
2060 error2:
2061  av_free(slice_offsets);
2062 
2063  return res;
2064 }
2065 
2066 static int output_ready(AVCodecContext *avctx, int flush)
2067 {
2068  NvencContext *ctx = avctx->priv_data;
2069  int nb_ready, nb_pending;
2070 
2071  nb_ready = av_fifo_size(ctx->output_surface_ready_queue) / sizeof(NvencSurface*);
2072  nb_pending = av_fifo_size(ctx->output_surface_queue) / sizeof(NvencSurface*);
2073  if (flush)
2074  return nb_ready > 0;
2075  return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth);
2076 }
2077 
2079 {
2080  NvencContext *ctx = avctx->priv_data;
2081  int sei_count = 0;
2082  int i, res;
2083 
2085  void *a53_data = NULL;
2086  size_t a53_size = 0;
2087 
2088  if (ff_alloc_a53_sei(frame, 0, &a53_data, &a53_size) < 0) {
2089  av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2090  }
2091 
2092  if (a53_data) {
2093  void *tmp = av_fast_realloc(ctx->sei_data,
2094  &ctx->sei_data_size,
2095  (sei_count + 1) * sizeof(*ctx->sei_data));
2096  if (!tmp) {
2097  av_free(a53_data);
2098  res = AVERROR(ENOMEM);
2099  goto error;
2100  } else {
2101  ctx->sei_data = tmp;
2102  ctx->sei_data[sei_count].payloadSize = (uint32_t)a53_size;
2103  ctx->sei_data[sei_count].payloadType = 4;
2104  ctx->sei_data[sei_count].payload = (uint8_t*)a53_data;
2105  sei_count++;
2106  }
2107  }
2108  }
2109 
2111  void *tc_data = NULL;
2112  size_t tc_size = 0;
2113 
2114  if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, &tc_data, &tc_size) < 0) {
2115  av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n");
2116  }
2117 
2118  if (tc_data) {
2119  void *tmp = av_fast_realloc(ctx->sei_data,
2120  &ctx->sei_data_size,
2121  (sei_count + 1) * sizeof(*ctx->sei_data));
2122  if (!tmp) {
2123  av_free(tc_data);
2124  res = AVERROR(ENOMEM);
2125  goto error;
2126  } else {
2127  ctx->sei_data = tmp;
2128  ctx->sei_data[sei_count].payloadSize = (uint32_t)tc_size;
2129  ctx->sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
2130  ctx->sei_data[sei_count].payload = (uint8_t*)tc_data;
2131  sei_count++;
2132  }
2133  }
2134  }
2135 
2136  for (i = 0; i < frame->nb_side_data; i++) {
2137  AVFrameSideData *side_data = frame->side_data[i];
2138  void *tmp;
2139 
2140  if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
2141  continue;
2142 
2143  tmp = av_fast_realloc(ctx->sei_data,
2144  &ctx->sei_data_size,
2145  (sei_count + 1) * sizeof(*ctx->sei_data));
2146  if (!tmp) {
2147  res = AVERROR(ENOMEM);
2148  goto error;
2149  } else {
2150  ctx->sei_data = tmp;
2151  ctx->sei_data[sei_count].payloadSize = side_data->size;
2152  ctx->sei_data[sei_count].payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
2153  ctx->sei_data[sei_count].payload = av_memdup(side_data->data, side_data->size);
2154 
2155  if (!ctx->sei_data[sei_count].payload) {
2156  res = AVERROR(ENOMEM);
2157  goto error;
2158  }
2159 
2160  sei_count++;
2161  }
2162  }
2163 
2164  return sei_count;
2165 
2166 error:
2167  for (i = 0; i < sei_count; i++)
2168  av_freep(&(ctx->sei_data[i].payload));
2169 
2170  return res;
2171 }
2172 
2173 static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
2174 {
2175  NvencContext *ctx = avctx->priv_data;
2176  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
2177  NVENCSTATUS ret;
2178 
2179  NV_ENC_RECONFIGURE_PARAMS params = { 0 };
2180  int needs_reconfig = 0;
2181  int needs_encode_config = 0;
2182  int reconfig_bitrate = 0, reconfig_dar = 0;
2183  int dw, dh;
2184 
2185  params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
2186  params.reInitEncodeParams = ctx->init_encode_params;
2187 
2188  compute_dar(avctx, &dw, &dh);
2189  if (dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight) {
2190  av_log(avctx, AV_LOG_VERBOSE,
2191  "aspect ratio change (DAR): %d:%d -> %d:%d\n",
2192  ctx->init_encode_params.darWidth,
2193  ctx->init_encode_params.darHeight, dw, dh);
2194 
2195  params.reInitEncodeParams.darHeight = dh;
2196  params.reInitEncodeParams.darWidth = dw;
2197 
2198  needs_reconfig = 1;
2199  reconfig_dar = 1;
2200  }
2201 
2202  if (ctx->rc != NV_ENC_PARAMS_RC_CONSTQP && ctx->support_dyn_bitrate) {
2203  if (avctx->bit_rate > 0 && params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate != avctx->bit_rate) {
2204  av_log(avctx, AV_LOG_VERBOSE,
2205  "avg bitrate change: %d -> %d\n",
2206  params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate,
2207  (uint32_t)avctx->bit_rate);
2208 
2209  params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate = avctx->bit_rate;
2210  reconfig_bitrate = 1;
2211  }
2212 
2213  if (avctx->rc_max_rate > 0 && ctx->encode_config.rcParams.maxBitRate != avctx->rc_max_rate) {
2214  av_log(avctx, AV_LOG_VERBOSE,
2215  "max bitrate change: %d -> %d\n",
2216  params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate,
2217  (uint32_t)avctx->rc_max_rate);
2218 
2219  params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate = avctx->rc_max_rate;
2220  reconfig_bitrate = 1;
2221  }
2222 
2223  if (avctx->rc_buffer_size > 0 && ctx->encode_config.rcParams.vbvBufferSize != avctx->rc_buffer_size) {
2224  av_log(avctx, AV_LOG_VERBOSE,
2225  "vbv buffer size change: %d -> %d\n",
2226  params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize,
2227  avctx->rc_buffer_size);
2228 
2229  params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize = avctx->rc_buffer_size;
2230  reconfig_bitrate = 1;
2231  }
2232 
2233  if (reconfig_bitrate) {
2234  params.resetEncoder = 1;
2235  params.forceIDR = 1;
2236 
2237  needs_encode_config = 1;
2238  needs_reconfig = 1;
2239  }
2240  }
2241 
2242  if (!needs_encode_config)
2243  params.reInitEncodeParams.encodeConfig = NULL;
2244 
2245  if (needs_reconfig) {
2246  ret = p_nvenc->nvEncReconfigureEncoder(ctx->nvencoder, &params);
2247  if (ret != NV_ENC_SUCCESS) {
2248  nvenc_print_error(avctx, ret, "failed to reconfigure nvenc");
2249  } else {
2250  if (reconfig_dar) {
2251  ctx->init_encode_params.darHeight = dh;
2252  ctx->init_encode_params.darWidth = dw;
2253  }
2254 
2255  if (reconfig_bitrate) {
2256  ctx->encode_config.rcParams.averageBitRate = params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate;
2257  ctx->encode_config.rcParams.maxBitRate = params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate;
2258  ctx->encode_config.rcParams.vbvBufferSize = params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize;
2259  }
2260 
2261  }
2262  }
2263 }
2264 
2265 static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
2266 {
2267  NVENCSTATUS nv_status;
2268  NvencSurface *tmp_out_surf, *in_surf;
2269  int res, res2;
2270  int sei_count = 0;
2271  int i;
2272 
2273  NvencContext *ctx = avctx->priv_data;
2274  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2275  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2276 
2277  NV_ENC_PIC_PARAMS pic_params = { 0 };
2278  pic_params.version = NV_ENC_PIC_PARAMS_VER;
2279 
2280  if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2281  return AVERROR(EINVAL);
2282 
2283  if (frame && frame->buf[0]) {
2284  in_surf = get_free_frame(ctx);
2285  if (!in_surf)
2286  return AVERROR(EAGAIN);
2287 
2288  res = nvenc_push_context(avctx);
2289  if (res < 0)
2290  return res;
2291 
2292  reconfig_encoder(avctx, frame);
2293 
2294  res = nvenc_upload_frame(avctx, frame, in_surf);
2295 
2296  res2 = nvenc_pop_context(avctx);
2297  if (res2 < 0)
2298  return res2;
2299 
2300  if (res)
2301  return res;
2302 
2303  pic_params.inputBuffer = in_surf->input_surface;
2304  pic_params.bufferFmt = in_surf->format;
2305  pic_params.inputWidth = in_surf->width;
2306  pic_params.inputHeight = in_surf->height;
2307  pic_params.inputPitch = in_surf->pitch;
2308  pic_params.outputBitstream = in_surf->output_surface;
2309 
2310  if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
2311  if (frame->top_field_first)
2312  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;
2313  else
2314  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;
2315  } else {
2316  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
2317  }
2318 
2319  if (ctx->forced_idr >= 0 && frame->pict_type == AV_PICTURE_TYPE_I) {
2320  pic_params.encodePicFlags =
2321  ctx->forced_idr ? NV_ENC_PIC_FLAG_FORCEIDR : NV_ENC_PIC_FLAG_FORCEINTRA;
2322  } else {
2323  pic_params.encodePicFlags = 0;
2324  }
2325 
2326  pic_params.inputTimeStamp = frame->pts;
2327 
2328  if (ctx->extra_sei) {
2329  res = prepare_sei_data_array(avctx, frame);
2330  if (res < 0)
2331  return res;
2332  sei_count = res;
2333  }
2334 
2335  nvenc_codec_specific_pic_params(avctx, &pic_params, ctx->sei_data, sei_count);
2336  } else {
2337  pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
2338  }
2339 
2340  res = nvenc_push_context(avctx);
2341  if (res < 0)
2342  return res;
2343 
2344  nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
2345 
2346  for (i = 0; i < sei_count; i++)
2347  av_freep(&(ctx->sei_data[i].payload));
2348 
2349  res = nvenc_pop_context(avctx);
2350  if (res < 0)
2351  return res;
2352 
2353  if (nv_status != NV_ENC_SUCCESS &&
2354  nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
2355  return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
2356 
2357  if (frame && frame->buf[0]) {
2358  av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL);
2359  timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);
2360  }
2361 
2362  /* all the pending buffers are now ready for output */
2363  if (nv_status == NV_ENC_SUCCESS) {
2364  while (av_fifo_size(ctx->output_surface_queue) > 0) {
2365  av_fifo_generic_read(ctx->output_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2366  av_fifo_generic_write(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2367  }
2368  }
2369 
2370  return 0;
2371 }
2372 
2374 {
2375  NvencSurface *tmp_out_surf;
2376  int res, res2;
2377 
2378  NvencContext *ctx = avctx->priv_data;
2379 
2380  AVFrame *frame = ctx->frame;
2381 
2382  if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2383  return AVERROR(EINVAL);
2384 
2385  if (!frame->buf[0]) {
2386  res = ff_encode_get_frame(avctx, frame);
2387  if (res < 0 && res != AVERROR_EOF)
2388  return res;
2389  }
2390 
2391  res = nvenc_send_frame(avctx, frame);
2392  if (res < 0) {
2393  if (res != AVERROR(EAGAIN))
2394  return res;
2395  } else
2397 
2398  if (output_ready(avctx, avctx->internal->draining)) {
2399  av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2400 
2401  res = nvenc_push_context(avctx);
2402  if (res < 0)
2403  return res;
2404 
2405  res = process_output_surface(avctx, pkt, tmp_out_surf);
2406 
2407  res2 = nvenc_pop_context(avctx);
2408  if (res2 < 0)
2409  return res2;
2410 
2411  if (res)
2412  return res;
2413 
2414  av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL);
2415  } else if (avctx->internal->draining) {
2416  return AVERROR_EOF;
2417  } else {
2418  return AVERROR(EAGAIN);
2419  }
2420 
2421  return 0;
2422 }
2423 
2425 {
2426  NvencContext *ctx = avctx->priv_data;
2427 
2428  nvenc_send_frame(avctx, NULL);
2429  av_fifo_reset(ctx->timestamp_list);
2430 }
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:1605
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:187
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:225
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:949
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:616
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:586
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:92
FF_PROFILE_H264_BASELINE
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:1553
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:2066
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:151
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:111
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:27
pixdesc.h
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:942
nvenc_set_timestamp
static int nvenc_set_timestamp(AVCodecContext *avctx, NV_ENC_LOCK_BITSTREAM *params, AVPacket *pkt)
Definition: nvenc.c:1931
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:576
P1
#define P1
Definition: cavsdsp.c:39
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:365
encode.h
AVCodecContext::b_quant_offset
float b_quant_offset
qscale offset between IP and B-frames
Definition: avcodec.h:660
FF_PROFILE_H264_HIGH_444_PREDICTIVE
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: avcodec.h:1565
reconfig_encoder
static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2173
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:197
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:197
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:503
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:1001
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:1154
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:396
ff_nvenc_encode_flush
av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
Definition: nvenc.c:2424
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:269
nvenc.h
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:292
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
SEI_TYPE_USER_DATA_UNREGISTERED
@ SEI_TYPE_USER_DATA_UNREGISTERED
Definition: sei.h:35
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1699
nvenc_upload_frame
static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, NvencSurface *nvenc_frame)
Definition: nvenc.c:1822
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:677
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:393
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:134
NvencSurface::format
NV_ENC_BUFFER_FORMAT format
Definition: nvenc.h:83
AVCodecContext::refs
int refs
number of reference frames
Definition: avcodec.h:921
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:464
FF_PROFILE_H264_HIGH
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1557
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:1704
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:145
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:261
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:98
avassert.h
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:935
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:181
AVFrameSideData::size
size_t size
Definition: frame.h:212
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:1602
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:486
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:668
ff_nvenc_encode_init
av_cold int ff_nvenc_encode_init(AVCodecContext *avctx)
Definition: nvenc.c:1645
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:485
width
#define width
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:450
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:402
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1215
AV_PIX_FMT_0BGR32
#define AV_PIX_FMT_0BGR32
Definition: pixfmt.h:367
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:516
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:41
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:1917
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:1183
NvencDynLoadFunctions::nvenc_dl
NvencFunctions * nvenc_dl
Definition: nvenc.h:89
AVCPBProperties
This structure describes the bitrate properties of an encoded bitstream.
Definition: defs.h:104
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
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:1168
NVENC_CAP
#define NVENC_CAP
Definition: nvenc.c:41
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:408
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:956
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:419
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:434
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:1603
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
AV_FRAME_DATA_SEI_UNREGISTERED
@ AV_FRAME_DATA_SEI_UNREGISTERED
User data unregistered metadata associated with a video frame.
Definition: frame.h:177
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:507
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
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:579
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:326
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:1041
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
AVFrameSideData::data
uint8_t * data
Definition: frame.h:211
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:1768
AVCodecHWConfigInternal
Definition: hwconfig.h:29
ff_nvenc_receive_packet
int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: nvenc.c:2373
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:364
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
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:371
AV_PIX_FMT_D3D11
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:303
AVCPBProperties::avg_bitrate
int64_t avg_bitrate
Average bitrate of the stream, in bits per second.
Definition: defs.h:119
get_free_frame
static NvencSurface * get_free_frame(NvencContext *ctx)
Definition: nvenc.c:1692
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:192
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:653
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:358
FAST
@ FAST
Definition: vf_guided.c:32
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:485
process_output_surface
static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSurface *tmpoutsurf)
Definition: nvenc.c:1945
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
AVCPBProperties::max_bitrate
int64_t max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition: defs.h:109
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:224
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:664
prepare_sei_data_array
static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2078
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:436
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:244
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:1895
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:557
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:594
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:439
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:1846
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:175
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:366
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:149
AVCPBProperties::buffer_size
int64_t buffer_size
The size of the buffer to which the ratecontrol is applied, in bits.
Definition: defs.h:125
cuda_check.h
atsc_a53.h
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
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:1884
AVCodecContext
main external API structure.
Definition: avcodec.h:384
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:77
NvencSurface::height
int height
Definition: nvenc.h:79
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1147
AVRational::den
int den
Denominator.
Definition: rational.h:60
timestamp_queue_dequeue
static int64_t timestamp_queue_dequeue(AVFifoBuffer *queue)
Definition: nvenc.c:1922
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:1514
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:684
AVFrameSideData::type
enum AVFrameSideDataType type
Definition: frame.h:210
NVENC_TWO_PASSES
@ NVENC_TWO_PASSES
Definition: nvenc.h:136
AV_CODEC_ID_H265
#define AV_CODEC_ID_H265
Definition: codec_id.h:225
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:1734
FF_PROFILE_H264_MAIN
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1555
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:438
AVCodecInternal::draining
int draining
checks API usage: after codec draining, flush is required to resume operation
Definition: internal.h:187
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
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:644
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:156
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
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:209
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:342
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:411
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:557
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:156
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:742
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:2265
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:2461