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