FFmpeg
nvenc.c
Go to the documentation of this file.
1 /*
2  * H.264/HEVC/AV1 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 #include "config_components.h"
24 
25 #include "nvenc.h"
26 #include "hevc_sei.h"
27 #if CONFIG_AV1_NVENC_ENCODER
28 #include "av1.h"
29 #endif
30 
32 #include "libavutil/hwcontext.h"
33 #include "libavutil/cuda_check.h"
34 #include "libavutil/imgutils.h"
35 #include "libavutil/mem.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/mathematics.h"
38 #include "atsc_a53.h"
39 #include "codec_desc.h"
40 #include "encode.h"
41 #include "internal.h"
42 #include "packet_internal.h"
43 
44 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, dl_fn->cuda_dl, x)
45 
46 #define NVENC_CAP 0x30
47 
48 #ifndef NVENC_NO_DEPRECATED_RC
49 #define IS_CBR(rc) (rc == NV_ENC_PARAMS_RC_CBR || \
50  rc == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ || \
51  rc == NV_ENC_PARAMS_RC_CBR_HQ)
52 #else
53 #define IS_CBR(rc) (rc == NV_ENC_PARAMS_RC_CBR)
54 #endif
55 
61  AV_PIX_FMT_P016, // Truncated to 10bits
62  AV_PIX_FMT_YUV444P16, // Truncated to 10bits
70  AV_PIX_FMT_GBRP16, // Truncated to 10bits
72 #if CONFIG_D3D11VA
74 #endif
76 };
77 
79  HW_CONFIG_ENCODER_FRAMES(CUDA, CUDA),
81 #if CONFIG_D3D11VA
82  HW_CONFIG_ENCODER_FRAMES(D3D11, D3D11VA),
84 #endif
85  NULL,
86 };
87 
88 #define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \
89  pix_fmt == AV_PIX_FMT_P016 || \
90  pix_fmt == AV_PIX_FMT_YUV444P16 || \
91  pix_fmt == AV_PIX_FMT_X2RGB10 || \
92  pix_fmt == AV_PIX_FMT_X2BGR10 || \
93  pix_fmt == AV_PIX_FMT_GBRP16)
94 
95 #define IS_RGB(pix_fmt) (pix_fmt == AV_PIX_FMT_0RGB32 || \
96  pix_fmt == AV_PIX_FMT_RGB32 || \
97  pix_fmt == AV_PIX_FMT_0BGR32 || \
98  pix_fmt == AV_PIX_FMT_BGR32 || \
99  pix_fmt == AV_PIX_FMT_X2RGB10 || \
100  pix_fmt == AV_PIX_FMT_X2BGR10)
101 
102 #define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \
103  pix_fmt == AV_PIX_FMT_YUV444P16 || \
104  pix_fmt == AV_PIX_FMT_GBRP || \
105  pix_fmt == AV_PIX_FMT_GBRP16 || \
106  (ctx->rgb_mode == NVENC_RGB_MODE_444 && IS_RGB(pix_fmt)))
107 
108 #define IS_GBRP(pix_fmt) (pix_fmt == AV_PIX_FMT_GBRP || \
109  pix_fmt == AV_PIX_FMT_GBRP16)
110 
111 static const struct {
112  NVENCSTATUS nverr;
113  int averr;
114  const char *desc;
115 } nvenc_errors[] = {
116  { NV_ENC_SUCCESS, 0, "success" },
117  { NV_ENC_ERR_NO_ENCODE_DEVICE, AVERROR(ENOENT), "no encode device" },
118  { NV_ENC_ERR_UNSUPPORTED_DEVICE, AVERROR(ENOSYS), "unsupported device" },
119  { NV_ENC_ERR_INVALID_ENCODERDEVICE, AVERROR(EINVAL), "invalid encoder device" },
120  { NV_ENC_ERR_INVALID_DEVICE, AVERROR(EINVAL), "invalid device" },
121  { NV_ENC_ERR_DEVICE_NOT_EXIST, AVERROR(EIO), "device does not exist" },
122  { NV_ENC_ERR_INVALID_PTR, AVERROR(EFAULT), "invalid ptr" },
123  { NV_ENC_ERR_INVALID_EVENT, AVERROR(EINVAL), "invalid event" },
124  { NV_ENC_ERR_INVALID_PARAM, AVERROR(EINVAL), "invalid param" },
125  { NV_ENC_ERR_INVALID_CALL, AVERROR(EINVAL), "invalid call" },
126  { NV_ENC_ERR_OUT_OF_MEMORY, AVERROR(ENOMEM), "out of memory" },
127  { NV_ENC_ERR_ENCODER_NOT_INITIALIZED, AVERROR(EINVAL), "encoder not initialized" },
128  { NV_ENC_ERR_UNSUPPORTED_PARAM, AVERROR(ENOSYS), "unsupported param" },
129  { NV_ENC_ERR_LOCK_BUSY, AVERROR(EAGAIN), "lock busy" },
130  { NV_ENC_ERR_NOT_ENOUGH_BUFFER, AVERROR_BUFFER_TOO_SMALL, "not enough buffer"},
131  { NV_ENC_ERR_INVALID_VERSION, AVERROR(EINVAL), "invalid version" },
132  { NV_ENC_ERR_MAP_FAILED, AVERROR(EIO), "map failed" },
133  { NV_ENC_ERR_NEED_MORE_INPUT, AVERROR(EAGAIN), "need more input" },
134  { NV_ENC_ERR_ENCODER_BUSY, AVERROR(EAGAIN), "encoder busy" },
135  { NV_ENC_ERR_EVENT_NOT_REGISTERD, AVERROR(EBADF), "event not registered" },
136  { NV_ENC_ERR_GENERIC, AVERROR_UNKNOWN, "generic error" },
137  { NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY, AVERROR(EINVAL), "incompatible client key" },
138  { NV_ENC_ERR_UNIMPLEMENTED, AVERROR(ENOSYS), "unimplemented" },
139  { NV_ENC_ERR_RESOURCE_REGISTER_FAILED, AVERROR(EIO), "resource register failed" },
140  { NV_ENC_ERR_RESOURCE_NOT_REGISTERED, AVERROR(EBADF), "resource not registered" },
141  { NV_ENC_ERR_RESOURCE_NOT_MAPPED, AVERROR(EBADF), "resource not mapped" },
142 };
143 
144 static int nvenc_map_error(NVENCSTATUS err, const char **desc)
145 {
146  int i;
147  for (i = 0; i < FF_ARRAY_ELEMS(nvenc_errors); i++) {
148  if (nvenc_errors[i].nverr == err) {
149  if (desc)
150  *desc = nvenc_errors[i].desc;
151  return nvenc_errors[i].averr;
152  }
153  }
154  if (desc)
155  *desc = "unknown error";
156  return AVERROR_UNKNOWN;
157 }
158 
159 static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err,
160  const char *error_string)
161 {
162  const char *desc;
163  const char *details = "(no details)";
164  int ret = nvenc_map_error(err, &desc);
165 
166 #ifdef NVENC_HAVE_GETLASTERRORSTRING
167  NvencContext *ctx = avctx->priv_data;
168  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
169 
170  if (p_nvenc && ctx->nvencoder)
171  details = p_nvenc->nvEncGetLastErrorString(ctx->nvencoder);
172 #endif
173 
174  av_log(avctx, AV_LOG_ERROR, "%s: %s (%d): %s\n", error_string, desc, err, details);
175 
176  return ret;
177 }
178 
179 typedef struct GUIDTuple {
180  const GUID guid;
181  int flags;
182 } GUIDTuple;
183 
184 #define PRESET_ALIAS(alias, name, ...) \
185  [PRESET_ ## alias] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ }
186 
187 #define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__)
188 
190 {
191  GUIDTuple presets[] = {
192 #ifdef NVENC_HAVE_NEW_PRESETS
193  PRESET(P1),
194  PRESET(P2),
195  PRESET(P3),
196  PRESET(P4),
197  PRESET(P5),
198  PRESET(P6),
199  PRESET(P7),
200  PRESET_ALIAS(SLOW, P7, NVENC_TWO_PASSES),
201  PRESET_ALIAS(MEDIUM, P4, NVENC_ONE_PASS),
203  // Compat aliases
208  PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY),
211  PRESET_ALIAS(LOSSLESS_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS),
213 #else
214  PRESET(DEFAULT),
215  PRESET(HP),
216  PRESET(HQ),
217  PRESET(BD),
218  PRESET_ALIAS(SLOW, HQ, NVENC_TWO_PASSES),
219  PRESET_ALIAS(MEDIUM, HQ, NVENC_ONE_PASS),
221  PRESET(LOW_LATENCY_DEFAULT, NVENC_LOWLATENCY),
222  PRESET(LOW_LATENCY_HP, NVENC_LOWLATENCY),
223  PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY),
224  PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS),
225  PRESET(LOSSLESS_HP, NVENC_LOSSLESS),
226 #endif
227  };
228 
229  GUIDTuple *t = &presets[ctx->preset];
230 
231  ctx->init_encode_params.presetGUID = t->guid;
232  ctx->flags = t->flags;
233 
234 #ifdef NVENC_HAVE_NEW_PRESETS
235  if (ctx->tuning_info == NV_ENC_TUNING_INFO_LOSSLESS)
237 #endif
238 }
239 
240 #undef PRESET
241 #undef PRESET_ALIAS
242 
244 {
245 #if NVENCAPI_CHECK_VERSION(12, 1)
246  const char *minver = "(unknown)";
247 #elif NVENCAPI_CHECK_VERSION(12, 0)
248 # if defined(_WIN32) || defined(__CYGWIN__)
249  const char *minver = "522.25";
250 # else
251  const char *minver = "520.56.06";
252 # endif
253 #elif NVENCAPI_CHECK_VERSION(11, 1)
254 # if defined(_WIN32) || defined(__CYGWIN__)
255  const char *minver = "471.41";
256 # else
257  const char *minver = "470.57.02";
258 # endif
259 #elif NVENCAPI_CHECK_VERSION(11, 0)
260 # if defined(_WIN32) || defined(__CYGWIN__)
261  const char *minver = "456.71";
262 # else
263  const char *minver = "455.28";
264 # endif
265 #elif NVENCAPI_CHECK_VERSION(10, 0)
266 # if defined(_WIN32) || defined(__CYGWIN__)
267  const char *minver = "450.51";
268 # else
269  const char *minver = "445.87";
270 # endif
271 #elif NVENCAPI_CHECK_VERSION(9, 1)
272 # if defined(_WIN32) || defined(__CYGWIN__)
273  const char *minver = "436.15";
274 # else
275  const char *minver = "435.21";
276 # endif
277 #elif NVENCAPI_CHECK_VERSION(9, 0)
278 # if defined(_WIN32) || defined(__CYGWIN__)
279  const char *minver = "418.81";
280 # else
281  const char *minver = "418.30";
282 # endif
283 #elif NVENCAPI_CHECK_VERSION(8, 2)
284 # if defined(_WIN32) || defined(__CYGWIN__)
285  const char *minver = "397.93";
286 # else
287  const char *minver = "396.24";
288 #endif
289 #elif NVENCAPI_CHECK_VERSION(8, 1)
290 # if defined(_WIN32) || defined(__CYGWIN__)
291  const char *minver = "390.77";
292 # else
293  const char *minver = "390.25";
294 # endif
295 #else
296 # if defined(_WIN32) || defined(__CYGWIN__)
297  const char *minver = "378.66";
298 # else
299  const char *minver = "378.13";
300 # endif
301 #endif
302  av_log(avctx, level, "The minimum required Nvidia driver for nvenc is %s or newer\n", minver);
303 }
304 
306 {
307  NvencContext *ctx = avctx->priv_data;
308  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
309  NVENCSTATUS err;
310  uint32_t nvenc_max_ver;
311  int ret;
312 
313  ret = cuda_load_functions(&dl_fn->cuda_dl, avctx);
314  if (ret < 0)
315  return ret;
316 
317  ret = nvenc_load_functions(&dl_fn->nvenc_dl, avctx);
318  if (ret < 0) {
320  return ret;
321  }
322 
323  err = dl_fn->nvenc_dl->NvEncodeAPIGetMaxSupportedVersion(&nvenc_max_ver);
324  if (err != NV_ENC_SUCCESS)
325  return nvenc_print_error(avctx, err, "Failed to query nvenc max version");
326 
327  av_log(avctx, AV_LOG_VERBOSE, "Loaded Nvenc version %d.%d\n", nvenc_max_ver >> 4, nvenc_max_ver & 0xf);
328 
329  if ((NVENCAPI_MAJOR_VERSION << 4 | NVENCAPI_MINOR_VERSION) > nvenc_max_ver) {
330  av_log(avctx, AV_LOG_ERROR, "Driver does not support the required nvenc API version. "
331  "Required: %d.%d Found: %d.%d\n",
332  NVENCAPI_MAJOR_VERSION, NVENCAPI_MINOR_VERSION,
333  nvenc_max_ver >> 4, nvenc_max_ver & 0xf);
335  return AVERROR(ENOSYS);
336  }
337 
338  dl_fn->nvenc_funcs.version = NV_ENCODE_API_FUNCTION_LIST_VER;
339 
340  err = dl_fn->nvenc_dl->NvEncodeAPICreateInstance(&dl_fn->nvenc_funcs);
341  if (err != NV_ENC_SUCCESS)
342  return nvenc_print_error(avctx, err, "Failed to create nvenc instance");
343 
344  av_log(avctx, AV_LOG_VERBOSE, "Nvenc initialized successfully\n");
345 
346  return 0;
347 }
348 
350 {
351  NvencContext *ctx = avctx->priv_data;
352  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
353 
354  if (ctx->d3d11_device)
355  return 0;
356 
357  return CHECK_CU(dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context));
358 }
359 
361 {
362  NvencContext *ctx = avctx->priv_data;
363  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
364  CUcontext dummy;
365 
366  if (ctx->d3d11_device)
367  return 0;
368 
369  return CHECK_CU(dl_fn->cuda_dl->cuCtxPopCurrent(&dummy));
370 }
371 
373 {
374  NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = { 0 };
375  NvencContext *ctx = avctx->priv_data;
376  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
377  NVENCSTATUS ret;
378 
379  params.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
380  params.apiVersion = NVENCAPI_VERSION;
381  if (ctx->d3d11_device) {
382  params.device = ctx->d3d11_device;
383  params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
384  } else {
385  params.device = ctx->cu_context;
386  params.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
387  }
388 
389  ret = p_nvenc->nvEncOpenEncodeSessionEx(&params, &ctx->nvencoder);
390  if (ret != NV_ENC_SUCCESS) {
391  ctx->nvencoder = NULL;
392  return nvenc_print_error(avctx, ret, "OpenEncodeSessionEx failed");
393  }
394 
395  return 0;
396 }
397 
399 {
400  NvencContext *ctx = avctx->priv_data;
401  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
402  int i, ret, count = 0;
403  GUID *guids = NULL;
404 
405  ret = p_nvenc->nvEncGetEncodeGUIDCount(ctx->nvencoder, &count);
406 
407  if (ret != NV_ENC_SUCCESS || !count)
408  return AVERROR(ENOSYS);
409 
410  guids = av_malloc(count * sizeof(GUID));
411  if (!guids)
412  return AVERROR(ENOMEM);
413 
414  ret = p_nvenc->nvEncGetEncodeGUIDs(ctx->nvencoder, guids, count, &count);
415  if (ret != NV_ENC_SUCCESS) {
416  ret = AVERROR(ENOSYS);
417  goto fail;
418  }
419 
420  ret = AVERROR(ENOSYS);
421  for (i = 0; i < count; i++) {
422  if (!memcmp(&guids[i], &ctx->init_encode_params.encodeGUID, sizeof(*guids))) {
423  ret = 0;
424  break;
425  }
426  }
427 
428 fail:
429  av_free(guids);
430 
431  return ret;
432 }
433 
434 static int nvenc_check_cap(AVCodecContext *avctx, NV_ENC_CAPS cap)
435 {
436  NvencContext *ctx = avctx->priv_data;
437  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
438  NV_ENC_CAPS_PARAM params = { 0 };
439  int ret, val = 0;
440 
441  params.version = NV_ENC_CAPS_PARAM_VER;
442  params.capsToQuery = cap;
443 
444  ret = p_nvenc->nvEncGetEncodeCaps(ctx->nvencoder, ctx->init_encode_params.encodeGUID, &params, &val);
445 
446  if (ret == NV_ENC_SUCCESS)
447  return val;
448  return 0;
449 }
450 
452 {
453  NvencContext *ctx = avctx->priv_data;
454  int tmp, ret;
455 
457  if (ret < 0) {
458  av_log(avctx, AV_LOG_WARNING, "Codec not supported\n");
459  return ret;
460  }
461 
462  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_YUV444_ENCODE);
463  if (IS_YUV444(ctx->data_pix_fmt) && ret <= 0) {
464  av_log(avctx, AV_LOG_WARNING, "YUV444P not supported\n");
465  return AVERROR(ENOSYS);
466  }
467 
468  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE);
469  if (ctx->flags & NVENC_LOSSLESS && ret <= 0) {
470  av_log(avctx, AV_LOG_WARNING, "Lossless encoding not supported\n");
471  return AVERROR(ENOSYS);
472  }
473 
474  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_WIDTH_MAX);
475  if (ret < avctx->width) {
476  av_log(avctx, AV_LOG_WARNING, "Width %d exceeds %d\n",
477  avctx->width, ret);
478  return AVERROR(ENOSYS);
479  }
480 
481  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_HEIGHT_MAX);
482  if (ret < avctx->height) {
483  av_log(avctx, AV_LOG_WARNING, "Height %d exceeds %d\n",
484  avctx->height, ret);
485  return AVERROR(ENOSYS);
486  }
487 
488  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_NUM_MAX_BFRAMES);
489  if (ret < avctx->max_b_frames) {
490  av_log(avctx, AV_LOG_WARNING, "Max B-frames %d exceed %d\n",
491  avctx->max_b_frames, ret);
492 
493  return AVERROR(ENOSYS);
494  }
495 
496  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_FIELD_ENCODING);
497  if (ret < 1 && avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
498  av_log(avctx, AV_LOG_WARNING,
499  "Interlaced encoding is not supported. Supported level: %d\n",
500  ret);
501  return AVERROR(ENOSYS);
502  }
503 
504  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_10BIT_ENCODE);
505  if (IS_10BIT(ctx->data_pix_fmt) && ret <= 0) {
506  av_log(avctx, AV_LOG_WARNING, "10 bit encode not supported\n");
507  return AVERROR(ENOSYS);
508  }
509 
510  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_LOOKAHEAD);
511  if (ctx->rc_lookahead > 0 && ret <= 0) {
512  av_log(avctx, AV_LOG_WARNING, "RC lookahead not supported\n");
513  return AVERROR(ENOSYS);
514  }
515 
516  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_TEMPORAL_AQ);
517  if (ctx->temporal_aq > 0 && ret <= 0) {
518  av_log(avctx, AV_LOG_WARNING, "Temporal AQ not supported\n");
519  return AVERROR(ENOSYS);
520  }
521 
522  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_WEIGHTED_PREDICTION);
523  if (ctx->weighted_pred > 0 && ret <= 0) {
524  av_log (avctx, AV_LOG_WARNING, "Weighted Prediction not supported\n");
525  return AVERROR(ENOSYS);
526  }
527 
528  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_CABAC);
529  if (ctx->coder == NV_ENC_H264_ENTROPY_CODING_MODE_CABAC && ret <= 0) {
530  av_log(avctx, AV_LOG_WARNING, "CABAC entropy coding not supported\n");
531  return AVERROR(ENOSYS);
532  }
533 
534 #ifdef NVENC_HAVE_BFRAME_REF_MODE
535  tmp = (ctx->b_ref_mode >= 0) ? ctx->b_ref_mode : NV_ENC_BFRAME_REF_MODE_DISABLED;
536  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE);
537  if (tmp == NV_ENC_BFRAME_REF_MODE_EACH && ret != 1 && ret != 3) {
538  av_log(avctx, AV_LOG_WARNING, "Each B frame as reference is not supported\n");
539  return AVERROR(ENOSYS);
540  } else if (tmp != NV_ENC_BFRAME_REF_MODE_DISABLED && ret == 0) {
541  av_log(avctx, AV_LOG_WARNING, "B frames as references are not supported\n");
542  return AVERROR(ENOSYS);
543  }
544 #else
545  tmp = (ctx->b_ref_mode >= 0) ? ctx->b_ref_mode : 0;
546  if (tmp > 0) {
547  av_log(avctx, AV_LOG_WARNING, "B frames as references need SDK 8.1 at build time\n");
548  return AVERROR(ENOSYS);
549  }
550 #endif
551 
552 #ifdef NVENC_HAVE_MULTIPLE_REF_FRAMES
553  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES);
554  if(avctx->refs != NV_ENC_NUM_REF_FRAMES_AUTOSELECT && ret <= 0) {
555  av_log(avctx, AV_LOG_WARNING, "Multiple reference frames are not supported by the device\n");
556  return AVERROR(ENOSYS);
557  }
558 #else
559  if(avctx->refs != 0) {
560  av_log(avctx, AV_LOG_WARNING, "Multiple reference frames need SDK 9.1 at build time\n");
561  return AVERROR(ENOSYS);
562  }
563 #endif
564 
565 #ifdef NVENC_HAVE_SINGLE_SLICE_INTRA_REFRESH
566  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH);
567  if(ctx->single_slice_intra_refresh && ret <= 0) {
568  av_log(avctx, AV_LOG_WARNING, "Single slice intra refresh not supported by the device\n");
569  return AVERROR(ENOSYS);
570  }
571 #else
572  if(ctx->single_slice_intra_refresh) {
573  av_log(avctx, AV_LOG_WARNING, "Single slice intra refresh needs SDK 11.1 at build time\n");
574  return AVERROR(ENOSYS);
575  }
576 #endif
577 
578  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_INTRA_REFRESH);
579  if((ctx->intra_refresh || ctx->single_slice_intra_refresh) && ret <= 0) {
580  av_log(avctx, AV_LOG_WARNING, "Intra refresh not supported by the device\n");
581  return AVERROR(ENOSYS);
582  }
583 
584 #ifndef NVENC_HAVE_HEVC_CONSTRAINED_ENCODING
585  if (ctx->constrained_encoding && avctx->codec->id == AV_CODEC_ID_HEVC) {
586  av_log(avctx, AV_LOG_WARNING, "HEVC constrained encoding needs SDK 10.0 at build time\n");
587  return AVERROR(ENOSYS);
588  }
589 #endif
590 
591  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_CONSTRAINED_ENCODING);
592  if(ctx->constrained_encoding && ret <= 0) {
593  av_log(avctx, AV_LOG_WARNING, "Constrained encoding not supported by the device\n");
594  return AVERROR(ENOSYS);
595  }
596 
597  ctx->support_dyn_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
598 
599  return 0;
600 }
601 
602 static av_cold int nvenc_check_device(AVCodecContext *avctx, int idx)
603 {
604  NvencContext *ctx = avctx->priv_data;
605  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
606  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
607  char name[128] = { 0};
608  int major, minor, ret;
609  CUdevice cu_device;
610  int loglevel = AV_LOG_VERBOSE;
611 
612  if (ctx->device == LIST_DEVICES)
613  loglevel = AV_LOG_INFO;
614 
615  ret = CHECK_CU(dl_fn->cuda_dl->cuDeviceGet(&cu_device, idx));
616  if (ret < 0)
617  return ret;
618 
619  ret = CHECK_CU(dl_fn->cuda_dl->cuDeviceGetName(name, sizeof(name), cu_device));
620  if (ret < 0)
621  return ret;
622 
623  ret = CHECK_CU(dl_fn->cuda_dl->cuDeviceComputeCapability(&major, &minor, cu_device));
624  if (ret < 0)
625  return ret;
626 
627  av_log(avctx, loglevel, "[ GPU #%d - < %s > has Compute SM %d.%d ]\n", idx, name, major, minor);
628  if (((major << 4) | minor) < NVENC_CAP) {
629  av_log(avctx, loglevel, "does not support NVENC\n");
630  goto fail;
631  }
632 
633  if (ctx->device != idx && ctx->device != ANY_DEVICE)
634  return -1;
635 
636  ret = CHECK_CU(dl_fn->cuda_dl->cuCtxCreate(&ctx->cu_context_internal, 0, cu_device));
637  if (ret < 0)
638  goto fail;
639 
640  ctx->cu_context = ctx->cu_context_internal;
641  ctx->cu_stream = NULL;
642 
643  if ((ret = nvenc_pop_context(avctx)) < 0)
644  goto fail2;
645 
646  if ((ret = nvenc_open_session(avctx)) < 0)
647  goto fail2;
648 
649  if ((ret = nvenc_check_capabilities(avctx)) < 0)
650  goto fail3;
651 
652  av_log(avctx, loglevel, "supports NVENC\n");
653 
654  dl_fn->nvenc_device_count++;
655 
656  if (ctx->device == idx || ctx->device == ANY_DEVICE)
657  return 0;
658 
659 fail3:
660  if ((ret = nvenc_push_context(avctx)) < 0)
661  return ret;
662 
663  p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
664  ctx->nvencoder = NULL;
665 
666  if ((ret = nvenc_pop_context(avctx)) < 0)
667  return ret;
668 
669 fail2:
670  CHECK_CU(dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal));
671  ctx->cu_context_internal = NULL;
672 
673 fail:
674  return AVERROR(ENOSYS);
675 }
676 
678 {
679  NvencContext *ctx = avctx->priv_data;
680  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
681 
682  switch (avctx->codec->id) {
683  case AV_CODEC_ID_H264:
684  ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_H264_GUID;
685  break;
686  case AV_CODEC_ID_HEVC:
687  ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_HEVC_GUID;
688  break;
689 #if CONFIG_AV1_NVENC_ENCODER
690  case AV_CODEC_ID_AV1:
691  ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_AV1_GUID;
692  break;
693 #endif
694  default:
695  return AVERROR_BUG;
696  }
697 
699 
701  av_log(avctx, AV_LOG_WARNING, "The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.\n");
702 
703  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11 || avctx->hw_frames_ctx || avctx->hw_device_ctx) {
704  AVHWFramesContext *frames_ctx;
705  AVHWDeviceContext *hwdev_ctx;
706  AVCUDADeviceContext *cuda_device_hwctx = NULL;
707 #if CONFIG_D3D11VA
708  AVD3D11VADeviceContext *d3d11_device_hwctx = NULL;
709 #endif
710  int ret;
711 
712  if (avctx->hw_frames_ctx) {
713  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
714  if (frames_ctx->format == AV_PIX_FMT_CUDA)
715  cuda_device_hwctx = frames_ctx->device_ctx->hwctx;
716 #if CONFIG_D3D11VA
717  else if (frames_ctx->format == AV_PIX_FMT_D3D11)
718  d3d11_device_hwctx = frames_ctx->device_ctx->hwctx;
719 #endif
720  else
721  return AVERROR(EINVAL);
722  } else if (avctx->hw_device_ctx) {
723  hwdev_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data;
724  if (hwdev_ctx->type == AV_HWDEVICE_TYPE_CUDA)
725  cuda_device_hwctx = hwdev_ctx->hwctx;
726 #if CONFIG_D3D11VA
727  else if (hwdev_ctx->type == AV_HWDEVICE_TYPE_D3D11VA)
728  d3d11_device_hwctx = hwdev_ctx->hwctx;
729 #endif
730  else
731  return AVERROR(EINVAL);
732  } else {
733  return AVERROR(EINVAL);
734  }
735 
736  if (cuda_device_hwctx) {
737  ctx->cu_context = cuda_device_hwctx->cuda_ctx;
738  ctx->cu_stream = cuda_device_hwctx->stream;
739  }
740 #if CONFIG_D3D11VA
741  else if (d3d11_device_hwctx) {
742  ctx->d3d11_device = d3d11_device_hwctx->device;
743  ID3D11Device_AddRef(ctx->d3d11_device);
744  }
745 #endif
746 
747  ret = nvenc_open_session(avctx);
748  if (ret < 0)
749  return ret;
750 
751  ret = nvenc_check_capabilities(avctx);
752  if (ret < 0) {
753  av_log(avctx, AV_LOG_FATAL, "Provided device doesn't support required NVENC features\n");
754  return ret;
755  }
756  } else {
757  int i, nb_devices = 0;
758 
759  if (CHECK_CU(dl_fn->cuda_dl->cuInit(0)) < 0)
760  return AVERROR_UNKNOWN;
761 
762  if (CHECK_CU(dl_fn->cuda_dl->cuDeviceGetCount(&nb_devices)) < 0)
763  return AVERROR_UNKNOWN;
764 
765  if (!nb_devices) {
766  av_log(avctx, AV_LOG_FATAL, "No CUDA capable devices found\n");
767  return AVERROR_EXTERNAL;
768  }
769 
770  av_log(avctx, AV_LOG_VERBOSE, "%d CUDA capable devices found\n", nb_devices);
771 
772  dl_fn->nvenc_device_count = 0;
773  for (i = 0; i < nb_devices; ++i) {
774  if ((nvenc_check_device(avctx, i)) >= 0 && ctx->device != LIST_DEVICES)
775  return 0;
776  }
777 
778  if (ctx->device == LIST_DEVICES)
779  return AVERROR_EXIT;
780 
781  if (!dl_fn->nvenc_device_count) {
782  av_log(avctx, AV_LOG_FATAL, "No capable devices found\n");
783  return AVERROR_EXTERNAL;
784  }
785 
786  av_log(avctx, AV_LOG_FATAL, "Requested GPU %d, but only %d GPUs are available!\n", ctx->device, nb_devices);
787  return AVERROR(EINVAL);
788  }
789 
790  return 0;
791 }
792 
793 static av_cold void set_constqp(AVCodecContext *avctx)
794 {
795  NvencContext *ctx = avctx->priv_data;
796  NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
797 #if CONFIG_AV1_NVENC_ENCODER
798  int qmax = avctx->codec->id == AV_CODEC_ID_AV1 ? 255 : 51;
799 #else
800  int qmax = 51;
801 #endif
802 
803  rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
804 
805  if (ctx->init_qp_p >= 0) {
806  rc->constQP.qpInterP = ctx->init_qp_p;
807  if (ctx->init_qp_i >= 0 && ctx->init_qp_b >= 0) {
808  rc->constQP.qpIntra = ctx->init_qp_i;
809  rc->constQP.qpInterB = ctx->init_qp_b;
810  } else if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
811  rc->constQP.qpIntra = av_clip(
812  rc->constQP.qpInterP * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, qmax);
813  rc->constQP.qpInterB = av_clip(
814  rc->constQP.qpInterP * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, qmax);
815  } else {
816  rc->constQP.qpIntra = rc->constQP.qpInterP;
817  rc->constQP.qpInterB = rc->constQP.qpInterP;
818  }
819  } else if (ctx->cqp >= 0) {
820  rc->constQP.qpInterP = rc->constQP.qpInterB = rc->constQP.qpIntra = ctx->cqp;
821  if (avctx->b_quant_factor != 0.0)
822  rc->constQP.qpInterB = av_clip(ctx->cqp * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, qmax);
823  if (avctx->i_quant_factor != 0.0)
824  rc->constQP.qpIntra = av_clip(ctx->cqp * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, qmax);
825  }
826 
827  avctx->qmin = -1;
828  avctx->qmax = -1;
829 }
830 
831 static av_cold void set_vbr(AVCodecContext *avctx)
832 {
833  NvencContext *ctx = avctx->priv_data;
834  NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
835  int qp_inter_p;
836 #if CONFIG_AV1_NVENC_ENCODER
837  int qmax = avctx->codec->id == AV_CODEC_ID_AV1 ? 255 : 51;
838 #else
839  int qmax = 51;
840 #endif
841 
842  if (avctx->qmin >= 0 && avctx->qmax >= 0) {
843  rc->enableMinQP = 1;
844  rc->enableMaxQP = 1;
845 
846  rc->minQP.qpInterB = avctx->qmin;
847  rc->minQP.qpInterP = avctx->qmin;
848  rc->minQP.qpIntra = avctx->qmin;
849 
850  rc->maxQP.qpInterB = avctx->qmax;
851  rc->maxQP.qpInterP = avctx->qmax;
852  rc->maxQP.qpIntra = avctx->qmax;
853 
854  qp_inter_p = (avctx->qmax + 3 * avctx->qmin) / 4; // biased towards Qmin
855  } else if (avctx->qmin >= 0) {
856  rc->enableMinQP = 1;
857 
858  rc->minQP.qpInterB = avctx->qmin;
859  rc->minQP.qpInterP = avctx->qmin;
860  rc->minQP.qpIntra = avctx->qmin;
861 
862  qp_inter_p = avctx->qmin;
863  } else {
864  qp_inter_p = 26; // default to 26
865  }
866 
867  rc->enableInitialRCQP = 1;
868 
869  if (ctx->init_qp_p < 0) {
870  rc->initialRCQP.qpInterP = qp_inter_p;
871  } else {
872  rc->initialRCQP.qpInterP = ctx->init_qp_p;
873  }
874 
875  if (ctx->init_qp_i < 0) {
876  if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
877  rc->initialRCQP.qpIntra = av_clip(
878  rc->initialRCQP.qpInterP * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, qmax);
879  } else {
880  rc->initialRCQP.qpIntra = rc->initialRCQP.qpInterP;
881  }
882  } else {
883  rc->initialRCQP.qpIntra = ctx->init_qp_i;
884  }
885 
886  if (ctx->init_qp_b < 0) {
887  if (avctx->i_quant_factor != 0.0 && avctx->b_quant_factor != 0.0) {
888  rc->initialRCQP.qpInterB = av_clip(
889  rc->initialRCQP.qpInterP * fabs(avctx->b_quant_factor) + avctx->b_quant_offset + 0.5, 0, qmax);
890  } else {
891  rc->initialRCQP.qpInterB = rc->initialRCQP.qpInterP;
892  }
893  } else {
894  rc->initialRCQP.qpInterB = ctx->init_qp_b;
895  }
896 }
897 
899 {
900  NvencContext *ctx = avctx->priv_data;
901  NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
902 
903  rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
904  rc->constQP.qpInterB = 0;
905  rc->constQP.qpInterP = 0;
906  rc->constQP.qpIntra = 0;
907 
908  avctx->qmin = -1;
909  avctx->qmax = -1;
910 }
911 
913 {
914  NvencContext *ctx = avctx->priv_data;
915  NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
916 
917  switch (ctx->rc) {
918  case NV_ENC_PARAMS_RC_CONSTQP:
919  set_constqp(avctx);
920  return;
921 #ifndef NVENC_NO_DEPRECATED_RC
922  case NV_ENC_PARAMS_RC_VBR_MINQP:
923  if (avctx->qmin < 0) {
924  av_log(avctx, AV_LOG_WARNING,
925  "The variable bitrate rate-control requires "
926  "the 'qmin' option set.\n");
927  set_vbr(avctx);
928  return;
929  }
930  /* fall through */
931  case NV_ENC_PARAMS_RC_VBR_HQ:
932 #endif
933  case NV_ENC_PARAMS_RC_VBR:
934  set_vbr(avctx);
935  break;
936  case NV_ENC_PARAMS_RC_CBR:
937 #ifndef NVENC_NO_DEPRECATED_RC
938  case NV_ENC_PARAMS_RC_CBR_HQ:
939  case NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ:
940 #endif
941  break;
942  }
943 
944  rc->rateControlMode = ctx->rc;
945 }
946 
948 {
949  NvencContext *ctx = avctx->priv_data;
950  // default minimum of 4 surfaces
951  // multiply by 2 for number of NVENCs on gpu (hardcode to 2)
952  // another multiply by 2 to avoid blocking next PBB group
953  int nb_surfaces = FFMAX(4, ctx->encode_config.frameIntervalP * 2 * 2);
954 
955  // lookahead enabled
956  if (ctx->rc_lookahead > 0) {
957  // +1 is to account for lkd_bound calculation later
958  // +4 is to allow sufficient pipelining with lookahead
959  nb_surfaces = FFMAX(1, FFMAX(nb_surfaces, ctx->rc_lookahead + ctx->encode_config.frameIntervalP + 1 + 4));
960  if (nb_surfaces > ctx->nb_surfaces && ctx->nb_surfaces > 0)
961  {
962  av_log(avctx, AV_LOG_WARNING,
963  "Defined rc_lookahead requires more surfaces, "
964  "increasing used surfaces %d -> %d\n", ctx->nb_surfaces, nb_surfaces);
965  }
966  ctx->nb_surfaces = FFMAX(nb_surfaces, ctx->nb_surfaces);
967  } else {
968  if (ctx->encode_config.frameIntervalP > 1 && ctx->nb_surfaces < nb_surfaces && ctx->nb_surfaces > 0)
969  {
970  av_log(avctx, AV_LOG_WARNING,
971  "Defined b-frame requires more surfaces, "
972  "increasing used surfaces %d -> %d\n", ctx->nb_surfaces, nb_surfaces);
973  ctx->nb_surfaces = FFMAX(ctx->nb_surfaces, nb_surfaces);
974  }
975  else if (ctx->nb_surfaces <= 0)
976  ctx->nb_surfaces = nb_surfaces;
977  // otherwise use user specified value
978  }
979 
980  ctx->nb_surfaces = FFMAX(1, FFMIN(MAX_REGISTERED_FRAMES, ctx->nb_surfaces));
981  ctx->async_depth = FFMIN(ctx->async_depth, ctx->nb_surfaces - 1);
982 
983  // Output in the worst case will only start when the surface buffer is completely full.
984  // Hence we need to keep at least the max amount of surfaces plus the max reorder delay around.
985  ctx->frame_data_array_nb = ctx->nb_surfaces + ctx->encode_config.frameIntervalP - 1;
986 
987  return 0;
988 }
989 
991 {
992  NvencContext *ctx = avctx->priv_data;
993 
994  if (avctx->global_quality > 0)
995  av_log(avctx, AV_LOG_WARNING, "Using global_quality with nvenc is deprecated. Use qp instead.\n");
996 
997  if (ctx->cqp < 0 && avctx->global_quality > 0)
998  ctx->cqp = avctx->global_quality;
999 
1000  if (avctx->bit_rate > 0) {
1001  ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate;
1002  } else if (ctx->encode_config.rcParams.averageBitRate > 0) {
1003  ctx->encode_config.rcParams.maxBitRate = ctx->encode_config.rcParams.averageBitRate;
1004  }
1005 
1006  if (avctx->rc_max_rate > 0)
1007  ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;
1008 
1009 #ifdef NVENC_HAVE_MULTIPASS
1010  ctx->encode_config.rcParams.multiPass = ctx->multipass;
1011 
1012  if (ctx->flags & NVENC_ONE_PASS)
1013  ctx->encode_config.rcParams.multiPass = NV_ENC_MULTI_PASS_DISABLED;
1014  if (ctx->flags & NVENC_TWO_PASSES || ctx->twopass > 0)
1015  ctx->encode_config.rcParams.multiPass = NV_ENC_TWO_PASS_FULL_RESOLUTION;
1016 
1017  if (ctx->rc < 0) {
1018  if (ctx->cbr) {
1019  ctx->rc = NV_ENC_PARAMS_RC_CBR;
1020  } else if (ctx->cqp >= 0) {
1021  ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
1022  } else if (ctx->quality >= 0.0f) {
1023  ctx->rc = NV_ENC_PARAMS_RC_VBR;
1024  }
1025  }
1026 #else
1027  if (ctx->rc < 0) {
1028  if (ctx->flags & NVENC_ONE_PASS)
1029  ctx->twopass = 0;
1030  if (ctx->flags & NVENC_TWO_PASSES)
1031  ctx->twopass = 1;
1032 
1033  if (ctx->twopass < 0)
1034  ctx->twopass = (ctx->flags & NVENC_LOWLATENCY) != 0;
1035 
1036  if (ctx->cbr) {
1037  if (ctx->twopass) {
1038  ctx->rc = NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ;
1039  } else {
1040  ctx->rc = NV_ENC_PARAMS_RC_CBR;
1041  }
1042  } else if (ctx->cqp >= 0) {
1043  ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
1044  } else if (ctx->twopass) {
1045  ctx->rc = NV_ENC_PARAMS_RC_VBR_HQ;
1046  } else if (avctx->qmin >= 0 && avctx->qmax >= 0) {
1047  ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP;
1048  }
1049  }
1050 #endif
1051 
1052  if (ctx->rc >= 0 && ctx->rc & RC_MODE_DEPRECATED) {
1053  av_log(avctx, AV_LOG_WARNING, "Specified rc mode is deprecated.\n");
1054  av_log(avctx, AV_LOG_WARNING, "Use -rc constqp/cbr/vbr, -tune and -multipass instead.\n");
1055 
1056  ctx->rc &= ~RC_MODE_DEPRECATED;
1057  }
1058 
1059 #ifdef NVENC_HAVE_QP_CHROMA_OFFSETS
1060  ctx->encode_config.rcParams.cbQPIndexOffset = ctx->qp_cb_offset;
1061  ctx->encode_config.rcParams.crQPIndexOffset = ctx->qp_cr_offset;
1062 #else
1063  if (ctx->qp_cb_offset || ctx->qp_cr_offset)
1064  av_log(avctx, AV_LOG_WARNING, "Failed setting QP CB/CR offsets, SDK 11.1 or greater required at compile time.\n");
1065 #endif
1066 
1067 #ifdef NVENC_HAVE_LDKFS
1068  if (ctx->ldkfs)
1069  ctx->encode_config.rcParams.lowDelayKeyFrameScale = ctx->ldkfs;
1070 #endif
1071 
1072  if (ctx->flags & NVENC_LOSSLESS) {
1073  set_lossless(avctx);
1074  } else if (ctx->rc >= 0) {
1076  } else {
1077  ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_VBR;
1078  set_vbr(avctx);
1079  }
1080 
1081  if (avctx->rc_buffer_size > 0) {
1082  ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size;
1083  } else if (ctx->encode_config.rcParams.averageBitRate > 0) {
1084  avctx->rc_buffer_size = ctx->encode_config.rcParams.vbvBufferSize = 2 * ctx->encode_config.rcParams.averageBitRate;
1085  }
1086 
1087  if (ctx->aq) {
1088  ctx->encode_config.rcParams.enableAQ = 1;
1089  ctx->encode_config.rcParams.aqStrength = ctx->aq_strength;
1090  av_log(avctx, AV_LOG_VERBOSE, "AQ enabled.\n");
1091  }
1092 
1093  if (ctx->temporal_aq) {
1094  ctx->encode_config.rcParams.enableTemporalAQ = 1;
1095  av_log(avctx, AV_LOG_VERBOSE, "Temporal AQ enabled.\n");
1096  }
1097 
1098  if (ctx->rc_lookahead > 0) {
1099  int lkd_bound = FFMIN(ctx->nb_surfaces, ctx->async_depth) -
1100  ctx->encode_config.frameIntervalP - 4;
1101 
1102  if (lkd_bound < 0) {
1103  ctx->encode_config.rcParams.enableLookahead = 0;
1104  av_log(avctx, AV_LOG_WARNING,
1105  "Lookahead not enabled. Increase buffer delay (-delay).\n");
1106  } else {
1107  ctx->encode_config.rcParams.enableLookahead = 1;
1108  ctx->encode_config.rcParams.lookaheadDepth = av_clip(ctx->rc_lookahead, 0, lkd_bound);
1109  ctx->encode_config.rcParams.disableIadapt = ctx->no_scenecut;
1110  ctx->encode_config.rcParams.disableBadapt = !ctx->b_adapt;
1111  av_log(avctx, AV_LOG_VERBOSE,
1112  "Lookahead enabled: depth %d, scenecut %s, B-adapt %s.\n",
1113  ctx->encode_config.rcParams.lookaheadDepth,
1114  ctx->encode_config.rcParams.disableIadapt ? "disabled" : "enabled",
1115  ctx->encode_config.rcParams.disableBadapt ? "disabled" : "enabled");
1116  if (ctx->encode_config.rcParams.lookaheadDepth < ctx->rc_lookahead)
1117  av_log(avctx, AV_LOG_WARNING, "Clipping lookahead depth to %d (from %d) due to lack of surfaces/delay",
1118  ctx->encode_config.rcParams.lookaheadDepth, ctx->rc_lookahead);
1119  }
1120  }
1121 
1122  if (ctx->strict_gop) {
1123  ctx->encode_config.rcParams.strictGOPTarget = 1;
1124  av_log(avctx, AV_LOG_VERBOSE, "Strict GOP target enabled.\n");
1125  }
1126 
1127  if (ctx->nonref_p)
1128  ctx->encode_config.rcParams.enableNonRefP = 1;
1129 
1130  if (ctx->zerolatency)
1131  ctx->encode_config.rcParams.zeroReorderDelay = 1;
1132 
1133  if (ctx->quality) {
1134  //convert from float to fixed point 8.8
1135  int tmp_quality = (int)(ctx->quality * 256.0f);
1136  ctx->encode_config.rcParams.targetQuality = (uint8_t)(tmp_quality >> 8);
1137  ctx->encode_config.rcParams.targetQualityLSB = (uint8_t)(tmp_quality & 0xff);
1138 
1139  av_log(avctx, AV_LOG_VERBOSE, "CQ(%d) mode enabled.\n", tmp_quality);
1140 
1141  // CQ mode shall discard avg bitrate/vbv buffer size and honor only max bitrate
1142  ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate = 0;
1143  ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size = 0;
1144  ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;
1145  }
1146 }
1147 
1149 {
1150  NvencContext *ctx = avctx->priv_data;
1151  NV_ENC_CONFIG *cc = &ctx->encode_config;
1152  NV_ENC_CONFIG_H264 *h264 = &cc->encodeCodecConfig.h264Config;
1153  NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui = &h264->h264VUIParameters;
1154 
1155  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(ctx->data_pix_fmt);
1156 
1157  if ((pixdesc->flags & AV_PIX_FMT_FLAG_RGB) && !IS_GBRP(ctx->data_pix_fmt)) {
1158  vui->colourMatrix = AVCOL_SPC_BT470BG;
1159  vui->colourPrimaries = avctx->color_primaries;
1160  vui->transferCharacteristics = avctx->color_trc;
1161  vui->videoFullRangeFlag = 0;
1162  } else {
1163  vui->colourMatrix = IS_GBRP(ctx->data_pix_fmt) ? AVCOL_SPC_RGB : avctx->colorspace;
1164  vui->colourPrimaries = avctx->color_primaries;
1165  vui->transferCharacteristics = avctx->color_trc;
1166  vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
1167  || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);
1168  }
1169 
1170  vui->colourDescriptionPresentFlag =
1171  (vui->colourMatrix != 2 || vui->colourPrimaries != 2 || vui->transferCharacteristics != 2);
1172 
1173  vui->videoSignalTypePresentFlag =
1174  (vui->colourDescriptionPresentFlag
1175  || vui->videoFormat != 5
1176  || vui->videoFullRangeFlag != 0);
1177 
1178  if (ctx->max_slice_size > 0) {
1179  h264->sliceMode = 1;
1180  h264->sliceModeData = ctx->max_slice_size;
1181  } else {
1182  h264->sliceMode = 3;
1183  h264->sliceModeData = avctx->slices > 0 ? avctx->slices : 1;
1184  }
1185 
1186  if (ctx->intra_refresh) {
1187  h264->enableIntraRefresh = 1;
1188  h264->intraRefreshPeriod = cc->gopLength;
1189  h264->intraRefreshCnt = cc->gopLength - 1;
1190  cc->gopLength = NVENC_INFINITE_GOPLENGTH;
1191 #ifdef NVENC_HAVE_SINGLE_SLICE_INTRA_REFRESH
1192  h264->singleSliceIntraRefresh = ctx->single_slice_intra_refresh;
1193 #endif
1194  }
1195 
1196  if (ctx->constrained_encoding)
1197  h264->enableConstrainedEncoding = 1;
1198 
1199  h264->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
1200  h264->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
1201  h264->outputAUD = ctx->aud;
1202 
1203  if (ctx->dpb_size >= 0) {
1204  /* 0 means "let the hardware decide" */
1205  h264->maxNumRefFrames = ctx->dpb_size;
1206  }
1207 
1208  h264->idrPeriod = cc->gopLength;
1209 
1210  if (IS_CBR(cc->rcParams.rateControlMode)) {
1211  h264->outputBufferingPeriodSEI = 1;
1212  }
1213 
1214  h264->outputPictureTimingSEI = 1;
1215 
1216 #ifndef NVENC_NO_DEPRECATED_RC
1217  if (cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ ||
1218  cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CBR_HQ ||
1219  cc->rcParams.rateControlMode == NV_ENC_PARAMS_RC_VBR_HQ) {
1220  h264->adaptiveTransformMode = NV_ENC_H264_ADAPTIVE_TRANSFORM_ENABLE;
1221  h264->fmoMode = NV_ENC_H264_FMO_DISABLE;
1222  }
1223 #endif
1224 
1225  if (ctx->flags & NVENC_LOSSLESS) {
1226  h264->qpPrimeYZeroTransformBypassFlag = 1;
1227  } else {
1228  switch(ctx->profile) {
1230  cc->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
1232  break;
1234  cc->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
1235  avctx->profile = AV_PROFILE_H264_MAIN;
1236  break;
1238  cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
1239  avctx->profile = AV_PROFILE_H264_HIGH;
1240  break;
1242  cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
1244  break;
1245  }
1246  }
1247 
1248  // force setting profile as high444p if input is AV_PIX_FMT_YUV444P
1249  if (IS_YUV444(ctx->data_pix_fmt)) {
1250  cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
1252  }
1253 
1254  h264->chromaFormatIDC = avctx->profile == AV_PROFILE_H264_HIGH_444_PREDICTIVE ? 3 : 1;
1255 
1256  h264->level = ctx->level;
1257 
1258 #ifdef NVENC_HAVE_NEW_BIT_DEPTH_API
1259  h264->inputBitDepth = h264->outputBitDepth =
1260  IS_10BIT(ctx->data_pix_fmt) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
1261 #endif
1262 
1263  if (ctx->coder >= 0)
1264  h264->entropyCodingMode = ctx->coder;
1265 
1266 #ifdef NVENC_HAVE_BFRAME_REF_MODE
1267  if (ctx->b_ref_mode >= 0)
1268  h264->useBFramesAsRef = ctx->b_ref_mode;
1269 #endif
1270 
1271 #ifdef NVENC_HAVE_MULTIPLE_REF_FRAMES
1272  h264->numRefL0 = avctx->refs;
1273  h264->numRefL1 = avctx->refs;
1274 #endif
1275 
1276  return 0;
1277 }
1278 
1280 {
1281  NvencContext *ctx = avctx->priv_data;
1282  NV_ENC_CONFIG *cc = &ctx->encode_config;
1283  NV_ENC_CONFIG_HEVC *hevc = &cc->encodeCodecConfig.hevcConfig;
1284  NV_ENC_CONFIG_HEVC_VUI_PARAMETERS *vui = &hevc->hevcVUIParameters;
1285 
1286  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(ctx->data_pix_fmt);
1287 
1288  if ((pixdesc->flags & AV_PIX_FMT_FLAG_RGB) && !IS_GBRP(ctx->data_pix_fmt)) {
1289  vui->colourMatrix = AVCOL_SPC_BT470BG;
1290  vui->colourPrimaries = avctx->color_primaries;
1291  vui->transferCharacteristics = avctx->color_trc;
1292  vui->videoFullRangeFlag = 0;
1293  } else {
1294  vui->colourMatrix = IS_GBRP(ctx->data_pix_fmt) ? AVCOL_SPC_RGB : avctx->colorspace;
1295  vui->colourPrimaries = avctx->color_primaries;
1296  vui->transferCharacteristics = avctx->color_trc;
1297  vui->videoFullRangeFlag = (avctx->color_range == AVCOL_RANGE_JPEG
1298  || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);
1299  }
1300 
1301  vui->colourDescriptionPresentFlag =
1302  (vui->colourMatrix != 2 || vui->colourPrimaries != 2 || vui->transferCharacteristics != 2);
1303 
1304  vui->videoSignalTypePresentFlag =
1305  (vui->colourDescriptionPresentFlag
1306  || vui->videoFormat != 5
1307  || vui->videoFullRangeFlag != 0);
1308 
1309  if (ctx->max_slice_size > 0) {
1310  hevc->sliceMode = 1;
1311  hevc->sliceModeData = ctx->max_slice_size;
1312  } else {
1313  hevc->sliceMode = 3;
1314  hevc->sliceModeData = avctx->slices > 0 ? avctx->slices : 1;
1315  }
1316 
1317  if (ctx->intra_refresh) {
1318  hevc->enableIntraRefresh = 1;
1319  hevc->intraRefreshPeriod = cc->gopLength;
1320  hevc->intraRefreshCnt = cc->gopLength - 1;
1321  cc->gopLength = NVENC_INFINITE_GOPLENGTH;
1322 #ifdef NVENC_HAVE_SINGLE_SLICE_INTRA_REFRESH
1323  hevc->singleSliceIntraRefresh = ctx->single_slice_intra_refresh;
1324 #endif
1325  }
1326 
1327 #ifdef NVENC_HAVE_HEVC_CONSTRAINED_ENCODING
1328  if (ctx->constrained_encoding)
1329  hevc->enableConstrainedEncoding = 1;
1330 #endif
1331 
1332  hevc->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
1333  hevc->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
1334  hevc->outputAUD = ctx->aud;
1335 
1336  if (ctx->dpb_size >= 0) {
1337  /* 0 means "let the hardware decide" */
1338  hevc->maxNumRefFramesInDPB = ctx->dpb_size;
1339  }
1340 
1341  hevc->idrPeriod = cc->gopLength;
1342 
1343  if (IS_CBR(cc->rcParams.rateControlMode)) {
1344  hevc->outputBufferingPeriodSEI = 1;
1345  }
1346 
1347  hevc->outputPictureTimingSEI = 1;
1348 
1349  switch (ctx->profile) {
1351  cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
1352  avctx->profile = AV_PROFILE_HEVC_MAIN;
1353  break;
1355  cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID;
1357  break;
1359  cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
1360  avctx->profile = AV_PROFILE_HEVC_REXT;
1361  break;
1362  }
1363 
1364  // force setting profile as main10 if input is 10 bit
1365  if (IS_10BIT(ctx->data_pix_fmt)) {
1366  cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID;
1368  }
1369 
1370  // force setting profile as rext if input is yuv444
1371  if (IS_YUV444(ctx->data_pix_fmt)) {
1372  cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
1373  avctx->profile = AV_PROFILE_HEVC_REXT;
1374  }
1375 
1376  hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : 1;
1377 
1378 #ifdef NVENC_HAVE_NEW_BIT_DEPTH_API
1379  hevc->inputBitDepth = hevc->outputBitDepth =
1380  IS_10BIT(ctx->data_pix_fmt) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
1381 #else
1382  hevc->pixelBitDepthMinus8 = IS_10BIT(ctx->data_pix_fmt) ? 2 : 0;
1383 #endif
1384 
1385  hevc->level = ctx->level;
1386 
1387  hevc->tier = ctx->tier;
1388 
1389 #ifdef NVENC_HAVE_HEVC_BFRAME_REF_MODE
1390  if (ctx->b_ref_mode >= 0)
1391  hevc->useBFramesAsRef = ctx->b_ref_mode;
1392 #endif
1393 
1394 #ifdef NVENC_HAVE_MULTIPLE_REF_FRAMES
1395  hevc->numRefL0 = avctx->refs;
1396  hevc->numRefL1 = avctx->refs;
1397 #endif
1398 
1399  return 0;
1400 }
1401 
1402 #if CONFIG_AV1_NVENC_ENCODER
1403 static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
1404 {
1405  NvencContext *ctx = avctx->priv_data;
1406  NV_ENC_CONFIG *cc = &ctx->encode_config;
1407  NV_ENC_CONFIG_AV1 *av1 = &cc->encodeCodecConfig.av1Config;
1408 
1409  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(ctx->data_pix_fmt);
1410 
1411  if ((pixdesc->flags & AV_PIX_FMT_FLAG_RGB) && !IS_GBRP(ctx->data_pix_fmt)) {
1412  av1->matrixCoefficients = AVCOL_SPC_BT470BG;
1413  av1->colorPrimaries = avctx->color_primaries;
1414  av1->transferCharacteristics = avctx->color_trc;
1415  av1->colorRange = 0;
1416  } else {
1417  av1->matrixCoefficients = IS_GBRP(ctx->data_pix_fmt) ? AVCOL_SPC_RGB : avctx->colorspace;
1418  av1->colorPrimaries = avctx->color_primaries;
1419  av1->transferCharacteristics = avctx->color_trc;
1420  av1->colorRange = (avctx->color_range == AVCOL_RANGE_JPEG
1421  || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ420P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ422P || ctx->data_pix_fmt == AV_PIX_FMT_YUVJ444P);
1422  }
1423 
1424  if (IS_YUV444(ctx->data_pix_fmt)) {
1425  av_log(avctx, AV_LOG_ERROR, "AV1 High Profile not supported, required for 4:4:4 encoding\n");
1426  return AVERROR(ENOTSUP);
1427  } else {
1428  cc->profileGUID = NV_ENC_AV1_PROFILE_MAIN_GUID;
1429  avctx->profile = AV_PROFILE_AV1_MAIN;
1430  }
1431 
1432  if (ctx->dpb_size >= 0) {
1433  /* 0 means "let the hardware decide" */
1434  av1->maxNumRefFramesInDPB = ctx->dpb_size;
1435  }
1436 
1437  if (ctx->intra_refresh) {
1438  av1->enableIntraRefresh = 1;
1439  av1->intraRefreshPeriod = cc->gopLength;
1440  av1->intraRefreshCnt = cc->gopLength - 1;
1441  cc->gopLength = NVENC_INFINITE_GOPLENGTH;
1442  }
1443 
1444  av1->idrPeriod = cc->gopLength;
1445 
1446  if (IS_CBR(cc->rcParams.rateControlMode)) {
1447  av1->enableBitstreamPadding = 1;
1448  }
1449 
1450  if (ctx->tile_cols >= 0)
1451  av1->numTileColumns = ctx->tile_cols;
1452  if (ctx->tile_rows >= 0)
1453  av1->numTileRows = ctx->tile_rows;
1454 
1455  av1->outputAnnexBFormat = 0;
1456 
1457  av1->level = ctx->level;
1458  av1->tier = ctx->tier;
1459 
1460  av1->enableTimingInfo = ctx->timing_info;
1461 
1462  /* mp4 encapsulation requires sequence headers to be present on all keyframes for AV1 */
1463  av1->disableSeqHdr = 0;
1464  av1->repeatSeqHdr = 1;
1465 
1466  av1->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : 1;
1467 
1468 #ifdef NVENC_HAVE_NEW_BIT_DEPTH_API
1469  av1->inputBitDepth = IS_10BIT(ctx->data_pix_fmt) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
1470  av1->outputBitDepth = (IS_10BIT(ctx->data_pix_fmt) || ctx->highbitdepth) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
1471 #else
1472  av1->inputPixelBitDepthMinus8 = IS_10BIT(ctx->data_pix_fmt) ? 2 : 0;
1473  av1->pixelBitDepthMinus8 = (IS_10BIT(ctx->data_pix_fmt) || ctx->highbitdepth) ? 2 : 0;
1474 #endif
1475 
1476  if (ctx->b_ref_mode >= 0)
1477  av1->useBFramesAsRef = ctx->b_ref_mode;
1478 
1479  av1->numFwdRefs = avctx->refs;
1480  av1->numBwdRefs = avctx->refs;
1481 
1482  return 0;
1483 }
1484 #endif
1485 
1487 {
1488  switch (avctx->codec->id) {
1489  case AV_CODEC_ID_H264:
1490  return nvenc_setup_h264_config(avctx);
1491  case AV_CODEC_ID_HEVC:
1492  return nvenc_setup_hevc_config(avctx);
1493 #if CONFIG_AV1_NVENC_ENCODER
1494  case AV_CODEC_ID_AV1:
1495  return nvenc_setup_av1_config(avctx);
1496 #endif
1497  /* Earlier switch/case will return if unknown codec is passed. */
1498  }
1499 
1500  return 0;
1501 }
1502 
1503 static void compute_dar(AVCodecContext *avctx, int *dw, int *dh) {
1504  int sw, sh;
1505 
1506  sw = avctx->width;
1507  sh = avctx->height;
1508 
1509 #if CONFIG_AV1_NVENC_ENCODER
1510  if (avctx->codec->id == AV_CODEC_ID_AV1) {
1511  /* For AV1 we actually need to calculate the render width/height, not the dar */
1512  if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0
1513  && avctx->sample_aspect_ratio.num != avctx->sample_aspect_ratio.den)
1514  {
1515  if (avctx->sample_aspect_ratio.num > avctx->sample_aspect_ratio.den) {
1516  sw = av_rescale(sw, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
1517  } else {
1518  sh = av_rescale(sh, avctx->sample_aspect_ratio.den, avctx->sample_aspect_ratio.num);
1519  }
1520  }
1521 
1522  *dw = sw;
1523  *dh = sh;
1524  return;
1525  }
1526 #endif
1527 
1528  if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {
1529  sw *= avctx->sample_aspect_ratio.num;
1530  sh *= avctx->sample_aspect_ratio.den;
1531  }
1532 
1533  av_reduce(dw, dh, sw, sh, 1024 * 1024);
1534 }
1535 
1537 {
1538  NvencContext *ctx = avctx->priv_data;
1539  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1540  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1541 
1542  NV_ENC_PRESET_CONFIG preset_config = { 0 };
1543  NVENCSTATUS nv_status = NV_ENC_SUCCESS;
1544  AVCPBProperties *cpb_props;
1545  int res = 0;
1546  int dw, dh;
1547 
1548  ctx->encode_config.version = NV_ENC_CONFIG_VER;
1549  ctx->init_encode_params.version = NV_ENC_INITIALIZE_PARAMS_VER;
1550 
1551  ctx->init_encode_params.encodeHeight = avctx->height;
1552  ctx->init_encode_params.encodeWidth = avctx->width;
1553 
1554  ctx->init_encode_params.encodeConfig = &ctx->encode_config;
1555 
1556  preset_config.version = NV_ENC_PRESET_CONFIG_VER;
1557  preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
1558 
1559 #ifdef NVENC_HAVE_NEW_PRESETS
1560  ctx->init_encode_params.tuningInfo = ctx->tuning_info;
1561 
1562  if (ctx->flags & NVENC_LOSSLESS)
1563  ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOSSLESS;
1564  else if (ctx->flags & NVENC_LOWLATENCY)
1565  ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOW_LATENCY;
1566 
1567  nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder,
1568  ctx->init_encode_params.encodeGUID,
1569  ctx->init_encode_params.presetGUID,
1570  ctx->init_encode_params.tuningInfo,
1571  &preset_config);
1572 #else
1573  nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder,
1574  ctx->init_encode_params.encodeGUID,
1575  ctx->init_encode_params.presetGUID,
1576  &preset_config);
1577 #endif
1578  if (nv_status != NV_ENC_SUCCESS)
1579  return nvenc_print_error(avctx, nv_status, "Cannot get the preset configuration");
1580 
1581  memcpy(&ctx->encode_config, &preset_config.presetCfg, sizeof(ctx->encode_config));
1582 
1583  ctx->encode_config.version = NV_ENC_CONFIG_VER;
1584 
1585  compute_dar(avctx, &dw, &dh);
1586  ctx->init_encode_params.darHeight = dh;
1587  ctx->init_encode_params.darWidth = dw;
1588 
1589  if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
1590  ctx->init_encode_params.frameRateNum = avctx->framerate.num;
1591  ctx->init_encode_params.frameRateDen = avctx->framerate.den;
1592  } else {
1593  ctx->init_encode_params.frameRateNum = avctx->time_base.den;
1595  ctx->init_encode_params.frameRateDen = avctx->time_base.num
1596 #if FF_API_TICKS_PER_FRAME
1597  * avctx->ticks_per_frame
1598 #endif
1599  ;
1601  }
1602 
1603  ctx->init_encode_params.enableEncodeAsync = 0;
1604  ctx->init_encode_params.enablePTD = 1;
1605 
1606 #ifdef NVENC_HAVE_NEW_PRESETS
1607  /* If lookahead isn't set from CLI, use value from preset.
1608  * P6 & P7 presets may enable lookahead for better quality.
1609  * */
1610  if (ctx->rc_lookahead == 0 && ctx->encode_config.rcParams.enableLookahead)
1611  ctx->rc_lookahead = ctx->encode_config.rcParams.lookaheadDepth;
1612 #endif
1613 
1614  if (ctx->weighted_pred == 1)
1615  ctx->init_encode_params.enableWeightedPrediction = 1;
1616 
1617  if (ctx->bluray_compat) {
1618  ctx->aud = 1;
1619  ctx->dpb_size = FFMIN(FFMAX(avctx->refs, 0), 6);
1620  avctx->max_b_frames = FFMIN(avctx->max_b_frames, 3);
1621  switch (avctx->codec->id) {
1622  case AV_CODEC_ID_H264:
1623  /* maximum level depends on used resolution */
1624  break;
1625  case AV_CODEC_ID_HEVC:
1626  ctx->level = NV_ENC_LEVEL_HEVC_51;
1627  ctx->tier = NV_ENC_TIER_HEVC_HIGH;
1628  break;
1629  }
1630  }
1631 
1632  if (avctx->gop_size > 0) {
1633  // only overwrite preset if a GOP size was selected as input
1634  ctx->encode_config.gopLength = avctx->gop_size;
1635  } else if (avctx->gop_size == 0) {
1636  ctx->encode_config.frameIntervalP = 0;
1637  ctx->encode_config.gopLength = 1;
1638  }
1639 
1640  if (avctx->max_b_frames >= 0 && ctx->encode_config.gopLength > 1) {
1641  /* 0 is intra-only, 1 is I/P only, 2 is one B-Frame, 3 two B-frames, and so on. */
1642  ctx->encode_config.frameIntervalP = avctx->max_b_frames + 1;
1643  }
1644 
1645  /* force to enable intra refresh */
1646  if(ctx->single_slice_intra_refresh)
1647  ctx->intra_refresh = 1;
1648 
1649  nvenc_recalc_surfaces(avctx);
1650 
1651  nvenc_setup_rate_control(avctx);
1652 
1653  if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
1654  ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD;
1655  } else {
1656  ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME;
1657  }
1658 
1659  res = nvenc_setup_codec_config(avctx);
1660  if (res)
1661  return res;
1662 
1663  res = nvenc_push_context(avctx);
1664  if (res < 0)
1665  return res;
1666 
1667  nv_status = p_nvenc->nvEncInitializeEncoder(ctx->nvencoder, &ctx->init_encode_params);
1668  if (nv_status != NV_ENC_SUCCESS) {
1669  nvenc_pop_context(avctx);
1670  return nvenc_print_error(avctx, nv_status, "InitializeEncoder failed");
1671  }
1672 
1673 #ifdef NVENC_HAVE_CUSTREAM_PTR
1674  if (ctx->cu_context) {
1675  nv_status = p_nvenc->nvEncSetIOCudaStreams(ctx->nvencoder, &ctx->cu_stream, &ctx->cu_stream);
1676  if (nv_status != NV_ENC_SUCCESS) {
1677  nvenc_pop_context(avctx);
1678  return nvenc_print_error(avctx, nv_status, "SetIOCudaStreams failed");
1679  }
1680  }
1681 #endif
1682 
1683  res = nvenc_pop_context(avctx);
1684  if (res < 0)
1685  return res;
1686 
1687  if (ctx->encode_config.frameIntervalP > 1)
1688  avctx->has_b_frames = 2;
1689 
1690  if (ctx->encode_config.rcParams.averageBitRate > 0)
1691  avctx->bit_rate = ctx->encode_config.rcParams.averageBitRate;
1692 
1693  cpb_props = ff_encode_add_cpb_side_data(avctx);
1694  if (!cpb_props)
1695  return AVERROR(ENOMEM);
1696  cpb_props->max_bitrate = ctx->encode_config.rcParams.maxBitRate;
1697  cpb_props->avg_bitrate = avctx->bit_rate;
1698  cpb_props->buffer_size = ctx->encode_config.rcParams.vbvBufferSize;
1699 
1700  return 0;
1701 }
1702 
1703 static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt)
1704 {
1705  switch (pix_fmt) {
1706  case AV_PIX_FMT_YUV420P:
1707  return NV_ENC_BUFFER_FORMAT_YV12;
1708  case AV_PIX_FMT_NV12:
1709  return NV_ENC_BUFFER_FORMAT_NV12;
1710  case AV_PIX_FMT_P010:
1711  case AV_PIX_FMT_P016:
1712  return NV_ENC_BUFFER_FORMAT_YUV420_10BIT;
1713  case AV_PIX_FMT_GBRP:
1714  case AV_PIX_FMT_YUV444P:
1715  return NV_ENC_BUFFER_FORMAT_YUV444;
1716  case AV_PIX_FMT_GBRP16:
1717  case AV_PIX_FMT_YUV444P16:
1718  return NV_ENC_BUFFER_FORMAT_YUV444_10BIT;
1719  case AV_PIX_FMT_0RGB32:
1720  case AV_PIX_FMT_RGB32:
1721  return NV_ENC_BUFFER_FORMAT_ARGB;
1722  case AV_PIX_FMT_0BGR32:
1723  case AV_PIX_FMT_BGR32:
1724  return NV_ENC_BUFFER_FORMAT_ABGR;
1725  case AV_PIX_FMT_X2RGB10:
1726  return NV_ENC_BUFFER_FORMAT_ARGB10;
1727  case AV_PIX_FMT_X2BGR10:
1728  return NV_ENC_BUFFER_FORMAT_ABGR10;
1729  default:
1730  return NV_ENC_BUFFER_FORMAT_UNDEFINED;
1731  }
1732 }
1733 
1734 static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx)
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  NvencSurface* tmp_surface = &ctx->surfaces[idx];
1740 
1741  NVENCSTATUS nv_status;
1742  NV_ENC_CREATE_BITSTREAM_BUFFER allocOut = { 0 };
1743  allocOut.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER;
1744 
1745  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1746  ctx->surfaces[idx].in_ref = av_frame_alloc();
1747  if (!ctx->surfaces[idx].in_ref)
1748  return AVERROR(ENOMEM);
1749  } else {
1750  NV_ENC_CREATE_INPUT_BUFFER allocSurf = { 0 };
1751 
1752  ctx->surfaces[idx].format = nvenc_map_buffer_format(ctx->data_pix_fmt);
1753  if (ctx->surfaces[idx].format == NV_ENC_BUFFER_FORMAT_UNDEFINED) {
1754  av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n",
1755  av_get_pix_fmt_name(ctx->data_pix_fmt));
1756  return AVERROR(EINVAL);
1757  }
1758 
1759  allocSurf.version = NV_ENC_CREATE_INPUT_BUFFER_VER;
1760  allocSurf.width = avctx->width;
1761  allocSurf.height = avctx->height;
1762  allocSurf.bufferFmt = ctx->surfaces[idx].format;
1763 
1764  nv_status = p_nvenc->nvEncCreateInputBuffer(ctx->nvencoder, &allocSurf);
1765  if (nv_status != NV_ENC_SUCCESS) {
1766  return nvenc_print_error(avctx, nv_status, "CreateInputBuffer failed");
1767  }
1768 
1769  ctx->surfaces[idx].input_surface = allocSurf.inputBuffer;
1770  ctx->surfaces[idx].width = allocSurf.width;
1771  ctx->surfaces[idx].height = allocSurf.height;
1772  }
1773 
1774  nv_status = p_nvenc->nvEncCreateBitstreamBuffer(ctx->nvencoder, &allocOut);
1775  if (nv_status != NV_ENC_SUCCESS) {
1776  int err = nvenc_print_error(avctx, nv_status, "CreateBitstreamBuffer failed");
1777  if (avctx->pix_fmt != AV_PIX_FMT_CUDA && avctx->pix_fmt != AV_PIX_FMT_D3D11)
1778  p_nvenc->nvEncDestroyInputBuffer(ctx->nvencoder, ctx->surfaces[idx].input_surface);
1779  av_frame_free(&ctx->surfaces[idx].in_ref);
1780  return err;
1781  }
1782 
1783  ctx->surfaces[idx].output_surface = allocOut.bitstreamBuffer;
1784 
1785  av_fifo_write(ctx->unused_surface_queue, &tmp_surface, 1);
1786 
1787  return 0;
1788 }
1789 
1791 {
1792  NvencContext *ctx = avctx->priv_data;
1793  int i, res = 0, res2;
1794 
1795  ctx->surfaces = av_calloc(ctx->nb_surfaces, sizeof(*ctx->surfaces));
1796  if (!ctx->surfaces)
1797  return AVERROR(ENOMEM);
1798 
1799  ctx->frame_data_array = av_calloc(ctx->frame_data_array_nb, sizeof(*ctx->frame_data_array));
1800  if (!ctx->frame_data_array)
1801  return AVERROR(ENOMEM);
1802 
1803  ctx->timestamp_list = av_fifo_alloc2(ctx->nb_surfaces, sizeof(int64_t), 0);
1804  if (!ctx->timestamp_list)
1805  return AVERROR(ENOMEM);
1806 
1807  ctx->unused_surface_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(NvencSurface*), 0);
1808  if (!ctx->unused_surface_queue)
1809  return AVERROR(ENOMEM);
1810 
1811  ctx->output_surface_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(NvencSurface*), 0);
1812  if (!ctx->output_surface_queue)
1813  return AVERROR(ENOMEM);
1814  ctx->output_surface_ready_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(NvencSurface*), 0);
1815  if (!ctx->output_surface_ready_queue)
1816  return AVERROR(ENOMEM);
1817 
1818  res = nvenc_push_context(avctx);
1819  if (res < 0)
1820  return res;
1821 
1822  for (i = 0; i < ctx->nb_surfaces; i++) {
1823  if ((res = nvenc_alloc_surface(avctx, i)) < 0)
1824  goto fail;
1825  }
1826 
1827 fail:
1828  res2 = nvenc_pop_context(avctx);
1829  if (res2 < 0)
1830  return res2;
1831 
1832  return res;
1833 }
1834 
1836 {
1837  NvencContext *ctx = avctx->priv_data;
1838  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1839  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1840 
1841  NVENCSTATUS nv_status;
1842  uint32_t outSize = 0;
1843  char tmpHeader[NV_MAX_SEQ_HDR_LEN];
1844 
1845  NV_ENC_SEQUENCE_PARAM_PAYLOAD payload = { 0 };
1846  payload.version = NV_ENC_SEQUENCE_PARAM_PAYLOAD_VER;
1847 
1848  payload.spsppsBuffer = tmpHeader;
1849  payload.inBufferSize = sizeof(tmpHeader);
1850  payload.outSPSPPSPayloadSize = &outSize;
1851 
1852  nv_status = p_nvenc->nvEncGetSequenceParams(ctx->nvencoder, &payload);
1853  if (nv_status != NV_ENC_SUCCESS) {
1854  return nvenc_print_error(avctx, nv_status, "GetSequenceParams failed");
1855  }
1856 
1857  avctx->extradata_size = outSize;
1859 
1860  if (!avctx->extradata) {
1861  return AVERROR(ENOMEM);
1862  }
1863 
1864  memcpy(avctx->extradata, tmpHeader, outSize);
1865 
1866  return 0;
1867 }
1868 
1870 {
1871  NvencContext *ctx = avctx->priv_data;
1872  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
1873  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
1874  int i, res;
1875 
1876  /* the encoder has to be flushed before it can be closed */
1877  if (ctx->nvencoder) {
1878  NV_ENC_PIC_PARAMS params = { .version = NV_ENC_PIC_PARAMS_VER,
1879  .encodePicFlags = NV_ENC_PIC_FLAG_EOS };
1880 
1881  res = nvenc_push_context(avctx);
1882  if (res < 0)
1883  return res;
1884 
1885  p_nvenc->nvEncEncodePicture(ctx->nvencoder, &params);
1886  }
1887 
1888  av_fifo_freep2(&ctx->timestamp_list);
1889  av_fifo_freep2(&ctx->output_surface_ready_queue);
1890  av_fifo_freep2(&ctx->output_surface_queue);
1891  av_fifo_freep2(&ctx->unused_surface_queue);
1892 
1893  if (ctx->frame_data_array) {
1894  for (i = 0; i < ctx->nb_surfaces; i++)
1895  av_buffer_unref(&ctx->frame_data_array[i].frame_opaque_ref);
1896  av_freep(&ctx->frame_data_array);
1897  }
1898 
1899  if (ctx->surfaces && (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11)) {
1900  for (i = 0; i < ctx->nb_registered_frames; i++) {
1901  if (ctx->registered_frames[i].mapped)
1902  p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[i].in_map.mappedResource);
1903  if (ctx->registered_frames[i].regptr)
1904  p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr);
1905  }
1906  ctx->nb_registered_frames = 0;
1907  }
1908 
1909  if (ctx->surfaces) {
1910  for (i = 0; i < ctx->nb_surfaces; ++i) {
1911  if (avctx->pix_fmt != AV_PIX_FMT_CUDA && avctx->pix_fmt != AV_PIX_FMT_D3D11)
1912  p_nvenc->nvEncDestroyInputBuffer(ctx->nvencoder, ctx->surfaces[i].input_surface);
1913  av_frame_free(&ctx->surfaces[i].in_ref);
1914  p_nvenc->nvEncDestroyBitstreamBuffer(ctx->nvencoder, ctx->surfaces[i].output_surface);
1915  }
1916  }
1917  av_freep(&ctx->surfaces);
1918  ctx->nb_surfaces = 0;
1919 
1920  av_frame_free(&ctx->frame);
1921 
1922  av_freep(&ctx->sei_data);
1923 
1924  if (ctx->nvencoder) {
1925  p_nvenc->nvEncDestroyEncoder(ctx->nvencoder);
1926 
1927  res = nvenc_pop_context(avctx);
1928  if (res < 0)
1929  return res;
1930  }
1931  ctx->nvencoder = NULL;
1932 
1933  if (ctx->cu_context_internal)
1934  CHECK_CU(dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal));
1935  ctx->cu_context = ctx->cu_context_internal = NULL;
1936 
1937 #if CONFIG_D3D11VA
1938  if (ctx->d3d11_device) {
1939  ID3D11Device_Release(ctx->d3d11_device);
1940  ctx->d3d11_device = NULL;
1941  }
1942 #endif
1943 
1944  nvenc_free_functions(&dl_fn->nvenc_dl);
1945  cuda_free_functions(&dl_fn->cuda_dl);
1946 
1947  dl_fn->nvenc_device_count = 0;
1948 
1949  av_log(avctx, AV_LOG_VERBOSE, "Nvenc unloaded\n");
1950 
1951  return 0;
1952 }
1953 
1955 {
1956  NvencContext *ctx = avctx->priv_data;
1957  int ret;
1958 
1959  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
1960  AVHWFramesContext *frames_ctx;
1961  if (!avctx->hw_frames_ctx) {
1962  av_log(avctx, AV_LOG_ERROR,
1963  "hw_frames_ctx must be set when using GPU frames as input\n");
1964  return AVERROR(EINVAL);
1965  }
1966  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1967  if (frames_ctx->format != avctx->pix_fmt) {
1968  av_log(avctx, AV_LOG_ERROR,
1969  "hw_frames_ctx must match the GPU frame type\n");
1970  return AVERROR(EINVAL);
1971  }
1972  ctx->data_pix_fmt = frames_ctx->sw_format;
1973  } else {
1974  ctx->data_pix_fmt = avctx->pix_fmt;
1975  }
1976 
1977  if (ctx->rgb_mode == NVENC_RGB_MODE_DISABLED && IS_RGB(ctx->data_pix_fmt)) {
1978  av_log(avctx, AV_LOG_ERROR, "Packed RGB input, but RGB support is disabled.\n");
1979  return AVERROR(EINVAL);
1980  }
1981 
1982  ctx->frame = av_frame_alloc();
1983  if (!ctx->frame)
1984  return AVERROR(ENOMEM);
1985 
1986  if ((ret = nvenc_load_libraries(avctx)) < 0)
1987  return ret;
1988 
1989  if ((ret = nvenc_setup_device(avctx)) < 0)
1990  return ret;
1991 
1992  if ((ret = nvenc_setup_encoder(avctx)) < 0)
1993  return ret;
1994 
1995  if ((ret = nvenc_setup_surfaces(avctx)) < 0)
1996  return ret;
1997 
1998  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1999  if ((ret = nvenc_setup_extradata(avctx)) < 0)
2000  return ret;
2001  }
2002 
2003  return 0;
2004 }
2005 
2007 {
2008  NvencSurface *tmp_surf;
2009 
2010  if (av_fifo_read(ctx->unused_surface_queue, &tmp_surf, 1) < 0)
2011  // queue empty
2012  return NULL;
2013 
2014  return tmp_surf;
2015 }
2016 
2017 static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *nv_surface,
2018  NV_ENC_LOCK_INPUT_BUFFER *lock_buffer_params, const AVFrame *frame)
2019 {
2020  int dst_linesize[4] = {
2021  lock_buffer_params->pitch,
2022  lock_buffer_params->pitch,
2023  lock_buffer_params->pitch,
2024  lock_buffer_params->pitch
2025  };
2026  uint8_t *dst_data[4];
2027  int ret;
2028 
2030  dst_linesize[1] = dst_linesize[2] >>= 1;
2031 
2032  ret = av_image_fill_pointers(dst_data, frame->format, nv_surface->height,
2033  lock_buffer_params->bufferDataPtr, dst_linesize);
2034  if (ret < 0)
2035  return ret;
2036 
2038  FFSWAP(uint8_t*, dst_data[1], dst_data[2]);
2039 
2040  av_image_copy2(dst_data, dst_linesize,
2042  avctx->width, avctx->height);
2043 
2044  return 0;
2045 }
2046 
2048 {
2049  NvencContext *ctx = avctx->priv_data;
2050  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2051  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2052  NVENCSTATUS nv_status;
2053 
2054  int i, first_round;
2055 
2056  if (ctx->nb_registered_frames == FF_ARRAY_ELEMS(ctx->registered_frames)) {
2057  for (first_round = 1; first_round >= 0; first_round--) {
2058  for (i = 0; i < ctx->nb_registered_frames; i++) {
2059  if (!ctx->registered_frames[i].mapped) {
2060  if (ctx->registered_frames[i].regptr) {
2061  if (first_round)
2062  continue;
2063  nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr);
2064  if (nv_status != NV_ENC_SUCCESS)
2065  return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource");
2066  ctx->registered_frames[i].ptr = NULL;
2067  ctx->registered_frames[i].regptr = NULL;
2068  }
2069  return i;
2070  }
2071  }
2072  }
2073  } else {
2074  return ctx->nb_registered_frames++;
2075  }
2076 
2077  av_log(avctx, AV_LOG_ERROR, "Too many registered CUDA frames\n");
2078  return AVERROR(ENOMEM);
2079 }
2080 
2082 {
2083  NvencContext *ctx = avctx->priv_data;
2084  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2085  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2086 
2088  NV_ENC_REGISTER_RESOURCE reg = { 0 };
2089  int i, idx, ret;
2090 
2091  for (i = 0; i < ctx->nb_registered_frames; i++) {
2092  if (avctx->pix_fmt == AV_PIX_FMT_CUDA && ctx->registered_frames[i].ptr == frame->data[0])
2093  return i;
2094  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])
2095  return i;
2096  }
2097 
2098  idx = nvenc_find_free_reg_resource(avctx);
2099  if (idx < 0)
2100  return idx;
2101 
2102  reg.version = NV_ENC_REGISTER_RESOURCE_VER;
2103  reg.width = frames_ctx->width;
2104  reg.height = frames_ctx->height;
2105  reg.pitch = frame->linesize[0];
2106  reg.resourceToRegister = frame->data[0];
2107 
2108  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
2109  reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR;
2110  }
2111  else if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
2112  reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
2113  reg.subResourceIndex = (intptr_t)frame->data[1];
2114  }
2115 
2116  reg.bufferFormat = nvenc_map_buffer_format(frames_ctx->sw_format);
2117  if (reg.bufferFormat == NV_ENC_BUFFER_FORMAT_UNDEFINED) {
2118  av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n",
2119  av_get_pix_fmt_name(frames_ctx->sw_format));
2120  return AVERROR(EINVAL);
2121  }
2122 
2123  ret = p_nvenc->nvEncRegisterResource(ctx->nvencoder, &reg);
2124  if (ret != NV_ENC_SUCCESS) {
2125  nvenc_print_error(avctx, ret, "Error registering an input resource");
2126  return AVERROR_UNKNOWN;
2127  }
2128 
2129  ctx->registered_frames[idx].ptr = frame->data[0];
2130  ctx->registered_frames[idx].ptr_index = reg.subResourceIndex;
2131  ctx->registered_frames[idx].regptr = reg.registeredResource;
2132  return idx;
2133 }
2134 
2136  NvencSurface *nvenc_frame)
2137 {
2138  NvencContext *ctx = avctx->priv_data;
2139  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2140  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2141 
2142  int res;
2143  NVENCSTATUS nv_status;
2144 
2145  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
2146  int reg_idx = nvenc_register_frame(avctx, frame);
2147  if (reg_idx < 0) {
2148  av_log(avctx, AV_LOG_ERROR, "Could not register an input HW frame\n");
2149  return reg_idx;
2150  }
2151 
2152  res = av_frame_ref(nvenc_frame->in_ref, frame);
2153  if (res < 0)
2154  return res;
2155 
2156  if (!ctx->registered_frames[reg_idx].mapped) {
2157  ctx->registered_frames[reg_idx].in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER;
2158  ctx->registered_frames[reg_idx].in_map.registeredResource = ctx->registered_frames[reg_idx].regptr;
2159  nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, &ctx->registered_frames[reg_idx].in_map);
2160  if (nv_status != NV_ENC_SUCCESS) {
2161  av_frame_unref(nvenc_frame->in_ref);
2162  return nvenc_print_error(avctx, nv_status, "Error mapping an input resource");
2163  }
2164  }
2165 
2166  ctx->registered_frames[reg_idx].mapped += 1;
2167 
2168  nvenc_frame->reg_idx = reg_idx;
2169  nvenc_frame->input_surface = ctx->registered_frames[reg_idx].in_map.mappedResource;
2170  nvenc_frame->format = ctx->registered_frames[reg_idx].in_map.mappedBufferFmt;
2171  nvenc_frame->pitch = frame->linesize[0];
2172 
2173  return 0;
2174  } else {
2175  NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };
2176 
2177  lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;
2178  lockBufferParams.inputBuffer = nvenc_frame->input_surface;
2179 
2180  nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);
2181  if (nv_status != NV_ENC_SUCCESS) {
2182  return nvenc_print_error(avctx, nv_status, "Failed locking nvenc input buffer");
2183  }
2184 
2185  nvenc_frame->pitch = lockBufferParams.pitch;
2186  res = nvenc_copy_frame(avctx, nvenc_frame, &lockBufferParams, frame);
2187 
2188  nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, nvenc_frame->input_surface);
2189  if (nv_status != NV_ENC_SUCCESS) {
2190  return nvenc_print_error(avctx, nv_status, "Failed unlocking input buffer!");
2191  }
2192 
2193  return res;
2194  }
2195 }
2196 
2198  NV_ENC_PIC_PARAMS *params,
2199  NV_ENC_SEI_PAYLOAD *sei_data,
2200  int sei_count)
2201 {
2202  NvencContext *ctx = avctx->priv_data;
2203 
2204  switch (avctx->codec->id) {
2205  case AV_CODEC_ID_H264:
2206  params->codecPicParams.h264PicParams.sliceMode =
2207  ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
2208  params->codecPicParams.h264PicParams.sliceModeData =
2209  ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
2210  if (sei_count > 0) {
2211  params->codecPicParams.h264PicParams.seiPayloadArray = sei_data;
2212  params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count;
2213  }
2214 
2215  break;
2216  case AV_CODEC_ID_HEVC:
2217  params->codecPicParams.hevcPicParams.sliceMode =
2218  ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
2219  params->codecPicParams.hevcPicParams.sliceModeData =
2220  ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
2221  if (sei_count > 0) {
2222  params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data;
2223  params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = sei_count;
2224  }
2225 
2226  break;
2227 #if CONFIG_AV1_NVENC_ENCODER
2228  case AV_CODEC_ID_AV1:
2229  params->codecPicParams.av1PicParams.numTileColumns =
2230  ctx->encode_config.encodeCodecConfig.av1Config.numTileColumns;
2231  params->codecPicParams.av1PicParams.numTileRows =
2232  ctx->encode_config.encodeCodecConfig.av1Config.numTileRows;
2233  if (sei_count > 0) {
2234  params->codecPicParams.av1PicParams.obuPayloadArray = sei_data;
2235  params->codecPicParams.av1PicParams.obuPayloadArrayCnt = sei_count;
2236  }
2237 
2238  break;
2239 #endif
2240  }
2241 }
2242 
2243 static inline void timestamp_queue_enqueue(AVFifo *queue, int64_t timestamp)
2244 {
2245  av_fifo_write(queue, &timestamp, 1);
2246 }
2247 
2248 static inline int64_t timestamp_queue_dequeue(AVFifo *queue)
2249 {
2250  int64_t timestamp = AV_NOPTS_VALUE;
2251  // The following call might fail if the queue is empty.
2252  av_fifo_read(queue, &timestamp, 1);
2253 
2254  return timestamp;
2255 }
2256 
2258  NV_ENC_LOCK_BITSTREAM *params,
2259  AVPacket *pkt)
2260 {
2261  NvencContext *ctx = avctx->priv_data;
2262 
2263  pkt->pts = params->outputTimeStamp;
2264 
2267  pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list) -
2268 #if FF_API_TICKS_PER_FRAME
2269  FFMAX(avctx->ticks_per_frame, 1) *
2270 #endif
2271  FFMAX(ctx->encode_config.frameIntervalP - 1, 0);
2273  } else {
2274  pkt->dts = pkt->pts;
2275  }
2276 
2277  return 0;
2278 }
2279 
2280 static int nvenc_store_frame_data(AVCodecContext *avctx, NV_ENC_PIC_PARAMS *pic_params, const AVFrame *frame)
2281 {
2282  NvencContext *ctx = avctx->priv_data;
2283  int res = 0;
2284 
2285  int idx = ctx->frame_data_array_pos;
2286  NvencFrameData *frame_data = &ctx->frame_data_array[idx];
2287 
2288  // in case the encoder got reconfigured, there might be leftovers
2290 
2291  if (frame->opaque_ref && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
2294  return AVERROR(ENOMEM);
2295  }
2296 
2299 
2300 #if FF_API_REORDERED_OPAQUE
2302  frame_data->reordered_opaque = frame->reordered_opaque;
2304 #endif
2305 
2306  ctx->frame_data_array_pos = (ctx->frame_data_array_pos + 1) % ctx->frame_data_array_nb;
2307  pic_params->inputDuration = idx;
2308 
2309  return res;
2310 }
2311 
2312 static int nvenc_retrieve_frame_data(AVCodecContext *avctx, NV_ENC_LOCK_BITSTREAM *lock_params, AVPacket *pkt)
2313 {
2314  NvencContext *ctx = avctx->priv_data;
2315  int res = 0;
2316 
2317  int idx = lock_params->outputDuration;
2318  NvencFrameData *frame_data = &ctx->frame_data_array[idx];
2319 
2321 
2322 #if FF_API_REORDERED_OPAQUE
2324  avctx->reordered_opaque = frame_data->reordered_opaque;
2326 #endif
2327 
2328  if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
2332  }
2333 
2335 
2336  return res;
2337 }
2338 
2340 {
2341  NvencContext *ctx = avctx->priv_data;
2342  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2343  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2344 
2345  NV_ENC_LOCK_BITSTREAM lock_params = { 0 };
2346  NVENCSTATUS nv_status;
2347  int res = 0;
2348 
2349  enum AVPictureType pict_type;
2350 
2351  lock_params.version = NV_ENC_LOCK_BITSTREAM_VER;
2352 
2353  lock_params.doNotWait = 0;
2354  lock_params.outputBitstream = tmpoutsurf->output_surface;
2355 
2356  nv_status = p_nvenc->nvEncLockBitstream(ctx->nvencoder, &lock_params);
2357  if (nv_status != NV_ENC_SUCCESS) {
2358  res = nvenc_print_error(avctx, nv_status, "Failed locking bitstream buffer");
2359  goto error;
2360  }
2361 
2362  res = ff_get_encode_buffer(avctx, pkt, lock_params.bitstreamSizeInBytes, 0);
2363 
2364  if (res < 0) {
2365  p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
2366  goto error;
2367  }
2368 
2369  memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes);
2370 
2371  nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface);
2372  if (nv_status != NV_ENC_SUCCESS) {
2373  res = nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open");
2374  goto error;
2375  }
2376 
2377 
2378  if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) {
2379  ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1;
2380  if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) {
2381  nv_status = p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource);
2382  if (nv_status != NV_ENC_SUCCESS) {
2383  res = nvenc_print_error(avctx, nv_status, "Failed unmapping input resource");
2384  goto error;
2385  }
2386  } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) {
2387  res = AVERROR_BUG;
2388  goto error;
2389  }
2390 
2391  av_frame_unref(tmpoutsurf->in_ref);
2392 
2393  tmpoutsurf->input_surface = NULL;
2394  }
2395 
2396  switch (lock_params.pictureType) {
2397  case NV_ENC_PIC_TYPE_IDR:
2399  case NV_ENC_PIC_TYPE_I:
2400  pict_type = AV_PICTURE_TYPE_I;
2401  break;
2402  case NV_ENC_PIC_TYPE_P:
2403  pict_type = AV_PICTURE_TYPE_P;
2404  break;
2405  case NV_ENC_PIC_TYPE_B:
2406  pict_type = AV_PICTURE_TYPE_B;
2407  break;
2408  case NV_ENC_PIC_TYPE_BI:
2409  pict_type = AV_PICTURE_TYPE_BI;
2410  break;
2411  default:
2412  av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered, expect the output to be broken.\n");
2413  av_log(avctx, AV_LOG_ERROR, "Please report this error and include as much information on how to reproduce it as possible.\n");
2414  res = AVERROR_EXTERNAL;
2415  goto error;
2416  }
2417 
2419  (lock_params.frameAvgQP - 1) * FF_QP2LAMBDA, NULL, 0, pict_type);
2420 
2421  res = nvenc_set_timestamp(avctx, &lock_params, pkt);
2422  if (res < 0)
2423  goto error2;
2424 
2425  res = nvenc_retrieve_frame_data(avctx, &lock_params, pkt);
2426  if (res < 0)
2427  goto error2;
2428 
2429  return 0;
2430 
2431 error:
2432  timestamp_queue_dequeue(ctx->timestamp_list);
2433 
2434 error2:
2435  return res;
2436 }
2437 
2438 static int output_ready(AVCodecContext *avctx, int flush)
2439 {
2440  NvencContext *ctx = avctx->priv_data;
2441  int nb_ready, nb_pending;
2442 
2443  nb_ready = av_fifo_can_read(ctx->output_surface_ready_queue);
2444  nb_pending = av_fifo_can_read(ctx->output_surface_queue);
2445  if (flush)
2446  return nb_ready > 0;
2447  return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth);
2448 }
2449 
2451 {
2452  NvencContext *ctx = avctx->priv_data;
2453  int sei_count = 0;
2454  int i, res;
2455 
2457  void *a53_data = NULL;
2458  size_t a53_size = 0;
2459 
2460  if (ff_alloc_a53_sei(frame, 0, &a53_data, &a53_size) < 0) {
2461  av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2462  }
2463 
2464  if (a53_data) {
2465  void *tmp = av_fast_realloc(ctx->sei_data,
2466  &ctx->sei_data_size,
2467  (sei_count + 1) * sizeof(*ctx->sei_data));
2468  if (!tmp) {
2469  av_free(a53_data);
2470  res = AVERROR(ENOMEM);
2471  goto error;
2472  } else {
2473  ctx->sei_data = tmp;
2474  ctx->sei_data[sei_count].payloadSize = (uint32_t)a53_size;
2475  ctx->sei_data[sei_count].payload = (uint8_t*)a53_data;
2476 
2477 #if CONFIG_AV1_NVENC_ENCODER
2478  if (avctx->codec->id == AV_CODEC_ID_AV1)
2479  ctx->sei_data[sei_count].payloadType = AV1_METADATA_TYPE_ITUT_T35;
2480  else
2481 #endif
2482  ctx->sei_data[sei_count].payloadType = SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35;
2483 
2484  sei_count++;
2485  }
2486  }
2487  }
2488 
2490  void *tc_data = NULL;
2491  size_t tc_size = 0;
2492 
2493  if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, &tc_data, &tc_size) < 0) {
2494  av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n");
2495  }
2496 
2497  if (tc_data) {
2498  void *tmp = av_fast_realloc(ctx->sei_data,
2499  &ctx->sei_data_size,
2500  (sei_count + 1) * sizeof(*ctx->sei_data));
2501  if (!tmp) {
2502  av_free(tc_data);
2503  res = AVERROR(ENOMEM);
2504  goto error;
2505  } else {
2506  ctx->sei_data = tmp;
2507  ctx->sei_data[sei_count].payloadSize = (uint32_t)tc_size;
2508  ctx->sei_data[sei_count].payload = (uint8_t*)tc_data;
2509 
2510 #if CONFIG_AV1_NVENC_ENCODER
2511  if (avctx->codec->id == AV_CODEC_ID_AV1)
2512  ctx->sei_data[sei_count].payloadType = AV1_METADATA_TYPE_TIMECODE;
2513  else
2514 #endif
2515  ctx->sei_data[sei_count].payloadType = SEI_TYPE_TIME_CODE;
2516 
2517  sei_count++;
2518  }
2519  }
2520  }
2521 
2522  if (!ctx->udu_sei)
2523  return sei_count;
2524 
2525  for (i = 0; i < frame->nb_side_data; i++) {
2526  AVFrameSideData *side_data = frame->side_data[i];
2527  void *tmp;
2528 
2529  if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
2530  continue;
2531 
2532  tmp = av_fast_realloc(ctx->sei_data,
2533  &ctx->sei_data_size,
2534  (sei_count + 1) * sizeof(*ctx->sei_data));
2535  if (!tmp) {
2536  res = AVERROR(ENOMEM);
2537  goto error;
2538  } else {
2539  ctx->sei_data = tmp;
2540  ctx->sei_data[sei_count].payloadSize = side_data->size;
2541  ctx->sei_data[sei_count].payloadType = SEI_TYPE_USER_DATA_UNREGISTERED;
2542  ctx->sei_data[sei_count].payload = av_memdup(side_data->data, side_data->size);
2543 
2544  if (!ctx->sei_data[sei_count].payload) {
2545  res = AVERROR(ENOMEM);
2546  goto error;
2547  }
2548 
2549  sei_count++;
2550  }
2551  }
2552 
2553  return sei_count;
2554 
2555 error:
2556  for (i = 0; i < sei_count; i++)
2557  av_freep(&(ctx->sei_data[i].payload));
2558 
2559  return res;
2560 }
2561 
2562 static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
2563 {
2564  NvencContext *ctx = avctx->priv_data;
2565  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
2566  NVENCSTATUS ret;
2567 
2568  NV_ENC_RECONFIGURE_PARAMS params = { 0 };
2569  int needs_reconfig = 0;
2570  int needs_encode_config = 0;
2571  int reconfig_bitrate = 0, reconfig_dar = 0;
2572  int dw, dh;
2573 
2574  params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
2575  params.reInitEncodeParams = ctx->init_encode_params;
2576 
2577  compute_dar(avctx, &dw, &dh);
2578  if (dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight) {
2579  av_log(avctx, AV_LOG_VERBOSE,
2580  "aspect ratio change (DAR): %d:%d -> %d:%d\n",
2581  ctx->init_encode_params.darWidth,
2582  ctx->init_encode_params.darHeight, dw, dh);
2583 
2584  params.reInitEncodeParams.darHeight = dh;
2585  params.reInitEncodeParams.darWidth = dw;
2586 
2587  needs_reconfig = 1;
2588  reconfig_dar = 1;
2589  }
2590 
2591  if (ctx->rc != NV_ENC_PARAMS_RC_CONSTQP && ctx->support_dyn_bitrate) {
2592  if (avctx->bit_rate > 0 && params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate != avctx->bit_rate) {
2593  av_log(avctx, AV_LOG_VERBOSE,
2594  "avg bitrate change: %d -> %d\n",
2595  params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate,
2596  (uint32_t)avctx->bit_rate);
2597 
2598  params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate = avctx->bit_rate;
2599  reconfig_bitrate = 1;
2600  }
2601 
2602  if (avctx->rc_max_rate > 0 && ctx->encode_config.rcParams.maxBitRate != avctx->rc_max_rate) {
2603  av_log(avctx, AV_LOG_VERBOSE,
2604  "max bitrate change: %d -> %d\n",
2605  params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate,
2606  (uint32_t)avctx->rc_max_rate);
2607 
2608  params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate = avctx->rc_max_rate;
2609  reconfig_bitrate = 1;
2610  }
2611 
2612  if (avctx->rc_buffer_size > 0 && ctx->encode_config.rcParams.vbvBufferSize != avctx->rc_buffer_size) {
2613  av_log(avctx, AV_LOG_VERBOSE,
2614  "vbv buffer size change: %d -> %d\n",
2615  params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize,
2616  avctx->rc_buffer_size);
2617 
2618  params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize = avctx->rc_buffer_size;
2619  reconfig_bitrate = 1;
2620  }
2621 
2622  if (reconfig_bitrate) {
2623  params.resetEncoder = 1;
2624  params.forceIDR = 1;
2625 
2626  needs_encode_config = 1;
2627  needs_reconfig = 1;
2628  }
2629  }
2630 
2631  if (!needs_encode_config)
2632  params.reInitEncodeParams.encodeConfig = NULL;
2633 
2634  if (needs_reconfig) {
2635  ret = p_nvenc->nvEncReconfigureEncoder(ctx->nvencoder, &params);
2636  if (ret != NV_ENC_SUCCESS) {
2637  nvenc_print_error(avctx, ret, "failed to reconfigure nvenc");
2638  } else {
2639  if (reconfig_dar) {
2640  ctx->init_encode_params.darHeight = dh;
2641  ctx->init_encode_params.darWidth = dw;
2642  }
2643 
2644  if (reconfig_bitrate) {
2645  ctx->encode_config.rcParams.averageBitRate = params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate;
2646  ctx->encode_config.rcParams.maxBitRate = params.reInitEncodeParams.encodeConfig->rcParams.maxBitRate;
2647  ctx->encode_config.rcParams.vbvBufferSize = params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize;
2648  }
2649 
2650  }
2651  }
2652 }
2653 
2654 static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
2655 {
2656  NVENCSTATUS nv_status;
2657  NvencSurface *tmp_out_surf, *in_surf;
2658  int res, res2;
2659  int sei_count = 0;
2660  int i;
2661 
2662  NvencContext *ctx = avctx->priv_data;
2663  NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
2664  NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
2665 
2666  NV_ENC_PIC_PARAMS pic_params = { 0 };
2667  pic_params.version = NV_ENC_PIC_PARAMS_VER;
2668 
2669  if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2670  return AVERROR(EINVAL);
2671 
2672  if (frame && frame->buf[0]) {
2673  in_surf = get_free_frame(ctx);
2674  if (!in_surf)
2675  return AVERROR(EAGAIN);
2676 
2677  res = nvenc_push_context(avctx);
2678  if (res < 0)
2679  return res;
2680 
2681  reconfig_encoder(avctx, frame);
2682 
2683  res = nvenc_upload_frame(avctx, frame, in_surf);
2684 
2685  res2 = nvenc_pop_context(avctx);
2686  if (res2 < 0)
2687  return res2;
2688 
2689  if (res)
2690  return res;
2691 
2692  pic_params.inputBuffer = in_surf->input_surface;
2693  pic_params.bufferFmt = in_surf->format;
2694  pic_params.inputWidth = in_surf->width;
2695  pic_params.inputHeight = in_surf->height;
2696  pic_params.inputPitch = in_surf->pitch;
2697  pic_params.outputBitstream = in_surf->output_surface;
2698 
2699  if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
2701  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;
2702  else
2703  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;
2704  } else {
2705  pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
2706  }
2707 
2708  if (ctx->forced_idr >= 0 && frame->pict_type == AV_PICTURE_TYPE_I) {
2709  pic_params.encodePicFlags =
2710  ctx->forced_idr ? NV_ENC_PIC_FLAG_FORCEIDR : NV_ENC_PIC_FLAG_FORCEINTRA;
2711  } else {
2712  pic_params.encodePicFlags = 0;
2713  }
2714 
2715  pic_params.inputTimeStamp = frame->pts;
2716 
2717  if (ctx->extra_sei) {
2718  res = prepare_sei_data_array(avctx, frame);
2719  if (res < 0)
2720  return res;
2721  sei_count = res;
2722  }
2723 
2724  res = nvenc_store_frame_data(avctx, &pic_params, frame);
2725  if (res < 0)
2726  return res;
2727 
2728  nvenc_codec_specific_pic_params(avctx, &pic_params, ctx->sei_data, sei_count);
2729  } else {
2730  pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
2731  }
2732 
2733  res = nvenc_push_context(avctx);
2734  if (res < 0)
2735  return res;
2736 
2737  nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
2738 
2739  for (i = 0; i < sei_count; i++)
2740  av_freep(&(ctx->sei_data[i].payload));
2741 
2742  res = nvenc_pop_context(avctx);
2743  if (res < 0)
2744  return res;
2745 
2746  if (nv_status != NV_ENC_SUCCESS &&
2747  nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
2748  return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
2749 
2750  if (frame && frame->buf[0]) {
2751  av_fifo_write(ctx->output_surface_queue, &in_surf, 1);
2752 
2754  timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);
2755  }
2756 
2757  /* all the pending buffers are now ready for output */
2758  if (nv_status == NV_ENC_SUCCESS) {
2759  while (av_fifo_read(ctx->output_surface_queue, &tmp_out_surf, 1) >= 0)
2760  av_fifo_write(ctx->output_surface_ready_queue, &tmp_out_surf, 1);
2761  }
2762 
2763  return 0;
2764 }
2765 
2767 {
2768  NvencSurface *tmp_out_surf;
2769  int res, res2;
2770 
2771  NvencContext *ctx = avctx->priv_data;
2772 
2773  AVFrame *frame = ctx->frame;
2774 
2775  if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder)
2776  return AVERROR(EINVAL);
2777 
2778  if (!frame->buf[0]) {
2779  res = ff_encode_get_frame(avctx, frame);
2780  if (res < 0 && res != AVERROR_EOF)
2781  return res;
2782  }
2783 
2784  res = nvenc_send_frame(avctx, frame);
2785  if (res < 0) {
2786  if (res != AVERROR(EAGAIN))
2787  return res;
2788  } else
2790 
2791  if (output_ready(avctx, avctx->internal->draining)) {
2792  av_fifo_read(ctx->output_surface_ready_queue, &tmp_out_surf, 1);
2793 
2794  res = nvenc_push_context(avctx);
2795  if (res < 0)
2796  return res;
2797 
2798  res = process_output_surface(avctx, pkt, tmp_out_surf);
2799 
2800  res2 = nvenc_pop_context(avctx);
2801  if (res2 < 0)
2802  return res2;
2803 
2804  if (res)
2805  return res;
2806 
2807  av_fifo_write(ctx->unused_surface_queue, &tmp_out_surf, 1);
2808  } else if (avctx->internal->draining) {
2809  return AVERROR_EOF;
2810  } else {
2811  return AVERROR(EAGAIN);
2812  }
2813 
2814  return 0;
2815 }
2816 
2818 {
2819  NvencContext *ctx = avctx->priv_data;
2820 
2821  nvenc_send_frame(avctx, NULL);
2822  av_fifo_reset2(ctx->timestamp_list);
2823 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
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:186
PRESET_ALIAS
#define PRESET_ALIAS(alias, name,...)
Definition: nvenc.c:184
AV_PIX_FMT_CUDA
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition: pixfmt.h:253
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:180
level
uint8_t level
Definition: svq3.c:204
av_clip
#define av_clip
Definition: common.h:96
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:1029
P3
#define P3
Definition: hevcdsp_template.c:1497
NV_ENC_HEVC_PROFILE_MAIN_10
@ NV_ENC_HEVC_PROFILE_MAIN_10
Definition: nvenc.h:158
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:824
AV1_METADATA_TYPE_ITUT_T35
@ AV1_METADATA_TYPE_ITUT_T35
Definition: av1.h:47
AV_PIX_FMT_BGR32
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:443
GUIDTuple
Definition: nvenc.c:179
NONE
@ NONE
Definition: af_afade.c:61
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:807
GUIDTuple::flags
int flags
Definition: nvenc.c:181
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2964
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
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:603
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_FRAME_DATA_A53_CC
@ AV_FRAME_DATA_A53_CC
ATSC A53 Part 4 Closed Captions.
Definition: frame.h:59
AV_PROFILE_H264_MAIN
#define AV_PROFILE_H264_MAIN
Definition: defs.h:111
AVFrame::nb_side_data
int nb_side_data
Definition: frame.h:611
nvenc_push_context
static int nvenc_push_context(AVCodecContext *avctx)
Definition: nvenc.c:349
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:209
AVPictureType
AVPictureType
Definition: avutil.h:277
output_ready
static int output_ready(AVCodecContext *avctx, int flush)
Definition: nvenc.c:2438
NvencContext
Definition: nvenc.h:182
AVCodecContext::codec_descriptor
const struct AVCodecDescriptor * codec_descriptor
AVCodecDescriptor.
Definition: avcodec.h:1824
AV_FRAME_DATA_S12M_TIMECODE
@ AV_FRAME_DATA_S12M_TIMECODE
Timecode which conforms to SMPTE ST 12-1.
Definition: frame.h:152
AV_PROFILE_HEVC_MAIN
#define AV_PROFILE_HEVC_MAIN
Definition: defs.h:158
NvencSurface::in_ref
AVFrame * in_ref
Definition: nvenc.h:94
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
AVFrame::opaque
void * opaque
Frame owner's private data.
Definition: frame.h:501
nvenc_store_frame_data
static int nvenc_store_frame_data(AVCodecContext *avctx, NV_ENC_PIC_PARAMS *pic_params, const AVFrame *frame)
Definition: nvenc.c:2280
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:452
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:1022
nvenc_set_timestamp
static int nvenc_set_timestamp(AVCodecContext *avctx, NV_ENC_LOCK_BITSTREAM *params, AVPacket *pkt)
Definition: nvenc.c:2257
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:673
P1
#define P1
Definition: cavsdsp.c:37
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:491
encode.h
AVCodecContext::b_quant_offset
float b_quant_offset
qscale offset between IP and B-frames
Definition: avcodec.h:736
NvencFrameData
Definition: nvenc.h:104
NV_ENC_HEVC_PROFILE_REXT
@ NV_ENC_HEVC_PROFILE_REXT
Definition: nvenc.h:159
reconfig_encoder
static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2562
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
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:600
ff_nvenc_pix_fmts
enum AVPixelFormat ff_nvenc_pix_fmts[]
Definition: nvenc.c:56
set_constqp
static av_cold void set_constqp(AVCodecContext *avctx)
Definition: nvenc.c:793
NvencSurface
Definition: nvenc.h:91
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:509
mathematics.h
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:649
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
nvenc_print_error
static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err, const char *error_string)
Definition: nvenc.c:159
BD
#define BD
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
AVCodecContext::qmax
int qmax
maximum quantizer
Definition: avcodec.h:1255
nverr
NVENCSTATUS nverr
Definition: nvenc.c:112
set_lossless
static av_cold void set_lossless(AVCodecContext *avctx)
Definition: nvenc.c:898
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:590
PRESET
#define PRESET(name,...)
Definition: nvenc.c:187
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:546
ff_nvenc_encode_flush
av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
Definition: nvenc.c:2817
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:334
nvenc.h
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:641
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:302
AV_HWDEVICE_TYPE_CUDA
@ AV_HWDEVICE_TYPE_CUDA
Definition: hwcontext.h:30
AVFrame::opaque_ref
AVBufferRef * opaque_ref
Frame owner's private data.
Definition: frame.h:768
compute_dar
static void compute_dar(AVCodecContext *avctx, int *dw, int *dh)
Definition: nvenc.c:1503
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1803
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:605
nvenc_upload_frame
static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, NvencSurface *nvenc_frame)
Definition: nvenc.c:2135
NvencDynLoadFunctions::nvenc_device_count
int nvenc_device_count
Definition: nvenc.h:122
AV_CODEC_FLAG_COPY_OPAQUE
#define AV_CODEC_FLAG_COPY_OPAQUE
Definition: avcodec.h:295
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:753
set_vbr
static av_cold void set_vbr(AVCodecContext *avctx)
Definition: nvenc.c:831
nvenc_map_error
static int nvenc_map_error(NVENCSTATUS err, const char **desc)
Definition: nvenc.c:144
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:450
AVPacket::opaque_ref
AVBufferRef * opaque_ref
AVBufferRef for free use by the API user.
Definition: packet.h:527
nvenc_check_cap
static int nvenc_check_cap(AVCodecContext *avctx, NV_ENC_CAPS cap)
Definition: nvenc.c:434
presets
static const Preset presets[]
Definition: vf_pseudocolor.c:286
nvenc_errors
static const struct @121 nvenc_errors[]
fail
#define fail()
Definition: checkasm.h:138
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
dummy
int dummy
Definition: motion.c:66
NvencSurface::format
NV_ENC_BUFFER_FORMAT format
Definition: nvenc.h:101
NV_ENC_H264_PROFILE_HIGH
@ NV_ENC_H264_PROFILE_HIGH
Definition: nvenc.h:152
AVCodecContext::refs
int refs
number of reference frames
Definition: avcodec.h:1001
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:189
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:521
val
static double val(void *priv, double ch)
Definition: aeval.c:78
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:2017
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
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
IS_GBRP
#define IS_GBRP(pix_fmt)
Definition: nvenc.c:108
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:243
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:326
nvenc_check_capabilities
static int nvenc_check_capabilities(AVCodecContext *avctx)
Definition: nvenc.c:451
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:88
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:1015
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:180
AVFrameSideData::size
size_t size
Definition: frame.h:249
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
NVENC_ONE_PASS
@ NVENC_ONE_PASS
Definition: nvenc.h:165
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:543
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:744
AVFrame::reordered_opaque
attribute_deprecated int64_t reordered_opaque
reordered opaque 64 bits (generally an integer or a double precision float PTS but can be anything).
Definition: frame.h:561
ff_nvenc_encode_init
av_cold int ff_nvenc_encode_init(AVCodecContext *avctx)
Definition: nvenc.c:1954
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:495
width
#define width
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:507
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:481
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1233
AV_PIX_FMT_0BGR32
#define AV_PIX_FMT_0BGR32
Definition: pixfmt.h:446
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
NvencDynLoadFunctions
Definition: nvenc.h:116
NVENC_DEPRECATED_PRESET
@ NVENC_DEPRECATED_PRESET
Definition: nvenc.h:168
ctx
AVFormatContext * ctx
Definition: movenc.c:48
SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
@ SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
Definition: sei.h:34
nvenc_setup_extradata
static av_cold int nvenc_setup_extradata(AVCodecContext *avctx)
Definition: nvenc.c:1835
timestamp_queue_enqueue
static void timestamp_queue_enqueue(AVFifo *queue, int64_t timestamp)
Definition: nvenc.c:2243
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:1284
timestamp_queue_dequeue
static int64_t timestamp_queue_dequeue(AVFifo *queue)
Definition: nvenc.c:2248
AVPacket::opaque
void * opaque
for some private data of the user
Definition: packet.h:516
NvencDynLoadFunctions::nvenc_dl
NvencFunctions * nvenc_dl
Definition: nvenc.h:119
AVCPBProperties
This structure describes the bitrate properties of an encoded bitstream.
Definition: defs.h:269
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
NvencSurface::pitch
int pitch
Definition: nvenc.h:98
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
frame
static AVFrame * frame
Definition: demux_decode.c:54
NvencSurface::input_surface
NV_ENC_INPUT_PTR input_surface
Definition: nvenc.h:93
AVCodecDescriptor::props
int props
Codec properties, a combination of AV_CODEC_PROP_* flags.
Definition: codec_desc.h:54
if
if(ret)
Definition: filter_design.txt:179
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1269
NVENC_CAP
#define NVENC_CAP
Definition: nvenc.c:46
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:487
IS_10BIT
#define IS_10BIT(pix_fmt)
Definition: nvenc.c:88
nvenc_setup_rate_control
static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)
Definition: nvenc.c:990
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
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:95
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:1039
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
SEI_TYPE_TIME_CODE
@ SEI_TYPE_TIME_CODE
Definition: sei.h:95
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:283
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:476
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:491
ff_nvenc_encode_close
av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
Definition: nvenc.c:1869
FrameData::duration
int64_t duration
Definition: librav1e.c:59
NVENC_RGB_MODE_DISABLED
@ NVENC_RGB_MODE_DISABLED
Definition: nvenc.h:177
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
FrameData::frame_opaque
void * frame_opaque
Definition: librav1e.c:64
ANY_DEVICE
@ ANY_DEVICE
Definition: nvenc.h:173
NvencDynLoadFunctions::cuda_dl
CudaFunctions * cuda_dl
Definition: nvenc.h:118
nvenc_setup_h264_config
static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
Definition: nvenc.c:1148
AVPixFmtDescriptor::flags
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:94
AV_PROFILE_HEVC_MAIN_10
#define AV_PROFILE_HEVC_MAIN_10
Definition: defs.h:159
AV_PROFILE_HEVC_REXT
#define AV_PROFILE_HEVC_REXT
Definition: defs.h:161
AV_FRAME_DATA_SEI_UNREGISTERED
@ AV_FRAME_DATA_SEI_UNREGISTERED
User data unregistered metadata associated with a video frame.
Definition: frame.h:178
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:563
av_fifo_reset2
void av_fifo_reset2(AVFifo *f)
Definition: fifo.c:280
AV_PIX_FMT_X2BGR10
#define AV_PIX_FMT_X2BGR10
Definition: pixfmt.h:527
AVCUDADeviceContext::stream
CUstream stream
Definition: hwcontext_cuda.h:44
desc
const char * desc
Definition: nvenc.c:114
nvenc_pop_context
static int nvenc_pop_context(AVCodecContext *avctx)
Definition: nvenc.c:360
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:442
HW_CONFIG_ENCODER_DEVICE
#define HW_CONFIG_ENCODER_DEVICE(format, device_type_)
Definition: hwconfig.h:93
AVFifo
Definition: fifo.c:35
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:643
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:361
nvenc_check_codec_support
static int nvenc_check_codec_support(AVCodecContext *avctx)
Definition: nvenc.c:398
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:136
AV_CODEC_PROP_REORDER
#define AV_CODEC_PROP_REORDER
Codec supports frame reordering.
Definition: codec_desc.h:92
ff_nvenc_hw_configs
const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[]
Definition: nvenc.c:78
MAX_REGISTERED_FRAMES
#define MAX_REGISTERED_FRAMES
Definition: nvenc.h:41
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:1019
nvenc_alloc_surface
static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx)
Definition: nvenc.c:1734
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVFrameSideData::data
uint8_t * data
Definition: frame.h:248
nvenc_check_device
static av_cold int nvenc_check_device(AVCodecContext *avctx, int idx)
Definition: nvenc.c:602
nvenc_register_frame
static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2081
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:427
AVCodecHWConfigInternal
Definition: hwconfig.h:25
frame_data
FrameData * frame_data(AVFrame *frame)
Get our axiliary frame data attached to the frame, allocating it if needed.
Definition: ffmpeg.c:429
NVENC_TWO_PASSES
@ NVENC_TWO_PASSES
Definition: nvenc.h:166
ff_nvenc_receive_packet
int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: nvenc.c:2766
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
height
#define height
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:441
NV_ENC_H264_PROFILE_BASELINE
@ NV_ENC_H264_PROFILE_BASELINE
Definition: nvenc.h:150
nvenc_override_rate_control
static void nvenc_override_rate_control(AVCodecContext *avctx)
Definition: nvenc.c:912
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:497
AV_PIX_FMT_D3D11
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:333
FrameData::frame_opaque_ref
AVBufferRef * frame_opaque_ref
Definition: librav1e.c:65
AVCPBProperties::avg_bitrate
int64_t avg_bitrate
Average bitrate of the stream, in bits per second.
Definition: defs.h:284
NVENC_LOSSLESS
@ NVENC_LOSSLESS
Definition: nvenc.h:164
NV_ENC_H264_PROFILE_MAIN
@ NV_ENC_H264_PROFILE_MAIN
Definition: nvenc.h:151
get_free_frame
static NvencSurface * get_free_frame(NvencContext *ctx)
Definition: nvenc.c:2006
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
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:729
AVCodec::id
enum AVCodecID id
Definition: codec.h:201
nvenc_open_session
static av_cold int nvenc_open_session(AVCodecContext *avctx)
Definition: nvenc.c:372
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:96
LIST_DEVICES
@ LIST_DEVICES
Definition: nvenc.h:172
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:484
FAST
@ FAST
Definition: vf_guided.c:32
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:542
process_output_surface
static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSurface *tmpoutsurf)
Definition: nvenc.c:2339
nvenc_load_libraries
static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
Definition: nvenc.c:305
nvenc_recalc_surfaces
static av_cold int nvenc_recalc_surfaces(AVCodecContext *avctx)
Definition: nvenc.c:947
AVD3D11VADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_d3d11va.h:45
IS_RGB
#define IS_RGB(pix_fmt)
Definition: nvenc.c:95
AVCPBProperties::max_bitrate
int64_t max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition: defs.h:274
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:590
prepare_sei_data_array
static int prepare_sei_data_array(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2450
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:622
AV_PIX_FMT_X2RGB10
#define AV_PIX_FMT_X2RGB10
Definition: pixfmt.h:526
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:254
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:1981
AVFrame::side_data
AVFrameSideData ** side_data
Definition: frame.h:610
IS_YUV444
#define IS_YUV444(pix_fmt)
Definition: nvenc.c:102
P2
#define P2
Definition: cavsdsp.c:36
IS_CBR
#define IS_CBR(rc)
Definition: nvenc.c:49
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
AVCodecContext::height
int height
Definition: avcodec.h:621
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:658
CHECK_CU
#define CHECK_CU(x)
Definition: nvenc.c:44
nvenc_map_buffer_format
static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt)
Definition: nvenc.c:1703
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:520
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:1940
NvencSurface::width
int width
Definition: nvenc.h:96
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
AV_PROFILE_H264_HIGH_444_PREDICTIVE
#define AV_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: defs.h:121
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:174
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:1536
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
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
averr
int averr
Definition: nvenc.c:113
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:445
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:290
NV_ENC_H264_PROFILE_HIGH_444P
@ NV_ENC_H264_PROFILE_HIGH_444P
Definition: nvenc.h:153
cuda_check.h
atsc_a53.h
AV_PROFILE_H264_BASELINE
#define AV_PROFILE_H264_BASELINE
Definition: defs.h:109
NV_ENC_HEVC_PROFILE_MAIN
@ NV_ENC_HEVC_PROFILE_MAIN
Definition: nvenc.h:157
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
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:2197
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:752
AVCodecContext
main external API structure.
Definition: avcodec.h:441
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:113
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:281
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:105
NvencSurface::height
int height
Definition: nvenc.h:97
SEI_TYPE_USER_DATA_UNREGISTERED
@ SEI_TYPE_USER_DATA_UNREGISTERED
Definition: sei.h:35
av_image_copy2
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition: imgutils.h:184
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1248
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1596
nvenc_setup_surfaces
static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx)
Definition: nvenc.c:1790
NVENC_LOWLATENCY
@ NVENC_LOWLATENCY
Definition: nvenc.h:163
AVCodecContext::i_quant_offset
float i_quant_offset
qscale offset between P and I-frames
Definition: avcodec.h:760
AVFrameSideData::type
enum AVFrameSideDataType type
Definition: frame.h:247
NvencSurface::output_surface
NV_ENC_OUTPUT_PTR output_surface
Definition: nvenc.h:100
AVCodecContext::ticks_per_frame
attribute_deprecated int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:579
nvenc_find_free_reg_resource
static int nvenc_find_free_reg_resource(AVCodecContext *avctx)
Definition: nvenc.c:2047
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
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:518
AVCodecInternal::draining
int draining
checks API usage: after codec draining, flush is required to resume operation
Definition: internal.h:129
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
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:121
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:367
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:720
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:209
packet_internal.h
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:246
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1055
DEFAULT
#define DEFAULT
Definition: avdct.c:28
AVPacket
This structure stores compressed data.
Definition: packet.h:468
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:468
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AV_PICTURE_TYPE_BI
@ AV_PICTURE_TYPE_BI
BI type.
Definition: avutil.h:285
nvenc_setup_device
static av_cold int nvenc_setup_device(AVCodecContext *avctx)
Definition: nvenc.c:677
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:621
AV1_METADATA_TYPE_TIMECODE
@ AV1_METADATA_TYPE_TIMECODE
Definition: av1.h:48
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
hwcontext.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:385
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
ff_encode_add_cpb_side_data
AVCPBProperties * ff_encode_add_cpb_side_data(AVCodecContext *avctx)
Add a CPB properties side data to an encoding context.
Definition: encode.c:870
nvenc_setup_codec_config
static av_cold int nvenc_setup_codec_config(AVCodecContext *avctx)
Definition: nvenc.c:1486
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:227
AV_PROFILE_AV1_MAIN
#define AV_PROFILE_AV1_MAIN
Definition: defs.h:167
codec_desc.h
int
int
Definition: ffmpeg_filter.c:368
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:822
nvenc_setup_hevc_config
static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
Definition: nvenc.c:1279
RC_MODE_DEPRECATED
#define RC_MODE_DEPRECATED
Definition: nvenc.h:42
nvenc_send_frame
static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:2654
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:2884
nvenc_retrieve_frame_data
static int nvenc_retrieve_frame_data(AVCodecContext *avctx, NV_ENC_LOCK_BITSTREAM *lock_params, AVPacket *pkt)
Definition: nvenc.c:2312